diff options
-rw-r--r-- | drivers/pinctrl/pinctrl-amd.c | 91 |
1 files changed, 41 insertions, 50 deletions
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 1482d132fbb8..e432ec887479 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c | |||
@@ -495,64 +495,54 @@ static struct irq_chip amd_gpio_irqchip = { | |||
495 | .flags = IRQCHIP_SKIP_SET_WAKE, | 495 | .flags = IRQCHIP_SKIP_SET_WAKE, |
496 | }; | 496 | }; |
497 | 497 | ||
498 | static void amd_gpio_irq_handler(struct irq_desc *desc) | 498 | #define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF)) |
499 | |||
500 | static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) | ||
499 | { | 501 | { |
500 | u32 i; | 502 | struct amd_gpio *gpio_dev = dev_id; |
501 | u32 off; | 503 | struct gpio_chip *gc = &gpio_dev->gc; |
502 | u32 reg; | 504 | irqreturn_t ret = IRQ_NONE; |
503 | u32 pin_reg; | 505 | unsigned int i, irqnr; |
504 | u64 reg64; | ||
505 | int handled = 0; | ||
506 | unsigned int irq; | ||
507 | unsigned long flags; | 506 | unsigned long flags; |
508 | struct irq_chip *chip = irq_desc_get_chip(desc); | 507 | u32 *regs, regval; |
509 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | 508 | u64 status, mask; |
510 | struct amd_gpio *gpio_dev = gpiochip_get_data(gc); | ||
511 | 509 | ||
512 | chained_irq_enter(chip, desc); | 510 | /* Read the wake status */ |
513 | /*enable GPIO interrupt again*/ | ||
514 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); | 511 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); |
515 | reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1); | 512 | status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1); |
516 | reg64 = reg; | 513 | status <<= 32; |
517 | reg64 = reg64 << 32; | 514 | status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0); |
518 | |||
519 | reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0); | ||
520 | reg64 |= reg; | ||
521 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); | 515 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); |
522 | 516 | ||
523 | /* | 517 | /* Bit 0-45 contain the relevant status bits */ |
524 | * first 46 bits indicates interrupt status. | 518 | status &= (1ULL << 46) - 1; |
525 | * one bit represents four interrupt sources. | 519 | regs = gpio_dev->base; |
526 | */ | 520 | for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) { |
527 | for (off = 0; off < 46 ; off++) { | 521 | if (!(status & mask)) |
528 | if (reg64 & BIT(off)) { | 522 | continue; |
529 | for (i = 0; i < 4; i++) { | 523 | status &= ~mask; |
530 | pin_reg = readl(gpio_dev->base + | 524 | |
531 | (off * 4 + i) * 4); | 525 | /* Each status bit covers four pins */ |
532 | if ((pin_reg & BIT(INTERRUPT_STS_OFF)) || | 526 | for (i = 0; i < 4; i++) { |
533 | (pin_reg & BIT(WAKE_STS_OFF))) { | 527 | regval = readl(regs + i); |
534 | irq = irq_find_mapping(gc->irqdomain, | 528 | if (!(regval & PIN_IRQ_PENDING)) |
535 | off * 4 + i); | 529 | continue; |
536 | generic_handle_irq(irq); | 530 | irq = irq_find_mapping(gc->irqdomain, irqnr + i); |
537 | writel(pin_reg, | 531 | generic_handle_irq(irq); |
538 | gpio_dev->base | 532 | /* Clear interrupt */ |
539 | + (off * 4 + i) * 4); | 533 | writel(regval, regs + i); |
540 | handled++; | 534 | ret = IRQ_HANDLED; |
541 | } | ||
542 | } | ||
543 | } | 535 | } |
544 | } | 536 | } |
545 | 537 | ||
546 | if (handled == 0) | 538 | /* Signal EOI to the GPIO unit */ |
547 | handle_bad_irq(desc); | ||
548 | |||
549 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); | 539 | raw_spin_lock_irqsave(&gpio_dev->lock, flags); |
550 | reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); | 540 | regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG); |
551 | reg |= EOI_MASK; | 541 | regval |= EOI_MASK; |
552 | writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG); | 542 | writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG); |
553 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); | 543 | raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); |
554 | 544 | ||
555 | chained_irq_exit(chip, desc); | 545 | return ret; |
556 | } | 546 | } |
557 | 547 | ||
558 | static int amd_get_groups_count(struct pinctrl_dev *pctldev) | 548 | static int amd_get_groups_count(struct pinctrl_dev *pctldev) |
@@ -821,10 +811,11 @@ static int amd_gpio_probe(struct platform_device *pdev) | |||
821 | goto out2; | 811 | goto out2; |
822 | } | 812 | } |
823 | 813 | ||
824 | gpiochip_set_chained_irqchip(&gpio_dev->gc, | 814 | ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0, |
825 | &amd_gpio_irqchip, | 815 | KBUILD_MODNAME, gpio_dev); |
826 | irq_base, | 816 | if (ret) |
827 | amd_gpio_irq_handler); | 817 | goto out2; |
818 | |||
828 | platform_set_drvdata(pdev, gpio_dev); | 819 | platform_set_drvdata(pdev, gpio_dev); |
829 | 820 | ||
830 | dev_dbg(&pdev->dev, "amd gpio driver loaded\n"); | 821 | dev_dbg(&pdev->dev, "amd gpio driver loaded\n"); |