|
@@ -294,6 +294,38 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * hw_wait_reg: wait the register value
|
|
|
+ *
|
|
|
+ * Sometimes, it needs to wait register value before going on.
|
|
|
+ * Eg, when switch to device mode, the vbus value should be lower
|
|
|
+ * than OTGSC_BSV before connects to host.
|
|
|
+ *
|
|
|
+ * @ci: the controller
|
|
|
+ * @reg: register index
|
|
|
+ * @mask: mast bit
|
|
|
+ * @value: the bit value to wait
|
|
|
+ * @timeout_ms: timeout in millisecond
|
|
|
+ *
|
|
|
+ * This function returns an error code if timeout
|
|
|
+ */
|
|
|
+int hw_wait_reg(struct ci_hdrc *ci, enum ci_hw_regs reg, u32 mask,
|
|
|
+ u32 value, unsigned int timeout_ms)
|
|
|
+{
|
|
|
+ unsigned long elapse = jiffies + msecs_to_jiffies(timeout_ms);
|
|
|
+
|
|
|
+ while (hw_read(ci, reg, mask) != value) {
|
|
|
+ if (time_after(jiffies, elapse)) {
|
|
|
+ dev_err(ci->dev, "timeout waiting for %08x in %d\n",
|
|
|
+ mask, reg);
|
|
|
+ return -ETIMEDOUT;
|
|
|
+ }
|
|
|
+ msleep(20);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static irqreturn_t ci_irq(int irq, void *data)
|
|
|
{
|
|
|
struct ci_hdrc *ci = data;
|