*
* @work: work queue item structure
*
+ * Handles below events:
+ * - Role switch for dual-role devices
+ * - CDNS3_ROLE_GADGET <--> CDNS3_ROLE_END for peripheral-only devices
*/
static void cdns3_role_switch(struct work_struct *work)
{
host = extcon_get_state(cdns->extcon, EXTCON_USB_HOST);
device = extcon_get_state(cdns->extcon, EXTCON_USB);
- if (host)
- cdns3_do_role_switch(cdns, CDNS3_ROLE_HOST);
- else if (device)
+ if (host) {
+ if (cdns->roles[CDNS3_ROLE_HOST])
+ cdns3_do_role_switch(cdns, CDNS3_ROLE_HOST);
+ return;
+ }
+
+ if (device)
cdns3_do_role_switch(cdns, CDNS3_ROLE_GADGET);
else
cdns3_do_role_switch(cdns, CDNS3_ROLE_END);
if (ret)
goto err1;
- INIT_WORK(&cdns->role_switch_wq, cdns3_role_switch);
- ret = cdns3_register_extcon(cdns);
- if (ret)
- goto err2;
-
ret = cdns3_core_init_role(cdns);
if (ret)
goto err2;
+ if (cdns->roles[CDNS3_ROLE_GADGET]) {
+ INIT_WORK(&cdns->role_switch_wq, cdns3_role_switch);
+ ret = cdns3_register_extcon(cdns);
+ if (ret)
+ goto err3;
+ }
+
cdns->role = cdns3_get_role(cdns);
dev_dbg(dev, "the init role is %d\n", cdns->role);
cdns_set_role(cdns, cdns->role);