diff options
Diffstat (limited to 'drivers/usb/dwc3/dwc3-st.c')
| -rw-r--r-- | drivers/usb/dwc3/dwc3-st.c | 68 |
1 files changed, 29 insertions, 39 deletions
diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index 505676fd3ba4..5d513decaacd 100644 --- a/drivers/usb/dwc3/dwc3-st.c +++ b/drivers/usb/dwc3/dwc3-st.c @@ -1,4 +1,5 @@ -/** +// SPDX-License-Identifier: GPL-2.0+ +/* * dwc3-st.c Support for dwc3 platform devices on ST Microelectronics platforms * * This is a small driver for the dwc3 to provide the glue logic @@ -10,14 +11,10 @@ * Contributors: Aymen Bouattay <aymen.bouattay@st.com> * Peter Griffin <peter.griffin@linaro.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * * Inspired by dwc3-omap.c and dwc3-exynos.c. */ +#include <linux/cleanup.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> @@ -201,7 +198,7 @@ static int st_dwc3_probe(struct platform_device *pdev) struct st_dwc3 *dwc3_data; struct resource *res; struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node, *child; + struct device_node *node = dev->of_node; struct platform_device *child_pdev; struct regmap *regmap; int ret; @@ -210,8 +207,8 @@ static int st_dwc3_probe(struct platform_device *pdev) if (!dwc3_data) return -ENOMEM; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg-glue"); - dwc3_data->glue_base = devm_ioremap_resource(dev, res); + dwc3_data->glue_base = + devm_platform_ioremap_resource_byname(pdev, "reg-glue"); if (IS_ERR(dwc3_data->glue_base)) return PTR_ERR(dwc3_data->glue_base); @@ -223,23 +220,26 @@ static int st_dwc3_probe(struct platform_device *pdev) dwc3_data->regmap = regmap; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscfg-reg"); - if (!res) { - ret = -ENXIO; - goto undo_platform_dev_alloc; - } + if (!res) + return -ENXIO; dwc3_data->syscfg_reg_off = res->start; - dev_vdbg(&pdev->dev, "glue-logic addr 0x%pK, syscfg-reg offset 0x%x\n", + dev_vdbg(dev, "glue-logic addr 0x%p, syscfg-reg offset 0x%x\n", dwc3_data->glue_base, dwc3_data->syscfg_reg_off); + struct device_node *child __free(device_node) = of_get_compatible_child(node, + "snps,dwc3"); + if (!child) { + dev_err(dev, "failed to find dwc3 core node\n"); + return -ENODEV; + } + dwc3_data->rstc_pwrdn = devm_reset_control_get_exclusive(dev, "powerdown"); - if (IS_ERR(dwc3_data->rstc_pwrdn)) { - dev_err(&pdev->dev, "could not get power controller\n"); - ret = PTR_ERR(dwc3_data->rstc_pwrdn); - goto undo_platform_dev_alloc; - } + if (IS_ERR(dwc3_data->rstc_pwrdn)) + return dev_err_probe(dev, PTR_ERR(dwc3_data->rstc_pwrdn), + "could not get power controller\n"); /* Manage PowerDown */ reset_control_deassert(dwc3_data->rstc_pwrdn); @@ -247,21 +247,14 @@ static int st_dwc3_probe(struct platform_device *pdev) dwc3_data->rstc_rst = devm_reset_control_get_shared(dev, "softreset"); if (IS_ERR(dwc3_data->rstc_rst)) { - dev_err(&pdev->dev, "could not get reset controller\n"); - ret = PTR_ERR(dwc3_data->rstc_rst); + ret = dev_err_probe(dev, PTR_ERR(dwc3_data->rstc_rst), + "could not get reset controller\n"); goto undo_powerdown; } /* Manage SoftReset */ reset_control_deassert(dwc3_data->rstc_rst); - child = of_get_child_by_name(node, "dwc3"); - if (!child) { - dev_err(&pdev->dev, "failed to find dwc3 core node\n"); - ret = -ENODEV; - goto undo_softreset; - } - /* Allocate and initialize the core */ ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { @@ -273,10 +266,11 @@ static int st_dwc3_probe(struct platform_device *pdev) if (!child_pdev) { dev_err(dev, "failed to find dwc3 core device\n"); ret = -ENODEV; - goto undo_softreset; + goto depopulate; } dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev); + platform_device_put(child_pdev); /* * Configure the USB port as device or host according to the static @@ -287,7 +281,7 @@ static int st_dwc3_probe(struct platform_device *pdev) ret = st_dwc3_drd_init(dwc3_data); if (ret) { dev_err(dev, "drd initialisation failed\n"); - goto undo_softreset; + goto depopulate; } /* ST glue logic init */ @@ -296,16 +290,16 @@ static int st_dwc3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dwc3_data); return 0; +depopulate: + of_platform_depopulate(dev); undo_softreset: reset_control_assert(dwc3_data->rstc_rst); undo_powerdown: reset_control_assert(dwc3_data->rstc_pwrdn); -undo_platform_dev_alloc: - platform_device_put(pdev); return ret; } -static int st_dwc3_remove(struct platform_device *pdev) +static void st_dwc3_remove(struct platform_device *pdev) { struct st_dwc3 *dwc3_data = platform_get_drvdata(pdev); @@ -313,11 +307,8 @@ static int st_dwc3_remove(struct platform_device *pdev) reset_control_assert(dwc3_data->rstc_pwrdn); reset_control_assert(dwc3_data->rstc_rst); - - return 0; } -#ifdef CONFIG_PM_SLEEP static int st_dwc3_suspend(struct device *dev) { struct st_dwc3 *dwc3_data = dev_get_drvdata(dev); @@ -351,9 +342,8 @@ static int st_dwc3_resume(struct device *dev) return 0; } -#endif /* CONFIG_PM_SLEEP */ -static SIMPLE_DEV_PM_OPS(st_dwc3_dev_pm_ops, st_dwc3_suspend, st_dwc3_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(st_dwc3_dev_pm_ops, st_dwc3_suspend, st_dwc3_resume); static const struct of_device_id st_dwc3_match[] = { { .compatible = "st,stih407-dwc3" }, @@ -368,7 +358,7 @@ static struct platform_driver st_dwc3_driver = { .driver = { .name = "usb-st-dwc3", .of_match_table = st_dwc3_match, - .pm = &st_dwc3_dev_pm_ops, + .pm = pm_sleep_ptr(&st_dwc3_dev_pm_ops), }, }; |
