diff options
Diffstat (limited to 'drivers/gpio/gpio-zynq.c')
-rw-r--r-- | drivers/gpio/gpio-zynq.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index c3145f91fda3..31ad5df5dbc9 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c | |||
@@ -95,6 +95,9 @@ struct zynq_gpio { | |||
95 | struct clk *clk; | 95 | struct clk *clk; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static struct irq_chip zynq_gpio_level_irqchip; | ||
99 | static struct irq_chip zynq_gpio_edge_irqchip; | ||
100 | |||
98 | /** | 101 | /** |
99 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank | 102 | * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank |
100 | * for a given pin in the GPIO device | 103 | * for a given pin in the GPIO device |
@@ -410,6 +413,15 @@ static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type) | |||
410 | gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); | 413 | gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); |
411 | writel_relaxed(int_any, | 414 | writel_relaxed(int_any, |
412 | gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); | 415 | gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); |
416 | |||
417 | if (type & IRQ_TYPE_LEVEL_MASK) { | ||
418 | __irq_set_chip_handler_name_locked(irq_data->irq, | ||
419 | &zynq_gpio_level_irqchip, handle_fasteoi_irq, NULL); | ||
420 | } else { | ||
421 | __irq_set_chip_handler_name_locked(irq_data->irq, | ||
422 | &zynq_gpio_edge_irqchip, handle_level_irq, NULL); | ||
423 | } | ||
424 | |||
413 | return 0; | 425 | return 0; |
414 | } | 426 | } |
415 | 427 | ||
@@ -424,9 +436,21 @@ static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) | |||
424 | } | 436 | } |
425 | 437 | ||
426 | /* irq chip descriptor */ | 438 | /* irq chip descriptor */ |
427 | static struct irq_chip zynq_gpio_irqchip = { | 439 | static struct irq_chip zynq_gpio_level_irqchip = { |
428 | .name = DRIVER_NAME, | 440 | .name = DRIVER_NAME, |
429 | .irq_enable = zynq_gpio_irq_enable, | 441 | .irq_enable = zynq_gpio_irq_enable, |
442 | .irq_eoi = zynq_gpio_irq_ack, | ||
443 | .irq_mask = zynq_gpio_irq_mask, | ||
444 | .irq_unmask = zynq_gpio_irq_unmask, | ||
445 | .irq_set_type = zynq_gpio_set_irq_type, | ||
446 | .irq_set_wake = zynq_gpio_set_wake, | ||
447 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, | ||
448 | }; | ||
449 | |||
450 | static struct irq_chip zynq_gpio_edge_irqchip = { | ||
451 | .name = DRIVER_NAME, | ||
452 | .irq_enable = zynq_gpio_irq_enable, | ||
453 | .irq_ack = zynq_gpio_irq_ack, | ||
430 | .irq_mask = zynq_gpio_irq_mask, | 454 | .irq_mask = zynq_gpio_irq_mask, |
431 | .irq_unmask = zynq_gpio_irq_unmask, | 455 | .irq_unmask = zynq_gpio_irq_unmask, |
432 | .irq_set_type = zynq_gpio_set_irq_type, | 456 | .irq_set_type = zynq_gpio_set_irq_type, |
@@ -469,10 +493,6 @@ static void zynq_gpio_irqhandler(unsigned int irq, struct irq_desc *desc) | |||
469 | offset); | 493 | offset); |
470 | generic_handle_irq(gpio_irq); | 494 | generic_handle_irq(gpio_irq); |
471 | } | 495 | } |
472 | |||
473 | /* clear IRQ in HW */ | ||
474 | writel_relaxed(int_sts, gpio->base_addr + | ||
475 | ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); | ||
476 | } | 496 | } |
477 | } | 497 | } |
478 | 498 | ||
@@ -610,14 +630,14 @@ static int zynq_gpio_probe(struct platform_device *pdev) | |||
610 | writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + | 630 | writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + |
611 | ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); | 631 | ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); |
612 | 632 | ||
613 | ret = gpiochip_irqchip_add(chip, &zynq_gpio_irqchip, 0, | 633 | ret = gpiochip_irqchip_add(chip, &zynq_gpio_edge_irqchip, 0, |
614 | handle_simple_irq, IRQ_TYPE_NONE); | 634 | handle_level_irq, IRQ_TYPE_NONE); |
615 | if (ret) { | 635 | if (ret) { |
616 | dev_err(&pdev->dev, "Failed to add irq chip\n"); | 636 | dev_err(&pdev->dev, "Failed to add irq chip\n"); |
617 | goto err_rm_gpiochip; | 637 | goto err_rm_gpiochip; |
618 | } | 638 | } |
619 | 639 | ||
620 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_irqchip, irq, | 640 | gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, irq, |
621 | zynq_gpio_irqhandler); | 641 | zynq_gpio_irqhandler); |
622 | 642 | ||
623 | pm_runtime_set_active(&pdev->dev); | 643 | pm_runtime_set_active(&pdev->dev); |