mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 21:07:02 +09:00
usb: dwc_otg_310: pcd: hold wake lock until phy suspended and clk disabled
When begin connecting to PC in device mode, the driver will hold a wake lock to prevent system from entering deep sleep. If it fails to connect to PC or doesn't detect the vbus, the driver will suspend usb phy and disable usb clk, and release the wake lock. If unlock the wake lock first, system may enter deep sleep before suspend usb phy and disable usb clk. Then wake up system by pull out the usb cable, it may cause usb interrupt abnormal. TEST=rk3126c connect the usb charger into the charging interface, after the system entered deep sleep, pull out the usb cable with the following log: irq 42: nobody cared (try booting with the "irqpoll" option) CPU: 0 PID: 146 Comm: charger Not tainted 3.10.104 #133 [<c0014088>] unwind_backtrace+0x0/0xe0 [<c00118cc>] show_stack+0x10/0x14 [<c00b0be0>] __report_bad_irq+0x28/0xb8 [<c00b0e68>] note_interrupt+0x138/0x1cc [<c00aef88>] handle_irq_event_percpu+0x2c0/0x2f4 [<c00aeff8>] handle_irq_event+0x3c/0x5c [<c00b1a20>] handle_fasteoi_irq+0xbc/0x124 [<c00ae764>] generic_handle_irq+0x20/0x30 [<c000e4cc>] handle_IRQ+0x64/0x8c [<c000853c>] gic_handle_irq+0x38/0x5c handlers: [<c042b3ec>] dwc_otg_common_irq [<c0438704>] dwc_otg_pcd_irq [<c03fab48>] usb_hcd_irq Disabling IRQ #42 Change-Id: Id36717ae68e02226255c1207aeded0bd6fb356cd Signed-off-by: Feng Mingli <fml@rock-chips.com> Signed-off-by: William Wu <william.wu@rock-chips.com>
This commit is contained in:
@@ -1664,11 +1664,6 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
|
||||
printk("**************soft reconnect**************\n");
|
||||
goto connect;
|
||||
} else if (_pcd->conn_status == 2) {
|
||||
/*
|
||||
* Release pcd->wake_lock if fail to connect,
|
||||
* and allow system to enter deep sleep.
|
||||
*/
|
||||
dwc_otg_msc_unlock(_pcd);
|
||||
_pcd->conn_status++;
|
||||
|
||||
if (pldata->bc_detect_cb && iddig) {
|
||||
@@ -1684,6 +1679,12 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
|
||||
udelay(3);
|
||||
pldata->clock_enable(pldata, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release pcd->wake_lock if fail to connect,
|
||||
* and allow system to enter deep sleep.
|
||||
*/
|
||||
dwc_otg_msc_unlock(_pcd);
|
||||
}
|
||||
} else {
|
||||
if (pldata->bc_detect_cb && iddig)
|
||||
@@ -1697,15 +1698,15 @@ static void dwc_otg_pcd_check_vbus_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (pldata->phy_status == USB_PHY_ENABLED) {
|
||||
/* Release wake lock */
|
||||
dwc_otg_msc_unlock(_pcd);
|
||||
|
||||
if (iddig || (usb_mode == USB_MODE_FORCE_DEVICE)) {
|
||||
/* No vbus detect here , suspend usb phy */
|
||||
pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
|
||||
udelay(3);
|
||||
pldata->clock_enable(pldata, 0);
|
||||
}
|
||||
|
||||
/* Release wake lock */
|
||||
dwc_otg_msc_unlock(_pcd);
|
||||
}
|
||||
|
||||
/* Bypass usb phy to uart mode */
|
||||
|
||||
Reference in New Issue
Block a user