Skip to content

Commit 4546760

Browse files
vladimirolteanlinusw
authored andcommitted
pinctrl: armada-37xx: use raw spinlocks for regmap to avoid invalid wait context
The irqchip->irq_set_type method is called by __irq_set_trigger() under the desc->lock raw spinlock. The armada-37xx implementation, armada_37xx_irq_set_type(), uses an MMIO regmap created by of_syscon_register(), which uses plain spinlocks (the kind that are sleepable on RT). Therefore, this is an invalid locking scheme for which we get a kernel splat stating just that ("[ BUG: Invalid wait context ]"), because the context in which the plain spinlock may sleep is atomic due to the raw spinlock. We need to go raw spinlocks all the way. Make this driver create its own MMIO regmap, with use_raw_spinlock=true, and stop relying on syscon to provide it. This patch depends on commit 67021f2 ("regmap: teach regmap to use raw spinlocks if requested in the config"). Cc: <stable@vger.kernel.org> # 5.15+ Fixes: 2f22760 ("pinctrl: armada-37xx: Add irqchip support") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20220716233745.1704677-3-vladimir.oltean@nxp.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 984245b commit 4546760

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

drivers/pinctrl/mvebu/pinctrl-armada-37xx.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,25 +1107,40 @@ static const struct of_device_id armada_37xx_pinctrl_of_match[] = {
11071107
{ },
11081108
};
11091109

1110+
static const struct regmap_config armada_37xx_pinctrl_regmap_config = {
1111+
.reg_bits = 32,
1112+
.val_bits = 32,
1113+
.reg_stride = 4,
1114+
.use_raw_spinlock = true,
1115+
};
1116+
11101117
static int __init armada_37xx_pinctrl_probe(struct platform_device *pdev)
11111118
{
11121119
struct armada_37xx_pinctrl *info;
11131120
struct device *dev = &pdev->dev;
1114-
struct device_node *np = dev->of_node;
11151121
struct regmap *regmap;
1122+
void __iomem *base;
11161123
int ret;
11171124

1125+
base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
1126+
if (IS_ERR(base)) {
1127+
dev_err(dev, "failed to ioremap base address: %pe\n", base);
1128+
return PTR_ERR(base);
1129+
}
1130+
1131+
regmap = devm_regmap_init_mmio(dev, base,
1132+
&armada_37xx_pinctrl_regmap_config);
1133+
if (IS_ERR(regmap)) {
1134+
dev_err(dev, "failed to create regmap: %pe\n", regmap);
1135+
return PTR_ERR(regmap);
1136+
}
1137+
11181138
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
11191139
if (!info)
11201140
return -ENOMEM;
11211141

11221142
info->dev = dev;
1123-
1124-
regmap = syscon_node_to_regmap(np);
1125-
if (IS_ERR(regmap))
1126-
return dev_err_probe(dev, PTR_ERR(regmap), "cannot get regmap\n");
11271143
info->regmap = regmap;
1128-
11291144
info->data = of_device_get_match_data(dev);
11301145

11311146
ret = armada_37xx_pinctrl_register(pdev, info);

0 commit comments

Comments
 (0)