aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorKeshava Munegowda <Keshava_mgowda@ti.com>2011-05-22 16:51:26 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-05-26 13:45:52 -0400
commit7e6502d577106fb5b202bbaac64c5f1b065e6daa (patch)
treeb534ce2e049696ce10130d6755dcc1840cdcdff4 /drivers/mfd
parent74e32d1b68f177f9c998041d789253df9c7f3575 (diff)
mfd: Add omap-usbhs runtime PM support
The usbhs core driver does not enable/disable the interface and functional clocks; These clocks are handled by hwmod and runtime pm, hence insted of the clock enable/disable, the runtime pm APIS are used. however,the port clocks and tll clocks are handled by the usbhs core. Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/omap-usb-host.c131
1 files changed, 9 insertions, 122 deletions
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 1717144fe7f4..855219526ccb 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -26,6 +26,7 @@
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <plat/usb.h> 28#include <plat/usb.h>
29#include <linux/pm_runtime.h>
29 30
30#define USBHS_DRIVER_NAME "usbhs-omap" 31#define USBHS_DRIVER_NAME "usbhs-omap"
31#define OMAP_EHCI_DEVICE "ehci-omap" 32#define OMAP_EHCI_DEVICE "ehci-omap"
@@ -146,9 +147,6 @@
146 147
147 148
148struct usbhs_hcd_omap { 149struct usbhs_hcd_omap {
149 struct clk *usbhost_ick;
150 struct clk *usbhost_hs_fck;
151 struct clk *usbhost_fs_fck;
152 struct clk *xclk60mhsp1_ck; 150 struct clk *xclk60mhsp1_ck;
153 struct clk *xclk60mhsp2_ck; 151 struct clk *xclk60mhsp2_ck;
154 struct clk *utmi_p1_fck; 152 struct clk *utmi_p1_fck;
@@ -158,8 +156,6 @@ struct usbhs_hcd_omap {
158 struct clk *usbhost_p2_fck; 156 struct clk *usbhost_p2_fck;
159 struct clk *usbtll_p2_fck; 157 struct clk *usbtll_p2_fck;
160 struct clk *init_60m_fclk; 158 struct clk *init_60m_fclk;
161 struct clk *usbtll_fck;
162 struct clk *usbtll_ick;
163 159
164 void __iomem *uhh_base; 160 void __iomem *uhh_base;
165 void __iomem *tll_base; 161 void __iomem *tll_base;
@@ -353,46 +349,13 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
353 omap->platdata.ehci_data = pdata->ehci_data; 349 omap->platdata.ehci_data = pdata->ehci_data;
354 omap->platdata.ohci_data = pdata->ohci_data; 350 omap->platdata.ohci_data = pdata->ohci_data;
355 351
356 omap->usbhost_ick = clk_get(dev, "usbhost_ick"); 352 pm_runtime_enable(&pdev->dev);
357 if (IS_ERR(omap->usbhost_ick)) {
358 ret = PTR_ERR(omap->usbhost_ick);
359 dev_err(dev, "usbhost_ick failed error:%d\n", ret);
360 goto err_end;
361 }
362
363 omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
364 if (IS_ERR(omap->usbhost_hs_fck)) {
365 ret = PTR_ERR(omap->usbhost_hs_fck);
366 dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
367 goto err_usbhost_ick;
368 }
369
370 omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
371 if (IS_ERR(omap->usbhost_fs_fck)) {
372 ret = PTR_ERR(omap->usbhost_fs_fck);
373 dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
374 goto err_usbhost_hs_fck;
375 }
376
377 omap->usbtll_fck = clk_get(dev, "usbtll_fck");
378 if (IS_ERR(omap->usbtll_fck)) {
379 ret = PTR_ERR(omap->usbtll_fck);
380 dev_err(dev, "usbtll_fck failed error:%d\n", ret);
381 goto err_usbhost_fs_fck;
382 }
383
384 omap->usbtll_ick = clk_get(dev, "usbtll_ick");
385 if (IS_ERR(omap->usbtll_ick)) {
386 ret = PTR_ERR(omap->usbtll_ick);
387 dev_err(dev, "usbtll_ick failed error:%d\n", ret);
388 goto err_usbtll_fck;
389 }
390 353
391 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); 354 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
392 if (IS_ERR(omap->utmi_p1_fck)) { 355 if (IS_ERR(omap->utmi_p1_fck)) {
393 ret = PTR_ERR(omap->utmi_p1_fck); 356 ret = PTR_ERR(omap->utmi_p1_fck);
394 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); 357 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
395 goto err_usbtll_ick; 358 goto err_end;
396 } 359 }
397 360
398 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); 361 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
@@ -522,22 +485,8 @@ err_xclk60mhsp1_ck:
522err_utmi_p1_fck: 485err_utmi_p1_fck:
523 clk_put(omap->utmi_p1_fck); 486 clk_put(omap->utmi_p1_fck);
524 487
525err_usbtll_ick:
526 clk_put(omap->usbtll_ick);
527
528err_usbtll_fck:
529 clk_put(omap->usbtll_fck);
530
531err_usbhost_fs_fck:
532 clk_put(omap->usbhost_fs_fck);
533
534err_usbhost_hs_fck:
535 clk_put(omap->usbhost_hs_fck);
536
537err_usbhost_ick:
538 clk_put(omap->usbhost_ick);
539
540err_end: 488err_end:
489 pm_runtime_disable(&pdev->dev);
541 kfree(omap); 490 kfree(omap);
542 491
543end_probe: 492end_probe:
@@ -571,11 +520,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
571 clk_put(omap->utmi_p2_fck); 520 clk_put(omap->utmi_p2_fck);
572 clk_put(omap->xclk60mhsp1_ck); 521 clk_put(omap->xclk60mhsp1_ck);
573 clk_put(omap->utmi_p1_fck); 522 clk_put(omap->utmi_p1_fck);
574 clk_put(omap->usbtll_ick); 523 pm_runtime_disable(&pdev->dev);
575 clk_put(omap->usbtll_fck);
576 clk_put(omap->usbhost_fs_fck);
577 clk_put(omap->usbhost_hs_fck);
578 clk_put(omap->usbhost_ick);
579 kfree(omap); 524 kfree(omap);
580 525
581 return 0; 526 return 0;
@@ -695,7 +640,6 @@ static int usbhs_enable(struct device *dev)
695 struct usbhs_omap_platform_data *pdata = &omap->platdata; 640 struct usbhs_omap_platform_data *pdata = &omap->platdata;
696 unsigned long flags = 0; 641 unsigned long flags = 0;
697 int ret = 0; 642 int ret = 0;
698 unsigned long timeout;
699 unsigned reg; 643 unsigned reg;
700 644
701 dev_dbg(dev, "starting TI HSUSB Controller\n"); 645 dev_dbg(dev, "starting TI HSUSB Controller\n");
@@ -708,11 +652,7 @@ static int usbhs_enable(struct device *dev)
708 if (omap->count > 0) 652 if (omap->count > 0)
709 goto end_count; 653 goto end_count;
710 654
711 clk_enable(omap->usbhost_ick); 655 pm_runtime_get_sync(dev);
712 clk_enable(omap->usbhost_hs_fck);
713 clk_enable(omap->usbhost_fs_fck);
714 clk_enable(omap->usbtll_fck);
715 clk_enable(omap->usbtll_ick);
716 656
717 if (pdata->ehci_data->phy_reset) { 657 if (pdata->ehci_data->phy_reset) {
718 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { 658 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
@@ -736,50 +676,6 @@ static int usbhs_enable(struct device *dev)
736 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); 676 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
737 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); 677 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
738 678
739 /* perform TLL soft reset, and wait until reset is complete */
740 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
741 OMAP_USBTLL_SYSCONFIG_SOFTRESET);
742
743 /* Wait for TLL reset to complete */
744 timeout = jiffies + msecs_to_jiffies(1000);
745 while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
746 & OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
747 cpu_relax();
748
749 if (time_after(jiffies, timeout)) {
750 dev_dbg(dev, "operation timed out\n");
751 ret = -EINVAL;
752 goto err_tll;
753 }
754 }
755
756 dev_dbg(dev, "TLL RESET DONE\n");
757
758 /* (1<<3) = no idle mode only for initial debugging */
759 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
760 OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
761 OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
762 OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
763
764 /* Put UHH in NoIdle/NoStandby mode */
765 reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
766 if (is_omap_usbhs_rev1(omap)) {
767 reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
768 | OMAP_UHH_SYSCONFIG_SIDLEMODE
769 | OMAP_UHH_SYSCONFIG_CACTIVITY
770 | OMAP_UHH_SYSCONFIG_MIDLEMODE);
771 reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
772
773
774 } else if (is_omap_usbhs_rev2(omap)) {
775 reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
776 reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
777 reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
778 reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
779 }
780
781 usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
782
783 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 679 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
784 /* setup ULPI bypass and burst configurations */ 680 /* setup ULPI bypass and burst configurations */
785 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN 681 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
@@ -919,6 +815,8 @@ end_count:
919 return 0; 815 return 0;
920 816
921err_tll: 817err_tll:
818 pm_runtime_put_sync(dev);
819 spin_unlock_irqrestore(&omap->lock, flags);
922 if (pdata->ehci_data->phy_reset) { 820 if (pdata->ehci_data->phy_reset) {
923 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 821 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
924 gpio_free(pdata->ehci_data->reset_gpio_port[0]); 822 gpio_free(pdata->ehci_data->reset_gpio_port[0]);
@@ -926,13 +824,6 @@ err_tll:
926 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) 824 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
927 gpio_free(pdata->ehci_data->reset_gpio_port[1]); 825 gpio_free(pdata->ehci_data->reset_gpio_port[1]);
928 } 826 }
929
930 clk_disable(omap->usbtll_ick);
931 clk_disable(omap->usbtll_fck);
932 clk_disable(omap->usbhost_fs_fck);
933 clk_disable(omap->usbhost_hs_fck);
934 clk_disable(omap->usbhost_ick);
935 spin_unlock_irqrestore(&omap->lock, flags);
936 return ret; 827 return ret;
937} 828}
938 829
@@ -1005,11 +896,7 @@ static void usbhs_disable(struct device *dev)
1005 clk_disable(omap->utmi_p1_fck); 896 clk_disable(omap->utmi_p1_fck);
1006 } 897 }
1007 898
1008 clk_disable(omap->usbtll_ick); 899 pm_runtime_put_sync(dev);
1009 clk_disable(omap->usbtll_fck);
1010 clk_disable(omap->usbhost_fs_fck);
1011 clk_disable(omap->usbhost_hs_fck);
1012 clk_disable(omap->usbhost_ick);
1013 900
1014 /* The gpio_free migh sleep; so unlock the spinlock */ 901 /* The gpio_free migh sleep; so unlock the spinlock */
1015 spin_unlock_irqrestore(&omap->lock, flags); 902 spin_unlock_irqrestore(&omap->lock, flags);