aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/omap-usb-tll.c
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2012-11-08 06:07:09 -0500
committerRoger Quadros <rogerq@ti.com>2013-02-13 06:22:39 -0500
commit0bde3e9fee74b668857b1664a70998d02807fb5b (patch)
tree77e948b1f22841e559be2e1c2d0cb6cdd392466d /drivers/mfd/omap-usb-tll.c
parent1a7a8d70cddcf4f6847e42b414da1c3113675873 (diff)
mfd: omap-usb-tll: Clean up clock handling
Every channel has a functional clock that is similarly named. It makes sense to use a for loop to manage these clocks as OMAPs can come with up to 3 channels. Dynamically allocate and get channel clocks depending on the number of clocks avaiable on the platform. Signed-off-by: Roger Quadros <rogerq@ti.com> Reviewed-by: Felipe Balbi <balbi@ti.com> Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/mfd/omap-usb-tll.c')
-rw-r--r--drivers/mfd/omap-usb-tll.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index 9a19cc722c76..bf7355e1126d 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -96,10 +96,9 @@
96#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL) 96#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
97 97
98struct usbtll_omap { 98struct usbtll_omap {
99 struct clk *usbtll_p1_fck;
100 struct clk *usbtll_p2_fck;
101 int nch; /* num. of channels */ 99 int nch; /* num. of channels */
102 struct usbhs_omap_platform_data *pdata; 100 struct usbhs_omap_platform_data *pdata;
101 struct clk **ch_clk;
103 /* secure the register updates */ 102 /* secure the register updates */
104 spinlock_t lock; 103 spinlock_t lock;
105}; 104};
@@ -225,26 +224,12 @@ static int usbtll_omap_probe(struct platform_device *pdev)
225 224
226 tll->pdata = pdata; 225 tll->pdata = pdata;
227 226
228 tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
229 if (IS_ERR(tll->usbtll_p1_fck)) {
230 ret = PTR_ERR(tll->usbtll_p1_fck);
231 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
232 return ret;
233 }
234
235 tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
236 if (IS_ERR(tll->usbtll_p2_fck)) {
237 ret = PTR_ERR(tll->usbtll_p2_fck);
238 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
239 goto err_p2_fck;
240 }
241
242 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 227 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
243 base = devm_request_and_ioremap(dev, res); 228 base = devm_request_and_ioremap(dev, res);
244 if (!base) { 229 if (!base) {
245 ret = -EADDRNOTAVAIL; 230 ret = -EADDRNOTAVAIL;
246 dev_err(dev, "Resource request/ioremap failed:%d\n", ret); 231 dev_err(dev, "Resource request/ioremap failed:%d\n", ret);
247 goto err_res; 232 return ret;
248 } 233 }
249 234
250 platform_set_drvdata(pdev, tll); 235 platform_set_drvdata(pdev, tll);
@@ -270,6 +255,29 @@ static int usbtll_omap_probe(struct platform_device *pdev)
270 break; 255 break;
271 } 256 }
272 257
258 spin_unlock_irqrestore(&tll->lock, flags);
259
260 tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]),
261 GFP_KERNEL);
262 if (!tll->ch_clk) {
263 ret = -ENOMEM;
264 dev_err(dev, "Couldn't allocate memory for channel clocks\n");
265 goto err_clk_alloc;
266 }
267
268 for (i = 0; i < tll->nch; i++) {
269 char clkname[] = "usb_tll_hs_usb_chx_clk";
270
271 snprintf(clkname, sizeof(clkname),
272 "usb_tll_hs_usb_ch%d_clk", i);
273 tll->ch_clk[i] = clk_get(dev, clkname);
274
275 if (IS_ERR(tll->ch_clk[i]))
276 dev_dbg(dev, "can't get clock : %s\n", clkname);
277 }
278
279 spin_lock_irqsave(&tll->lock, flags);
280
273 if (is_ehci_tll_mode(pdata->port_mode[0]) || 281 if (is_ehci_tll_mode(pdata->port_mode[0]) ||
274 is_ehci_tll_mode(pdata->port_mode[1]) || 282 is_ehci_tll_mode(pdata->port_mode[1]) ||
275 is_ehci_tll_mode(pdata->port_mode[2]) || 283 is_ehci_tll_mode(pdata->port_mode[2]) ||
@@ -321,11 +329,9 @@ static int usbtll_omap_probe(struct platform_device *pdev)
321 329
322 return 0; 330 return 0;
323 331
324err_res: 332err_clk_alloc:
325 clk_put(tll->usbtll_p2_fck); 333 pm_runtime_put_sync(dev);
326 334 pm_runtime_disable(dev);
327err_p2_fck:
328 clk_put(tll->usbtll_p1_fck);
329 335
330 return ret; 336 return ret;
331} 337}
@@ -339,9 +345,12 @@ err_p2_fck:
339static int usbtll_omap_remove(struct platform_device *pdev) 345static int usbtll_omap_remove(struct platform_device *pdev)
340{ 346{
341 struct usbtll_omap *tll = platform_get_drvdata(pdev); 347 struct usbtll_omap *tll = platform_get_drvdata(pdev);
348 int i;
349
350 for (i = 0; i < tll->nch; i++)
351 if (!IS_ERR(tll->ch_clk[i]))
352 clk_put(tll->ch_clk[i]);
342 353
343 clk_put(tll->usbtll_p2_fck);
344 clk_put(tll->usbtll_p1_fck);
345 pm_runtime_disable(&pdev->dev); 354 pm_runtime_disable(&pdev->dev);
346 return 0; 355 return 0;
347} 356}
@@ -351,6 +360,7 @@ static int usbtll_runtime_resume(struct device *dev)
351 struct usbtll_omap *tll = dev_get_drvdata(dev); 360 struct usbtll_omap *tll = dev_get_drvdata(dev);
352 struct usbhs_omap_platform_data *pdata = tll->pdata; 361 struct usbhs_omap_platform_data *pdata = tll->pdata;
353 unsigned long flags; 362 unsigned long flags;
363 int i;
354 364
355 dev_dbg(dev, "usbtll_runtime_resume\n"); 365 dev_dbg(dev, "usbtll_runtime_resume\n");
356 366
@@ -361,11 +371,20 @@ static int usbtll_runtime_resume(struct device *dev)
361 371
362 spin_lock_irqsave(&tll->lock, flags); 372 spin_lock_irqsave(&tll->lock, flags);
363 373
364 if (is_ehci_tll_mode(pdata->port_mode[0])) 374 for (i = 0; i < tll->nch; i++) {
365 clk_enable(tll->usbtll_p1_fck); 375 if (is_ehci_tll_mode(pdata->port_mode[i])) {
376 int r;
366 377
367 if (is_ehci_tll_mode(pdata->port_mode[1])) 378 if (IS_ERR(tll->ch_clk[i]))
368 clk_enable(tll->usbtll_p2_fck); 379 continue;
380
381 r = clk_enable(tll->ch_clk[i]);
382 if (r) {
383 dev_err(dev,
384 "Error enabling ch %d clock: %d\n", i, r);
385 }
386 }
387 }
369 388
370 spin_unlock_irqrestore(&tll->lock, flags); 389 spin_unlock_irqrestore(&tll->lock, flags);
371 390
@@ -377,6 +396,7 @@ static int usbtll_runtime_suspend(struct device *dev)
377 struct usbtll_omap *tll = dev_get_drvdata(dev); 396 struct usbtll_omap *tll = dev_get_drvdata(dev);
378 struct usbhs_omap_platform_data *pdata = tll->pdata; 397 struct usbhs_omap_platform_data *pdata = tll->pdata;
379 unsigned long flags; 398 unsigned long flags;
399 int i;
380 400
381 dev_dbg(dev, "usbtll_runtime_suspend\n"); 401 dev_dbg(dev, "usbtll_runtime_suspend\n");
382 402
@@ -387,11 +407,12 @@ static int usbtll_runtime_suspend(struct device *dev)
387 407
388 spin_lock_irqsave(&tll->lock, flags); 408 spin_lock_irqsave(&tll->lock, flags);
389 409
390 if (is_ehci_tll_mode(pdata->port_mode[0])) 410 for (i = 0; i < tll->nch; i++) {
391 clk_disable(tll->usbtll_p1_fck); 411 if (is_ehci_tll_mode(pdata->port_mode[i])) {
392 412 if (!IS_ERR(tll->ch_clk[i]))
393 if (is_ehci_tll_mode(pdata->port_mode[1])) 413 clk_disable(tll->ch_clk[i]);
394 clk_disable(tll->usbtll_p2_fck); 414 }
415 }
395 416
396 spin_unlock_irqrestore(&tll->lock, flags); 417 spin_unlock_irqrestore(&tll->lock, flags);
397 418