diff options
-rw-r--r-- | drivers/gpio/Kconfig | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-xlp.c | 21 |
2 files changed, 12 insertions, 11 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 597b8d4ab74f..77a796d2f9e1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -512,7 +512,7 @@ config GPIO_XILINX | |||
512 | 512 | ||
513 | config GPIO_XLP | 513 | config GPIO_XLP |
514 | tristate "Netlogic XLP GPIO support" | 514 | tristate "Netlogic XLP GPIO support" |
515 | depends on CPU_XLP | 515 | depends on CPU_XLP && OF_GPIO |
516 | select GPIOLIB_IRQCHIP | 516 | select GPIOLIB_IRQCHIP |
517 | help | 517 | help |
518 | This driver provides support for GPIO interface on Netlogic XLP MIPS64 | 518 | This driver provides support for GPIO interface on Netlogic XLP MIPS64 |
diff --git a/drivers/gpio/gpio-xlp.c b/drivers/gpio/gpio-xlp.c index e02499a15e72..bc06a2cd2c1d 100644 --- a/drivers/gpio/gpio-xlp.c +++ b/drivers/gpio/gpio-xlp.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/irqchip/chained_irq.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * XLP GPIO has multiple 32 bit registers for each feature where each register | 24 | * XLP GPIO has multiple 32 bit registers for each feature where each register |
@@ -208,25 +209,28 @@ static struct irq_chip xlp_gpio_irq_chip = { | |||
208 | .flags = IRQCHIP_ONESHOT_SAFE, | 209 | .flags = IRQCHIP_ONESHOT_SAFE, |
209 | }; | 210 | }; |
210 | 211 | ||
211 | static irqreturn_t xlp_gpio_generic_handler(int irq, void *data) | 212 | static void xlp_gpio_generic_handler(struct irq_desc *desc) |
212 | { | 213 | { |
213 | struct xlp_gpio_priv *priv = data; | 214 | struct xlp_gpio_priv *priv = irq_desc_get_handler_data(desc); |
215 | struct irq_chip *irqchip = irq_desc_get_chip(desc); | ||
214 | int gpio, regoff; | 216 | int gpio, regoff; |
215 | u32 gpio_stat; | 217 | u32 gpio_stat; |
216 | 218 | ||
217 | regoff = -1; | 219 | regoff = -1; |
218 | gpio_stat = 0; | 220 | gpio_stat = 0; |
221 | |||
222 | chained_irq_enter(irqchip, desc); | ||
219 | for_each_set_bit(gpio, priv->gpio_enabled_mask, XLP_MAX_NR_GPIO) { | 223 | for_each_set_bit(gpio, priv->gpio_enabled_mask, XLP_MAX_NR_GPIO) { |
220 | if (regoff != gpio / XLP_GPIO_REGSZ) { | 224 | if (regoff != gpio / XLP_GPIO_REGSZ) { |
221 | regoff = gpio / XLP_GPIO_REGSZ; | 225 | regoff = gpio / XLP_GPIO_REGSZ; |
222 | gpio_stat = readl(priv->gpio_intr_stat + regoff * 4); | 226 | gpio_stat = readl(priv->gpio_intr_stat + regoff * 4); |
223 | } | 227 | } |
228 | |||
224 | if (gpio_stat & BIT(gpio % XLP_GPIO_REGSZ)) | 229 | if (gpio_stat & BIT(gpio % XLP_GPIO_REGSZ)) |
225 | generic_handle_irq(irq_find_mapping( | 230 | generic_handle_irq(irq_find_mapping( |
226 | priv->chip.irqdomain, gpio)); | 231 | priv->chip.irqdomain, gpio)); |
227 | } | 232 | } |
228 | 233 | chained_irq_exit(irqchip, desc); | |
229 | return IRQ_HANDLED; | ||
230 | } | 234 | } |
231 | 235 | ||
232 | static int xlp_gpio_dir_output(struct gpio_chip *gc, unsigned gpio, int state) | 236 | static int xlp_gpio_dir_output(struct gpio_chip *gc, unsigned gpio, int state) |
@@ -378,12 +382,6 @@ static int xlp_gpio_probe(struct platform_device *pdev) | |||
378 | gc->get = xlp_gpio_get; | 382 | gc->get = xlp_gpio_get; |
379 | 383 | ||
380 | spin_lock_init(&priv->lock); | 384 | spin_lock_init(&priv->lock); |
381 | |||
382 | err = devm_request_irq(&pdev->dev, irq, xlp_gpio_generic_handler, | ||
383 | IRQ_TYPE_NONE, pdev->name, priv); | ||
384 | if (err) | ||
385 | return err; | ||
386 | |||
387 | irq_base = irq_alloc_descs(-1, XLP_GPIO_IRQ_BASE, gc->ngpio, 0); | 385 | irq_base = irq_alloc_descs(-1, XLP_GPIO_IRQ_BASE, gc->ngpio, 0); |
388 | if (irq_base < 0) { | 386 | if (irq_base < 0) { |
389 | dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); | 387 | dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n"); |
@@ -401,6 +399,9 @@ static int xlp_gpio_probe(struct platform_device *pdev) | |||
401 | goto out_gpio_remove; | 399 | goto out_gpio_remove; |
402 | } | 400 | } |
403 | 401 | ||
402 | gpiochip_set_chained_irqchip(gc, &xlp_gpio_irq_chip, irq, | ||
403 | xlp_gpio_generic_handler); | ||
404 | |||
404 | dev_info(&pdev->dev, "registered %d GPIOs\n", gc->ngpio); | 405 | dev_info(&pdev->dev, "registered %d GPIOs\n", gc->ngpio); |
405 | 406 | ||
406 | return 0; | 407 | return 0; |