diff options
Diffstat (limited to 'drivers/pinctrl/pinctrl-rockchip.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 45 |
1 files changed, 20 insertions, 25 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 3c22dbebc80f..43eacc924b7e 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
@@ -1398,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1398 | { | 1398 | { |
1399 | struct irq_chip *chip = irq_get_chip(irq); | 1399 | struct irq_chip *chip = irq_get_chip(irq); |
1400 | struct rockchip_pin_bank *bank = irq_get_handler_data(irq); | 1400 | struct rockchip_pin_bank *bank = irq_get_handler_data(irq); |
1401 | u32 polarity = 0, data = 0; | ||
1402 | u32 pend; | 1401 | u32 pend; |
1403 | bool edge_changed = false; | ||
1404 | unsigned long flags; | ||
1405 | 1402 | ||
1406 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); | 1403 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); |
1407 | 1404 | ||
@@ -1409,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1409 | 1406 | ||
1410 | pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); | 1407 | pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); |
1411 | 1408 | ||
1412 | if (bank->toggle_edge_mode) { | ||
1413 | polarity = readl_relaxed(bank->reg_base + | ||
1414 | GPIO_INT_POLARITY); | ||
1415 | data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); | ||
1416 | } | ||
1417 | |||
1418 | while (pend) { | 1409 | while (pend) { |
1419 | unsigned int virq; | 1410 | unsigned int virq; |
1420 | 1411 | ||
@@ -1434,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1434 | * needs manual intervention. | 1425 | * needs manual intervention. |
1435 | */ | 1426 | */ |
1436 | if (bank->toggle_edge_mode & BIT(irq)) { | 1427 | if (bank->toggle_edge_mode & BIT(irq)) { |
1437 | if (data & BIT(irq)) | 1428 | u32 data, data_old, polarity; |
1438 | polarity &= ~BIT(irq); | 1429 | unsigned long flags; |
1439 | else | ||
1440 | polarity |= BIT(irq); | ||
1441 | 1430 | ||
1442 | edge_changed = true; | 1431 | data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); |
1443 | } | 1432 | do { |
1433 | spin_lock_irqsave(&bank->slock, flags); | ||
1444 | 1434 | ||
1445 | generic_handle_irq(virq); | 1435 | polarity = readl_relaxed(bank->reg_base + |
1446 | } | 1436 | GPIO_INT_POLARITY); |
1437 | if (data & BIT(irq)) | ||
1438 | polarity &= ~BIT(irq); | ||
1439 | else | ||
1440 | polarity |= BIT(irq); | ||
1441 | writel(polarity, | ||
1442 | bank->reg_base + GPIO_INT_POLARITY); | ||
1447 | 1443 | ||
1448 | if (bank->toggle_edge_mode && edge_changed) { | 1444 | spin_unlock_irqrestore(&bank->slock, flags); |
1449 | /* Interrupt params should only be set with ints disabled */ | ||
1450 | spin_lock_irqsave(&bank->slock, flags); | ||
1451 | 1445 | ||
1452 | data = readl_relaxed(bank->reg_base + GPIO_INTEN); | 1446 | data_old = data; |
1453 | writel_relaxed(0, bank->reg_base + GPIO_INTEN); | 1447 | data = readl_relaxed(bank->reg_base + |
1454 | writel(polarity, bank->reg_base + GPIO_INT_POLARITY); | 1448 | GPIO_EXT_PORT); |
1455 | writel(data, bank->reg_base + GPIO_INTEN); | 1449 | } while ((data & BIT(irq)) != (data_old & BIT(irq))); |
1450 | } | ||
1456 | 1451 | ||
1457 | spin_unlock_irqrestore(&bank->slock, flags); | 1452 | generic_handle_irq(virq); |
1458 | } | 1453 | } |
1459 | 1454 | ||
1460 | chained_irq_exit(chip, desc); | 1455 | chained_irq_exit(chip, desc); |