aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-omap3.c
diff options
context:
space:
mode:
authorBenoit Goby <benoit@android.com>2011-07-26 17:51:44 -0700
committerBenoit Goby <benoit@android.com>2011-07-28 23:24:06 -0700
commite50bc2a90c69d09a5fee40f1afaebf19bd559352 (patch)
treeb33aaca1aa4b474616ddb4f41b4cc2a8b29210e9 /drivers/usb/host/ohci-omap3.c
parent502842eac405249cd2c05ca8216fef548447f6c0 (diff)
downloadkernel_samsung_tuna-e50bc2a90c69d09a5fee40f1afaebf19bd559352.zip
kernel_samsung_tuna-e50bc2a90c69d09a5fee40f1afaebf19bd559352.tar.gz
kernel_samsung_tuna-e50bc2a90c69d09a5fee40f1afaebf19bd559352.tar.bz2
OMAP4: USBHS: Enable remote wakeup using I/O pads
This patch implements remote wakeup using I/O pads of USB ports. When there is no device connected to USB host (EHCI/OHCI) the clocks are disabled in the bus suspend path. The clocks are enabled when I/O interrupt triggers. The USBHS clock and port clocks are enabled using workqueue triggered by PRCM interrupt handler of I/O. omap_hwmod API's are used to configure mux settings and to enable IO pad wakeup capability for EHCI/OHCI. Also omap_hwmod API is used to check for IO-PAD wakeup event status. Change-Id: Ia5a4458dd690c44f81bdc56bd1be39e458ed4509 Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Keshava Munegowda <Keshava_mgowda@ti.com> Signed-off-by: Partha Basak <p-basak2@ti.com> Signed-off-by: Moiz Sonasath <m-sonasath@ti.com> Signed-off-by: Benoit Goby <benoit@android.com> Tested-by: Vikram Pandita <vikram.pandita@ti.com>
Diffstat (limited to 'drivers/usb/host/ohci-omap3.c')
-rw-r--r--drivers/usb/host/ohci-omap3.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index a1a7981..875a837 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -31,6 +31,7 @@
#include <linux/platform_device.h>
#include <plat/usb.h>
+#include <plat/omap_hwmod.h>
#include <linux/pm_runtime.h>
/*-------------------------------------------------------------------------*/
@@ -42,6 +43,51 @@ static int ohci_omap3_init(struct usb_hcd *hcd)
return ohci_init(hcd_to_ohci(hcd));
}
+static int ohci_omap3_bus_suspend(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ struct omap_hwmod *oh;
+ int ret = 0;
+
+ dev_dbg(dev, "ohci_omap3_bus_suspend\n");
+
+ ret = ohci_bus_suspend(hcd);
+
+ /* Delay required so that after ohci suspend
+ * smart stand by can be set in the driver.
+ * required for power mangament
+ */
+ msleep(5);
+
+ if (ret != 0) {
+ dev_dbg(dev, "ohci_omap3_bus_suspend failed %d\n", ret);
+ return ret;
+ }
+
+ oh = omap_hwmod_lookup(USBHS_OHCI_HWMODNAME);
+
+ omap_hwmod_enable_ioring_wakeup(oh);
+
+ if (dev->parent)
+ pm_runtime_put_sync(dev->parent);
+
+ return ret;
+}
+
+
+static int ohci_omap3_bus_resume(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+
+ dev_dbg(dev, "ohci_omap3_bus_resume\n");
+
+ if (dev->parent)
+ pm_runtime_get_sync(dev->parent);
+
+ return ohci_bus_resume(hcd);
+}
+
+
/*-------------------------------------------------------------------------*/
static int ohci_omap3_start(struct usb_hcd *hcd)
@@ -105,8 +151,8 @@ static const struct hc_driver ohci_omap3_hc_driver = {
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
+ .bus_suspend = ohci_omap3_bus_suspend,
+ .bus_resume = ohci_omap3_bus_resume,
#endif
.start_port_reset = ohci_start_port_reset,
};
@@ -230,33 +276,12 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev)
hcd->driver->shutdown(hcd);
}
-
-static int omap_ohci_resume(struct device *dev)
-{
- if (dev->parent)
- pm_runtime_get_sync(dev->parent);
- return 0;
-}
-
-static int omap_ohci_suspend(struct device *dev)
-{
- if (dev->parent)
- pm_runtime_put_sync(dev->parent);
- return 0;
-}
-
-static const struct dev_pm_ops omap_ohci_dev_pm_ops = {
- .suspend = omap_ohci_suspend,
- .resume = omap_ohci_resume,
-};
-
static struct platform_driver ohci_hcd_omap3_driver = {
.probe = ohci_hcd_omap3_probe,
.remove = __devexit_p(ohci_hcd_omap3_remove),
.shutdown = ohci_hcd_omap3_shutdown,
.driver = {
.name = "ohci-omap3",
- .pm = &omap_ohci_dev_pm_ops,
},
};