diff options
author | Roger Quadros <rogerq@ti.com> | 2013-01-29 08:00:03 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-09 03:46:23 -0400 |
commit | 9f4a3ece05a6c2f2dc5e4967602e9927addab97e (patch) | |
tree | 562d2e4d87906238d8e145466477f1263dd2211b | |
parent | 662e469e91d85438444703aa60dc35ac27b06773 (diff) |
mfd: omap-usb-tll: Move configuration code to omap_tll_init()
This is because we want to get rid of platform_data usage from probe().
The only information we need is PORT_MODE, and this can be supplied
to us by the user (i.e. omap-usb-host.c).
We also move channel clock management from runtime PM handlers into
omap_tll_enable/disable().
Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/omap-usb-host.c | 7 | ||||
-rw-r--r-- | drivers/mfd/omap-usb-tll.c | 204 | ||||
-rw-r--r-- | drivers/mfd/omap-usb.h | 5 |
3 files changed, 107 insertions, 109 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 2520facd4ccc..eb5db28b3fbd 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -278,7 +278,7 @@ static int usbhs_runtime_resume(struct device *dev) | |||
278 | 278 | ||
279 | dev_dbg(dev, "usbhs_runtime_resume\n"); | 279 | dev_dbg(dev, "usbhs_runtime_resume\n"); |
280 | 280 | ||
281 | omap_tll_enable(); | 281 | omap_tll_enable(pdata); |
282 | 282 | ||
283 | if (!IS_ERR(omap->ehci_logic_fck)) | 283 | if (!IS_ERR(omap->ehci_logic_fck)) |
284 | clk_enable(omap->ehci_logic_fck); | 284 | clk_enable(omap->ehci_logic_fck); |
@@ -353,7 +353,7 @@ static int usbhs_runtime_suspend(struct device *dev) | |||
353 | if (!IS_ERR(omap->ehci_logic_fck)) | 353 | if (!IS_ERR(omap->ehci_logic_fck)) |
354 | clk_disable(omap->ehci_logic_fck); | 354 | clk_disable(omap->ehci_logic_fck); |
355 | 355 | ||
356 | omap_tll_disable(); | 356 | omap_tll_disable(pdata); |
357 | 357 | ||
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
@@ -527,6 +527,9 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
527 | 527 | ||
528 | omap->pdata = pdata; | 528 | omap->pdata = pdata; |
529 | 529 | ||
530 | /* Initialize the TLL subsystem */ | ||
531 | omap_tll_init(pdata); | ||
532 | |||
530 | pm_runtime_enable(dev); | 533 | pm_runtime_enable(dev); |
531 | 534 | ||
532 | platform_set_drvdata(pdev, omap); | 535 | platform_set_drvdata(pdev, omap); |
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 0aef1a768880..f7d2568729c1 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /** | 1 | /** |
2 | * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI | 2 | * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI |
3 | * | 3 | * |
4 | * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com | 4 | * Copyright (C) 2012-2013 Texas Instruments Incorporated - http://www.ti.com |
5 | * Author: Keshava Munegowda <keshava_mgowda@ti.com> | 5 | * Author: Keshava Munegowda <keshava_mgowda@ti.com> |
6 | * Author: Roger Quadros <rogerq@ti.com> | ||
6 | * | 7 | * |
7 | * This program is free software: you can redistribute it and/or modify | 8 | * This program is free software: you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 of | 9 | * it under the terms of the GNU General Public License version 2 of |
@@ -105,8 +106,8 @@ | |||
105 | 106 | ||
106 | struct usbtll_omap { | 107 | struct usbtll_omap { |
107 | int nch; /* num. of channels */ | 108 | int nch; /* num. of channels */ |
108 | struct usbhs_omap_platform_data *pdata; | ||
109 | struct clk **ch_clk; | 109 | struct clk **ch_clk; |
110 | void __iomem *base; | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | /*-------------------------------------------------------------------------*/ | 113 | /*-------------------------------------------------------------------------*/ |
@@ -210,14 +211,10 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode) | |||
210 | static int usbtll_omap_probe(struct platform_device *pdev) | 211 | static int usbtll_omap_probe(struct platform_device *pdev) |
211 | { | 212 | { |
212 | struct device *dev = &pdev->dev; | 213 | struct device *dev = &pdev->dev; |
213 | struct usbhs_omap_platform_data *pdata = dev->platform_data; | ||
214 | void __iomem *base; | ||
215 | struct resource *res; | 214 | struct resource *res; |
216 | struct usbtll_omap *tll; | 215 | struct usbtll_omap *tll; |
217 | unsigned reg; | ||
218 | int ret = 0; | 216 | int ret = 0; |
219 | int i, ver; | 217 | int i, ver; |
220 | bool needs_tll; | ||
221 | 218 | ||
222 | dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); | 219 | dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); |
223 | 220 | ||
@@ -227,16 +224,9 @@ static int usbtll_omap_probe(struct platform_device *pdev) | |||
227 | return -ENOMEM; | 224 | return -ENOMEM; |
228 | } | 225 | } |
229 | 226 | ||
230 | if (!pdata) { | ||
231 | dev_err(dev, "Platform data missing\n"); | ||
232 | return -ENODEV; | ||
233 | } | ||
234 | |||
235 | tll->pdata = pdata; | ||
236 | |||
237 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 227 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
238 | base = devm_request_and_ioremap(dev, res); | 228 | tll->base = devm_request_and_ioremap(dev, res); |
239 | if (!base) { | 229 | if (!tll->base) { |
240 | ret = -EADDRNOTAVAIL; | 230 | ret = -EADDRNOTAVAIL; |
241 | dev_err(dev, "Resource request/ioremap failed:%d\n", ret); | 231 | dev_err(dev, "Resource request/ioremap failed:%d\n", ret); |
242 | return ret; | 232 | return ret; |
@@ -246,7 +236,7 @@ static int usbtll_omap_probe(struct platform_device *pdev) | |||
246 | pm_runtime_enable(dev); | 236 | pm_runtime_enable(dev); |
247 | pm_runtime_get_sync(dev); | 237 | pm_runtime_get_sync(dev); |
248 | 238 | ||
249 | ver = usbtll_read(base, OMAP_USBTLL_REVISION); | 239 | ver = usbtll_read(tll->base, OMAP_USBTLL_REVISION); |
250 | switch (ver) { | 240 | switch (ver) { |
251 | case OMAP_USBTLL_REV1: | 241 | case OMAP_USBTLL_REV1: |
252 | case OMAP_USBTLL_REV4: | 242 | case OMAP_USBTLL_REV4: |
@@ -283,11 +273,77 @@ static int usbtll_omap_probe(struct platform_device *pdev) | |||
283 | dev_dbg(dev, "can't get clock : %s\n", clkname); | 273 | dev_dbg(dev, "can't get clock : %s\n", clkname); |
284 | } | 274 | } |
285 | 275 | ||
276 | pm_runtime_put_sync(dev); | ||
277 | /* only after this can omap_tll_enable/disable work */ | ||
278 | spin_lock(&tll_lock); | ||
279 | tll_dev = dev; | ||
280 | spin_unlock(&tll_lock); | ||
281 | |||
282 | return 0; | ||
283 | |||
284 | err_clk_alloc: | ||
285 | pm_runtime_put_sync(dev); | ||
286 | pm_runtime_disable(dev); | ||
287 | |||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | /** | ||
292 | * usbtll_omap_remove - shutdown processing for UHH & TLL HCDs | ||
293 | * @pdev: USB Host Controller being removed | ||
294 | * | ||
295 | * Reverses the effect of usbtll_omap_probe(). | ||
296 | */ | ||
297 | static int usbtll_omap_remove(struct platform_device *pdev) | ||
298 | { | ||
299 | struct usbtll_omap *tll = platform_get_drvdata(pdev); | ||
300 | int i; | ||
301 | |||
302 | spin_lock(&tll_lock); | ||
303 | tll_dev = NULL; | ||
304 | spin_unlock(&tll_lock); | ||
305 | |||
306 | for (i = 0; i < tll->nch; i++) | ||
307 | if (!IS_ERR(tll->ch_clk[i])) | ||
308 | clk_put(tll->ch_clk[i]); | ||
309 | |||
310 | pm_runtime_disable(&pdev->dev); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static struct platform_driver usbtll_omap_driver = { | ||
315 | .driver = { | ||
316 | .name = (char *)usbtll_driver_name, | ||
317 | .owner = THIS_MODULE, | ||
318 | }, | ||
319 | .probe = usbtll_omap_probe, | ||
320 | .remove = usbtll_omap_remove, | ||
321 | }; | ||
322 | |||
323 | int omap_tll_init(struct usbhs_omap_platform_data *pdata) | ||
324 | { | ||
325 | int i; | ||
326 | bool needs_tll; | ||
327 | unsigned reg; | ||
328 | struct usbtll_omap *tll; | ||
329 | |||
330 | spin_lock(&tll_lock); | ||
331 | |||
332 | if (!tll_dev) { | ||
333 | spin_unlock(&tll_lock); | ||
334 | return -ENODEV; | ||
335 | } | ||
336 | |||
337 | tll = dev_get_drvdata(tll_dev); | ||
338 | |||
286 | needs_tll = false; | 339 | needs_tll = false; |
287 | for (i = 0; i < tll->nch; i++) | 340 | for (i = 0; i < tll->nch; i++) |
288 | needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]); | 341 | needs_tll |= omap_usb_mode_needs_tll(pdata->port_mode[i]); |
289 | 342 | ||
343 | pm_runtime_get_sync(tll_dev); | ||
344 | |||
290 | if (needs_tll) { | 345 | if (needs_tll) { |
346 | void __iomem *base = tll->base; | ||
291 | 347 | ||
292 | /* Program Common TLL register */ | 348 | /* Program Common TLL register */ |
293 | reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); | 349 | reg = usbtll_read(base, OMAP_TLL_SHARED_CONF); |
@@ -336,51 +392,29 @@ static int usbtll_omap_probe(struct platform_device *pdev) | |||
336 | } | 392 | } |
337 | } | 393 | } |
338 | 394 | ||
339 | pm_runtime_put_sync(dev); | 395 | pm_runtime_put_sync(tll_dev); |
340 | /* only after this can omap_tll_enable/disable work */ | 396 | |
341 | spin_lock(&tll_lock); | ||
342 | tll_dev = dev; | ||
343 | spin_unlock(&tll_lock); | 397 | spin_unlock(&tll_lock); |
344 | 398 | ||
345 | return 0; | 399 | return 0; |
346 | |||
347 | err_clk_alloc: | ||
348 | pm_runtime_put_sync(dev); | ||
349 | pm_runtime_disable(dev); | ||
350 | |||
351 | return ret; | ||
352 | } | 400 | } |
401 | EXPORT_SYMBOL_GPL(omap_tll_init); | ||
353 | 402 | ||
354 | /** | 403 | int omap_tll_enable(struct usbhs_omap_platform_data *pdata) |
355 | * usbtll_omap_remove - shutdown processing for UHH & TLL HCDs | ||
356 | * @pdev: USB Host Controller being removed | ||
357 | * | ||
358 | * Reverses the effect of usbtll_omap_probe(). | ||
359 | */ | ||
360 | static int usbtll_omap_remove(struct platform_device *pdev) | ||
361 | { | 404 | { |
362 | struct usbtll_omap *tll = platform_get_drvdata(pdev); | ||
363 | int i; | 405 | int i; |
406 | struct usbtll_omap *tll; | ||
364 | 407 | ||
365 | spin_lock(&tll_lock); | 408 | spin_lock(&tll_lock); |
366 | tll_dev = NULL; | ||
367 | spin_unlock(&tll_lock); | ||
368 | |||
369 | for (i = 0; i < tll->nch; i++) | ||
370 | if (!IS_ERR(tll->ch_clk[i])) | ||
371 | clk_put(tll->ch_clk[i]); | ||
372 | 409 | ||
373 | pm_runtime_disable(&pdev->dev); | 410 | if (!tll_dev) { |
374 | return 0; | 411 | spin_unlock(&tll_lock); |
375 | } | 412 | return -ENODEV; |
413 | } | ||
376 | 414 | ||
377 | static int usbtll_runtime_resume(struct device *dev) | 415 | tll = dev_get_drvdata(tll_dev); |
378 | { | ||
379 | struct usbtll_omap *tll = dev_get_drvdata(dev); | ||
380 | struct usbhs_omap_platform_data *pdata = tll->pdata; | ||
381 | int i; | ||
382 | 416 | ||
383 | dev_dbg(dev, "usbtll_runtime_resume\n"); | 417 | pm_runtime_get_sync(tll_dev); |
384 | 418 | ||
385 | for (i = 0; i < tll->nch; i++) { | 419 | for (i = 0; i < tll->nch; i++) { |
386 | if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { | 420 | if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { |
@@ -391,22 +425,31 @@ static int usbtll_runtime_resume(struct device *dev) | |||
391 | 425 | ||
392 | r = clk_enable(tll->ch_clk[i]); | 426 | r = clk_enable(tll->ch_clk[i]); |
393 | if (r) { | 427 | if (r) { |
394 | dev_err(dev, | 428 | dev_err(tll_dev, |
395 | "Error enabling ch %d clock: %d\n", i, r); | 429 | "Error enabling ch %d clock: %d\n", i, r); |
396 | } | 430 | } |
397 | } | 431 | } |
398 | } | 432 | } |
399 | 433 | ||
434 | spin_unlock(&tll_lock); | ||
435 | |||
400 | return 0; | 436 | return 0; |
401 | } | 437 | } |
438 | EXPORT_SYMBOL_GPL(omap_tll_enable); | ||
402 | 439 | ||
403 | static int usbtll_runtime_suspend(struct device *dev) | 440 | int omap_tll_disable(struct usbhs_omap_platform_data *pdata) |
404 | { | 441 | { |
405 | struct usbtll_omap *tll = dev_get_drvdata(dev); | ||
406 | struct usbhs_omap_platform_data *pdata = tll->pdata; | ||
407 | int i; | 442 | int i; |
443 | struct usbtll_omap *tll; | ||
444 | |||
445 | spin_lock(&tll_lock); | ||
446 | |||
447 | if (!tll_dev) { | ||
448 | spin_unlock(&tll_lock); | ||
449 | return -ENODEV; | ||
450 | } | ||
408 | 451 | ||
409 | dev_dbg(dev, "usbtll_runtime_suspend\n"); | 452 | tll = dev_get_drvdata(tll_dev); |
410 | 453 | ||
411 | for (i = 0; i < tll->nch; i++) { | 454 | for (i = 0; i < tll->nch; i++) { |
412 | if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { | 455 | if (omap_usb_mode_needs_tll(pdata->port_mode[i])) { |
@@ -415,60 +458,11 @@ static int usbtll_runtime_suspend(struct device *dev) | |||
415 | } | 458 | } |
416 | } | 459 | } |
417 | 460 | ||
418 | return 0; | 461 | pm_runtime_put_sync(tll_dev); |
419 | } | ||
420 | |||
421 | static const struct dev_pm_ops usbtllomap_dev_pm_ops = { | ||
422 | SET_RUNTIME_PM_OPS(usbtll_runtime_suspend, | ||
423 | usbtll_runtime_resume, | ||
424 | NULL) | ||
425 | }; | ||
426 | |||
427 | static struct platform_driver usbtll_omap_driver = { | ||
428 | .driver = { | ||
429 | .name = (char *)usbtll_driver_name, | ||
430 | .owner = THIS_MODULE, | ||
431 | .pm = &usbtllomap_dev_pm_ops, | ||
432 | }, | ||
433 | .probe = usbtll_omap_probe, | ||
434 | .remove = usbtll_omap_remove, | ||
435 | }; | ||
436 | |||
437 | int omap_tll_enable(void) | ||
438 | { | ||
439 | int ret; | ||
440 | |||
441 | spin_lock(&tll_lock); | ||
442 | |||
443 | if (!tll_dev) { | ||
444 | pr_err("%s: OMAP USB TLL not initialized\n", __func__); | ||
445 | ret = -ENODEV; | ||
446 | } else { | ||
447 | ret = pm_runtime_get_sync(tll_dev); | ||
448 | } | ||
449 | 462 | ||
450 | spin_unlock(&tll_lock); | 463 | spin_unlock(&tll_lock); |
451 | 464 | ||
452 | return ret; | 465 | return 0; |
453 | } | ||
454 | EXPORT_SYMBOL_GPL(omap_tll_enable); | ||
455 | |||
456 | int omap_tll_disable(void) | ||
457 | { | ||
458 | int ret; | ||
459 | |||
460 | spin_lock(&tll_lock); | ||
461 | |||
462 | if (!tll_dev) { | ||
463 | pr_err("%s: OMAP USB TLL not initialized\n", __func__); | ||
464 | ret = -ENODEV; | ||
465 | } else { | ||
466 | ret = pm_runtime_put_sync(tll_dev); | ||
467 | } | ||
468 | |||
469 | spin_unlock(&tll_lock); | ||
470 | |||
471 | return ret; | ||
472 | } | 466 | } |
473 | EXPORT_SYMBOL_GPL(omap_tll_disable); | 467 | EXPORT_SYMBOL_GPL(omap_tll_disable); |
474 | 468 | ||
diff --git a/drivers/mfd/omap-usb.h b/drivers/mfd/omap-usb.h index 972aa961b064..2a508b6aeac8 100644 --- a/drivers/mfd/omap-usb.h +++ b/drivers/mfd/omap-usb.h | |||
@@ -1,2 +1,3 @@ | |||
1 | extern int omap_tll_enable(void); | 1 | extern int omap_tll_init(struct usbhs_omap_platform_data *pdata); |
2 | extern int omap_tll_disable(void); | 2 | extern int omap_tll_enable(struct usbhs_omap_platform_data *pdata); |
3 | extern int omap_tll_disable(struct usbhs_omap_platform_data *pdata); | ||