diff options
Diffstat (limited to 'drivers/gpio/gpio-timberdale.c')
| -rw-r--r-- | drivers/gpio/gpio-timberdale.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index de14949a3fe5..f488939dd00a 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -43,9 +43,10 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, unsigned offset, bool enabled) { struct timbgpio *tgpio = gpiochip_get_data(gpio); + unsigned long flags; u32 reg; - spin_lock(&tgpio->lock); + spin_lock_irqsave(&tgpio->lock, flags); reg = ioread32(tgpio->membase + offset); if (enabled) @@ -54,7 +55,7 @@ static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, reg &= ~(1 << index); iowrite32(reg, tgpio->membase + offset); - spin_unlock(&tgpio->lock); + spin_unlock_irqrestore(&tgpio->lock, flags); return 0; } @@ -79,10 +80,9 @@ static int timbgpio_gpio_direction_output(struct gpio_chip *gpio, return timbgpio_update_bit(gpio, nr, TGPIODIR, false); } -static void timbgpio_gpio_set(struct gpio_chip *gpio, - unsigned nr, int val) +static int timbgpio_gpio_set(struct gpio_chip *gpio, unsigned int nr, int val) { - timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0); + return timbgpio_update_bit(gpio, nr, TGPIOVAL, val != 0); } static int timbgpio_to_irq(struct gpio_chip *gpio, unsigned offset) @@ -102,20 +102,26 @@ static void timbgpio_irq_disable(struct irq_data *d) { struct timbgpio *tgpio = irq_data_get_irq_chip_data(d); int offset = d->irq - tgpio->irq_base; + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; spin_lock_irqsave(&tgpio->lock, flags); tgpio->last_ier &= ~(1UL << offset); iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); spin_unlock_irqrestore(&tgpio->lock, flags); + + gpiochip_disable_irq(&tgpio->gpio, hwirq); } static void timbgpio_irq_enable(struct irq_data *d) { struct timbgpio *tgpio = irq_data_get_irq_chip_data(d); int offset = d->irq - tgpio->irq_base; + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; + gpiochip_enable_irq(&tgpio->gpio, hwirq); + spin_lock_irqsave(&tgpio->lock, flags); tgpio->last_ier |= 1UL << offset; iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); @@ -131,7 +137,7 @@ static int timbgpio_irq_type(struct irq_data *d, unsigned trigger) u32 ver; int ret = 0; - if (offset < 0 || offset > tgpio->gpio.ngpio) + if (offset < 0 || offset >= tgpio->gpio.ngpio) return -EINVAL; ver = ioread32(tgpio->membase + TGPIO_VER); @@ -204,11 +210,13 @@ static void timbgpio_irq(struct irq_desc *desc) iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); } -static struct irq_chip timbgpio_irqchip = { +static const struct irq_chip timbgpio_irqchip = { .name = "GPIO", .irq_enable = timbgpio_irq_enable, .irq_disable = timbgpio_irq_disable, .irq_set_type = timbgpio_irq_type, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static int timbgpio_probe(struct platform_device *pdev) @@ -256,8 +264,6 @@ static int timbgpio_probe(struct platform_device *pdev) if (err) return err; - platform_set_drvdata(pdev, tgpio); - /* make sure to disable interrupts */ iowrite32(0x0, tgpio->membase + TGPIO_IER); |
