aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ehci-orion.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 9298be7c0f9b..9c98bac0a5bc 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -42,6 +42,12 @@
42 42
43#define DRIVER_DESC "EHCI orion driver" 43#define DRIVER_DESC "EHCI orion driver"
44 44
45#define hcd_to_orion_priv(h) ((struct orion_ehci_hcd *)hcd_to_ehci(h)->priv)
46
47struct orion_ehci_hcd {
48 struct clk *clk;
49};
50
45static const char hcd_name[] = "ehci-orion"; 51static const char hcd_name[] = "ehci-orion";
46 52
47static struct hc_driver __read_mostly ehci_orion_hc_driver; 53static struct hc_driver __read_mostly ehci_orion_hc_driver;
@@ -137,6 +143,10 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
137 } 143 }
138} 144}
139 145
146static const struct ehci_driver_overrides orion_overrides __initconst = {
147 .extra_priv_size = sizeof(struct orion_ehci_hcd),
148};
149
140static int ehci_orion_drv_probe(struct platform_device *pdev) 150static int ehci_orion_drv_probe(struct platform_device *pdev)
141{ 151{
142 struct orion_ehci_data *pd = dev_get_platdata(&pdev->dev); 152 struct orion_ehci_data *pd = dev_get_platdata(&pdev->dev);
@@ -144,10 +154,10 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
144 struct resource *res; 154 struct resource *res;
145 struct usb_hcd *hcd; 155 struct usb_hcd *hcd;
146 struct ehci_hcd *ehci; 156 struct ehci_hcd *ehci;
147 struct clk *clk;
148 void __iomem *regs; 157 void __iomem *regs;
149 int irq, err; 158 int irq, err;
150 enum orion_ehci_phy_ver phy_version; 159 enum orion_ehci_phy_ver phy_version;
160 struct orion_ehci_hcd *priv;
151 161
152 if (usb_disabled()) 162 if (usb_disabled())
153 return -ENODEV; 163 return -ENODEV;
@@ -187,17 +197,11 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
187 goto err; 197 goto err;
188 } 198 }
189 199
190 /* Not all platforms can gate the clock, so it is not
191 an error if the clock does not exists. */
192 clk = devm_clk_get(&pdev->dev, NULL);
193 if (!IS_ERR(clk))
194 clk_prepare_enable(clk);
195
196 hcd = usb_create_hcd(&ehci_orion_hc_driver, 200 hcd = usb_create_hcd(&ehci_orion_hc_driver,
197 &pdev->dev, dev_name(&pdev->dev)); 201 &pdev->dev, dev_name(&pdev->dev));
198 if (!hcd) { 202 if (!hcd) {
199 err = -ENOMEM; 203 err = -ENOMEM;
200 goto err_create_hcd; 204 goto err;
201 } 205 }
202 206
203 hcd->rsrc_start = res->start; 207 hcd->rsrc_start = res->start;
@@ -208,6 +212,15 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
208 ehci->caps = hcd->regs + 0x100; 212 ehci->caps = hcd->regs + 0x100;
209 hcd->has_tt = 1; 213 hcd->has_tt = 1;
210 214
215 priv = hcd_to_orion_priv(hcd);
216 /*
217 * Not all platforms can gate the clock, so it is not an error if
218 * the clock does not exists.
219 */
220 priv->clk = devm_clk_get(&pdev->dev, NULL);
221 if (!IS_ERR(priv->clk))
222 clk_prepare_enable(priv->clk);
223
211 /* 224 /*
212 * (Re-)program MBUS remapping windows if we are asked to. 225 * (Re-)program MBUS remapping windows if we are asked to.
213 */ 226 */
@@ -243,10 +256,9 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)
243 return 0; 256 return 0;
244 257
245err_add_hcd: 258err_add_hcd:
259 if (!IS_ERR(priv->clk))
260 clk_disable_unprepare(priv->clk);
246 usb_put_hcd(hcd); 261 usb_put_hcd(hcd);
247err_create_hcd:
248 if (!IS_ERR(clk))
249 clk_disable_unprepare(clk);
250err: 262err:
251 dev_err(&pdev->dev, "init %s fail, %d\n", 263 dev_err(&pdev->dev, "init %s fail, %d\n",
252 dev_name(&pdev->dev), err); 264 dev_name(&pdev->dev), err);
@@ -257,14 +269,15 @@ err:
257static int ehci_orion_drv_remove(struct platform_device *pdev) 269static int ehci_orion_drv_remove(struct platform_device *pdev)
258{ 270{
259 struct usb_hcd *hcd = platform_get_drvdata(pdev); 271 struct usb_hcd *hcd = platform_get_drvdata(pdev);
260 struct clk *clk; 272 struct orion_ehci_hcd *priv = hcd_to_orion_priv(hcd);
261 273
262 usb_remove_hcd(hcd); 274 usb_remove_hcd(hcd);
275
276 if (!IS_ERR(priv->clk))
277 clk_disable_unprepare(priv->clk);
278
263 usb_put_hcd(hcd); 279 usb_put_hcd(hcd);
264 280
265 clk = devm_clk_get(&pdev->dev, NULL);
266 if (!IS_ERR(clk))
267 clk_disable_unprepare(clk);
268 return 0; 281 return 0;
269} 282}
270 283
@@ -292,7 +305,7 @@ static int __init ehci_orion_init(void)
292 305
293 pr_info("%s: " DRIVER_DESC "\n", hcd_name); 306 pr_info("%s: " DRIVER_DESC "\n", hcd_name);
294 307
295 ehci_init_driver(&ehci_orion_hc_driver, NULL); 308 ehci_init_driver(&ehci_orion_hc_driver, &orion_overrides);
296 return platform_driver_register(&ehci_orion_driver); 309 return platform_driver_register(&ehci_orion_driver);
297} 310}
298module_init(ehci_orion_init); 311module_init(ehci_orion_init);