linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove
@ 2016-11-22 16:10 Charles Keepax
  2016-11-22 16:10 ` [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it Charles Keepax
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Charles Keepax @ 2016-11-22 16:10 UTC (permalink / raw)
  To: lee.jones; +Cc: linux-kernel, patches

As DCVDD will often be supplied by a child node of the MFD, we
can't call mfd_remove_devices as the first step in arizona_dev_exit
as might be expected (tidy up the children before we tidy up the
MFD). We need to disable and put the DCVDD regulator before we call
mfd_remove_devices, to prevent PM runtime from turning this back on we
also need to disable the PM runtime before we do this. Finally we can
not clean up the IRQs until all the MFD children have been removed, as
they may have registered IRQs themselves.

This creates a window of time where the interrupts are enabled but
the PM runtime, on which the IRQ handler depends, is not available,
any interrupts in this window will go unhandled and fill the log with
failed to resume device messages. To avoid this we simply disable the
main IRQ at the start of arizona_dev_exit, we don't need to actually
handle any IRQs in this window as we are removing the driver.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

Changes since v1:
 - Just a rebase

Thanks,
Charles

 drivers/mfd/arizona-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 41767f7..b6d4bc6 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -1553,6 +1553,7 @@ EXPORT_SYMBOL_GPL(arizona_dev_init);
 
 int arizona_dev_exit(struct arizona *arizona)
 {
+	disable_irq(arizona->irq);
 	pm_runtime_disable(arizona->dev);
 
 	regulator_disable(arizona->dcvdd);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it
  2016-11-22 16:10 [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Charles Keepax
@ 2016-11-22 16:10 ` Charles Keepax
  2016-12-09 10:50   ` Lee Jones
  2016-11-22 16:10 ` [PATCH 3/4] mfd: arizona: Add defines for IRQs on the main Arizona IRQ domain Charles Keepax
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Charles Keepax @ 2016-11-22 16:10 UTC (permalink / raw)
  To: lee.jones; +Cc: linux-kernel, patches

We have arizona_map_irq we might as well use it rather than hard coding
it in several places.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

Changes since v1:
 - Just a rebase

Thanks,
Charles

 drivers/mfd/arizona-irq.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 2e01975..724fa54 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -204,7 +204,7 @@ static const struct irq_domain_ops arizona_domain_ops = {
 int arizona_irq_init(struct arizona *arizona)
 {
 	int flags = IRQF_ONESHOT;
-	int ret, i;
+	int ret;
 	const struct regmap_irq_chip *aod, *irq;
 	struct irq_data *irq_data;
 
@@ -368,9 +368,8 @@ int arizona_irq_init(struct arizona *arizona)
 	}
 
 	/* Make sure the boot done IRQ is unmasked for resumes */
-	i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE);
-	ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT,
-				   "Boot done", arizona);
+	ret = arizona_request_irq(arizona, ARIZONA_IRQ_BOOT_DONE, "Boot done",
+				  arizona_boot_done, arizona);
 	if (ret != 0) {
 		dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
 			arizona->irq, ret);
@@ -379,10 +378,9 @@ int arizona_irq_init(struct arizona *arizona)
 
 	/* Handle control interface errors in the core */
 	if (arizona->ctrlif_error) {
-		i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
-		ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
-					   IRQF_ONESHOT,
-					   "Control interface error", arizona);
+		ret = arizona_request_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR,
+					  "Control interface error",
+					  arizona_ctrlif_err, arizona);
 		if (ret != 0) {
 			dev_err(arizona->dev,
 				"Failed to request CTRLIF_ERR %d: %d\n",
@@ -394,7 +392,7 @@ int arizona_irq_init(struct arizona *arizona)
 	return 0;
 
 err_ctrlif:
-	free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
+	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
 err_boot_done:
 	free_irq(arizona->irq, arizona);
 err_main_irq:
@@ -410,9 +408,9 @@ int arizona_irq_init(struct arizona *arizona)
 int arizona_irq_exit(struct arizona *arizona)
 {
 	if (arizona->ctrlif_error)
-		free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR),
-			 arizona);
-	free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
+		arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
+	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
+
 	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
 			    arizona->irq_chip);
 	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] mfd: arizona: Add defines for IRQs on the main Arizona IRQ domain
  2016-11-22 16:10 [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Charles Keepax
  2016-11-22 16:10 ` [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it Charles Keepax
@ 2016-11-22 16:10 ` Charles Keepax
  2016-12-09 10:51   ` Lee Jones
  2016-11-22 16:10 ` [PATCH v4 4/4] mfd: arizona: Correctly clean up after IRQs Charles Keepax
  2016-12-09  9:30 ` [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Lee Jones
  3 siblings, 1 reply; 8+ messages in thread
From: Charles Keepax @ 2016-11-22 16:10 UTC (permalink / raw)
  To: lee.jones; +Cc: linux-kernel, patches

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
 drivers/mfd/arizona-irq.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 724fa54..88729cf 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -26,6 +26,9 @@
 
 #include "arizona.h"
 
+#define ARIZONA_AOD_IRQ_INDEX 0
+#define ARIZONA_MAIN_IRQ_INDEX 1
+
 static int arizona_map_irq(struct arizona *arizona, int irq)
 {
 	int ret;
@@ -319,7 +322,8 @@ int arizona_irq_init(struct arizona *arizona)
 
 	if (aod) {
 		ret = regmap_add_irq_chip(arizona->regmap,
-					  irq_create_mapping(arizona->virq, 0),
+					  irq_create_mapping(arizona->virq,
+							ARIZONA_AOD_IRQ_INDEX),
 					  IRQF_ONESHOT, 0, aod,
 					  &arizona->aod_irq_chip);
 		if (ret != 0) {
@@ -330,7 +334,8 @@ int arizona_irq_init(struct arizona *arizona)
 	}
 
 	ret = regmap_add_irq_chip(arizona->regmap,
-				  irq_create_mapping(arizona->virq, 1),
+				  irq_create_mapping(arizona->virq,
+						     ARIZONA_MAIN_IRQ_INDEX),
 				  IRQF_ONESHOT, 0, irq,
 				  &arizona->irq_chip);
 	if (ret != 0) {
@@ -396,10 +401,12 @@ int arizona_irq_init(struct arizona *arizona)
 err_boot_done:
 	free_irq(arizona->irq, arizona);
 err_main_irq:
-	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
+	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
+					     ARIZONA_MAIN_IRQ_INDEX),
 			    arizona->irq_chip);
 err_aod:
-	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
+	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
+					     ARIZONA_AOD_IRQ_INDEX),
 			    arizona->aod_irq_chip);
 err:
 	return ret;
@@ -411,9 +418,11 @@ int arizona_irq_exit(struct arizona *arizona)
 		arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
 	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
 
-	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
+	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
+					     ARIZONA_MAIN_IRQ_INDEX),
 			    arizona->irq_chip);
-	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
+	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
+					     ARIZONA_AOD_IRQ_INDEX),
 			    arizona->aod_irq_chip);
 	free_irq(arizona->irq, arizona);
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 4/4] mfd: arizona: Correctly clean up after IRQs
  2016-11-22 16:10 [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Charles Keepax
  2016-11-22 16:10 ` [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it Charles Keepax
  2016-11-22 16:10 ` [PATCH 3/4] mfd: arizona: Add defines for IRQs on the main Arizona IRQ domain Charles Keepax
@ 2016-11-22 16:10 ` Charles Keepax
  2016-12-09 10:57   ` Lee Jones
  2016-12-09  9:30 ` [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Lee Jones
  3 siblings, 1 reply; 8+ messages in thread
From: Charles Keepax @ 2016-11-22 16:10 UTC (permalink / raw)
  To: lee.jones; +Cc: linux-kernel, patches

Currently we leak a lot of things when tearing down the IRQs this patch
fixes this cleaning up both the IRQ mappings and the IRQ domain itself.

Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---

Changes since v3:
 - Just included the other patches in the chain.

Thanks
Charles

 drivers/mfd/arizona-irq.c | 59 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 88729cf..09cf369 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -210,6 +210,7 @@ int arizona_irq_init(struct arizona *arizona)
 	int ret;
 	const struct regmap_irq_chip *aod, *irq;
 	struct irq_data *irq_data;
+	unsigned int virq;
 
 	arizona->ctrlif_error = true;
 
@@ -321,26 +322,34 @@ int arizona_irq_init(struct arizona *arizona)
 	}
 
 	if (aod) {
-		ret = regmap_add_irq_chip(arizona->regmap,
-					  irq_create_mapping(arizona->virq,
-							ARIZONA_AOD_IRQ_INDEX),
-					  IRQF_ONESHOT, 0, aod,
-					  &arizona->aod_irq_chip);
+		virq = irq_create_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX);
+		if (!virq) {
+			dev_err(arizona->dev, "Failed to map AOD IRQs\n");
+			ret = -EINVAL;
+			goto err_domain;
+		}
+
+		ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
+					  0, aod, &arizona->aod_irq_chip);
 		if (ret != 0) {
 			dev_err(arizona->dev,
 				"Failed to add AOD IRQs: %d\n", ret);
-			goto err;
+			goto err_map_aod;
 		}
 	}
 
-	ret = regmap_add_irq_chip(arizona->regmap,
-				  irq_create_mapping(arizona->virq,
-						     ARIZONA_MAIN_IRQ_INDEX),
-				  IRQF_ONESHOT, 0, irq,
-				  &arizona->irq_chip);
+	virq = irq_create_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX);
+	if (!virq) {
+		dev_err(arizona->dev, "Failed to map main IRQs\n");
+		ret = -EINVAL;
+		goto err_aod;
+	}
+
+	ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
+				  0, irq, &arizona->irq_chip);
 	if (ret != 0) {
 		dev_err(arizona->dev, "Failed to add main IRQs: %d\n", ret);
-		goto err_aod;
+		goto err_map_main_irq;
 	}
 
 	/* Used to emulate edge trigger and to work around broken pinmux */
@@ -404,26 +413,40 @@ int arizona_irq_init(struct arizona *arizona)
 	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
 					     ARIZONA_MAIN_IRQ_INDEX),
 			    arizona->irq_chip);
+err_map_main_irq:
+	irq_dispose_mapping(irq_find_mapping(arizona->virq,
+					     ARIZONA_MAIN_IRQ_INDEX));
 err_aod:
 	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
 					     ARIZONA_AOD_IRQ_INDEX),
 			    arizona->aod_irq_chip);
+err_map_aod:
+	irq_dispose_mapping(irq_find_mapping(arizona->virq,
+					     ARIZONA_AOD_IRQ_INDEX));
+err_domain:
+	irq_domain_remove(arizona->virq);
 err:
 	return ret;
 }
 
 int arizona_irq_exit(struct arizona *arizona)
 {
+	unsigned int virq;
+
 	if (arizona->ctrlif_error)
 		arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
 	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
 
-	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
-					     ARIZONA_MAIN_IRQ_INDEX),
-			    arizona->irq_chip);
-	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
-					     ARIZONA_AOD_IRQ_INDEX),
-			    arizona->aod_irq_chip);
+	virq = irq_find_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX);
+	regmap_del_irq_chip(virq, arizona->irq_chip);
+	irq_dispose_mapping(virq);
+
+	virq = irq_find_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX);
+	regmap_del_irq_chip(virq, arizona->aod_irq_chip);
+	irq_dispose_mapping(virq);
+
+	irq_domain_remove(arizona->virq);
+
 	free_irq(arizona->irq, arizona);
 
 	return 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove
  2016-11-22 16:10 [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Charles Keepax
                   ` (2 preceding siblings ...)
  2016-11-22 16:10 ` [PATCH v4 4/4] mfd: arizona: Correctly clean up after IRQs Charles Keepax
@ 2016-12-09  9:30 ` Lee Jones
  3 siblings, 0 replies; 8+ messages in thread
From: Lee Jones @ 2016-12-09  9:30 UTC (permalink / raw)
  To: Charles Keepax; +Cc: linux-kernel, patches

On Tue, 22 Nov 2016, Charles Keepax wrote:

> As DCVDD will often be supplied by a child node of the MFD, we
> can't call mfd_remove_devices as the first step in arizona_dev_exit
> as might be expected (tidy up the children before we tidy up the
> MFD). We need to disable and put the DCVDD regulator before we call
> mfd_remove_devices, to prevent PM runtime from turning this back on we
> also need to disable the PM runtime before we do this. Finally we can
> not clean up the IRQs until all the MFD children have been removed, as
> they may have registered IRQs themselves.
> 
> This creates a window of time where the interrupts are enabled but
> the PM runtime, on which the IRQ handler depends, is not available,
> any interrupts in this window will go unhandled and fill the log with
> failed to resume device messages. To avoid this we simply disable the
> main IRQ at the start of arizona_dev_exit, we don't need to actually
> handle any IRQs in this window as we are removing the driver.
> 
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
> 
> Changes since v1:
>  - Just a rebase
> 
> Thanks,
> Charles
> 
>  drivers/mfd/arizona-core.c | 1 +
>  1 file changed, 1 insertion(+)

Applied for v4.11, thanks.

> diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
> index 41767f7..b6d4bc6 100644
> --- a/drivers/mfd/arizona-core.c
> +++ b/drivers/mfd/arizona-core.c
> @@ -1553,6 +1553,7 @@ EXPORT_SYMBOL_GPL(arizona_dev_init);
>  
>  int arizona_dev_exit(struct arizona *arizona)
>  {
> +	disable_irq(arizona->irq);
>  	pm_runtime_disable(arizona->dev);
>  
>  	regulator_disable(arizona->dcvdd);

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it
  2016-11-22 16:10 ` [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it Charles Keepax
@ 2016-12-09 10:50   ` Lee Jones
  0 siblings, 0 replies; 8+ messages in thread
From: Lee Jones @ 2016-12-09 10:50 UTC (permalink / raw)
  To: Charles Keepax; +Cc: linux-kernel, patches

On Tue, 22 Nov 2016, Charles Keepax wrote:

> We have arizona_map_irq we might as well use it rather than hard coding
> it in several places.
> 
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
> 
> Changes since v1:
>  - Just a rebase
> 
> Thanks,
> Charles
> 
>  drivers/mfd/arizona-irq.c | 22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)

Applied for v4.11, thanks.

> diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
> index 2e01975..724fa54 100644
> --- a/drivers/mfd/arizona-irq.c
> +++ b/drivers/mfd/arizona-irq.c
> @@ -204,7 +204,7 @@ static const struct irq_domain_ops arizona_domain_ops = {
>  int arizona_irq_init(struct arizona *arizona)
>  {
>  	int flags = IRQF_ONESHOT;
> -	int ret, i;
> +	int ret;
>  	const struct regmap_irq_chip *aod, *irq;
>  	struct irq_data *irq_data;
>  
> @@ -368,9 +368,8 @@ int arizona_irq_init(struct arizona *arizona)
>  	}
>  
>  	/* Make sure the boot done IRQ is unmasked for resumes */
> -	i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE);
> -	ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT,
> -				   "Boot done", arizona);
> +	ret = arizona_request_irq(arizona, ARIZONA_IRQ_BOOT_DONE, "Boot done",
> +				  arizona_boot_done, arizona);
>  	if (ret != 0) {
>  		dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
>  			arizona->irq, ret);
> @@ -379,10 +378,9 @@ int arizona_irq_init(struct arizona *arizona)
>  
>  	/* Handle control interface errors in the core */
>  	if (arizona->ctrlif_error) {
> -		i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
> -		ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
> -					   IRQF_ONESHOT,
> -					   "Control interface error", arizona);
> +		ret = arizona_request_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR,
> +					  "Control interface error",
> +					  arizona_ctrlif_err, arizona);
>  		if (ret != 0) {
>  			dev_err(arizona->dev,
>  				"Failed to request CTRLIF_ERR %d: %d\n",
> @@ -394,7 +392,7 @@ int arizona_irq_init(struct arizona *arizona)
>  	return 0;
>  
>  err_ctrlif:
> -	free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
> +	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
>  err_boot_done:
>  	free_irq(arizona->irq, arizona);
>  err_main_irq:
> @@ -410,9 +408,9 @@ int arizona_irq_init(struct arizona *arizona)
>  int arizona_irq_exit(struct arizona *arizona)
>  {
>  	if (arizona->ctrlif_error)
> -		free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR),
> -			 arizona);
> -	free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
> +		arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
> +	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
> +
>  	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
>  			    arizona->irq_chip);
>  	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/4] mfd: arizona: Add defines for IRQs on the main Arizona IRQ domain
  2016-11-22 16:10 ` [PATCH 3/4] mfd: arizona: Add defines for IRQs on the main Arizona IRQ domain Charles Keepax
@ 2016-12-09 10:51   ` Lee Jones
  0 siblings, 0 replies; 8+ messages in thread
From: Lee Jones @ 2016-12-09 10:51 UTC (permalink / raw)
  To: Charles Keepax; +Cc: linux-kernel, patches

On Tue, 22 Nov 2016, Charles Keepax wrote:

> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
>  drivers/mfd/arizona-irq.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)

Applied for v4.11, thanks.

> diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
> index 724fa54..88729cf 100644
> --- a/drivers/mfd/arizona-irq.c
> +++ b/drivers/mfd/arizona-irq.c
> @@ -26,6 +26,9 @@
>  
>  #include "arizona.h"
>  
> +#define ARIZONA_AOD_IRQ_INDEX 0
> +#define ARIZONA_MAIN_IRQ_INDEX 1
> +
>  static int arizona_map_irq(struct arizona *arizona, int irq)
>  {
>  	int ret;
> @@ -319,7 +322,8 @@ int arizona_irq_init(struct arizona *arizona)
>  
>  	if (aod) {
>  		ret = regmap_add_irq_chip(arizona->regmap,
> -					  irq_create_mapping(arizona->virq, 0),
> +					  irq_create_mapping(arizona->virq,
> +							ARIZONA_AOD_IRQ_INDEX),
>  					  IRQF_ONESHOT, 0, aod,
>  					  &arizona->aod_irq_chip);
>  		if (ret != 0) {
> @@ -330,7 +334,8 @@ int arizona_irq_init(struct arizona *arizona)
>  	}
>  
>  	ret = regmap_add_irq_chip(arizona->regmap,
> -				  irq_create_mapping(arizona->virq, 1),
> +				  irq_create_mapping(arizona->virq,
> +						     ARIZONA_MAIN_IRQ_INDEX),
>  				  IRQF_ONESHOT, 0, irq,
>  				  &arizona->irq_chip);
>  	if (ret != 0) {
> @@ -396,10 +401,12 @@ int arizona_irq_init(struct arizona *arizona)
>  err_boot_done:
>  	free_irq(arizona->irq, arizona);
>  err_main_irq:
> -	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
> +	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
> +					     ARIZONA_MAIN_IRQ_INDEX),
>  			    arizona->irq_chip);
>  err_aod:
> -	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
> +	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
> +					     ARIZONA_AOD_IRQ_INDEX),
>  			    arizona->aod_irq_chip);
>  err:
>  	return ret;
> @@ -411,9 +418,11 @@ int arizona_irq_exit(struct arizona *arizona)
>  		arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
>  	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
>  
> -	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 1),
> +	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
> +					     ARIZONA_MAIN_IRQ_INDEX),
>  			    arizona->irq_chip);
> -	regmap_del_irq_chip(irq_find_mapping(arizona->virq, 0),
> +	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
> +					     ARIZONA_AOD_IRQ_INDEX),
>  			    arizona->aod_irq_chip);
>  	free_irq(arizona->irq, arizona);
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 4/4] mfd: arizona: Correctly clean up after IRQs
  2016-11-22 16:10 ` [PATCH v4 4/4] mfd: arizona: Correctly clean up after IRQs Charles Keepax
@ 2016-12-09 10:57   ` Lee Jones
  0 siblings, 0 replies; 8+ messages in thread
From: Lee Jones @ 2016-12-09 10:57 UTC (permalink / raw)
  To: Charles Keepax; +Cc: linux-kernel, patches

On Tue, 22 Nov 2016, Charles Keepax wrote:

> Currently we leak a lot of things when tearing down the IRQs this patch
> fixes this cleaning up both the IRQ mappings and the IRQ domain itself.
> 
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
> 
> Changes since v3:
>  - Just included the other patches in the chain.
> 
> Thanks
> Charles
> 
>  drivers/mfd/arizona-irq.c | 59 ++++++++++++++++++++++++++++++++---------------
>  1 file changed, 41 insertions(+), 18 deletions(-)

Applied for v4.11, thanks.

> diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
> index 88729cf..09cf369 100644
> --- a/drivers/mfd/arizona-irq.c
> +++ b/drivers/mfd/arizona-irq.c
> @@ -210,6 +210,7 @@ int arizona_irq_init(struct arizona *arizona)
>  	int ret;
>  	const struct regmap_irq_chip *aod, *irq;
>  	struct irq_data *irq_data;
> +	unsigned int virq;
>  
>  	arizona->ctrlif_error = true;
>  
> @@ -321,26 +322,34 @@ int arizona_irq_init(struct arizona *arizona)
>  	}
>  
>  	if (aod) {
> -		ret = regmap_add_irq_chip(arizona->regmap,
> -					  irq_create_mapping(arizona->virq,
> -							ARIZONA_AOD_IRQ_INDEX),
> -					  IRQF_ONESHOT, 0, aod,
> -					  &arizona->aod_irq_chip);
> +		virq = irq_create_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX);
> +		if (!virq) {
> +			dev_err(arizona->dev, "Failed to map AOD IRQs\n");
> +			ret = -EINVAL;
> +			goto err_domain;
> +		}
> +
> +		ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
> +					  0, aod, &arizona->aod_irq_chip);
>  		if (ret != 0) {
>  			dev_err(arizona->dev,
>  				"Failed to add AOD IRQs: %d\n", ret);
> -			goto err;
> +			goto err_map_aod;
>  		}
>  	}
>  
> -	ret = regmap_add_irq_chip(arizona->regmap,
> -				  irq_create_mapping(arizona->virq,
> -						     ARIZONA_MAIN_IRQ_INDEX),
> -				  IRQF_ONESHOT, 0, irq,
> -				  &arizona->irq_chip);
> +	virq = irq_create_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX);
> +	if (!virq) {
> +		dev_err(arizona->dev, "Failed to map main IRQs\n");
> +		ret = -EINVAL;
> +		goto err_aod;
> +	}
> +
> +	ret = regmap_add_irq_chip(arizona->regmap, virq, IRQF_ONESHOT,
> +				  0, irq, &arizona->irq_chip);
>  	if (ret != 0) {
>  		dev_err(arizona->dev, "Failed to add main IRQs: %d\n", ret);
> -		goto err_aod;
> +		goto err_map_main_irq;
>  	}
>  
>  	/* Used to emulate edge trigger and to work around broken pinmux */
> @@ -404,26 +413,40 @@ int arizona_irq_init(struct arizona *arizona)
>  	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
>  					     ARIZONA_MAIN_IRQ_INDEX),
>  			    arizona->irq_chip);
> +err_map_main_irq:
> +	irq_dispose_mapping(irq_find_mapping(arizona->virq,
> +					     ARIZONA_MAIN_IRQ_INDEX));
>  err_aod:
>  	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
>  					     ARIZONA_AOD_IRQ_INDEX),
>  			    arizona->aod_irq_chip);
> +err_map_aod:
> +	irq_dispose_mapping(irq_find_mapping(arizona->virq,
> +					     ARIZONA_AOD_IRQ_INDEX));
> +err_domain:
> +	irq_domain_remove(arizona->virq);
>  err:
>  	return ret;
>  }
>  
>  int arizona_irq_exit(struct arizona *arizona)
>  {
> +	unsigned int virq;
> +
>  	if (arizona->ctrlif_error)
>  		arizona_free_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR, arizona);
>  	arizona_free_irq(arizona, ARIZONA_IRQ_BOOT_DONE, arizona);
>  
> -	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
> -					     ARIZONA_MAIN_IRQ_INDEX),
> -			    arizona->irq_chip);
> -	regmap_del_irq_chip(irq_find_mapping(arizona->virq,
> -					     ARIZONA_AOD_IRQ_INDEX),
> -			    arizona->aod_irq_chip);
> +	virq = irq_find_mapping(arizona->virq, ARIZONA_MAIN_IRQ_INDEX);
> +	regmap_del_irq_chip(virq, arizona->irq_chip);
> +	irq_dispose_mapping(virq);
> +
> +	virq = irq_find_mapping(arizona->virq, ARIZONA_AOD_IRQ_INDEX);
> +	regmap_del_irq_chip(virq, arizona->aod_irq_chip);
> +	irq_dispose_mapping(virq);
> +
> +	irq_domain_remove(arizona->virq);
> +
>  	free_irq(arizona->irq, arizona);
>  
>  	return 0;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-12-09 10:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-22 16:10 [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Charles Keepax
2016-11-22 16:10 ` [PATCH v2 2/4] mfd: arizona: Use arizona_map_irq instead of hard coding it Charles Keepax
2016-12-09 10:50   ` Lee Jones
2016-11-22 16:10 ` [PATCH 3/4] mfd: arizona: Add defines for IRQs on the main Arizona IRQ domain Charles Keepax
2016-12-09 10:51   ` Lee Jones
2016-11-22 16:10 ` [PATCH v4 4/4] mfd: arizona: Correctly clean up after IRQs Charles Keepax
2016-12-09 10:57   ` Lee Jones
2016-12-09  9:30 ` [PATCH v2 1/4] mfd: arizona: Disable IRQs during driver remove Lee Jones

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).