X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fusb%2Fgadget%2Fcomposite.c;h=c2684b5adc02c074a4554929ea973c29b52b5c88;hb=28acc1a88c75b08b2ab502a546da61b131b86f5c;hp=bf555327937f29f7d7eb4814a46291a358318f44;hpb=4a4414416d5d6f9a6522aa6900473e3cdc5f1393;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index bf555327937f..c2684b5adc02 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -107,6 +107,27 @@ void usb_function_set_enabled(struct usb_function *f, int enabled) kobject_uevent(&f->dev->kobj, KOBJ_CHANGE); } + +void usb_composite_force_reset(struct usb_composite_dev *cdev) +{ + unsigned long flags; + + spin_lock_irqsave(&cdev->lock, flags); + /* force reenumeration */ + if (cdev && cdev->gadget && + cdev->gadget->speed != USB_SPEED_UNKNOWN) { + /* avoid sending a disconnect switch event until after we disconnect */ + cdev->mute_switch = 1; + spin_unlock_irqrestore(&cdev->lock, flags); + + usb_gadget_disconnect(cdev->gadget); + msleep(10); + usb_gadget_connect(cdev->gadget); + } else { + spin_unlock_irqrestore(&cdev->lock, flags); + } +} + /** * usb_add_function() - add a function to a configuration * @config: the configuration @@ -1114,11 +1135,15 @@ static void composite_disconnect(struct usb_gadget *gadget) spin_lock_irqsave(&cdev->lock, flags); if (cdev->config) reset_config(cdev); + if (composite->disconnect) composite->disconnect(cdev); - spin_unlock_irqrestore(&cdev->lock, flags); - schedule_work(&cdev->switch_work); + if (cdev->mute_switch) + cdev->mute_switch = 0; + else + schedule_work(&cdev->switch_work); + spin_unlock_irqrestore(&cdev->lock, flags); } /*-------------------------------------------------------------------------*/