aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r--drivers/usb/chipidea/ci.h3
-rw-r--r--drivers/usb/chipidea/core.c19
-rw-r--r--drivers/usb/chipidea/host.c7
-rw-r--r--drivers/usb/chipidea/udc.c6
4 files changed, 27 insertions, 8 deletions
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index 005c67cb3afb..73fddb69459b 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -471,4 +471,7 @@ void ci_platform_configure(struct ci_hdrc *ci);
void dbg_create_files(struct ci_hdrc *ci);
void dbg_remove_files(struct ci_hdrc *ci);
+
+void ci_platform_set_pin_state(struct ci_hdrc *ci, struct pinctrl_state *pins);
+
#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 484b1cd23431..3fce9fd14427 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -185,6 +185,22 @@ u8 hw_port_test_get(struct ci_hdrc *ci)
return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
}
+/**
+ * ci_platform_set_pin_state: set target pinctrl state with optional delay
+ *
+ * @ci: the controller
+ * @pins: the target pin-state
+ *
+ * This function returns nothing
+ */
+void ci_platform_set_pin_state(struct ci_hdrc *ci, struct pinctrl_state *pins)
+{
+ pinctrl_select_state(ci->platdata->pctl, pins);
+ if (ci->platdata->pin_switch_delay_us)
+ usleep_range(ci->platdata->pin_switch_delay_us,
+ ci->platdata->pin_switch_delay_us + 50);
+}
+
static void hw_wait_phy_stable(void)
{
/*
@@ -816,6 +832,9 @@ static int ci_get_platdata(struct device *dev,
if (!platdata->enter_lpm)
platdata->enter_lpm = ci_hdrc_enter_lpm_common;
+ of_property_read_u32(dev->of_node, "pin-switch-delay-us",
+ &platdata->pin_switch_delay_us);
+
return 0;
}
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index ebe7400243b1..7740c0e93317 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -170,8 +170,7 @@ static int host_start(struct ci_hdrc *ci)
}
if (ci->platdata->pins_host)
- pinctrl_select_state(ci->platdata->pctl,
- ci->platdata->pins_host);
+ ci_platform_set_pin_state(ci, ci->platdata->pins_host);
ci->hcd = hcd;
@@ -225,8 +224,8 @@ static void host_stop(struct ci_hdrc *ci)
ci->otg.host = NULL;
if (ci->platdata->pins_host && ci->platdata->pins_default)
- pinctrl_select_state(ci->platdata->pctl,
- ci->platdata->pins_default);
+ ci_platform_set_pin_state(ci, ci->platdata->pins_default);
+
}
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 54c09245ad05..fdf4661fd039 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -2154,8 +2154,7 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
static int udc_id_switch_for_device(struct ci_hdrc *ci)
{
if (ci->platdata->pins_device)
- pinctrl_select_state(ci->platdata->pctl,
- ci->platdata->pins_device);
+ ci_platform_set_pin_state(ci, ci->platdata->pins_device);
if (ci->is_otg)
/* Clear and enable BSV irq */
@@ -2177,8 +2176,7 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)
ci->vbus_active = 0;
if (ci->platdata->pins_device && ci->platdata->pins_default)
- pinctrl_select_state(ci->platdata->pctl,
- ci->platdata->pins_default);
+ ci_platform_set_pin_state(ci, ci->platdata->pins_default);
}
#ifdef CONFIG_PM_SLEEP