Commit 06efe0e5 authored by Linus Torvalds's avatar Linus Torvalds

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
parents eef8f4c2 dbe752a3
...@@ -7410,6 +7410,7 @@ F: drivers/crypto/picoxcell* ...@@ -7410,6 +7410,7 @@ F: drivers/crypto/picoxcell*
PIN CONTROL SUBSYSTEM PIN CONTROL SUBSYSTEM
M: Linus Walleij <linus.walleij@linaro.org> M: Linus Walleij <linus.walleij@linaro.org>
L: linux-gpio@vger.kernel.org L: linux-gpio@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
S: Maintained S: Maintained
F: drivers/pinctrl/ F: drivers/pinctrl/
F: include/linux/pinctrl/ F: include/linux/pinctrl/
......
...@@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) ...@@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
if (pctldev == NULL) if (pctldev == NULL)
return; return;
mutex_lock(&pinctrldev_list_mutex);
mutex_lock(&pctldev->mutex); mutex_lock(&pctldev->mutex);
pinctrl_remove_device_debugfs(pctldev); pinctrl_remove_device_debugfs(pctldev);
mutex_unlock(&pctldev->mutex);
if (!IS_ERR(pctldev->p)) if (!IS_ERR(pctldev->p))
pinctrl_put(pctldev->p); pinctrl_put(pctldev->p);
mutex_lock(&pinctrldev_list_mutex);
mutex_lock(&pctldev->mutex);
/* TODO: check that no pinmuxes are still active? */ /* TODO: check that no pinmuxes are still active? */
list_del(&pctldev->node); list_del(&pctldev->node);
/* Destroy descriptor tree */ /* Destroy descriptor tree */
......
...@@ -1398,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) ...@@ -1398,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
{ {
struct irq_chip *chip = irq_get_chip(irq); struct irq_chip *chip = irq_get_chip(irq);
struct rockchip_pin_bank *bank = irq_get_handler_data(irq); struct rockchip_pin_bank *bank = irq_get_handler_data(irq);
u32 polarity = 0, data = 0;
u32 pend; u32 pend;
bool edge_changed = false;
unsigned long flags;
dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);
...@@ -1409,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) ...@@ -1409,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
if (bank->toggle_edge_mode) {
polarity = readl_relaxed(bank->reg_base +
GPIO_INT_POLARITY);
data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
}
while (pend) { while (pend) {
unsigned int virq; unsigned int virq;
...@@ -1434,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) ...@@ -1434,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
* needs manual intervention. * needs manual intervention.
*/ */
if (bank->toggle_edge_mode & BIT(irq)) { if (bank->toggle_edge_mode & BIT(irq)) {
u32 data, data_old, polarity;
unsigned long flags;
data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
do {
spin_lock_irqsave(&bank->slock, flags);
polarity = readl_relaxed(bank->reg_base +
GPIO_INT_POLARITY);
if (data & BIT(irq)) if (data & BIT(irq))
polarity &= ~BIT(irq); polarity &= ~BIT(irq);
else else
polarity |= BIT(irq); polarity |= BIT(irq);
writel(polarity,
bank->reg_base + GPIO_INT_POLARITY);
edge_changed = true; spin_unlock_irqrestore(&bank->slock, flags);
}
generic_handle_irq(virq); data_old = data;
data = readl_relaxed(bank->reg_base +
GPIO_EXT_PORT);
} while ((data & BIT(irq)) != (data_old & BIT(irq)));
} }
if (bank->toggle_edge_mode && edge_changed) { generic_handle_irq(virq);
/* Interrupt params should only be set with ints disabled */
spin_lock_irqsave(&bank->slock, flags);
data = readl_relaxed(bank->reg_base + GPIO_INTEN);
writel_relaxed(0, bank->reg_base + GPIO_INTEN);
writel(polarity, bank->reg_base + GPIO_INT_POLARITY);
writel(data, bank->reg_base + GPIO_INTEN);
spin_unlock_irqrestore(&bank->slock, flags);
} }
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
......
...@@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev) ...@@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev)
/* load the gpio chip */ /* load the gpio chip */
xway_chip.dev = &pdev->dev; xway_chip.dev = &pdev->dev;
of_gpiochip_add(&xway_chip);
ret = gpiochip_add(&xway_chip); ret = gpiochip_add(&xway_chip);
if (ret) { if (ret) {
of_gpiochip_remove(&xway_chip);
dev_err(&pdev->dev, "Failed to register gpio chip\n"); dev_err(&pdev->dev, "Failed to register gpio chip\n");
return ret; return ret;
} }
......
...@@ -865,10 +865,10 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action, ...@@ -865,10 +865,10 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action,
static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl)
{ {
int i = 0; int i;
const struct msm_function *func = pctrl->soc->functions; const struct msm_function *func = pctrl->soc->functions;
for (; i <= pctrl->soc->nfunctions; i++) for (i = 0; i < pctrl->soc->nfunctions; i++)
if (!strcmp(func[i].name, "ps_hold")) { if (!strcmp(func[i].name, "ps_hold")) {
pctrl->restart_nb.notifier_call = msm_ps_hold_restart; pctrl->restart_nb.notifier_call = msm_ps_hold_restart;
pctrl->restart_nb.priority = 128; pctrl->restart_nb.priority = 128;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment