X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fusb%2Fchipidea%2Fudc.c;fp=kernel%2Fdrivers%2Fusb%2Fchipidea%2Fudc.c;h=d8a045fc1fdba82e92f7f43410ffd3935f6acc9b;hb=52f993b8e89487ec9ee15a7fb4979e0f09a45b27;hp=391a1225b0ba330cd818028f240cb151e8ade65c;hpb=c189ccac5702322ed843fe17057035b7222a59b6;p=kvmfornfv.git diff --git a/kernel/drivers/usb/chipidea/udc.c b/kernel/drivers/usb/chipidea/udc.c index 391a1225b..d8a045fc1 100644 --- a/kernel/drivers/usb/chipidea/udc.c +++ b/kernel/drivers/usb/chipidea/udc.c @@ -939,6 +939,15 @@ static int isr_setup_status_phase(struct ci_hdrc *ci) int retval; struct ci_hw_ep *hwep; + /* + * Unexpected USB controller behavior, caused by bad signal integrity + * or ground reference problems, can lead to isr_setup_status_phase + * being called with ci->status equal to NULL. + * If this situation occurs, you should review your USB hardware design. + */ + if (WARN_ON_ONCE(!ci->status)) + return -EPIPE; + hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in; ci->status->context = ci; ci->status->complete = isr_setup_status_complete; @@ -1585,8 +1594,11 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); - /* Data+ pullup controlled by OTG state machine in OTG fsm mode */ - if (ci_otg_is_fsm_mode(ci)) + /* + * Data+ pullup controlled by OTG state machine in OTG fsm mode; + * and don't touch Data+ in host mode for dual role config. + */ + if (ci_otg_is_fsm_mode(ci) || ci->role == CI_ROLE_HOST) return 0; pm_runtime_get_sync(&ci->gadget.dev); @@ -1872,8 +1884,6 @@ static int udc_start(struct ci_hdrc *ci) struct usb_otg_caps *otg_caps = &ci->platdata->ci_otg_caps; int retval = 0; - spin_lock_init(&ci->lock); - ci->gadget.ops = &usb_gadget_ops; ci->gadget.speed = USB_SPEED_UNKNOWN; ci->gadget.max_speed = USB_SPEED_HIGH;