diff options
author | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2019-10-23 13:22:14 +0300 |
---|---|---|
committer | Oleksandr Suvorov <oleksandr.suvorov@toradex.com> | 2021-01-27 20:36:27 +0200 |
commit | 98df0f961258750869e4df640d0d64aec0a9808f (patch) | |
tree | 795498c7e4c4e0c2a3d67fad5a555023fb5e2587 /drivers/gpio | |
parent | d70c368df6541aca57c10aefa4b14cf7e511a3e9 (diff) |
gpio: mxc: Fix clean up on probing
- Fix order of after-error clean procedures upon probing new device.
- Refactor handling of wakeup PAD setup.
Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
(cherry picked from commit f62ce7ec98206218b4fc56891cb34ab263fc1d5c)
Conflicts:
drivers/gpio/gpio-mxc.c
Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
Guarded the label out_clk_disable: with
Deleted whitespace
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-mxc.c | 89 |
1 files changed, 54 insertions, 35 deletions
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 5a2cf486a686..7285cdce5446 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -589,6 +589,37 @@ static void mxc_gpio_free(struct gpio_chip *chip, unsigned offset) pm_runtime_put(chip->parent); } +#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP +/* + * parse pad wakeup info from dtb, each pad has to provide + * <pin_id, type, line>, these info should be put in each + * gpio node and with a "pad-wakeup-num" to indicate the + * total lines are with pad wakeup enabled. + */ +static int setup_pad_wakeup(struct mxc_gpio_port *port, + struct device_node *np) +{ + int i; + int err = 0; + + for (i = 0; i < port->pad_wakeup_num; i++) { + if ((err = of_property_read_u32_index(np, "pad-wakeup", + i * 3 + 0, &port->pad_wakeup[i].pin_id))) + return err; + if ((err = of_property_read_u32_index(np, "pad-wakeup", + i * 3 + 1, &port->pad_wakeup[i].type))) + return err; + if ((err = of_property_read_u32_index(np, "pad-wakeup", + i * 3 + 2, &port->pad_wakeup[i].line))) + return err; + } + err = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_PAD, true); + + + return err; +} +#endif + static int mxc_gpio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -596,9 +627,6 @@ static int mxc_gpio_probe(struct platform_device *pdev) int irq_count; int irq_base = 0; int err; -#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP - int i; -#endif mxc_gpio_get_hw(pdev); @@ -638,30 +666,18 @@ static int mxc_gpio_probe(struct platform_device *pdev) } #ifdef CONFIG_GPIO_MXC_PAD_WAKEUP - /* - * parse pad wakeup info from dtb, each pad has to provide - * <pin_id, type, line>, these info should be put in each - * gpio node and with a "pad-wakeup-num" to indicate the - * total lines are with pad wakeup enabled. - */ - if (!of_property_read_u32(np, "pad-wakeup-num", &port->pad_wakeup_num)) { - if (port->pad_wakeup_num != 0) { - if (!gpio_ipc_handle) { - err = imx_scu_get_handle(&gpio_ipc_handle); - if (err) - return err; - } - for (i = 0; i < port->pad_wakeup_num; i++) { - of_property_read_u32_index(np, "pad-wakeup", - i * 3 + 0, &port->pad_wakeup[i].pin_id); - of_property_read_u32_index(np, "pad-wakeup", - i * 3 + 1, &port->pad_wakeup[i].type); - of_property_read_u32_index(np, "pad-wakeup", - i * 3 + 2, &port->pad_wakeup[i].line); - } - err = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, IMX_SC_IRQ_PAD, true); + if (!of_property_read_u32(np, "pad-wakeup-num", &port->pad_wakeup_num) + && port->pad_wakeup_num != 0) { + if (!gpio_ipc_handle) { + err = imx_scu_get_handle(&gpio_ipc_handle); if (err) - dev_warn(&pdev->dev, "Enable irq failed, GPIO pad wakeup NOT supported\n"); + goto out_clk_disable; + } + + err = setup_pad_wakeup(port, np); + if (err) { + dev_warn(&pdev->dev, "Enable irq failed, GPIO pad wakeup NOT supported\n"); + goto out_clk_disable; } } #endif @@ -673,7 +689,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); err = pm_runtime_get_sync(&pdev->dev); if (err < 0) - goto out_pm_dis; + goto out_pm_disable; /* disable the interrupt and clear the status */ if (!noclearirq) { @@ -705,7 +721,7 @@ static int mxc_gpio_probe(struct platform_device *pdev) port->base + GPIO_GDIR, NULL, BGPIOF_READ_OUTPUT_REG_SET); if (err) - goto out_bgio; + goto out_pm_put; if (of_property_read_bool(np, "gpio-ranges")) { port->gc.request = gpiochip_generic_request; @@ -726,19 +742,19 @@ static int mxc_gpio_probe(struct platform_device *pdev) err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port); if (err) - goto out_bgio; + goto out_pm_put; irq_base = devm_irq_alloc_descs(&pdev->dev, -1, 0, 32, numa_node_id()); if (irq_base < 0) { err = irq_base; - goto out_bgio; + goto out_pm_put; } port->domain = irq_domain_add_legacy(np, 32, irq_base, 0, &irq_domain_simple_ops, NULL); if (!port->domain) { err = -ENODEV; - goto out_bgio; + goto out_pm_put; } /* gpio-mxc can be a generic irq chip */ @@ -753,12 +769,15 @@ static int mxc_gpio_probe(struct platform_device *pdev) return 0; -out_pm_dis: - pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(port->clk); out_irqdomain_remove: irq_domain_remove(port->domain); -out_bgio: +out_pm_put: + pm_runtime_put(&pdev->dev); +out_pm_disable: + pm_runtime_disable(&pdev->dev); +#ifdef CONFIG_GPIO_MXC_PAD_WAKEUP +out_clk_disable: +#endif clk_disable_unprepare(port->clk); dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err); return err; |