aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ehci-platform.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index c7dd93aad20c..2f5b9ce3e042 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -29,6 +29,7 @@
29#include <linux/of.h> 29#include <linux/of.h>
30#include <linux/phy/phy.h> 30#include <linux/phy/phy.h>
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/reset.h>
32#include <linux/usb.h> 33#include <linux/usb.h>
33#include <linux/usb/hcd.h> 34#include <linux/usb/hcd.h>
34#include <linux/usb/ehci_pdriver.h> 35#include <linux/usb/ehci_pdriver.h>
@@ -41,6 +42,7 @@
41 42
42struct ehci_platform_priv { 43struct ehci_platform_priv {
43 struct clk *clks[EHCI_MAX_CLKS]; 44 struct clk *clks[EHCI_MAX_CLKS];
45 struct reset_control *rst;
44 struct phy *phy; 46 struct phy *phy;
45}; 47};
46 48
@@ -208,6 +210,18 @@ static int ehci_platform_probe(struct platform_device *dev)
208 } 210 }
209 } 211 }
210 212
213 priv->rst = devm_reset_control_get_optional(&dev->dev, NULL);
214 if (IS_ERR(priv->rst)) {
215 err = PTR_ERR(priv->rst);
216 if (err == -EPROBE_DEFER)
217 goto err_put_clks;
218 priv->rst = NULL;
219 } else {
220 err = reset_control_deassert(priv->rst);
221 if (err)
222 goto err_put_clks;
223 }
224
211 if (pdata->big_endian_desc) 225 if (pdata->big_endian_desc)
212 ehci->big_endian_desc = 1; 226 ehci->big_endian_desc = 1;
213 if (pdata->big_endian_mmio) 227 if (pdata->big_endian_mmio)
@@ -218,7 +232,7 @@ static int ehci_platform_probe(struct platform_device *dev)
218 dev_err(&dev->dev, 232 dev_err(&dev->dev,
219 "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n"); 233 "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n");
220 err = -EINVAL; 234 err = -EINVAL;
221 goto err_put_clks; 235 goto err_reset;
222 } 236 }
223#endif 237#endif
224#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC 238#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
@@ -226,14 +240,14 @@ static int ehci_platform_probe(struct platform_device *dev)
226 dev_err(&dev->dev, 240 dev_err(&dev->dev,
227 "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n"); 241 "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n");
228 err = -EINVAL; 242 err = -EINVAL;
229 goto err_put_clks; 243 goto err_reset;
230 } 244 }
231#endif 245#endif
232 246
233 if (pdata->power_on) { 247 if (pdata->power_on) {
234 err = pdata->power_on(dev); 248 err = pdata->power_on(dev);
235 if (err < 0) 249 if (err < 0)
236 goto err_put_clks; 250 goto err_reset;
237 } 251 }
238 252
239 hcd->rsrc_start = res_mem->start; 253 hcd->rsrc_start = res_mem->start;
@@ -256,6 +270,9 @@ static int ehci_platform_probe(struct platform_device *dev)
256err_power: 270err_power:
257 if (pdata->power_off) 271 if (pdata->power_off)
258 pdata->power_off(dev); 272 pdata->power_off(dev);
273err_reset:
274 if (priv->rst)
275 reset_control_assert(priv->rst);
259err_put_clks: 276err_put_clks:
260 while (--clk >= 0) 277 while (--clk >= 0)
261 clk_put(priv->clks[clk]); 278 clk_put(priv->clks[clk]);
@@ -280,6 +297,9 @@ static int ehci_platform_remove(struct platform_device *dev)
280 if (pdata->power_off) 297 if (pdata->power_off)
281 pdata->power_off(dev); 298 pdata->power_off(dev);
282 299
300 if (priv->rst)
301 reset_control_assert(priv->rst);
302
283 for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) 303 for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
284 clk_put(priv->clks[clk]); 304 clk_put(priv->clks[clk]);
285 305