diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-20 04:23:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-01-20 04:23:41 -0500 |
commit | 06efe0e54018cb19cf0807447dc3ac747ffcfd1c (patch) | |
tree | ae5dcb7d12943a0d977f68c40b0d79052f346b11 | |
parent | eef8f4c2acac6fae84f2d959a145fa3cad4d00c9 (diff) | |
parent | dbe752a34d4bd862de154d1e1f8eb9b649601f77 (diff) |
Merge tag 'pinctrl-v3.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl
Pull pin control fixes from Linus Walleij:
"Here is a (hopefully final) slew of pin control fixes for the v3.19
series. The deadlock fix is kind of serious and tagged for stable,
the rest is business as usual.
- Fix two deadlocks around the pin control mutexes, a long-standing
issue that manifest itself in plug/unplug of pin controllers.
(Tagged for stable.)
- Handle an error path with zero functions in the Qualcomm pin
controller.
- Drop a bogus second GPIO chip added in the Lantiq driver.
- Fix sudden IRQ loss on Rockchip pin controllers.
- Register the GIT tree in MAINTAINERS"
* tag 'pinctrl-v3.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
pinctrl: MAINTAINERS: add git tree reference
pinctrl: qcom: Don't iterate past end of function array
pinctrl: lantiq: remove bogus of_gpio_chip_add
pinctrl: Fix two deadlocks
pinctrl: rockchip: Avoid losing interrupts when supporting both edges
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/pinctrl/core.c | 5 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-rockchip.c | 45 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-xway.c | 2 | ||||
-rw-r--r-- | drivers/pinctrl/qcom/pinctrl-msm.c | 4 |
5 files changed, 26 insertions, 31 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 56de2e34c9f3..64e13d5c1e65 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -7410,6 +7410,7 @@ F: drivers/crypto/picoxcell* | |||
7410 | PIN CONTROL SUBSYSTEM | 7410 | PIN CONTROL SUBSYSTEM |
7411 | M: Linus Walleij <linus.walleij@linaro.org> | 7411 | M: Linus Walleij <linus.walleij@linaro.org> |
7412 | L: linux-gpio@vger.kernel.org | 7412 | L: linux-gpio@vger.kernel.org |
7413 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git | ||
7413 | S: Maintained | 7414 | S: Maintained |
7414 | F: drivers/pinctrl/ | 7415 | F: drivers/pinctrl/ |
7415 | F: include/linux/pinctrl/ | 7416 | F: include/linux/pinctrl/ |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e4f65510c87e..89dca77ca038 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) | |||
1801 | if (pctldev == NULL) | 1801 | if (pctldev == NULL) |
1802 | return; | 1802 | return; |
1803 | 1803 | ||
1804 | mutex_lock(&pinctrldev_list_mutex); | ||
1805 | mutex_lock(&pctldev->mutex); | 1804 | mutex_lock(&pctldev->mutex); |
1806 | |||
1807 | pinctrl_remove_device_debugfs(pctldev); | 1805 | pinctrl_remove_device_debugfs(pctldev); |
1806 | mutex_unlock(&pctldev->mutex); | ||
1808 | 1807 | ||
1809 | if (!IS_ERR(pctldev->p)) | 1808 | if (!IS_ERR(pctldev->p)) |
1810 | pinctrl_put(pctldev->p); | 1809 | pinctrl_put(pctldev->p); |
1811 | 1810 | ||
1811 | mutex_lock(&pinctrldev_list_mutex); | ||
1812 | mutex_lock(&pctldev->mutex); | ||
1812 | /* TODO: check that no pinmuxes are still active? */ | 1813 | /* TODO: check that no pinmuxes are still active? */ |
1813 | list_del(&pctldev->node); | 1814 | list_del(&pctldev->node); |
1814 | /* Destroy descriptor tree */ | 1815 | /* Destroy descriptor tree */ |
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); |
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index c5cef59f5965..779950c62e53 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c | |||
@@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev) | |||
798 | 798 | ||
799 | /* load the gpio chip */ | 799 | /* load the gpio chip */ |
800 | xway_chip.dev = &pdev->dev; | 800 | xway_chip.dev = &pdev->dev; |
801 | of_gpiochip_add(&xway_chip); | ||
802 | ret = gpiochip_add(&xway_chip); | 801 | ret = gpiochip_add(&xway_chip); |
803 | if (ret) { | 802 | if (ret) { |
804 | of_gpiochip_remove(&xway_chip); | ||
805 | dev_err(&pdev->dev, "Failed to register gpio chip\n"); | 803 | dev_err(&pdev->dev, "Failed to register gpio chip\n"); |
806 | return ret; | 804 | return ret; |
807 | } | 805 | } |
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index e730935fa457..ed7017df065d 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -865,10 +865,10 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action, | |||
865 | 865 | ||
866 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) | 866 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) |
867 | { | 867 | { |
868 | int i = 0; | 868 | int i; |
869 | const struct msm_function *func = pctrl->soc->functions; | 869 | const struct msm_function *func = pctrl->soc->functions; |
870 | 870 | ||
871 | for (; i <= pctrl->soc->nfunctions; i++) | 871 | for (i = 0; i < pctrl->soc->nfunctions; i++) |
872 | if (!strcmp(func[i].name, "ps_hold")) { | 872 | if (!strcmp(func[i].name, "ps_hold")) { |
873 | pctrl->restart_nb.notifier_call = msm_ps_hold_restart; | 873 | pctrl->restart_nb.notifier_call = msm_ps_hold_restart; |
874 | pctrl->restart_nb.priority = 128; | 874 | pctrl->restart_nb.priority = 128; |