aboutsummaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch165
1 files changed, 165 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch
new file mode 100644
index 00000000..94d5f591
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch
@@ -0,0 +1,165 @@
+From bf583f2924fd9b2f0356cbd0bbfd58c48d98ef15 Mon Sep 17 00:00:00 2001
+From: Keshava Munegowda <Keshava_mgowda@ti.com>
+Date: Wed, 1 Jun 2011 11:03:03 -0700
+Subject: [PATCH 07/13] mfd: global Suspend and resume support of ehci and ohci
+
+The global suspend and resume functions for usbhs core driver
+are implemented.These routine are called when the global suspend
+and resume occurs. Before calling these functions, the
+bus suspend and resume of ehci and ohci drivers are called
+from runtime pm.
+
+Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
+---
+ drivers/mfd/omap-usb-host.c | 103 +++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 103 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
+index 43de12a..32d19e2 100644
+--- a/drivers/mfd/omap-usb-host.c
++++ b/drivers/mfd/omap-usb-host.c
+@@ -146,6 +146,10 @@
+ #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
+
+
++/* USBHS state bits */
++#define OMAP_USBHS_INIT 0
++#define OMAP_USBHS_SUSPEND 4
++
+ struct usbhs_hcd_omap {
+ struct clk *xclk60mhsp1_ck;
+ struct clk *xclk60mhsp2_ck;
+@@ -165,6 +169,7 @@ struct usbhs_hcd_omap {
+ u32 usbhs_rev;
+ spinlock_t lock;
+ int count;
++ unsigned long state;
+ };
+ /*-------------------------------------------------------------------------*/
+
+@@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev)
+ (pdata->ehci_data->reset_gpio_port[1], 1);
+ }
+
++ set_bit(OMAP_USBHS_INIT, &omap->state);
++
+ end_count:
+ omap->count++;
+ spin_unlock_irqrestore(&omap->lock, flags);
+@@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev)
+ }
+
+ pm_runtime_put_sync(dev);
++ clear_bit(OMAP_USBHS_INIT, &omap->state);
+
+ /* The gpio_free migh sleep; so unlock the spinlock */
+ spin_unlock_irqrestore(&omap->lock, flags);
+@@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(omap_usbhs_disable);
+
++#ifdef CONFIG_PM
++
++static int usbhs_resume(struct device *dev)
++{
++ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
++ struct usbhs_omap_platform_data *pdata = &omap->platdata;
++ unsigned long flags = 0;
++
++ dev_dbg(dev, "Resuming TI HSUSB Controller\n");
++
++ if (!pdata) {
++ dev_dbg(dev, "missing platform_data\n");
++ return -ENODEV;
++ }
++
++ spin_lock_irqsave(&omap->lock, flags);
++
++ if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
++ !test_bit(OMAP_USBHS_SUSPEND, &omap->state))
++ goto end_resume;
++
++ pm_runtime_get_sync(dev);
++
++ if (is_omap_usbhs_rev2(omap)) {
++ if (is_ehci_tll_mode(pdata->port_mode[0])) {
++ clk_enable(omap->usbhost_p1_fck);
++ clk_enable(omap->usbtll_p1_fck);
++ }
++ if (is_ehci_tll_mode(pdata->port_mode[1])) {
++ clk_enable(omap->usbhost_p2_fck);
++ clk_enable(omap->usbtll_p2_fck);
++ }
++ clk_enable(omap->utmi_p1_fck);
++ clk_enable(omap->utmi_p2_fck);
++ }
++ clear_bit(OMAP_USBHS_SUSPEND, &omap->state);
++
++end_resume:
++ spin_unlock_irqrestore(&omap->lock, flags);
++ return 0;
++}
++
++
++static int usbhs_suspend(struct device *dev)
++{
++ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
++ struct usbhs_omap_platform_data *pdata = &omap->platdata;
++ unsigned long flags = 0;
++
++ dev_dbg(dev, "Suspending TI HSUSB Controller\n");
++
++ if (!pdata) {
++ dev_dbg(dev, "missing platform_data\n");
++ return -ENODEV;
++ }
++
++ spin_lock_irqsave(&omap->lock, flags);
++
++ if (!test_bit(OMAP_USBHS_INIT, &omap->state) ||
++ test_bit(OMAP_USBHS_SUSPEND, &omap->state))
++ goto end_suspend;
++
++ if (is_omap_usbhs_rev2(omap)) {
++ if (is_ehci_tll_mode(pdata->port_mode[0])) {
++ clk_disable(omap->usbhost_p1_fck);
++ clk_disable(omap->usbtll_p1_fck);
++ }
++ if (is_ehci_tll_mode(pdata->port_mode[1])) {
++ clk_disable(omap->usbhost_p2_fck);
++ clk_disable(omap->usbtll_p2_fck);
++ }
++ clk_disable(omap->utmi_p2_fck);
++ clk_disable(omap->utmi_p1_fck);
++ }
++
++ set_bit(OMAP_USBHS_SUSPEND, &omap->state);
++ pm_runtime_put_sync(dev);
++
++end_suspend:
++ spin_unlock_irqrestore(&omap->lock, flags);
++ return 0;
++}
++
++
++static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
++ .suspend = usbhs_suspend,
++ .resume = usbhs_resume,
++};
++
++#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops)
++#else
++#define USBHS_OMAP_DEV_PM_OPS NULL
++#endif
++
+ static struct platform_driver usbhs_omap_driver = {
+ .driver = {
+ .name = (char *)usbhs_driver_name,
+ .owner = THIS_MODULE,
++ .pm = USBHS_OMAP_DEV_PM_OPS,
+ },
+ .remove = __exit_p(usbhs_omap_remove),
+ };
+--
+1.6.6.1
+