Pin control fixes for the v3.19 series:
- 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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJUvhsCAAoJEEEQszewGV1zZMoP/AoewI2od036rhGKD5IqH1/F 6khikDo6e3TbAHdx4iGWVzzFOK+V66lc4eokTIMDfxiaovcSBNqYBVdaIM/xunc0 S7jxTGp1EdSMqyYv6L7h+EycDAZ/sfHobOWhhgV38o5fWuGI5fGzIC2Pj0kWU/vr sMInof+dJeSPLLYMMruQpik08tku5tuGHlPnA8knRCkZxHtHWwqYiU+zl2gfDfvO uC0cQm+rXtUn/m6ua0pRSjujZDyxVOkLiBHk01qfqNfCDlBgg4J9wI+HE08HWaMC lr03oV4nZQ91aEih16g4UgsOGnxHfDZS6EU6alCWIyUPs3LEwZ07twCk1lLAjkAu Jswx8bZCmbndUfcnoImgtJLT+7zU8utBpbhzHi5rmoHF0/pVA/estk1lRGanid1B OHg3HZv30T9xdVvZCVHUD+O4b/8HQWB8EJte5yt3Qs+B6M/N3Fw1o5+fgCTXR9C1 zTRVu3VIOOX8IuY3rJ7DCme/b/N2kAkGAckbnOSoTx1MO4ECIAR0CCiF2eKzjwi6 xCAeA+4aEsJXAQQqMY4UBdpgdXtc9hRW5C4iMjcbPicoZqgAJhL8kyIyuJjOgHDy 4l6hFhFaLGEIzWMfpP7wi9y/CyZabeKq30UgInJu1GJsj7H/ZE7aPSv/vjrGyEh6 4ukizhEn8NEhVm15SUbg =YGym -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
06efe0e540
|
@ -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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
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,29 +1425,33 @@ 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)) {
|
||||||
if (data & BIT(irq))
|
u32 data, data_old, polarity;
|
||||||
polarity &= ~BIT(irq);
|
unsigned long flags;
|
||||||
else
|
|
||||||
polarity |= BIT(irq);
|
|
||||||
|
|
||||||
edge_changed = true;
|
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))
|
||||||
|
polarity &= ~BIT(irq);
|
||||||
|
else
|
||||||
|
polarity |= BIT(irq);
|
||||||
|
writel(polarity,
|
||||||
|
bank->reg_base + GPIO_INT_POLARITY);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&bank->slock, flags);
|
||||||
|
|
||||||
|
data_old = data;
|
||||||
|
data = readl_relaxed(bank->reg_base +
|
||||||
|
GPIO_EXT_PORT);
|
||||||
|
} while ((data & BIT(irq)) != (data_old & BIT(irq)));
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_handle_irq(virq);
|
generic_handle_irq(virq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bank->toggle_edge_mode && edge_changed) {
|
|
||||||
/* 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)
|
||||||
|
|
||||||
/* 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,
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue