Skip to content

Commit

Permalink
pinctrl: stm32: check irq controller availability at probe
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Fabien Dessenne authored and Linus Walleij committed May 3, 2019
1 parent 2646671 commit d86f4d7
Showing 1 changed file with 27 additions and 10 deletions.
37 changes: 27 additions & 10 deletions drivers/pinctrl/stm32/pinctrl-stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1122,23 +1122,35 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
return 0;
}

static struct irq_domain *stm32_pctrl_get_irq_domain(struct device_node *np)
{
struct device_node *parent;
struct irq_domain *domain;

if (!of_find_property(np, "interrupt-parent", NULL))
return NULL;

parent = of_irq_find_parent(np);
if (!parent)
return ERR_PTR(-ENXIO);

domain = irq_find_host(parent);
if (!domain)
/* domain not registered yet */
return ERR_PTR(-EPROBE_DEFER);

return domain;
}

static int stm32_pctrl_dt_setup_irq(struct platform_device *pdev,
struct stm32_pinctrl *pctl)
{
struct device_node *np = pdev->dev.of_node, *parent;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct regmap *rm;
int offset, ret, i;
int mask, mask_width;

parent = of_irq_find_parent(np);
if (!parent)
return -ENXIO;

pctl->domain = irq_find_host(parent);
if (!pctl->domain)
return -ENXIO;

pctl->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(pctl->regmap))
return PTR_ERR(pctl->regmap);
Expand Down Expand Up @@ -1264,6 +1276,11 @@ int stm32_pctl_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, pctl);

/* check for IRQ controller (may require deferred probe) */
pctl->domain = stm32_pctrl_get_irq_domain(np);
if (IS_ERR(pctl->domain))
return PTR_ERR(pctl->domain);

/* hwspinlock is optional */
hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0);
if (hwlock_id < 0) {
Expand Down Expand Up @@ -1294,7 +1311,7 @@ int stm32_pctl_probe(struct platform_device *pdev)
return -EINVAL;
}

if (of_find_property(np, "interrupt-parent", NULL)) {
if (pctl->domain) {
ret = stm32_pctrl_dt_setup_irq(pdev, pctl);
if (ret)
return ret;
Expand Down

0 comments on commit d86f4d7

Please sign in to comment.