Commit 628ef0d2 authored by Peter Chen's avatar Peter Chen Committed by Felipe Balbi

usb: udc: add usb_udc_vbus_handler

This commit updates udc core vbus status, and try to connect
or disconnect gadget.
Signed-off-by: default avatarPeter Chen <peter.chen@freescale.com>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent dfea9c94
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
* @dev - the child device to the actual controller * @dev - the child device to the actual controller
* @gadget - the gadget. For use by the class code * @gadget - the gadget. For use by the class code
* @list - for use by the udc class driver * @list - for use by the udc class driver
* @vbus - for udcs who care about vbus status, this value is real vbus status;
* for udcs who do not care about vbus status, this value is always true
* *
* This represents the internal data structure which is used by the UDC-class * This represents the internal data structure which is used by the UDC-class
* to hold information about udc driver and gadget together. * to hold information about udc driver and gadget together.
...@@ -44,6 +46,7 @@ struct usb_udc { ...@@ -44,6 +46,7 @@ struct usb_udc {
struct usb_gadget *gadget; struct usb_gadget *gadget;
struct device dev; struct device dev;
struct list_head list; struct list_head list;
bool vbus;
}; };
static struct class *udc_class; static struct class *udc_class;
...@@ -145,6 +148,34 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state); ...@@ -145,6 +148,34 @@ EXPORT_SYMBOL_GPL(usb_gadget_set_state);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static void usb_udc_connect_control(struct usb_udc *udc)
{
if (udc->vbus)
usb_gadget_connect(udc->gadget);
else
usb_gadget_disconnect(udc->gadget);
}
/**
* usb_udc_vbus_handler - updates the udc core vbus status, and try to
* connect or disconnect gadget
* @gadget: The gadget which vbus change occurs
* @status: The vbus status
*
* The udc driver calls it when it wants to connect or disconnect gadget
* according to vbus status.
*/
void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status)
{
struct usb_udc *udc = gadget->udc;
if (udc) {
udc->vbus = status;
usb_udc_connect_control(udc);
}
}
EXPORT_SYMBOL_GPL(usb_udc_vbus_handler);
/** /**
* usb_gadget_udc_reset - notifies the udc core that bus reset occurs * usb_gadget_udc_reset - notifies the udc core that bus reset occurs
* @gadget: The gadget which bus reset occurs * @gadget: The gadget which bus reset occurs
...@@ -278,6 +309,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, ...@@ -278,6 +309,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
goto err4; goto err4;
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED); usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
mutex_unlock(&udc_lock); mutex_unlock(&udc_lock);
...@@ -381,7 +413,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri ...@@ -381,7 +413,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
driver->unbind(udc->gadget); driver->unbind(udc->gadget);
goto err1; goto err1;
} }
usb_gadget_connect(udc->gadget); usb_udc_connect_control(udc);
kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
return 0; return 0;
......
...@@ -1032,6 +1032,10 @@ extern void usb_gadget_udc_reset(struct usb_gadget *gadget, ...@@ -1032,6 +1032,10 @@ extern void usb_gadget_udc_reset(struct usb_gadget *gadget,
extern void usb_gadget_giveback_request(struct usb_ep *ep, extern void usb_gadget_giveback_request(struct usb_ep *ep,
struct usb_request *req); struct usb_request *req);
/*-------------------------------------------------------------------------*/
/* utility to update vbus status for udc core, it may be scheduled */
extern void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment