aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/chipidea/ci.h3
-rw-r--r--drivers/usb/chipidea/core.c32
-rw-r--r--drivers/usb/chipidea/otg.c34
3 files changed, 30 insertions, 39 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index cd414559040f..05bc4d631cb9 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -428,9 +428,6 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);
428 428
429u8 hw_port_test_get(struct ci_hdrc *ci); 429u8 hw_port_test_get(struct ci_hdrc *ci);
430 430
431int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
432 u32 value, unsigned int timeout_ms);
433
434void ci_platform_configure(struct ci_hdrc *ci); 431void ci_platform_configure(struct ci_hdrc *ci);
435 432
436int dbg_create_files(struct ci_hdrc *ci); 433int dbg_create_files(struct ci_hdrc *ci);
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 3dbb4a21ab44..6e0d614a8075 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -516,38 +516,6 @@ int hw_device_reset(struct ci_hdrc *ci)
516 return 0; 516 return 0;
517} 517}
518 518
519/**
520 * hw_wait_reg: wait the register value
521 *
522 * Sometimes, it needs to wait register value before going on.
523 * Eg, when switch to device mode, the vbus value should be lower
524 * than OTGSC_BSV before connects to host.
525 *
526 * @ci: the controller
527 * @reg: register index
528 * @mask: mast bit
529 * @value: the bit value to wait
530 * @timeout_ms: timeout in millisecond
531 *
532 * This function returns an error code if timeout
533 */
534int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
535 u32 value, unsigned int timeout_ms)
536{
537 unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
538
539 while (hw_read(ci, reg, mask) != value) {
540 if (time_after(jiffies, elapse)) {
541 dev_err(ci->dev, "timeout waiting for %08x in %d\n",
542 mask, reg);
543 return -ETIMEDOUT;
544 }
545 msleep(20);
546 }
547
548 return 0;
549}
550
551static irqreturn_t ci_irq(int irq, void *data) 519static irqreturn_t ci_irq(int irq, void *data)
552{ 520{
553 struct ci_hdrc *ci = data; 521 struct ci_hdrc *ci = data;
diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
index 03b6743461d1..a829607c3e4d 100644
--- a/drivers/usb/chipidea/otg.c
+++ b/drivers/usb/chipidea/otg.c
@@ -104,7 +104,31 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
104 usb_gadget_vbus_disconnect(&ci->gadget); 104 usb_gadget_vbus_disconnect(&ci->gadget);
105} 105}
106 106
107#define CI_VBUS_STABLE_TIMEOUT_MS 5000 107/**
108 * When we switch to device mode, the vbus value should be lower
109 * than OTGSC_BSV before connecting to host.
110 *
111 * @ci: the controller
112 *
113 * This function returns an error code if timeout
114 */
115static int hw_wait_vbus_lower_bsv(struct ci_hdrc *ci)
116{
117 unsigned long elapse = jiffies + msecs_to_jiffies(5000);
118 u32 mask = OTGSC_BSV;
119
120 while (hw_read_otgsc(ci, mask)) {
121 if (time_after(jiffies, elapse)) {
122 dev_err(ci->dev, "timeout waiting for %08x in OTGSC\n",
123 mask);
124 return -ETIMEDOUT;
125 }
126 msleep(20);
127 }
128
129 return 0;
130}
131
108static void ci_handle_id_switch(struct ci_hdrc *ci) 132static void ci_handle_id_switch(struct ci_hdrc *ci)
109{ 133{
110 enum ci_role role = ci_otg_role(ci); 134 enum ci_role role = ci_otg_role(ci);
@@ -116,9 +140,11 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
116 ci_role_stop(ci); 140 ci_role_stop(ci);
117 141
118 if (role == CI_ROLE_GADGET) 142 if (role == CI_ROLE_GADGET)
119 /* wait vbus lower than OTGSC_BSV */ 143 /*
120 hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0, 144 * wait vbus lower than OTGSC_BSV before connecting
121 CI_VBUS_STABLE_TIMEOUT_MS); 145 * to host
146 */
147 hw_wait_vbus_lower_bsv(ci);
122 148
123 ci_role_start(ci, role); 149 ci_role_start(ci, role);
124 } 150 }