[PATCH 06/13] soc/fsl/qbman_portals: add APIs to retrieve the probing status

2019-03-29 Thread laurentiu . tudor
From: Laurentiu Tudor 

Add a couple of new APIs to check the probing status of the required
cpu bound qman and bman portals:
 'int bman_portals_probed()' and 'int qman_portals_probed()'.
They return the following values.
 *  1 if qman/bman portals were all probed correctly
 *  0 if qman/bman portals were not yet probed
 * -1 if probing of qman/bman portals failed
Portals are considered successful probed if no error occurred during
the probing of any of the portals and if enough portals were probed
to have one available for each cpu.
The error handling paths were slightly rearranged in order to fit this
new functionality without being too intrusive.
Drivers that use qman/bman portal driver services are required to use
these APIs before calling any functions exported by these drivers or
otherwise they will crash the kernel.
First user will be the dpaa1 ethernet driver, coming in a subsequent
patch.

Signed-off-by: Laurentiu Tudor 
---
 drivers/soc/fsl/qbman/bman_portal.c | 22 ++
 drivers/soc/fsl/qbman/qman_portal.c | 23 +++
 include/soc/fsl/bman.h  |  8 
 include/soc/fsl/qman.h  |  9 +
 4 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/fsl/qbman/bman_portal.c 
b/drivers/soc/fsl/qbman/bman_portal.c
index 2c95cf59f3e7..7819bc29936d 100644
--- a/drivers/soc/fsl/qbman/bman_portal.c
+++ b/drivers/soc/fsl/qbman/bman_portal.c
@@ -32,6 +32,7 @@
 
 static struct bman_portal *affine_bportals[NR_CPUS];
 static struct cpumask portal_cpus;
+static int __bman_portals_probed;
 /* protect bman global registers and global data shared among portals */
 static DEFINE_SPINLOCK(bman_lock);
 
@@ -87,6 +88,12 @@ static int bman_online_cpu(unsigned int cpu)
return 0;
 }
 
+int bman_portals_probed(void)
+{
+   return __bman_portals_probed;
+}
+EXPORT_SYMBOL_GPL(bman_portals_probed);
+
 static int bman_portal_probe(struct platform_device *pdev)
 {
struct device *dev = &pdev->dev;
@@ -104,8 +111,10 @@ static int bman_portal_probe(struct platform_device *pdev)
}
 
pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
-   if (!pcfg)
+   if (!pcfg) {
+   __bman_portals_probed = -1;
return -ENOMEM;
+   }
 
pcfg->dev = dev;
 
@@ -113,14 +122,14 @@ static int bman_portal_probe(struct platform_device *pdev)
 DPAA_PORTAL_CE);
if (!addr_phys[0]) {
dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
-   return -ENXIO;
+   goto err_ioremap1;
}
 
addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
 DPAA_PORTAL_CI);
if (!addr_phys[1]) {
dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
-   return -ENXIO;
+   goto err_ioremap1;
}
 
pcfg->cpu = -1;
@@ -128,7 +137,7 @@ static int bman_portal_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_err(dev, "Can't get %pOF IRQ'\n", node);
-   return -ENXIO;
+   goto err_ioremap1;
}
pcfg->irq = irq;
 
@@ -156,6 +165,9 @@ static int bman_portal_probe(struct platform_device *pdev)
}
 
cpumask_set_cpu(cpu, &portal_cpus);
+   if (!__bman_portals_probed &&
+   cpumask_weight(&portal_cpus) == num_online_cpus())
+   __bman_portals_probed = 1;
spin_unlock(&bman_lock);
pcfg->cpu = cpu;
 
@@ -175,6 +187,8 @@ static int bman_portal_probe(struct platform_device *pdev)
 err_ioremap2:
memunmap(pcfg->addr_virt_ce);
 err_ioremap1:
+__bman_portals_probed = -1;
+
return -ENXIO;
 }
 
diff --git a/drivers/soc/fsl/qbman/qman_portal.c 
b/drivers/soc/fsl/qbman/qman_portal.c
index bce56da2b01f..11ba6c77c0d6 100644
--- a/drivers/soc/fsl/qbman/qman_portal.c
+++ b/drivers/soc/fsl/qbman/qman_portal.c
@@ -39,6 +39,7 @@ EXPORT_SYMBOL(qman_dma_portal);
 #define CONFIG_FSL_DPA_PIRQ_FAST  1
 
 static struct cpumask portal_cpus;
+static int __qman_portals_probed;
 /* protect qman global registers and global data shared among portals */
 static DEFINE_SPINLOCK(qman_lock);
 
@@ -221,6 +222,12 @@ static int qman_online_cpu(unsigned int cpu)
return 0;
 }
 
+int qman_portals_probed(void)
+{
+   return __qman_portals_probed;
+}
+EXPORT_SYMBOL_GPL(qman_portals_probed);
+
 static int qman_portal_probe(struct platform_device *pdev)
 {
struct device *dev = &pdev->dev;
@@ -240,8 +247,10 @@ static int qman_portal_probe(struct platform_device *pdev)
}
 
pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
-   if (!pcfg)
+   if (!pcfg) {
+   __qman_portals_probed = -1;
return -ENOMEM;
+   }
 
pcfg->dev = dev;
 
@@ -249,19 +258,20 @@ static int qman_portal_probe(stru

Re: [PATCH 06/13] soc/fsl/qbman_portals: add APIs to retrieve the probing status

2019-04-01 Thread Li Yang
On Fri, Mar 29, 2019 at 9:03 AM  wrote:
>
> From: Laurentiu Tudor 
>
> Add a couple of new APIs to check the probing status of the required
> cpu bound qman and bman portals:
>  'int bman_portals_probed()' and 'int qman_portals_probed()'.
> They return the following values.
>  *  1 if qman/bman portals were all probed correctly
>  *  0 if qman/bman portals were not yet probed
>  * -1 if probing of qman/bman portals failed
> Portals are considered successful probed if no error occurred during
> the probing of any of the portals and if enough portals were probed
> to have one available for each cpu.
> The error handling paths were slightly rearranged in order to fit this
> new functionality without being too intrusive.
> Drivers that use qman/bman portal driver services are required to use
> these APIs before calling any functions exported by these drivers or
> otherwise they will crash the kernel.
> First user will be the dpaa1 ethernet driver, coming in a subsequent
> patch.
>
> Signed-off-by: Laurentiu Tudor 
> ---
>  drivers/soc/fsl/qbman/bman_portal.c | 22 ++
>  drivers/soc/fsl/qbman/qman_portal.c | 23 +++
>  include/soc/fsl/bman.h  |  8 
>  include/soc/fsl/qman.h  |  9 +
>  4 files changed, 54 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/soc/fsl/qbman/bman_portal.c 
> b/drivers/soc/fsl/qbman/bman_portal.c
> index 2c95cf59f3e7..7819bc29936d 100644
> --- a/drivers/soc/fsl/qbman/bman_portal.c
> +++ b/drivers/soc/fsl/qbman/bman_portal.c
> @@ -32,6 +32,7 @@
>
>  static struct bman_portal *affine_bportals[NR_CPUS];
>  static struct cpumask portal_cpus;
> +static int __bman_portals_probed;
>  /* protect bman global registers and global data shared among portals */
>  static DEFINE_SPINLOCK(bman_lock);
>
> @@ -87,6 +88,12 @@ static int bman_online_cpu(unsigned int cpu)
> return 0;
>  }
>
> +int bman_portals_probed(void)
> +{
> +   return __bman_portals_probed;
> +}
> +EXPORT_SYMBOL_GPL(bman_portals_probed);
> +
>  static int bman_portal_probe(struct platform_device *pdev)
>  {
> struct device *dev = &pdev->dev;
> @@ -104,8 +111,10 @@ static int bman_portal_probe(struct platform_device 
> *pdev)
> }
>
> pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL);
> -   if (!pcfg)
> +   if (!pcfg) {
> +   __bman_portals_probed = -1;
> return -ENOMEM;
> +   }
>
> pcfg->dev = dev;
>
> @@ -113,14 +122,14 @@ static int bman_portal_probe(struct platform_device 
> *pdev)
>  DPAA_PORTAL_CE);
> if (!addr_phys[0]) {
> dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
> -   return -ENXIO;
> +   goto err_ioremap1;
> }
>
> addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
>  DPAA_PORTAL_CI);
> if (!addr_phys[1]) {
> dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
> -   return -ENXIO;
> +   goto err_ioremap1;
> }
>
> pcfg->cpu = -1;
> @@ -128,7 +137,7 @@ static int bman_portal_probe(struct platform_device *pdev)
> irq = platform_get_irq(pdev, 0);
> if (irq <= 0) {
> dev_err(dev, "Can't get %pOF IRQ'\n", node);
> -   return -ENXIO;
> +   goto err_ioremap1;
> }
> pcfg->irq = irq;
>
> @@ -156,6 +165,9 @@ static int bman_portal_probe(struct platform_device *pdev)
> }
>
> cpumask_set_cpu(cpu, &portal_cpus);
> +   if (!__bman_portals_probed &&
> +   cpumask_weight(&portal_cpus) == num_online_cpus())
> +   __bman_portals_probed = 1;

Given the fact that the portal_cpus bit will get set even for offline
cpus, this is not correct either.  Probably the previous code for
checking cpu >= nr_cpu_ids is actually the right way to do it.

> spin_unlock(&bman_lock);
> pcfg->cpu = cpu;
>
> @@ -175,6 +187,8 @@ static int bman_portal_probe(struct platform_device *pdev)
>  err_ioremap2:
> memunmap(pcfg->addr_virt_ce);
>  err_ioremap1:
> +__bman_portals_probed = -1;
> +
> return -ENXIO;
>  }
>
> diff --git a/drivers/soc/fsl/qbman/qman_portal.c 
> b/drivers/soc/fsl/qbman/qman_portal.c
> index bce56da2b01f..11ba6c77c0d6 100644
> --- a/drivers/soc/fsl/qbman/qman_portal.c
> +++ b/drivers/soc/fsl/qbman/qman_portal.c
> @@ -39,6 +39,7 @@ EXPORT_SYMBOL(qman_dma_portal);
>  #define CONFIG_FSL_DPA_PIRQ_FAST  1
>
>  static struct cpumask portal_cpus;
> +static int __qman_portals_probed;
>  /* protect qman global registers and global data shared among portals */
>  static DEFINE_SPINLOCK(qman_lock);
>
> @@ -221,6 +222,12 @@ static int qman_online_cpu(unsigned int cpu)
> return 0;
>  }
>
> +int qman_portals_probed(void)
> +{
> +   return __qman_portals_probed;
> +}
> +EXPORT_SYMBOL_GPL(qman_port