forked from luck/tmp_suning_uos_patched
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:
commit
061913712d
|
@ -113,6 +113,8 @@ static void mtk_eint_mask(struct irq_data *d)
|
|||
void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
|
||||
eint->regs->mask_set);
|
||||
|
||||
eint->cur_mask[d->hwirq >> 5] &= ~mask;
|
||||
|
||||
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,
|
||||
eint->regs->mask_clr);
|
||||
|
||||
eint->cur_mask[d->hwirq >> 5] |= mask;
|
||||
|
||||
writel(mask, reg);
|
||||
|
||||
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)
|
||||
{
|
||||
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 mtk_eint *eint = irq_desc_get_handler_data(desc);
|
||||
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);
|
||||
int dual_edge, start_level, curr_level;
|
||||
|
||||
|
@ -328,10 +319,24 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
|
|||
status = readl(reg);
|
||||
while (status) {
|
||||
offset = __ffs(status);
|
||||
mask_offset = eint_num >> 5;
|
||||
index = eint_num + offset;
|
||||
virq = irq_find_mapping(eint->domain, index);
|
||||
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];
|
||||
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)
|
||||
{
|
||||
mtk_eint_chip_read_mask(eint, eint->base, eint->cur_mask);
|
||||
mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -771,6 +771,10 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
|||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
mcp->irq_controller =
|
||||
device_property_read_bool(dev, "interrupt-controller");
|
||||
if (mcp->irq && mcp->irq_controller) {
|
||||
|
@ -812,10 +816,6 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (one_regmap_config) {
|
||||
mcp->pinctrl_desc.name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"mcp23xxx-pinctrl.%d", raw_chip_address);
|
||||
|
|
|
@ -396,7 +396,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info,
|
|||
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,
|
||||
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.
|
||||
* bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of
|
||||
* ALT1
|
||||
* bit 0 of f goes in BIT(pin) of ALT[0], bit 1 of f goes in BIT(pin) of
|
||||
* ALT[1]
|
||||
* This is racy because both registers can't be updated at the same time
|
||||
* 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);
|
||||
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));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32)))
|
||||
|
||||
static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
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);
|
||||
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));
|
||||
|
||||
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);
|
||||
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);
|
||||
regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, offset),
|
||||
regmap_update_bits(info->map, REG_ALT(1, info, offset),
|
||||
BIT(p), 0);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user