Pin control fixes for the v5.2 cycle:

- Fix IRQ setup in the MCP23s08.
 - Fix pin setup on pins > 31 in the Ocelot driver.
 - Fix IRQs in the Mediatek driver.
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJdFd2eAAoJEEEQszewGV1zW8AP/jkDznsyrjSkHOFSjiAjv5aF
 Yte85bupFkw5y2dMwH/nyF/dQOz34ZwmVA4fuIn/IcY+0+PbdRVJ9dd2suNhO9o3
 LULso6rTayKh0+9U+ARS/D9sW73jOvUbAdSCMacGLqwmzaiAUBDdopfQobYq7j3Y
 ikjeEhHMRoMOJmXOk9JJ9nENBfRS/wGU/G7hALOiuLd/A0X7YkGVP4Y3ViKA77Ec
 Y7Dcd7fV57XXxh5vvQIbtLrzAY4LlJiFpXyK8p3rf8Fewq2NT2N3oQgQdsap7Dce
 8pZxbBr6sw8X++yc2t1OLMkfM6y6iLoHVdwpmOQmU3ZV+3JINWq8Y8oRvH6nOXkM
 fLBowKEhc1TMFZzujUkDq+tHZw+1ofOJdJHplRsLC9Yy5dP0tEyuyuKhnIByNY63
 mH6C4uNYT5h2SPN6aYF1GFdk8b89jQ3r3fdvSAjbEiJ0FTBueuzQlv5iS1Ujhkh7
 gTkWVX0MG6faEKn8rEElZVAECf0TlCYov76OG2UF0+nZTbA2aeIjnmnQpcwZhgVl
 ll1IGiJfKcyqihvbQJv2ZEZliozA3nqon7K9+R68FL3NnJewQcMRx959FG+eMhQw
 oNp4IPfUSu+4O+m5VjwMeONXHIAMFYQ2MO0idMQGU80BXi+o8gjW/BJYo4WPTlHc
 bcUfedYYxJzOpYvoKuto
 =/GFO
 -----END PGP SIGNATURE-----

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

Pull pin control fixes from Linus Walleij:
 "Sorry to bomb in fixes this late. Maybe I can comfort you by saying it
  is only driver fixes, and mostly IRQ handling which is something GPIO
  and pin control drivers never get right. You think it works and then
  it doesn't.

  Summary:

   - Fix IRQ setup in the MCP23s08.

   - Fix pin setup on pins > 31 in the Ocelot driver.

   - Fix IRQs in the Mediatek driver"

* tag 'pinctrl-v5.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: mediatek: Update cur_mask in mask/mask ops
  pinctrl: mediatek: Ignore interrupts that are wake only during resume
  pinctrl: ocelot: fix pinmuxing for pins after 31
  pinctrl: ocelot: fix gpio direction for pins after 31
  pinctrl: mcp23s08: Fix add_data and irqchip_add_nested call order
This commit is contained in:
Linus Torvalds 2019-06-29 16:51:10 +08:00
commit 061913712d
3 changed files with 33 additions and 27 deletions

View File

@ -113,6 +113,8 @@ static void mtk_eint_mask(struct irq_data *d)
void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq, void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
eint->regs->mask_set); eint->regs->mask_set);
eint->cur_mask[d->hwirq >> 5] &= ~mask;
writel(mask, reg); writel(mask, reg);
} }
@ -123,6 +125,8 @@ static void mtk_eint_unmask(struct irq_data *d)
void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq, void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
eint->regs->mask_clr); eint->regs->mask_clr);
eint->cur_mask[d->hwirq >> 5] |= mask;
writel(mask, reg); writel(mask, reg);
if (eint->dual_edge[d->hwirq]) if (eint->dual_edge[d->hwirq])
@ -217,19 +221,6 @@ static void mtk_eint_chip_write_mask(const struct mtk_eint *eint,
} }
} }
static void mtk_eint_chip_read_mask(const struct mtk_eint *eint,
void __iomem *base, u32 *buf)
{
int port;
void __iomem *reg;
for (port = 0; port < eint->hw->ports; port++) {
reg = base + eint->regs->mask + (port << 2);
buf[port] = ~readl_relaxed(reg);
/* Mask is 0 when irq is enabled, and 1 when disabled. */
}
}
static int mtk_eint_irq_request_resources(struct irq_data *d) static int mtk_eint_irq_request_resources(struct irq_data *d)
{ {
struct mtk_eint *eint = irq_data_get_irq_chip_data(d); struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
@ -318,7 +309,7 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_chip *chip = irq_desc_get_chip(desc);
struct mtk_eint *eint = irq_desc_get_handler_data(desc); struct mtk_eint *eint = irq_desc_get_handler_data(desc);
unsigned int status, eint_num; unsigned int status, eint_num;
int offset, index, virq; int offset, mask_offset, index, virq;
void __iomem *reg = mtk_eint_get_offset(eint, 0, eint->regs->stat); void __iomem *reg = mtk_eint_get_offset(eint, 0, eint->regs->stat);
int dual_edge, start_level, curr_level; int dual_edge, start_level, curr_level;
@ -328,10 +319,24 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
status = readl(reg); status = readl(reg);
while (status) { while (status) {
offset = __ffs(status); offset = __ffs(status);
mask_offset = eint_num >> 5;
index = eint_num + offset; index = eint_num + offset;
virq = irq_find_mapping(eint->domain, index); virq = irq_find_mapping(eint->domain, index);
status &= ~BIT(offset); status &= ~BIT(offset);
/*
* If we get an interrupt on pin that was only required
* for wake (but no real interrupt requested), mask the
* interrupt (as would mtk_eint_resume do anyway later
* in the resume sequence).
*/
if (eint->wake_mask[mask_offset] & BIT(offset) &&
!(eint->cur_mask[mask_offset] & BIT(offset))) {
writel_relaxed(BIT(offset), reg -
eint->regs->stat +
eint->regs->mask_set);
}
dual_edge = eint->dual_edge[index]; dual_edge = eint->dual_edge[index];
if (dual_edge) { if (dual_edge) {
/* /*
@ -370,7 +375,6 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
int mtk_eint_do_suspend(struct mtk_eint *eint) int mtk_eint_do_suspend(struct mtk_eint *eint)
{ {
mtk_eint_chip_read_mask(eint, eint->base, eint->cur_mask);
mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask); mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
return 0; return 0;

View File

@ -771,6 +771,10 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
if (ret < 0) if (ret < 0)
goto fail; goto fail;
ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
if (ret < 0)
goto fail;
mcp->irq_controller = mcp->irq_controller =
device_property_read_bool(dev, "interrupt-controller"); device_property_read_bool(dev, "interrupt-controller");
if (mcp->irq && mcp->irq_controller) { if (mcp->irq && mcp->irq_controller) {
@ -812,10 +816,6 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
goto fail; goto fail;
} }
ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
if (ret < 0)
goto fail;
if (one_regmap_config) { if (one_regmap_config) {
mcp->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL, mcp->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
"mcp23xxx-pinctrl.%d", raw_chip_address); "mcp23xxx-pinctrl.%d", raw_chip_address);

View File

@ -396,7 +396,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
return -1; return -1;
} }
#define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) #define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32))))
static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group) unsigned int selector, unsigned int group)
@ -412,19 +412,21 @@ static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev,
/* /*
* f is encoded on two bits. * f is encoded on two bits.
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of * bit 0 of f goes in BIT(pin) of ALT[0], bit 1 of f goes in BIT(pin) of
* ALT1 * ALT[1]
* This is racy because both registers can't be updated at the same time * This is racy because both registers can't be updated at the same time
* but it doesn't matter much for now. * but it doesn't matter much for now.
*/ */
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, pin->pin), regmap_update_bits(info->map, REG_ALT(0, info, pin->pin),
BIT(p), f << p); BIT(p), f << p);
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, pin->pin), regmap_update_bits(info->map, REG_ALT(1, info, pin->pin),
BIT(p), f << (p - 1)); BIT(p), f << (p - 1));
return 0; return 0;
} }
#define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32)))
static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, struct pinctrl_gpio_range *range,
unsigned int pin, bool input) unsigned int pin, bool input)
@ -432,7 +434,7 @@ static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev,
struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
unsigned int p = pin % 32; unsigned int p = pin % 32;
regmap_update_bits(info->map, REG(OCELOT_GPIO_OE, info, p), BIT(p), regmap_update_bits(info->map, REG(OCELOT_GPIO_OE, info, pin), BIT(p),
input ? 0 : BIT(p)); input ? 0 : BIT(p));
return 0; return 0;
@ -445,9 +447,9 @@ static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev,
struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
unsigned int p = offset % 32; unsigned int p = offset % 32;
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, offset), regmap_update_bits(info->map, REG_ALT(0, info, offset),
BIT(p), 0); BIT(p), 0);
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, offset), regmap_update_bits(info->map, REG_ALT(1, info, offset),
BIT(p), 0); BIT(p), 0);
return 0; return 0;