aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-05-13 11:44:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-27 18:53:00 -0400
commit4615f3bd089fc4c549ed90e14982b360779feb50 (patch)
treed9a0820c9679ca20a4af417c90f021affc8d55e8 /drivers/usb/host
parent38e0c109404506266e33c29c77c2da39630954a4 (diff)
usb: ohci-platform: Enable optional use of reset controller
The OHCI controllers used in the Allwinner A31 are asserted in reset using a global reset controller. Add optional support for such a controller in the OHCI platform driver. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/ohci-platform.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index b6002c951c5c..4369299064c7 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -24,6 +24,7 @@
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/phy/phy.h> 25#include <linux/phy/phy.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/reset.h>
27#include <linux/usb/ohci_pdriver.h> 28#include <linux/usb/ohci_pdriver.h>
28#include <linux/usb.h> 29#include <linux/usb.h>
29#include <linux/usb/hcd.h> 30#include <linux/usb/hcd.h>
@@ -36,6 +37,7 @@
36 37
37struct ohci_platform_priv { 38struct ohci_platform_priv {
38 struct clk *clks[OHCI_MAX_CLKS]; 39 struct clk *clks[OHCI_MAX_CLKS];
40 struct reset_control *rst;
39 struct phy *phy; 41 struct phy *phy;
40}; 42};
41 43
@@ -191,6 +193,19 @@ static int ohci_platform_probe(struct platform_device *dev)
191 break; 193 break;
192 } 194 }
193 } 195 }
196
197 }
198
199 priv->rst = devm_reset_control_get_optional(&dev->dev, NULL);
200 if (IS_ERR(priv->rst)) {
201 err = PTR_ERR(priv->rst);
202 if (err == -EPROBE_DEFER)
203 goto err_put_clks;
204 priv->rst = NULL;
205 } else {
206 err = reset_control_deassert(priv->rst);
207 if (err)
208 goto err_put_clks;
194 } 209 }
195 210
196 if (pdata->big_endian_desc) 211 if (pdata->big_endian_desc)
@@ -203,7 +218,7 @@ static int ohci_platform_probe(struct platform_device *dev)
203 dev_err(&dev->dev, 218 dev_err(&dev->dev,
204 "Error: CONFIG_USB_OHCI_BIG_ENDIAN_MMIO not set\n"); 219 "Error: CONFIG_USB_OHCI_BIG_ENDIAN_MMIO not set\n");
205 err = -EINVAL; 220 err = -EINVAL;
206 goto err_put_clks; 221 goto err_reset;
207 } 222 }
208#endif 223#endif
209#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC 224#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC
@@ -211,14 +226,14 @@ static int ohci_platform_probe(struct platform_device *dev)
211 dev_err(&dev->dev, 226 dev_err(&dev->dev,
212 "Error: CONFIG_USB_OHCI_BIG_ENDIAN_DESC not set\n"); 227 "Error: CONFIG_USB_OHCI_BIG_ENDIAN_DESC not set\n");
213 err = -EINVAL; 228 err = -EINVAL;
214 goto err_put_clks; 229 goto err_reset;
215 } 230 }
216#endif 231#endif
217 232
218 if (pdata->power_on) { 233 if (pdata->power_on) {
219 err = pdata->power_on(dev); 234 err = pdata->power_on(dev);
220 if (err < 0) 235 if (err < 0)
221 goto err_put_clks; 236 goto err_reset;
222 } 237 }
223 238
224 hcd->rsrc_start = res_mem->start; 239 hcd->rsrc_start = res_mem->start;
@@ -242,6 +257,9 @@ static int ohci_platform_probe(struct platform_device *dev)
242err_power: 257err_power:
243 if (pdata->power_off) 258 if (pdata->power_off)
244 pdata->power_off(dev); 259 pdata->power_off(dev);
260err_reset:
261 if (priv->rst)
262 reset_control_assert(priv->rst);
245err_put_clks: 263err_put_clks:
246 while (--clk >= 0) 264 while (--clk >= 0)
247 clk_put(priv->clks[clk]); 265 clk_put(priv->clks[clk]);
@@ -266,6 +284,9 @@ static int ohci_platform_remove(struct platform_device *dev)
266 if (pdata->power_off) 284 if (pdata->power_off)
267 pdata->power_off(dev); 285 pdata->power_off(dev);
268 286
287 if (priv->rst)
288 reset_control_assert(priv->rst);
289
269 for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) 290 for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++)
270 clk_put(priv->clks[clk]); 291 clk_put(priv->clks[clk]);
271 292