Commit bd5bca13 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-v4.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pin control fixes from Linus Walleij:

 - A complicated IRQ fix for the MSM driver (see commit)

 - Fix the group/function check in the Ingenic driver

 - Deal with a possible NULL pointer dereference in the Madera driver

* tag 'pinctrl-v4.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: madera: Fix possible NULL pointer with pdata config
  pinctrl: ingenic: Fix group & function error checking
  pinctrl: msm: Really mask level interrupts to prevent latching
parents f1c03a46 5bc5a671
...@@ -1040,7 +1040,7 @@ static int madera_pin_probe(struct platform_device *pdev) ...@@ -1040,7 +1040,7 @@ static int madera_pin_probe(struct platform_device *pdev)
} }
/* if the configuration is provided through pdata, apply it */ /* if the configuration is provided through pdata, apply it */
if (pdata) { if (pdata && pdata->gpio_configs) {
ret = pinctrl_register_mappings(pdata->gpio_configs, ret = pinctrl_register_mappings(pdata->gpio_configs,
pdata->n_gpio_configs); pdata->n_gpio_configs);
if (ret) { if (ret) {
......
...@@ -793,7 +793,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev) ...@@ -793,7 +793,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
err = pinctrl_generic_add_group(jzpc->pctl, group->name, err = pinctrl_generic_add_group(jzpc->pctl, group->name,
group->pins, group->num_pins, group->data); group->pins, group->num_pins, group->data);
if (err) { if (err < 0) {
dev_err(dev, "Failed to register group %s\n", dev_err(dev, "Failed to register group %s\n",
group->name); group->name);
return err; return err;
...@@ -806,7 +806,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev) ...@@ -806,7 +806,7 @@ static int ingenic_pinctrl_probe(struct platform_device *pdev)
err = pinmux_generic_add_function(jzpc->pctl, func->name, err = pinmux_generic_add_function(jzpc->pctl, func->name,
func->group_names, func->num_group_names, func->group_names, func->num_group_names,
func->data); func->data);
if (err) { if (err < 0) {
dev_err(dev, "Failed to register function %s\n", dev_err(dev, "Failed to register function %s\n",
func->name); func->name);
return err; return err;
......
...@@ -634,6 +634,29 @@ static void msm_gpio_irq_mask(struct irq_data *d) ...@@ -634,6 +634,29 @@ static void msm_gpio_irq_mask(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags); raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_cfg_reg); val = readl(pctrl->regs + g->intr_cfg_reg);
/*
* There are two bits that control interrupt forwarding to the CPU. The
* RAW_STATUS_EN bit causes the level or edge sensed on the line to be
* latched into the interrupt status register when the hardware detects
* an irq that it's configured for (either edge for edge type or level
* for level type irq). The 'non-raw' status enable bit causes the
* hardware to assert the summary interrupt to the CPU if the latched
* status bit is set. There's a bug though, the edge detection logic
* seems to have a problem where toggling the RAW_STATUS_EN bit may
* cause the status bit to latch spuriously when there isn't any edge
* so we can't touch that bit for edge type irqs and we have to keep
* the bit set anyway so that edges are latched while the line is masked.
*
* To make matters more complicated, leaving the RAW_STATUS_EN bit
* enabled all the time causes level interrupts to re-latch into the
* status register because the level is still present on the line after
* we ack it. We clear the raw status enable bit during mask here and
* set the bit on unmask so the interrupt can't latch into the hardware
* while it's masked.
*/
if (irqd_get_trigger_type(d) & IRQ_TYPE_LEVEL_MASK)
val &= ~BIT(g->intr_raw_status_bit);
val &= ~BIT(g->intr_enable_bit); val &= ~BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg); writel(val, pctrl->regs + g->intr_cfg_reg);
...@@ -655,6 +678,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d) ...@@ -655,6 +678,7 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags); raw_spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_cfg_reg); val = readl(pctrl->regs + g->intr_cfg_reg);
val |= BIT(g->intr_raw_status_bit);
val |= BIT(g->intr_enable_bit); val |= BIT(g->intr_enable_bit);
writel(val, pctrl->regs + g->intr_cfg_reg); writel(val, pctrl->regs + g->intr_cfg_reg);
......
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