Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: stm32: check irq controller availability at probe

It is not guaranteed that the IRQ controller driver is probed before
the pin controller driver gets probed.
Considering this, check for the irq domain availability during probe
and return EPROBE_DEFER if needed.

Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
Acked-by: Alexandre TORGUE <alexandre.torgue@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Fabien Dessenne and committed by
Linus Walleij
d86f4d71 26466711

+27 -10
+27 -10
drivers/pinctrl/stm32/pinctrl-stm32.c
··· 1122 1122 return 0; 1123 1123 } 1124 1124 1125 + static struct irq_domain *stm32_pctrl_get_irq_domain(struct device_node *np) 1126 + { 1127 + struct device_node *parent; 1128 + struct irq_domain *domain; 1129 + 1130 + if (!of_find_property(np, "interrupt-parent", NULL)) 1131 + return NULL; 1132 + 1133 + parent = of_irq_find_parent(np); 1134 + if (!parent) 1135 + return ERR_PTR(-ENXIO); 1136 + 1137 + domain = irq_find_host(parent); 1138 + if (!domain) 1139 + /* domain not registered yet */ 1140 + return ERR_PTR(-EPROBE_DEFER); 1141 + 1142 + return domain; 1143 + } 1144 + 1125 1145 static int stm32_pctrl_dt_setup_irq(struct platform_device *pdev, 1126 1146 struct stm32_pinctrl *pctl) 1127 1147 { 1128 - struct device_node *np = pdev->dev.of_node, *parent; 1148 + struct device_node *np = pdev->dev.of_node; 1129 1149 struct device *dev = &pdev->dev; 1130 1150 struct regmap *rm; 1131 1151 int offset, ret, i; 1132 1152 int mask, mask_width; 1133 - 1134 - parent = of_irq_find_parent(np); 1135 - if (!parent) 1136 - return -ENXIO; 1137 - 1138 - pctl->domain = irq_find_host(parent); 1139 - if (!pctl->domain) 1140 - return -ENXIO; 1141 1153 1142 1154 pctl->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); 1143 1155 if (IS_ERR(pctl->regmap)) ··· 1276 1264 1277 1265 platform_set_drvdata(pdev, pctl); 1278 1266 1267 + /* check for IRQ controller (may require deferred probe) */ 1268 + pctl->domain = stm32_pctrl_get_irq_domain(np); 1269 + if (IS_ERR(pctl->domain)) 1270 + return PTR_ERR(pctl->domain); 1271 + 1279 1272 /* hwspinlock is optional */ 1280 1273 hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0); 1281 1274 if (hwlock_id < 0) { ··· 1311 1294 return -EINVAL; 1312 1295 } 1313 1296 1314 - if (of_find_property(np, "interrupt-parent", NULL)) { 1297 + if (pctl->domain) { 1315 1298 ret = stm32_pctrl_dt_setup_irq(pdev, pctl); 1316 1299 if (ret) 1317 1300 return ret;