summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2010-09-29 14:05:11 +0800
committerAlan Tull <alan.tull@freescale.com>2010-10-08 13:33:10 -0500
commitffd4c24b9d66147c0960b687817b5535166672ef (patch)
treee3f5eb4c5e3bff538208b602c91291dd7f4c6f27 /drivers
parentf89ac0af8d6fbc1de406c44107b0c851ad729755 (diff)
ENGR00132073-2 usb: wakeup capability should be controlled by user
Driver part The usb wakeup system capability should be controlled by user, For example, the users don't expect wakeup system at below situations: 1. When they plug in Micro B line, maybe the users just want to charge from PC 2. Plug in a usb device, such as usb camera or usb 3G moden The wakeup capability can be controlled by sys interface 1. At otg mode: echo enabled > /sys/devices/platform/fsl-usb2-otg/power/wakeup 2. At non-otg mode: device mode: echo enabled > /sys/devices/platform/fsl-usb2-otg/power/wakeup host mode echo enabled > /sys/devices/platform/fsl-ehci.x/power/wakeup x is the usb port num (from 0 to n-1) NOTE: The user must load one gadget module if he wants to usb otg wakeup function. Signed-off-by: Peter Chen <peter.chen@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/gadget/arcotg_udc.c28
-rw-r--r--drivers/usb/host/ehci-arc.c23
2 files changed, 39 insertions, 12 deletions
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index 0eee633d9323..ee72f6103e9f 100644
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -3050,6 +3050,22 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
return 0;
}
+static bool udc_can_wakeup_system(void)
+{
+ struct fsl_usb2_platform_data *pdata = udc_controller->pdata;
+
+ if (pdata->operating_mode == FSL_USB2_DR_OTG)
+ if (device_may_wakeup(udc_controller->transceiver->dev))
+ return true;
+ else
+ return false;
+ else
+ if (device_may_wakeup(udc_controller->gadget.dev.parent))
+ return true;
+ else
+ return false;
+}
+
static int udc_suspend(struct fsl_udc *udc)
{
u32 mode, usbcmd;
@@ -3063,7 +3079,7 @@ static int udc_suspend(struct fsl_udc *udc)
printk(KERN_DEBUG "udc suspend begins\n");
if (udc_controller->gadget.dev.parent->power.status
== DPM_SUSPENDING) {
- if (!device_may_wakeup(udc_controller->gadget.dev.parent))
+ if (!udc_can_wakeup_system())
dr_wake_up_enable(udc, false);
else
dr_wake_up_enable(udc, true);
@@ -3095,14 +3111,6 @@ static int udc_suspend(struct fsl_udc *udc)
usbcmd = fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP;
fsl_writel(usbcmd, &dr_regs->usbcmd);
- /* if the suspend is not for switch to host in otg mode */
- if ((!(udc->gadget.is_otg)) ||
- (fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)) {
- if (device_may_wakeup(udc_controller->gadget.dev.parent)) {
- dr_wake_up_enable(udc, true);
- }
- }
-
dr_phy_low_power_mode(udc, true);
printk(KERN_DEBUG "USB Gadget suspend ends\n");
out:
@@ -3162,7 +3170,7 @@ static int fsl_udc_resume(struct platform_device *pdev)
* set the abilities to wakeup itself. Otherwise, the usb
* subsystem will not leave from low power mode.
*/
- if (!device_may_wakeup(udc_controller->gadget.dev.parent) &&
+ if (!udc_can_wakeup_system() &&
udc_controller->gadget.dev.parent->power.status
== DPM_RESUMING){
if (udc_controller->pdata->usb_clock_for_pm)
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index b4bea17b9e03..60e11b913e63 100644
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -539,6 +539,25 @@ static int ehci_fsl_drv_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
+
+static bool host_can_wakeup_system(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+ if (pdata->operating_mode == FSL_USB2_DR_OTG)
+ if (device_may_wakeup(ehci->transceiver->dev))
+ return true;
+ else
+ return false;
+ else
+ if (device_may_wakeup(&(pdev->dev)))
+ return true;
+ else
+ return false;
+}
+
/* suspend/resume, section 4.3 */
/* These routines rely on the bus (pci, platform, etc)
@@ -561,7 +580,7 @@ static int ehci_fsl_drv_suspend(struct platform_device *pdev,
/* Only handles OTG mode switch event, system suspend event will be done in bus suspend */
if (pdev->dev.power.status == DPM_SUSPENDING) {
printk(KERN_DEBUG "%s, pm event \n", __func__);
- if (!device_may_wakeup(&(pdev->dev))) {
+ if (!host_can_wakeup_system(pdev)) {
int mask;
/* Need open clock for register access */
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
@@ -643,7 +662,7 @@ static int ehci_fsl_drv_resume(struct platform_device *pdev)
printk(KERN_DEBUG "ehci fsl drv resume begins: %s\n", pdata->name);
if (pdev->dev.power.status == DPM_RESUMING) {
printk(KERN_DEBUG "%s, pm event \n", __func__);
- if (!device_may_wakeup(&(pdev->dev))) {
+ if (!host_can_wakeup_system(pdev)) {
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
fsl_usb_clk_gate(hcd->self.controller->platform_data, true);
}