.. | .. |
---|
22 | 22 | #include <linux/irq.h> |
---|
23 | 23 | #include <linux/gpio/driver.h> |
---|
24 | 24 | #include <linux/bitops.h> |
---|
| 25 | +#include <linux/interrupt.h> |
---|
25 | 26 | |
---|
26 | 27 | #define MPC8XXX_GPIO_PINS 32 |
---|
27 | 28 | |
---|
.. | .. |
---|
32 | 33 | #define GPIO_IMR 0x10 |
---|
33 | 34 | #define GPIO_ICR 0x14 |
---|
34 | 35 | #define GPIO_ICR2 0x18 |
---|
| 36 | +#define GPIO_IBE 0x18 |
---|
35 | 37 | |
---|
36 | 38 | struct mpc8xxx_gpio_chip { |
---|
37 | 39 | struct gpio_chip gc; |
---|
.. | .. |
---|
105 | 107 | return -ENXIO; |
---|
106 | 108 | } |
---|
107 | 109 | |
---|
108 | | -static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc) |
---|
| 110 | +static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data) |
---|
109 | 111 | { |
---|
110 | | - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc); |
---|
111 | | - struct irq_chip *chip = irq_desc_get_chip(desc); |
---|
| 112 | + struct mpc8xxx_gpio_chip *mpc8xxx_gc = data; |
---|
112 | 113 | struct gpio_chip *gc = &mpc8xxx_gc->gc; |
---|
113 | | - unsigned int mask; |
---|
| 114 | + unsigned long mask; |
---|
| 115 | + int i; |
---|
114 | 116 | |
---|
115 | 117 | mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER) |
---|
116 | 118 | & gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR); |
---|
117 | | - if (mask) |
---|
118 | | - generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, |
---|
119 | | - 32 - ffs(mask))); |
---|
120 | | - if (chip->irq_eoi) |
---|
121 | | - chip->irq_eoi(&desc->irq_data); |
---|
| 119 | + for_each_set_bit(i, &mask, 32) |
---|
| 120 | + generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, 31 - i)); |
---|
| 121 | + |
---|
| 122 | + return IRQ_HANDLED; |
---|
122 | 123 | } |
---|
123 | 124 | |
---|
124 | 125 | static void mpc8xxx_irq_unmask(struct irq_data *d) |
---|
.. | .. |
---|
168 | 169 | |
---|
169 | 170 | switch (flow_type) { |
---|
170 | 171 | case IRQ_TYPE_EDGE_FALLING: |
---|
| 172 | + case IRQ_TYPE_LEVEL_LOW: |
---|
171 | 173 | raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); |
---|
172 | 174 | gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, |
---|
173 | 175 | gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) |
---|
.. | .. |
---|
291 | 293 | { .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, }, |
---|
292 | 294 | { .compatible = "fsl,mpc5125-gpio", .data = &mpc5125_gpio_devtype, }, |
---|
293 | 295 | { .compatible = "fsl,pq3-gpio", }, |
---|
| 296 | + { .compatible = "fsl,ls1028a-gpio", }, |
---|
| 297 | + { .compatible = "fsl,ls1088a-gpio", }, |
---|
294 | 298 | { .compatible = "fsl,qoriq-gpio", }, |
---|
295 | 299 | {} |
---|
296 | 300 | }; |
---|
.. | .. |
---|
359 | 363 | |
---|
360 | 364 | gc->to_irq = mpc8xxx_gpio_to_irq; |
---|
361 | 365 | |
---|
362 | | - ret = gpiochip_add_data(gc, mpc8xxx_gc); |
---|
| 366 | + /* |
---|
| 367 | + * The GPIO Input Buffer Enable register(GPIO_IBE) is used to control |
---|
| 368 | + * the input enable of each individual GPIO port. When an individual |
---|
| 369 | + * GPIO port’s direction is set to input (GPIO_GPDIR[DRn=0]), the |
---|
| 370 | + * associated input enable must be set (GPIOxGPIE[IEn]=1) to propagate |
---|
| 371 | + * the port value to the GPIO Data Register. |
---|
| 372 | + */ |
---|
| 373 | + if (of_device_is_compatible(np, "fsl,qoriq-gpio") || |
---|
| 374 | + of_device_is_compatible(np, "fsl,ls1028a-gpio") || |
---|
| 375 | + of_device_is_compatible(np, "fsl,ls1088a-gpio")) |
---|
| 376 | + gc->write_reg(mpc8xxx_gc->regs + GPIO_IBE, 0xffffffff); |
---|
| 377 | + |
---|
| 378 | + ret = devm_gpiochip_add_data(&pdev->dev, gc, mpc8xxx_gc); |
---|
363 | 379 | if (ret) { |
---|
364 | 380 | pr_err("%pOF: GPIO chip registration failed with status %d\n", |
---|
365 | 381 | np, ret); |
---|
.. | .. |
---|
379 | 395 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff); |
---|
380 | 396 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0); |
---|
381 | 397 | |
---|
382 | | - irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, |
---|
383 | | - mpc8xxx_gpio_irq_cascade, mpc8xxx_gc); |
---|
| 398 | + ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn, |
---|
| 399 | + mpc8xxx_gpio_irq_cascade, |
---|
| 400 | + IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", |
---|
| 401 | + mpc8xxx_gc); |
---|
| 402 | + if (ret) { |
---|
| 403 | + dev_err(&pdev->dev, "%s: failed to devm_request_irq(%d), ret = %d\n", |
---|
| 404 | + np->full_name, mpc8xxx_gc->irqn, ret); |
---|
| 405 | + goto err; |
---|
| 406 | + } |
---|
| 407 | + |
---|
384 | 408 | return 0; |
---|
385 | 409 | err: |
---|
| 410 | + if (mpc8xxx_gc->irq) |
---|
| 411 | + irq_domain_remove(mpc8xxx_gc->irq); |
---|
386 | 412 | iounmap(mpc8xxx_gc->regs); |
---|
387 | 413 | return ret; |
---|
388 | 414 | } |
---|
.. | .. |
---|
396 | 422 | irq_domain_remove(mpc8xxx_gc->irq); |
---|
397 | 423 | } |
---|
398 | 424 | |
---|
399 | | - gpiochip_remove(&mpc8xxx_gc->gc); |
---|
400 | 425 | iounmap(mpc8xxx_gc->regs); |
---|
401 | 426 | |
---|
402 | 427 | return 0; |
---|