linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers
@ 2014-07-25  6:54 Mika Westerberg
  2014-07-25  6:54 ` [PATCH 1/3] gpio: lynxpoint: Convert to use gpiolib irqchip Mika Westerberg
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Mika Westerberg @ 2014-07-25  6:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alexandre Courbot, Rafael J. Wysocki, Zhu Lejun, Yang Bin,
	Mathias Nyman, Mika Westerberg, linux-gpio, linux-kernel

Hi,

As discussed in this thread:

https://www.mail-archive.com/linux-gpio%40vger.kernel.org/msg02929.html

This series converts the Intel Lynxpoint and Baytrail GPIO drivers to use
the new irqchip helper functions and then moves ACPI event registration to
happen in the helpers as well.

Mika Westerberg (3):
  gpio: lynxpoint: Convert to use gpiolib irqchip
  pinctrl: baytrail: Convert to use gpiolib irqchip
  gpio / ACPI: Move event handling registration to gpiolib irqchip helpers

 drivers/gpio/Kconfig               |  2 +-
 drivers/gpio/gpio-lynxpoint.c      | 93 ++++++++++----------------------------
 drivers/gpio/gpiolib-acpi.c        | 38 ++++++++++++----
 drivers/gpio/gpiolib.c             |  4 ++
 drivers/gpio/gpiolib.h             |  9 ++++
 drivers/pinctrl/Kconfig            |  2 +-
 drivers/pinctrl/pinctrl-baytrail.c | 87 ++++++++---------------------------
 7 files changed, 87 insertions(+), 148 deletions(-)

-- 
2.0.1

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

* [PATCH 1/3] gpio: lynxpoint: Convert to use gpiolib irqchip
  2014-07-25  6:54 [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers Mika Westerberg
@ 2014-07-25  6:54 ` Mika Westerberg
  2014-07-25  6:54 ` [PATCH 2/3] pinctrl: baytrail: " Mika Westerberg
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Mika Westerberg @ 2014-07-25  6:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alexandre Courbot, Rafael J. Wysocki, Zhu Lejun, Yang Bin,
	Mathias Nyman, Mika Westerberg, linux-gpio, linux-kernel

Instead of open-coding irqchip handling in the driver we can take advantage
of the new irqchip helpers provided by the gpiolib core.

While doing this we also make sure that we call gpiochip_irqchip_add()
after the gpiochip itself is registered as required.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/gpio/Kconfig          |  2 +-
 drivers/gpio/gpio-lynxpoint.c | 93 ++++++++++++-------------------------------
 2 files changed, 26 insertions(+), 69 deletions(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 4a1b5113e527..e70297c20487 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -423,7 +423,7 @@ config GPIO_GE_FPGA
 config GPIO_LYNXPOINT
 	tristate "Intel Lynxpoint GPIO support"
 	depends on ACPI && X86
-	select IRQ_DOMAIN
+	select GPIOLIB_IRQCHIP
 	help
 	  driver for GPIO functionality on Intel Lynxpoint PCH chipset
 	  Requires ACPI device enumeration code to set up a platform device.
diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c
index 2bea89b72508..7e3305ae8ec6 100644
--- a/drivers/gpio/gpio-lynxpoint.c
+++ b/drivers/gpio/gpio-lynxpoint.c
@@ -25,9 +25,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/irqdomain.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
@@ -62,7 +60,6 @@
 
 struct lp_gpio {
 	struct gpio_chip	chip;
-	struct irq_domain	*domain;
 	struct platform_device	*pdev;
 	spinlock_t		lock;
 	unsigned long		reg_base;
@@ -151,7 +148,8 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
 
 static int lp_irq_type(struct irq_data *d, unsigned type)
 {
-	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
 	u32 hwirq = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 value;
@@ -236,16 +234,11 @@ static int lp_gpio_direction_output(struct gpio_chip *chip,
 	return 0;
 }
 
-static int lp_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct lp_gpio *lg = container_of(chip, struct lp_gpio, chip);
-	return irq_create_mapping(lg->domain, offset);
-}
-
 static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc)
 {
 	struct irq_data *data = irq_desc_get_irq_data(desc);
-	struct lp_gpio *lg = irq_data_get_irq_handler_data(data);
+	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+	struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
 	u32 base, pin, mask;
 	unsigned long reg, ena, pending;
@@ -262,7 +255,7 @@ static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc)
 			mask = BIT(pin);
 			/* Clear before handling so we don't lose an edge */
 			outl(mask, reg);
-			irq = irq_find_mapping(lg->domain, base + pin);
+			irq = irq_find_mapping(lg->chip.irqdomain, base + pin);
 			generic_handle_irq(irq);
 		}
 	}
@@ -279,7 +272,8 @@ static void lp_irq_mask(struct irq_data *d)
 
 static void lp_irq_enable(struct irq_data *d)
 {
-	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
 	u32 hwirq = irqd_to_hwirq(d);
 	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
@@ -291,7 +285,8 @@ static void lp_irq_enable(struct irq_data *d)
 
 static void lp_irq_disable(struct irq_data *d)
 {
-	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
 	u32 hwirq = irqd_to_hwirq(d);
 	unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
 	unsigned long flags;
@@ -301,26 +296,6 @@ static void lp_irq_disable(struct irq_data *d)
 	spin_unlock_irqrestore(&lg->lock, flags);
 }
 
-static int lp_irq_reqres(struct irq_data *d)
-{
-	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
-
-	if (gpio_lock_as_irq(&lg->chip, irqd_to_hwirq(d))) {
-		dev_err(lg->chip.dev,
-			"unable to lock HW IRQ %lu for IRQ\n",
-			irqd_to_hwirq(d));
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void lp_irq_relres(struct irq_data *d)
-{
-	struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
-
-	gpio_unlock_as_irq(&lg->chip, irqd_to_hwirq(d));
-}
-
 static struct irq_chip lp_irqchip = {
 	.name = "LP-GPIO",
 	.irq_mask = lp_irq_mask,
@@ -328,8 +303,6 @@ static struct irq_chip lp_irqchip = {
 	.irq_enable = lp_irq_enable,
 	.irq_disable = lp_irq_disable,
 	.irq_set_type = lp_irq_type,
-	.irq_request_resources = lp_irq_reqres,
-	.irq_release_resources = lp_irq_relres,
 	.flags = IRQCHIP_SKIP_SET_WAKE,
 };
 
@@ -348,22 +321,6 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg)
 	}
 }
 
-static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq,
-			    irq_hw_number_t hwirq)
-{
-	struct lp_gpio *lg = d->host_data;
-
-	irq_set_chip_and_handler(irq, &lp_irqchip, handle_simple_irq);
-	irq_set_chip_data(irq, lg);
-	irq_set_irq_type(irq, IRQ_TYPE_NONE);
-
-	return 0;
-}
-
-static const struct irq_domain_ops lp_gpio_irq_ops = {
-	.map = lp_gpio_irq_map,
-};
-
 static int lp_gpio_probe(struct platform_device *pdev)
 {
 	struct lp_gpio *lg;
@@ -371,7 +328,6 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	struct resource *io_rc, *irq_rc;
 	struct device *dev = &pdev->dev;
 	unsigned long reg_len;
-	unsigned hwirq;
 	int ret = -ENODEV;
 
 	lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
@@ -414,27 +370,28 @@ static int lp_gpio_probe(struct platform_device *pdev)
 	gc->can_sleep = false;
 	gc->dev = dev;
 
+	ret = gpiochip_add(gc);
+	if (ret) {
+		dev_err(dev, "failed adding lp-gpio chip\n");
+		return ret;
+	}
+
 	/* set up interrupts  */
 	if (irq_rc && irq_rc->start) {
-		hwirq = irq_rc->start;
-		gc->to_irq = lp_gpio_to_irq;
-
-		lg->domain = irq_domain_add_linear(NULL, LP_NUM_GPIO,
-						   &lp_gpio_irq_ops, lg);
-		if (!lg->domain)
-			return -ENXIO;
-
 		lp_gpio_irq_init_hw(lg);
+		ret = gpiochip_irqchip_add(gc, &lp_irqchip, 0,
+					   handle_simple_irq, IRQ_TYPE_NONE);
+		if (ret) {
+			dev_err(dev, "failed to add irqchip\n");
+			gpiochip_remove(gc);
+			return ret;
+		}
 
-		irq_set_handler_data(hwirq, lg);
-		irq_set_chained_handler(hwirq, lp_gpio_irq_handler);
+		gpiochip_set_chained_irqchip(gc, &lp_irqchip,
+					     (unsigned)irq_rc->start,
+					     lp_gpio_irq_handler);
 	}
 
-	ret = gpiochip_add(gc);
-	if (ret) {
-		dev_err(dev, "failed adding lp-gpio chip\n");
-		return ret;
-	}
 	pm_runtime_enable(dev);
 
 	return 0;
-- 
2.0.1

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

* [PATCH 2/3] pinctrl: baytrail: Convert to use gpiolib irqchip
  2014-07-25  6:54 [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers Mika Westerberg
  2014-07-25  6:54 ` [PATCH 1/3] gpio: lynxpoint: Convert to use gpiolib irqchip Mika Westerberg
@ 2014-07-25  6:54 ` Mika Westerberg
  2014-07-25  6:54 ` [PATCH 3/3] gpio / ACPI: Move event handling registration to gpiolib irqchip helpers Mika Westerberg
  2014-07-28 10:22 ` [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use " Linus Walleij
  3 siblings, 0 replies; 5+ messages in thread
From: Mika Westerberg @ 2014-07-25  6:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alexandre Courbot, Rafael J. Wysocki, Zhu Lejun, Yang Bin,
	Mathias Nyman, Mika Westerberg, linux-gpio, linux-kernel

Instead of open-coding irqchip handling in the driver we can take advantage
of the new irqchip helpers provided by the gpiolib core.

While doing this we also make sure that we call gpiochip_irqchip_add()
after the gpiochip itself is registered as required.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/pinctrl/Kconfig            |  2 +-
 drivers/pinctrl/pinctrl-baytrail.c | 87 +++++++++-----------------------------
 2 files changed, 20 insertions(+), 69 deletions(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 0042ccb46b9a..bd6f9926a569 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -93,7 +93,7 @@ config PINCTRL_AT91
 config PINCTRL_BAYTRAIL
 	bool "Intel Baytrail GPIO pin control"
 	depends on GPIOLIB && ACPI && X86
-	select IRQ_DOMAIN
+	select GPIOLIB_IRQCHIP
 	help
 	  driver for memory mapped GPIO functionality on Intel Baytrail
 	  platforms. Supports 3 banks with 102, 28 and 44 gpios.
diff --git a/drivers/pinctrl/pinctrl-baytrail.c b/drivers/pinctrl/pinctrl-baytrail.c
index 975572e2f260..cb5419ca6577 100644
--- a/drivers/pinctrl/pinctrl-baytrail.c
+++ b/drivers/pinctrl/pinctrl-baytrail.c
@@ -25,9 +25,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/irqdomain.h>
 #include <linux/acpi.h>
 #include <linux/platform_device.h>
 #include <linux/seq_file.h>
@@ -137,7 +135,6 @@ static struct pinctrl_gpio_range byt_ranges[] = {
 
 struct byt_gpio {
 	struct gpio_chip		chip;
-	struct irq_domain		*domain;
 	struct platform_device		*pdev;
 	spinlock_t			lock;
 	void __iomem			*reg_base;
@@ -217,7 +214,7 @@ static void byt_gpio_free(struct gpio_chip *chip, unsigned offset)
 
 static int byt_irq_type(struct irq_data *d, unsigned type)
 {
-	struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
+	struct byt_gpio *vg = to_byt_gpio(irq_data_get_irq_chip_data(d));
 	u32 offset = irqd_to_hwirq(d);
 	u32 value;
 	unsigned long flags;
@@ -393,16 +390,10 @@ static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 	spin_unlock_irqrestore(&vg->lock, flags);
 }
 
-static int byt_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct byt_gpio *vg = to_byt_gpio(chip);
-	return irq_create_mapping(vg->domain, offset);
-}
-
 static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
 	struct irq_data *data = irq_desc_get_irq_data(desc);
-	struct byt_gpio *vg = irq_data_get_irq_handler_data(data);
+	struct byt_gpio *vg = to_byt_gpio(irq_desc_get_handler_data(desc));
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
 	u32 base, pin, mask;
 	void __iomem *reg;
@@ -421,7 +412,7 @@ static void byt_gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			/* Clear before handling so we can't lose an edge */
 			writel(mask, reg);
 
-			virq = irq_find_mapping(vg->domain, base + pin);
+			virq = irq_find_mapping(vg->chip.irqdomain, base + pin);
 			generic_handle_irq(virq);
 
 			/* In case bios or user sets triggering incorretly a pin
@@ -454,33 +445,11 @@ static void byt_irq_mask(struct irq_data *d)
 {
 }
 
-static int byt_irq_reqres(struct irq_data *d)
-{
-	struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
-	if (gpio_lock_as_irq(&vg->chip, irqd_to_hwirq(d))) {
-		dev_err(vg->chip.dev,
-			"unable to lock HW IRQ %lu for IRQ\n",
-			irqd_to_hwirq(d));
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void byt_irq_relres(struct irq_data *d)
-{
-	struct byt_gpio *vg = irq_data_get_irq_chip_data(d);
-
-	gpio_unlock_as_irq(&vg->chip, irqd_to_hwirq(d));
-}
-
 static struct irq_chip byt_irqchip = {
 	.name = "BYT-GPIO",
 	.irq_mask = byt_irq_mask,
 	.irq_unmask = byt_irq_unmask,
 	.irq_set_type = byt_irq_type,
-	.irq_request_resources = byt_irq_reqres,
-	.irq_release_resources = byt_irq_relres,
 };
 
 static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
@@ -501,23 +470,6 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
 	}
 }
 
-static int byt_gpio_irq_map(struct irq_domain *d, unsigned int virq,
-			    irq_hw_number_t hw)
-{
-	struct byt_gpio *vg = d->host_data;
-
-	irq_set_chip_and_handler_name(virq, &byt_irqchip, handle_simple_irq,
-				      "demux");
-	irq_set_chip_data(virq, vg);
-	irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
-	return 0;
-}
-
-static const struct irq_domain_ops byt_gpio_irq_ops = {
-	.map = byt_gpio_irq_map,
-};
-
 static int byt_gpio_probe(struct platform_device *pdev)
 {
 	struct byt_gpio *vg;
@@ -527,7 +479,6 @@ static int byt_gpio_probe(struct platform_device *pdev)
 	struct acpi_device *acpi_dev;
 	struct pinctrl_gpio_range *range;
 	acpi_handle handle = ACPI_HANDLE(dev);
-	unsigned hwirq;
 	int ret;
 
 	if (acpi_bus_get_device(handle, &acpi_dev))
@@ -574,27 +525,27 @@ static int byt_gpio_probe(struct platform_device *pdev)
 	gc->can_sleep = false;
 	gc->dev = dev;
 
+	ret = gpiochip_add(gc);
+	if (ret) {
+		dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
+		return ret;
+	}
+
 	/* set up interrupts  */
 	irq_rc = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (irq_rc && irq_rc->start) {
-		hwirq = irq_rc->start;
-		gc->to_irq = byt_gpio_to_irq;
-
-		vg->domain = irq_domain_add_linear(NULL, gc->ngpio,
-						   &byt_gpio_irq_ops, vg);
-		if (!vg->domain)
-			return -ENXIO;
-
 		byt_gpio_irq_init_hw(vg);
+		ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0,
+					   handle_simple_irq, IRQ_TYPE_NONE);
+		if (ret) {
+			dev_err(dev, "failed to add irqchip\n");
+			gpiochip_remove(gc);
+			return ret;
+		}
 
-		irq_set_handler_data(hwirq, vg);
-		irq_set_chained_handler(hwirq, byt_gpio_irq_handler);
-	}
-
-	ret = gpiochip_add(gc);
-	if (ret) {
-		dev_err(&pdev->dev, "failed adding byt-gpio chip\n");
-		return ret;
+		gpiochip_set_chained_irqchip(gc, &byt_irqchip,
+					     (unsigned)irq_rc->start,
+					     byt_gpio_irq_handler);
 	}
 
 	pm_runtime_enable(dev);
-- 
2.0.1

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

* [PATCH 3/3] gpio / ACPI: Move event handling registration to gpiolib irqchip helpers
  2014-07-25  6:54 [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers Mika Westerberg
  2014-07-25  6:54 ` [PATCH 1/3] gpio: lynxpoint: Convert to use gpiolib irqchip Mika Westerberg
  2014-07-25  6:54 ` [PATCH 2/3] pinctrl: baytrail: " Mika Westerberg
@ 2014-07-25  6:54 ` Mika Westerberg
  2014-07-28 10:22 ` [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use " Linus Walleij
  3 siblings, 0 replies; 5+ messages in thread
From: Mika Westerberg @ 2014-07-25  6:54 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Alexandre Courbot, Rafael J. Wysocki, Zhu Lejun, Yang Bin,
	Mathias Nyman, Mika Westerberg, linux-gpio, linux-kernel

Since now we have irqchip helpers that the GPIO chip drivers are supposed
to use if possible, we can move the registration of ACPI events to happen
in these helpers. This seems to be more natural place and might encourage
GPIO chip driver writers to take advantage of the irqchip helpers.

We make the functions available to GPIO chip drivers via private gpiolib.h,
just in case generic irqchip helpers are not suitable.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/gpio/gpiolib-acpi.c | 38 ++++++++++++++++++++++++++++----------
 drivers/gpio/gpiolib.c      |  4 ++++
 drivers/gpio/gpiolib.h      |  9 +++++++++
 3 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index 4a987917c186..f3edaeaf3b64 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -221,7 +221,7 @@ fail_free_desc:
 
 /**
  * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
- * @acpi_gpio:      ACPI GPIO chip
+ * @chip:      GPIO chip
  *
  * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
  * handled by ACPI event methods which need to be called from the GPIO
@@ -229,11 +229,21 @@ fail_free_desc:
  * gpio pins have acpi event methods and assigns interrupt handlers that calls
  * the acpi event methods for those pins.
  */
-static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
+void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
 {
-	struct gpio_chip *chip = acpi_gpio->chip;
+	struct acpi_gpio_chip *acpi_gpio;
+	acpi_handle handle;
+	acpi_status status;
+
+	if (!chip->dev || !chip->to_irq)
+		return;
 
-	if (!chip->to_irq)
+	handle = ACPI_HANDLE(chip->dev);
+	if (!handle)
+		return;
+
+	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
+	if (ACPI_FAILURE(status))
 		return;
 
 	INIT_LIST_HEAD(&acpi_gpio->events);
@@ -243,17 +253,27 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
 
 /**
  * acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts.
- * @acpi_gpio:      ACPI GPIO chip
+ * @chip:      GPIO chip
  *
  * Free interrupts associated with GPIO ACPI event method for the given
  * GPIO chip.
  */
-static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
+void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
 {
+	struct acpi_gpio_chip *acpi_gpio;
 	struct acpi_gpio_event *event, *ep;
-	struct gpio_chip *chip = acpi_gpio->chip;
+	acpi_handle handle;
+	acpi_status status;
+
+	if (!chip->dev || !chip->to_irq)
+		return;
 
-	if (!chip->to_irq)
+	handle = ACPI_HANDLE(chip->dev);
+	if (!handle)
+		return;
+
+	status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
+	if (ACPI_FAILURE(status))
 		return;
 
 	list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
@@ -525,7 +545,6 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
 		return;
 	}
 
-	acpi_gpiochip_request_interrupts(acpi_gpio);
 	acpi_gpiochip_request_regions(acpi_gpio);
 }
 
@@ -549,7 +568,6 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
 	}
 
 	acpi_gpiochip_free_regions(acpi_gpio);
-	acpi_gpiochip_free_interrupts(acpi_gpio);
 
 	acpi_detach_data(handle, acpi_gpio_chip_dh);
 	kfree(acpi_gpio);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 2ebc9071e354..5a543969ad40 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1474,6 +1474,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip)
 {
 	unsigned int offset;
 
+	acpi_gpiochip_free_interrupts(gpiochip);
+
 	/* Remove all IRQ mappings and delete the domain */
 	if (gpiochip->irqdomain) {
 		for (offset = 0; offset < gpiochip->ngpio; offset++)
@@ -1567,6 +1569,8 @@ int gpiochip_irqchip_add(struct gpio_chip *gpiochip,
 			gpiochip->irq_base = irq_base;
 	}
 
+	acpi_gpiochip_request_interrupts(gpiochip);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(gpiochip_irqchip_add);
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 1a4103dd38df..6c45cef6620c 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -31,12 +31,21 @@ struct acpi_gpio_info {
 void acpi_gpiochip_add(struct gpio_chip *chip);
 void acpi_gpiochip_remove(struct gpio_chip *chip);
 
+void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
+void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
+
 struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
 					  struct acpi_gpio_info *info);
 #else
 static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
 static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
 
+static inline void
+acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
+
+static inline void
+acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
+
 static inline struct gpio_desc *
 acpi_get_gpiod_by_index(struct device *dev, int index,
 			struct acpi_gpio_info *info)
-- 
2.0.1


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

* Re: [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers
  2014-07-25  6:54 [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers Mika Westerberg
                   ` (2 preceding siblings ...)
  2014-07-25  6:54 ` [PATCH 3/3] gpio / ACPI: Move event handling registration to gpiolib irqchip helpers Mika Westerberg
@ 2014-07-28 10:22 ` Linus Walleij
  3 siblings, 0 replies; 5+ messages in thread
From: Linus Walleij @ 2014-07-28 10:22 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Alexandre Courbot, Rafael J. Wysocki, Zhu Lejun, Yang Bin,
	Mathias Nyman, linux-gpio@vger.kernel.org,
	linux-kernel@vger.kernel.org

On Fri, Jul 25, 2014 at 8:54 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> This series converts the Intel Lynxpoint and Baytrail GPIO drivers to use
> the new irqchip helper functions and then moves ACPI event registration to
> happen in the helpers as well.

Excellent patch set and irresistable to merge.

Applied patches 1 & 3 to the GPIO tree and patch 2 to the pinctrl tree.

Yours,
Linus Walleij

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

end of thread, other threads:[~2014-07-28 10:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-25  6:54 [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use irqchip helpers Mika Westerberg
2014-07-25  6:54 ` [PATCH 1/3] gpio: lynxpoint: Convert to use gpiolib irqchip Mika Westerberg
2014-07-25  6:54 ` [PATCH 2/3] pinctrl: baytrail: " Mika Westerberg
2014-07-25  6:54 ` [PATCH 3/3] gpio / ACPI: Move event handling registration to gpiolib irqchip helpers Mika Westerberg
2014-07-28 10:22 ` [PATCH 0/3] gpio: Convert two Intel GPIO drivers to use " Linus Walleij

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).