1
0
Fork 0

MLK-20343 usb: chipidea: udc: using structure ci_hdrc device for runtime PM

At current code, it doesn't maintain ci->gadget.dev's runtime PM
status well. Eg, after system resume, call pm_runtime_put_sync for
ci->dev will cause ci->dev's runtime suspend is called if its
power.usage is 0 even the power.usage is 1 for its child ci->gadget.dev.
at that time. It causes the oops this ticket describes that visiting
clock without AHB clock.

To fix this issue, we use ci_hdrc device instead of ci->gadget.dev
for runtime PM APIs at udc driver, in the way, we handle runtime
PM APIs for single device structure.

Reviewed-by: Jun Li <jun.li@nxp.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
5.4-rM2-2.2.x-imx-squashed
Peter Chen 2018-11-14 16:43:52 +08:00 committed by Dong Aisheng
parent a320ed8dd7
commit 55276da7e4
1 changed files with 5 additions and 8 deletions

View File

@ -1617,12 +1617,12 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
if (ci_otg_is_fsm_mode(ci) || ci->role == CI_ROLE_HOST)
return 0;
pm_runtime_get_sync(&ci->gadget.dev);
pm_runtime_get_sync(ci->dev);
if (is_on)
hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
else
hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
pm_runtime_put_sync(&ci->gadget.dev);
pm_runtime_put_sync(ci->dev);
return 0;
}
@ -1818,7 +1818,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
CI_HDRC_CONTROLLER_STOPPED_EVENT);
_gadget_stop_activity(&ci->gadget);
spin_lock_irqsave(&ci->lock, flags);
pm_runtime_put(&ci->gadget.dev);
pm_runtime_put(ci->dev);
}
ci->driver = NULL;
@ -1953,9 +1953,6 @@ static int udc_start(struct ci_hdrc *ci)
if (retval)
goto destroy_eps;
pm_runtime_no_callbacks(&ci->gadget.dev);
pm_runtime_enable(&ci->gadget.dev);
return retval;
destroy_eps:
@ -2012,7 +2009,7 @@ void ci_hdrc_gadget_connect(struct usb_gadget *gadget, int is_active)
struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget);
if (is_active) {
pm_runtime_get_sync(&gadget->dev);
pm_runtime_get_sync(ci->dev);
hw_device_reset(ci);
hw_device_state(ci, ci->ep0out->qh.dma);
usb_gadget_set_state(gadget, USB_STATE_POWERED);
@ -2026,7 +2023,7 @@ void ci_hdrc_gadget_connect(struct usb_gadget *gadget, int is_active)
ci->platdata->notify_event(ci,
CI_HDRC_CONTROLLER_STOPPED_EVENT);
_gadget_stop_activity(gadget);
pm_runtime_put_sync(&gadget->dev);
pm_runtime_put_sync(ci->dev);
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
}
}