diff options
Diffstat (limited to 'drivers/gpio/gpio-dln2.c')
-rw-r--r-- | drivers/gpio/gpio-dln2.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 8a33c2fc174d..71fa437b491f 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -200,9 +200,9 @@ static int dln2_gpio_get_direction(struct gpio_chip *chip, unsigned offset) struct dln2_gpio *dln2 = gpiochip_get_data(chip); if (test_bit(offset, dln2->output_enabled)) - return 0; + return GPIO_LINE_DIRECTION_OUT; - return 1; + return GPIO_LINE_DIRECTION_IN; } static int dln2_gpio_get(struct gpio_chip *chip, unsigned int offset) @@ -214,7 +214,7 @@ static int dln2_gpio_get(struct gpio_chip *chip, unsigned int offset) if (dir < 0) return dir; - if (dir == 1) + if (dir == GPIO_LINE_DIRECTION_IN) return dln2_gpio_pin_get_in_val(dln2, offset); return dln2_gpio_pin_get_out_val(dln2, offset); @@ -305,6 +305,7 @@ static void dln2_irq_unmask(struct irq_data *irqd) struct dln2_gpio *dln2 = gpiochip_get_data(gc); int pin = irqd_to_hwirq(irqd); + gpiochip_enable_irq(gc, pin); set_bit(pin, dln2->unmasked_irqs); } @@ -315,6 +316,7 @@ static void dln2_irq_mask(struct irq_data *irqd) int pin = irqd_to_hwirq(irqd); clear_bit(pin, dln2->unmasked_irqs); + gpiochip_disable_irq(gc, pin); } static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) @@ -383,19 +385,21 @@ static void dln2_irq_bus_unlock(struct irq_data *irqd) mutex_unlock(&dln2->irq_lock); } -static struct irq_chip dln2_gpio_irqchip = { +static const struct irq_chip dln2_irqchip = { .name = "dln2-irq", .irq_mask = dln2_irq_mask, .irq_unmask = dln2_irq_unmask, .irq_set_type = dln2_irq_set_type, .irq_bus_lock = dln2_irq_bus_lock, .irq_bus_sync_unlock = dln2_irq_bus_unlock, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, }; static void dln2_gpio_event(struct platform_device *pdev, u16 echo, const void *data, int len) { - int pin, irq; + int pin, ret; const struct { __le16 count; @@ -416,30 +420,27 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo, return; } - irq = irq_find_mapping(dln2->gpio.irq.domain, pin); - if (!irq) { - dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin); - return; - } - switch (dln2->irq_type[pin]) { case DLN2_GPIO_EVENT_CHANGE_RISING: - if (event->value) - generic_handle_irq(irq); + if (!event->value) + return; break; case DLN2_GPIO_EVENT_CHANGE_FALLING: - if (!event->value) - generic_handle_irq(irq); + if (event->value) + return; break; - default: - generic_handle_irq(irq); } + + ret = generic_handle_domain_irq(dln2->gpio.irq.domain, pin); + if (unlikely(ret)) + dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin); } static int dln2_gpio_probe(struct platform_device *pdev) { struct dln2_gpio *dln2; struct device *dev = &pdev->dev; + struct gpio_irq_chip *girq; int pins; int ret; @@ -476,6 +477,15 @@ static int dln2_gpio_probe(struct platform_device *pdev) dln2->gpio.direction_output = dln2_gpio_direction_output; dln2->gpio.set_config = dln2_gpio_set_config; + girq = &dln2->gpio.irq; + gpio_irq_chip_set_chip(girq, &dln2_irqchip); + /* The event comes from the outside so no parent handler */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + platform_set_drvdata(pdev, dln2); ret = devm_gpiochip_add_data(dev, &dln2->gpio, dln2); @@ -484,13 +494,6 @@ static int dln2_gpio_probe(struct platform_device *pdev) return ret; } - ret = gpiochip_irqchip_add(&dln2->gpio, &dln2_gpio_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); - if (ret < 0) { - dev_err(dev, "failed to add irq chip: %d\n", ret); - return ret; - } - ret = dln2_register_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV, dln2_gpio_event); if (ret) { |