diff options
-rw-r--r-- | drivers/usb/chipidea/ci.h | 3 | ||||
-rw-r--r-- | drivers/usb/chipidea/core.c | 32 | ||||
-rw-r--r-- | drivers/usb/chipidea/otg.c | 34 |
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 | ||
429 | u8 hw_port_test_get(struct ci_hdrc *ci); | 429 | u8 hw_port_test_get(struct ci_hdrc *ci); |
430 | 430 | ||
431 | int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask, | ||
432 | u32 value, unsigned int timeout_ms); | ||
433 | |||
434 | void ci_platform_configure(struct ci_hdrc *ci); | 431 | void ci_platform_configure(struct ci_hdrc *ci); |
435 | 432 | ||
436 | int dbg_create_files(struct ci_hdrc *ci); | 433 | int 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 | */ | ||
534 | int 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 | |||
551 | static irqreturn_t ci_irq(int irq, void *data) | 519 | static 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 | */ | ||
115 | static 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 | |||
108 | static void ci_handle_id_switch(struct ci_hdrc *ci) | 132 | static 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 | } |