Skip to content

Commit

Permalink
Merge tag 'pinctrl-v3.19-3' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/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
  • Loading branch information
torvalds committed Jan 20, 2015
2 parents eef8f4c + dbe752a commit 06efe0e
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 31 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -7410,6 +7410,7 @@ F: drivers/crypto/picoxcell*
PIN CONTROL SUBSYSTEM
M: Linus Walleij <[email protected]>
L: [email protected]
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
S: Maintained
F: drivers/pinctrl/
F: include/linux/pinctrl/
Expand Down
5 changes: 3 additions & 2 deletions drivers/pinctrl/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
if (pctldev == NULL)
return;

mutex_lock(&pinctrldev_list_mutex);
mutex_lock(&pctldev->mutex);

pinctrl_remove_device_debugfs(pctldev);
mutex_unlock(&pctldev->mutex);

if (!IS_ERR(pctldev->p))
pinctrl_put(pctldev->p);

mutex_lock(&pinctrldev_list_mutex);
mutex_lock(&pctldev->mutex);
/* TODO: check that no pinmuxes are still active? */
list_del(&pctldev->node);
/* Destroy descriptor tree */
Expand Down
45 changes: 20 additions & 25 deletions drivers/pinctrl/pinctrl-rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,23 +1398,14 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = irq_get_chip(irq);
struct rockchip_pin_bank *bank = irq_get_handler_data(irq);
u32 polarity = 0, data = 0;
u32 pend;
bool edge_changed = false;
unsigned long flags;

dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name);

chained_irq_enter(chip, desc);

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) {
unsigned int virq;

Expand All @@ -1434,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc)
* needs manual intervention.
*/
if (bank->toggle_edge_mode & BIT(irq)) {
if (data & BIT(irq))
polarity &= ~BIT(irq);
else
polarity |= BIT(irq);
u32 data, data_old, polarity;
unsigned long flags;

edge_changed = true;
}
data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT);
do {
spin_lock_irqsave(&bank->slock, flags);

generic_handle_irq(virq);
}
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);

if (bank->toggle_edge_mode && edge_changed) {
/* Interrupt params should only be set with ints disabled */
spin_lock_irqsave(&bank->slock, flags);
spin_unlock_irqrestore(&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);
data_old = data;
data = readl_relaxed(bank->reg_base +
GPIO_EXT_PORT);
} while ((data & BIT(irq)) != (data_old & BIT(irq)));
}

spin_unlock_irqrestore(&bank->slock, flags);
generic_handle_irq(virq);
}

chained_irq_exit(chip, desc);
Expand Down
2 changes: 0 additions & 2 deletions drivers/pinctrl/pinctrl-xway.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev)

/* load the gpio chip */
xway_chip.dev = &pdev->dev;
of_gpiochip_add(&xway_chip);
ret = gpiochip_add(&xway_chip);
if (ret) {
of_gpiochip_remove(&xway_chip);
dev_err(&pdev->dev, "Failed to register gpio chip\n");
return ret;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/pinctrl/qcom/pinctrl-msm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
int i = 0;
int i;
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")) {
pctrl->restart_nb.notifier_call = msm_ps_hold_restart;
pctrl->restart_nb.priority = 128;
Expand Down

0 comments on commit 06efe0e

Please sign in to comment.