diff options
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.patch | 165 |
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 + |