aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi Jun <b47624@freescale.com>2015-02-10 23:45:02 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-18 11:19:12 -0400
commit6594591741883e004aaba105951337878698b054 (patch)
tree7ef13ec6ae9fe91f8436dc4dae66d4881f74433c
parent6adb9b7b5fb64be3c3e4d57578ea1446da91a8f9 (diff)
usb: chipidea: host: turn on vbus before add hcd if early vbus on is required
If CI_HDRC_TURN_VBUS_EARLY_ON is set, turn on vbus before adding hcd, so it will not set reg_vbus of ehci_ci_priv, then vbus will not be handled by ehci core. Signed-off-by: Li Jun <jun.li@freescale.com> Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/chipidea/host.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index feb9f0735227..21fe1a314313 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -44,11 +44,10 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
44 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 44 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
45 struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv; 45 struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
46 struct device *dev = hcd->self.controller; 46 struct device *dev = hcd->self.controller;
47 struct ci_hdrc *ci = dev_get_drvdata(dev);
48 int ret = 0; 47 int ret = 0;
49 int port = HCS_N_PORTS(ehci->hcs_params); 48 int port = HCS_N_PORTS(ehci->hcs_params);
50 49
51 if (priv->reg_vbus && !ci_otg_is_fsm_mode(ci)) { 50 if (priv->reg_vbus) {
52 if (port > 1) { 51 if (port > 1) {
53 dev_warn(dev, 52 dev_warn(dev,
54 "Not support multi-port regulator control\n"); 53 "Not support multi-port regulator control\n");
@@ -114,12 +113,23 @@ static int host_start(struct ci_hdrc *ci)
114 priv = (struct ehci_ci_priv *)ehci->priv; 113 priv = (struct ehci_ci_priv *)ehci->priv;
115 priv->reg_vbus = NULL; 114 priv->reg_vbus = NULL;
116 115
117 if (ci->platdata->reg_vbus) 116 if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
118 priv->reg_vbus = ci->platdata->reg_vbus; 117 if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
118 ret = regulator_enable(ci->platdata->reg_vbus);
119 if (ret) {
120 dev_err(ci->dev,
121 "Failed to enable vbus regulator, ret=%d\n",
122 ret);
123 goto put_hcd;
124 }
125 } else {
126 priv->reg_vbus = ci->platdata->reg_vbus;
127 }
128 }
119 129
120 ret = usb_add_hcd(hcd, 0, 0); 130 ret = usb_add_hcd(hcd, 0, 0);
121 if (ret) { 131 if (ret) {
122 goto put_hcd; 132 goto disable_reg;
123 } else { 133 } else {
124 struct usb_otg *otg = &ci->otg; 134 struct usb_otg *otg = &ci->otg;
125 135
@@ -139,6 +149,10 @@ static int host_start(struct ci_hdrc *ci)
139 149
140 return ret; 150 return ret;
141 151
152disable_reg:
153 if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
154 (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
155 regulator_disable(ci->platdata->reg_vbus);
142put_hcd: 156put_hcd:
143 usb_put_hcd(hcd); 157 usb_put_hcd(hcd);
144 158
@@ -152,6 +166,9 @@ static void host_stop(struct ci_hdrc *ci)
152 if (hcd) { 166 if (hcd) {
153 usb_remove_hcd(hcd); 167 usb_remove_hcd(hcd);
154 usb_put_hcd(hcd); 168 usb_put_hcd(hcd);
169 if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
170 (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
171 regulator_disable(ci->platdata->reg_vbus);
155 } 172 }
156} 173}
157 174