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