diff options
-rw-r--r-- | drivers/mfd/omap-usb-host.c | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 9fa0215e3df4..bdfc8b7b5aff 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -93,6 +93,8 @@ | |||
93 | struct usbhs_hcd_omap { | 93 | struct usbhs_hcd_omap { |
94 | int nports; | 94 | int nports; |
95 | struct clk **utmi_clk; | 95 | struct clk **utmi_clk; |
96 | struct clk **hsic60m_clk; | ||
97 | struct clk **hsic480m_clk; | ||
96 | 98 | ||
97 | struct clk *xclk60mhsp1_ck; | 99 | struct clk *xclk60mhsp1_ck; |
98 | struct clk *xclk60mhsp2_ck; | 100 | struct clk *xclk60mhsp2_ck; |
@@ -286,13 +288,40 @@ static int usbhs_runtime_resume(struct device *dev) | |||
286 | clk_enable(omap->ehci_logic_fck); | 288 | clk_enable(omap->ehci_logic_fck); |
287 | 289 | ||
288 | for (i = 0; i < omap->nports; i++) { | 290 | for (i = 0; i < omap->nports; i++) { |
289 | if (!is_ehci_tll_mode(pdata->port_mode[i]) || | 291 | switch (pdata->port_mode[i]) { |
290 | IS_ERR(omap->utmi_clk[i])) | 292 | case OMAP_EHCI_PORT_MODE_HSIC: |
291 | continue; | 293 | if (!IS_ERR(omap->hsic60m_clk[i])) { |
292 | 294 | r = clk_enable(omap->hsic60m_clk[i]); | |
293 | r = clk_enable(omap->utmi_clk[i]); | 295 | if (r) { |
294 | if (r) | 296 | dev_err(dev, |
295 | dev_err(dev, "Can't enable port %d clk : %d\n", i, r); | 297 | "Can't enable port %d hsic60m clk:%d\n", |
298 | i, r); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | if (!IS_ERR(omap->hsic480m_clk[i])) { | ||
303 | r = clk_enable(omap->hsic480m_clk[i]); | ||
304 | if (r) { | ||
305 | dev_err(dev, | ||
306 | "Can't enable port %d hsic480m clk:%d\n", | ||
307 | i, r); | ||
308 | } | ||
309 | } | ||
310 | /* Fall through as HSIC mode needs utmi_clk */ | ||
311 | |||
312 | case OMAP_EHCI_PORT_MODE_TLL: | ||
313 | if (!IS_ERR(omap->utmi_clk[i])) { | ||
314 | r = clk_enable(omap->utmi_clk[i]); | ||
315 | if (r) { | ||
316 | dev_err(dev, | ||
317 | "Can't enable port %d clk : %d\n", | ||
318 | i, r); | ||
319 | } | ||
320 | } | ||
321 | break; | ||
322 | default: | ||
323 | break; | ||
324 | } | ||
296 | } | 325 | } |
297 | 326 | ||
298 | spin_unlock_irqrestore(&omap->lock, flags); | 327 | spin_unlock_irqrestore(&omap->lock, flags); |
@@ -312,9 +341,22 @@ static int usbhs_runtime_suspend(struct device *dev) | |||
312 | spin_lock_irqsave(&omap->lock, flags); | 341 | spin_lock_irqsave(&omap->lock, flags); |
313 | 342 | ||
314 | for (i = 0; i < omap->nports; i++) { | 343 | for (i = 0; i < omap->nports; i++) { |
315 | if (is_ehci_tll_mode(pdata->port_mode[i]) && | 344 | switch (pdata->port_mode[i]) { |
316 | !IS_ERR(omap->utmi_clk[i])) | 345 | case OMAP_EHCI_PORT_MODE_HSIC: |
317 | clk_disable(omap->utmi_clk[i]); | 346 | if (!IS_ERR(omap->hsic60m_clk[i])) |
347 | clk_disable(omap->hsic60m_clk[i]); | ||
348 | |||
349 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
350 | clk_disable(omap->hsic480m_clk[i]); | ||
351 | /* Fall through as utmi_clks were used in HSIC mode */ | ||
352 | |||
353 | case OMAP_EHCI_PORT_MODE_TLL: | ||
354 | if (!IS_ERR(omap->utmi_clk[i])) | ||
355 | clk_disable(omap->utmi_clk[i]); | ||
356 | break; | ||
357 | default: | ||
358 | break; | ||
359 | } | ||
318 | } | 360 | } |
319 | 361 | ||
320 | if (!IS_ERR(omap->ehci_logic_fck)) | 362 | if (!IS_ERR(omap->ehci_logic_fck)) |
@@ -520,7 +562,10 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
520 | 562 | ||
521 | i = sizeof(struct clk *) * omap->nports; | 563 | i = sizeof(struct clk *) * omap->nports; |
522 | omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL); | 564 | omap->utmi_clk = devm_kzalloc(dev, i, GFP_KERNEL); |
523 | if (!omap->utmi_clk) { | 565 | omap->hsic480m_clk = devm_kzalloc(dev, i, GFP_KERNEL); |
566 | omap->hsic60m_clk = devm_kzalloc(dev, i, GFP_KERNEL); | ||
567 | |||
568 | if (!omap->utmi_clk || !omap->hsic480m_clk || !omap->hsic60m_clk) { | ||
524 | dev_err(dev, "Memory allocation failed\n"); | 569 | dev_err(dev, "Memory allocation failed\n"); |
525 | ret = -ENOMEM; | 570 | ret = -ENOMEM; |
526 | goto err_mem; | 571 | goto err_mem; |
@@ -578,7 +623,7 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
578 | } | 623 | } |
579 | 624 | ||
580 | for (i = 0; i < omap->nports; i++) { | 625 | for (i = 0; i < omap->nports; i++) { |
581 | char clkname[] = "usb_host_hs_utmi_px_clk"; | 626 | char clkname[30]; |
582 | 627 | ||
583 | /* clock names are indexed from 1*/ | 628 | /* clock names are indexed from 1*/ |
584 | snprintf(clkname, sizeof(clkname), | 629 | snprintf(clkname, sizeof(clkname), |
@@ -592,6 +637,20 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
592 | if (IS_ERR(omap->utmi_clk[i])) | 637 | if (IS_ERR(omap->utmi_clk[i])) |
593 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 638 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", |
594 | clkname, PTR_ERR(omap->utmi_clk[i])); | 639 | clkname, PTR_ERR(omap->utmi_clk[i])); |
640 | |||
641 | snprintf(clkname, sizeof(clkname), | ||
642 | "usb_host_hs_hsic480m_p%d_clk", i + 1); | ||
643 | omap->hsic480m_clk[i] = clk_get(dev, clkname); | ||
644 | if (IS_ERR(omap->hsic480m_clk[i])) | ||
645 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | ||
646 | clkname, PTR_ERR(omap->hsic480m_clk[i])); | ||
647 | |||
648 | snprintf(clkname, sizeof(clkname), | ||
649 | "usb_host_hs_hsic60m_p%d_clk", i + 1); | ||
650 | omap->hsic60m_clk[i] = clk_get(dev, clkname); | ||
651 | if (IS_ERR(omap->hsic60m_clk[i])) | ||
652 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | ||
653 | clkname, PTR_ERR(omap->hsic60m_clk[i])); | ||
595 | } | 654 | } |
596 | 655 | ||
597 | if (is_ehci_phy_mode(pdata->port_mode[0])) { | 656 | if (is_ehci_phy_mode(pdata->port_mode[0])) { |
@@ -635,9 +694,14 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
635 | err_alloc: | 694 | err_alloc: |
636 | omap_usbhs_deinit(&pdev->dev); | 695 | omap_usbhs_deinit(&pdev->dev); |
637 | 696 | ||
638 | for (i = 0; i < omap->nports; i++) | 697 | for (i = 0; i < omap->nports; i++) { |
639 | if (!IS_ERR(omap->utmi_clk[i])) | 698 | if (!IS_ERR(omap->utmi_clk[i])) |
640 | clk_put(omap->utmi_clk[i]); | 699 | clk_put(omap->utmi_clk[i]); |
700 | if (!IS_ERR(omap->hsic60m_clk[i])) | ||
701 | clk_put(omap->hsic60m_clk[i]); | ||
702 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
703 | clk_put(omap->hsic480m_clk[i]); | ||
704 | } | ||
641 | 705 | ||
642 | clk_put(omap->init_60m_fclk); | 706 | clk_put(omap->init_60m_fclk); |
643 | 707 | ||
@@ -676,9 +740,14 @@ static int usbhs_omap_remove(struct platform_device *pdev) | |||
676 | 740 | ||
677 | omap_usbhs_deinit(&pdev->dev); | 741 | omap_usbhs_deinit(&pdev->dev); |
678 | 742 | ||
679 | for (i = 0; i < omap->nports; i++) | 743 | for (i = 0; i < omap->nports; i++) { |
680 | if (!IS_ERR(omap->utmi_clk[i])) | 744 | if (!IS_ERR(omap->utmi_clk[i])) |
681 | clk_put(omap->utmi_clk[i]); | 745 | clk_put(omap->utmi_clk[i]); |
746 | if (!IS_ERR(omap->hsic60m_clk[i])) | ||
747 | clk_put(omap->hsic60m_clk[i]); | ||
748 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
749 | clk_put(omap->hsic480m_clk[i]); | ||
750 | } | ||
682 | 751 | ||
683 | clk_put(omap->init_60m_fclk); | 752 | clk_put(omap->init_60m_fclk); |
684 | clk_put(omap->utmi_p1_gfclk); | 753 | clk_put(omap->utmi_p1_gfclk); |