diff options
-rw-r--r-- | drivers/gpio/gpio-dwapb.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index faac594287b3..803e1d1f4b5a 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -647,6 +647,36 @@ static int dwapb_get_reset(struct dwapb_gpio *gpio) return devm_add_action_or_reset(gpio->dev, dwapb_assert_reset, gpio); } +static void dwapb_disable_clks(void *data) +{ + struct dwapb_gpio *gpio = data; + + clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks); +} + +static int dwapb_get_clks(struct dwapb_gpio *gpio) +{ + int err; + + /* Optional bus and debounce clocks */ + gpio->clks[0].id = "bus"; + gpio->clks[1].id = "db"; + err = devm_clk_bulk_get_optional(gpio->dev, DWAPB_NR_CLOCKS, + gpio->clks); + if (err) { + dev_err(gpio->dev, "Cannot get APB/Debounce clocks\n"); + return err; + } + + err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks); + if (err) { + dev_err(gpio->dev, "Cannot enable APB/Debounce clocks\n"); + return err; + } + + return devm_add_action_or_reset(gpio->dev, dwapb_disable_clks, gpio); +} + static const struct of_device_id dwapb_of_match[] = { { .compatible = "snps,dw-apb-gpio", .data = (void *)0}, { .compatible = "apm,xgene-gpio-v2", .data = (void *)GPIO_REG_OFFSET_V2}, @@ -699,21 +729,9 @@ static int dwapb_gpio_probe(struct platform_device *pdev) if (IS_ERR(gpio->regs)) return PTR_ERR(gpio->regs); - /* Optional bus and debounce clocks */ - gpio->clks[0].id = "bus"; - gpio->clks[1].id = "db"; - err = devm_clk_bulk_get_optional(&pdev->dev, DWAPB_NR_CLOCKS, - gpio->clks); - if (err) { - dev_err(&pdev->dev, "Cannot get APB/Debounce clocks\n"); - return err; - } - - err = clk_bulk_prepare_enable(DWAPB_NR_CLOCKS, gpio->clks); - if (err) { - dev_err(&pdev->dev, "Cannot enable APB/Debounce clocks\n"); + err = dwapb_get_clks(gpio); + if (err) return err; - } gpio->flags = (uintptr_t)device_get_match_data(dev); @@ -728,7 +746,6 @@ static int dwapb_gpio_probe(struct platform_device *pdev) out_unregister: dwapb_gpio_unregister(gpio); - clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks); return err; } @@ -738,7 +755,6 @@ static int dwapb_gpio_remove(struct platform_device *pdev) struct dwapb_gpio *gpio = platform_get_drvdata(pdev); dwapb_gpio_unregister(gpio); - clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks); return 0; } |