summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>2020-07-30 17:28:05 +0200
committerLinus Walleij <linus.walleij@linaro.org>2020-08-27 10:32:58 +0200
commit4731d80f5ea9b8d754e2a5708b645a9eeef0c9e4 (patch)
tree6153ec18f489ffca5ac0466fa0978e4dd7b252f1 /drivers
parentgpio: dwapb: Discard ACPI GPIO-chip IRQs request (diff)
downloadlinux-4731d80f5ea9b8d754e2a5708b645a9eeef0c9e4.tar.xz
linux-4731d80f5ea9b8d754e2a5708b645a9eeef0c9e4.zip
gpio: dwapb: Get reset control by means of resource managed interface
The reset control interface provides the resource managed version of the reset_control_get() method. The only thing which needs to be also automated is the reset lane assertion on the device removal. It can be implemented by means of the custom action definition. After that the reset control will be purely managed by the device resources interface. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20200730152808.2955-9-Sergey.Semin@baikalelectronics.ru Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpio-dwapb.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 707e9087ca59..faac594287b3 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -621,6 +621,32 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev)
return pdata;
}
+static void dwapb_assert_reset(void *data)
+{
+ struct dwapb_gpio *gpio = data;
+
+ reset_control_assert(gpio->rst);
+}
+
+static int dwapb_get_reset(struct dwapb_gpio *gpio)
+{
+ int err;
+
+ gpio->rst = devm_reset_control_get_optional_shared(gpio->dev, NULL);
+ if (IS_ERR(gpio->rst)) {
+ dev_err(gpio->dev, "Cannot get reset descriptor\n");
+ return PTR_ERR(gpio->rst);
+ }
+
+ err = reset_control_deassert(gpio->rst);
+ if (err) {
+ dev_err(gpio->dev, "Cannot deassert reset lane\n");
+ return err;
+ }
+
+ return devm_add_action_or_reset(gpio->dev, dwapb_assert_reset, 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},
@@ -660,11 +686,9 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
gpio->dev = &pdev->dev;
gpio->nr_ports = pdata->nports;
- gpio->rst = devm_reset_control_get_optional_shared(dev, NULL);
- if (IS_ERR(gpio->rst))
- return PTR_ERR(gpio->rst);
-
- reset_control_deassert(gpio->rst);
+ err = dwapb_get_reset(gpio);
+ if (err)
+ return err;
gpio->ports = devm_kcalloc(&pdev->dev, gpio->nr_ports,
sizeof(*gpio->ports), GFP_KERNEL);
@@ -714,7 +738,6 @@ static int dwapb_gpio_remove(struct platform_device *pdev)
struct dwapb_gpio *gpio = platform_get_drvdata(pdev);
dwapb_gpio_unregister(gpio);
- reset_control_assert(gpio->rst);
clk_bulk_disable_unprepare(DWAPB_NR_CLOCKS, gpio->clks);
return 0;