xref: /OK3568_Linux_fs/kernel/drivers/usb/chipidea/host.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * host.c - ChipIdea USB host controller driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2012 Intel Corporation
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Alexander Shishkin
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/io.h>
12*4882a593Smuzhiyun #include <linux/usb.h>
13*4882a593Smuzhiyun #include <linux/usb/hcd.h>
14*4882a593Smuzhiyun #include <linux/usb/chipidea.h>
15*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
16*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "../host/ehci.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include "ci.h"
21*4882a593Smuzhiyun #include "bits.h"
22*4882a593Smuzhiyun #include "host.h"
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static struct hc_driver __read_mostly ci_ehci_hc_driver;
25*4882a593Smuzhiyun static int (*orig_bus_suspend)(struct usb_hcd *hcd);
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun struct ehci_ci_priv {
28*4882a593Smuzhiyun 	struct regulator *reg_vbus;
29*4882a593Smuzhiyun 	bool enabled;
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun 
ehci_ci_portpower(struct usb_hcd * hcd,int portnum,bool enable)32*4882a593Smuzhiyun static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
35*4882a593Smuzhiyun 	struct ehci_ci_priv *priv = (struct ehci_ci_priv *)ehci->priv;
36*4882a593Smuzhiyun 	struct device *dev = hcd->self.controller;
37*4882a593Smuzhiyun 	struct ci_hdrc *ci = dev_get_drvdata(dev);
38*4882a593Smuzhiyun 	int ret = 0;
39*4882a593Smuzhiyun 	int port = HCS_N_PORTS(ehci->hcs_params);
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	if (priv->reg_vbus && enable != priv->enabled) {
42*4882a593Smuzhiyun 		if (port > 1) {
43*4882a593Smuzhiyun 			dev_warn(dev,
44*4882a593Smuzhiyun 				"Not support multi-port regulator control\n");
45*4882a593Smuzhiyun 			return 0;
46*4882a593Smuzhiyun 		}
47*4882a593Smuzhiyun 		if (enable)
48*4882a593Smuzhiyun 			ret = regulator_enable(priv->reg_vbus);
49*4882a593Smuzhiyun 		else
50*4882a593Smuzhiyun 			ret = regulator_disable(priv->reg_vbus);
51*4882a593Smuzhiyun 		if (ret) {
52*4882a593Smuzhiyun 			dev_err(dev,
53*4882a593Smuzhiyun 				"Failed to %s vbus regulator, ret=%d\n",
54*4882a593Smuzhiyun 				enable ? "enable" : "disable", ret);
55*4882a593Smuzhiyun 			return ret;
56*4882a593Smuzhiyun 		}
57*4882a593Smuzhiyun 		priv->enabled = enable;
58*4882a593Smuzhiyun 	}
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {
61*4882a593Smuzhiyun 		/*
62*4882a593Smuzhiyun 		 * Marvell 28nm HSIC PHY requires forcing the port to HS mode.
63*4882a593Smuzhiyun 		 * As HSIC is always HS, this should be safe for others.
64*4882a593Smuzhiyun 		 */
65*4882a593Smuzhiyun 		hw_port_test_set(ci, 5);
66*4882a593Smuzhiyun 		hw_port_test_set(ci, 0);
67*4882a593Smuzhiyun 	}
68*4882a593Smuzhiyun 	return 0;
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
ehci_ci_reset(struct usb_hcd * hcd)71*4882a593Smuzhiyun static int ehci_ci_reset(struct usb_hcd *hcd)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct device *dev = hcd->self.controller;
74*4882a593Smuzhiyun 	struct ci_hdrc *ci = dev_get_drvdata(dev);
75*4882a593Smuzhiyun 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
76*4882a593Smuzhiyun 	int ret;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	ret = ehci_setup(hcd);
79*4882a593Smuzhiyun 	if (ret)
80*4882a593Smuzhiyun 		return ret;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	ehci->need_io_watchdog = 0;
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	if (ci->platdata->notify_event) {
85*4882a593Smuzhiyun 		ret = ci->platdata->notify_event(ci,
86*4882a593Smuzhiyun 				CI_HDRC_CONTROLLER_RESET_EVENT);
87*4882a593Smuzhiyun 		if (ret)
88*4882a593Smuzhiyun 			return ret;
89*4882a593Smuzhiyun 	}
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	ci_platform_configure(ci);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	return ret;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun static const struct ehci_driver_overrides ehci_ci_overrides = {
97*4882a593Smuzhiyun 	.extra_priv_size = sizeof(struct ehci_ci_priv),
98*4882a593Smuzhiyun 	.port_power	 = ehci_ci_portpower,
99*4882a593Smuzhiyun 	.reset		 = ehci_ci_reset,
100*4882a593Smuzhiyun };
101*4882a593Smuzhiyun 
host_irq(struct ci_hdrc * ci)102*4882a593Smuzhiyun static irqreturn_t host_irq(struct ci_hdrc *ci)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	return usb_hcd_irq(ci->irq, ci->hcd);
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
host_start(struct ci_hdrc * ci)107*4882a593Smuzhiyun static int host_start(struct ci_hdrc *ci)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	struct usb_hcd *hcd;
110*4882a593Smuzhiyun 	struct ehci_hcd *ehci;
111*4882a593Smuzhiyun 	struct ehci_ci_priv *priv;
112*4882a593Smuzhiyun 	int ret;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	if (usb_disabled())
115*4882a593Smuzhiyun 		return -ENODEV;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	hcd = __usb_create_hcd(&ci_ehci_hc_driver, ci->dev->parent,
118*4882a593Smuzhiyun 			       ci->dev, dev_name(ci->dev), NULL);
119*4882a593Smuzhiyun 	if (!hcd)
120*4882a593Smuzhiyun 		return -ENOMEM;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	dev_set_drvdata(ci->dev, ci);
123*4882a593Smuzhiyun 	hcd->rsrc_start = ci->hw_bank.phys;
124*4882a593Smuzhiyun 	hcd->rsrc_len = ci->hw_bank.size;
125*4882a593Smuzhiyun 	hcd->regs = ci->hw_bank.abs;
126*4882a593Smuzhiyun 	hcd->has_tt = 1;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	hcd->power_budget = ci->platdata->power_budget;
129*4882a593Smuzhiyun 	hcd->tpl_support = ci->platdata->tpl_support;
130*4882a593Smuzhiyun 	if (ci->phy || ci->usb_phy) {
131*4882a593Smuzhiyun 		hcd->skip_phy_initialization = 1;
132*4882a593Smuzhiyun 		if (ci->usb_phy)
133*4882a593Smuzhiyun 			hcd->usb_phy = ci->usb_phy;
134*4882a593Smuzhiyun 	}
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	ehci = hcd_to_ehci(hcd);
137*4882a593Smuzhiyun 	ehci->caps = ci->hw_bank.cap;
138*4882a593Smuzhiyun 	ehci->has_hostpc = ci->hw_bank.lpm;
139*4882a593Smuzhiyun 	ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
140*4882a593Smuzhiyun 	ehci->imx28_write_fix = ci->imx28_write_fix;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	priv = (struct ehci_ci_priv *)ehci->priv;
143*4882a593Smuzhiyun 	priv->reg_vbus = NULL;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci)) {
146*4882a593Smuzhiyun 		if (ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON) {
147*4882a593Smuzhiyun 			ret = regulator_enable(ci->platdata->reg_vbus);
148*4882a593Smuzhiyun 			if (ret) {
149*4882a593Smuzhiyun 				dev_err(ci->dev,
150*4882a593Smuzhiyun 				"Failed to enable vbus regulator, ret=%d\n",
151*4882a593Smuzhiyun 									ret);
152*4882a593Smuzhiyun 				goto put_hcd;
153*4882a593Smuzhiyun 			}
154*4882a593Smuzhiyun 		} else {
155*4882a593Smuzhiyun 			priv->reg_vbus = ci->platdata->reg_vbus;
156*4882a593Smuzhiyun 		}
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (ci->platdata->pins_host)
160*4882a593Smuzhiyun 		pinctrl_select_state(ci->platdata->pctl,
161*4882a593Smuzhiyun 				     ci->platdata->pins_host);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	ret = usb_add_hcd(hcd, 0, 0);
164*4882a593Smuzhiyun 	if (ret) {
165*4882a593Smuzhiyun 		goto disable_reg;
166*4882a593Smuzhiyun 	} else {
167*4882a593Smuzhiyun 		struct usb_otg *otg = &ci->otg;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 		ci->hcd = hcd;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 		if (ci_otg_is_fsm_mode(ci)) {
172*4882a593Smuzhiyun 			otg->host = &hcd->self;
173*4882a593Smuzhiyun 			hcd->self.otg_port = 1;
174*4882a593Smuzhiyun 		}
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 		if (ci->platdata->notify_event &&
177*4882a593Smuzhiyun 			(ci->platdata->flags & CI_HDRC_IMX_IS_HSIC))
178*4882a593Smuzhiyun 			ci->platdata->notify_event
179*4882a593Smuzhiyun 				(ci, CI_HDRC_IMX_HSIC_ACTIVE_EVENT);
180*4882a593Smuzhiyun 	}
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	return ret;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun disable_reg:
185*4882a593Smuzhiyun 	if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
186*4882a593Smuzhiyun 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
187*4882a593Smuzhiyun 		regulator_disable(ci->platdata->reg_vbus);
188*4882a593Smuzhiyun put_hcd:
189*4882a593Smuzhiyun 	usb_put_hcd(hcd);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	return ret;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
host_stop(struct ci_hdrc * ci)194*4882a593Smuzhiyun static void host_stop(struct ci_hdrc *ci)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun 	struct usb_hcd *hcd = ci->hcd;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	if (hcd) {
199*4882a593Smuzhiyun 		if (ci->platdata->notify_event)
200*4882a593Smuzhiyun 			ci->platdata->notify_event(ci,
201*4882a593Smuzhiyun 				CI_HDRC_CONTROLLER_STOPPED_EVENT);
202*4882a593Smuzhiyun 		usb_remove_hcd(hcd);
203*4882a593Smuzhiyun 		ci->role = CI_ROLE_END;
204*4882a593Smuzhiyun 		synchronize_irq(ci->irq);
205*4882a593Smuzhiyun 		usb_put_hcd(hcd);
206*4882a593Smuzhiyun 		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
207*4882a593Smuzhiyun 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
208*4882a593Smuzhiyun 				regulator_disable(ci->platdata->reg_vbus);
209*4882a593Smuzhiyun 	}
210*4882a593Smuzhiyun 	ci->hcd = NULL;
211*4882a593Smuzhiyun 	ci->otg.host = NULL;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	if (ci->platdata->pins_host && ci->platdata->pins_default)
214*4882a593Smuzhiyun 		pinctrl_select_state(ci->platdata->pctl,
215*4882a593Smuzhiyun 				     ci->platdata->pins_default);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 
ci_hdrc_host_destroy(struct ci_hdrc * ci)219*4882a593Smuzhiyun void ci_hdrc_host_destroy(struct ci_hdrc *ci)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun 	if (ci->role == CI_ROLE_HOST && ci->hcd)
222*4882a593Smuzhiyun 		host_stop(ci);
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun /* The below code is based on tegra ehci driver */
ci_ehci_hub_control(struct usb_hcd * hcd,u16 typeReq,u16 wValue,u16 wIndex,char * buf,u16 wLength)226*4882a593Smuzhiyun static int ci_ehci_hub_control(
227*4882a593Smuzhiyun 	struct usb_hcd	*hcd,
228*4882a593Smuzhiyun 	u16		typeReq,
229*4882a593Smuzhiyun 	u16		wValue,
230*4882a593Smuzhiyun 	u16		wIndex,
231*4882a593Smuzhiyun 	char		*buf,
232*4882a593Smuzhiyun 	u16		wLength
233*4882a593Smuzhiyun )
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
236*4882a593Smuzhiyun 	unsigned int	ports = HCS_N_PORTS(ehci->hcs_params);
237*4882a593Smuzhiyun 	u32 __iomem	*status_reg;
238*4882a593Smuzhiyun 	u32		temp, port_index;
239*4882a593Smuzhiyun 	unsigned long	flags;
240*4882a593Smuzhiyun 	int		retval = 0;
241*4882a593Smuzhiyun 	struct device *dev = hcd->self.controller;
242*4882a593Smuzhiyun 	struct ci_hdrc *ci = dev_get_drvdata(dev);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	port_index = wIndex & 0xff;
245*4882a593Smuzhiyun 	port_index -= (port_index > 0);
246*4882a593Smuzhiyun 	status_reg = &ehci->regs->port_status[port_index];
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	spin_lock_irqsave(&ehci->lock, flags);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
251*4882a593Smuzhiyun 		if (!wIndex || wIndex > ports) {
252*4882a593Smuzhiyun 			retval = -EPIPE;
253*4882a593Smuzhiyun 			goto done;
254*4882a593Smuzhiyun 		}
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 		temp = ehci_readl(ehci, status_reg);
257*4882a593Smuzhiyun 		if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
258*4882a593Smuzhiyun 			retval = -EPIPE;
259*4882a593Smuzhiyun 			goto done;
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 		temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
263*4882a593Smuzhiyun 		temp |= PORT_WKDISC_E | PORT_WKOC_E;
264*4882a593Smuzhiyun 		ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 		/*
267*4882a593Smuzhiyun 		 * If a transaction is in progress, there may be a delay in
268*4882a593Smuzhiyun 		 * suspending the port. Poll until the port is suspended.
269*4882a593Smuzhiyun 		 */
270*4882a593Smuzhiyun 		if (ehci_handshake(ehci, status_reg, PORT_SUSPEND,
271*4882a593Smuzhiyun 			PORT_SUSPEND, 5000))
272*4882a593Smuzhiyun 			ehci_err(ehci, "timeout waiting for SUSPEND\n");
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 		if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
275*4882a593Smuzhiyun 			if (ci->platdata->notify_event)
276*4882a593Smuzhiyun 				ci->platdata->notify_event(ci,
277*4882a593Smuzhiyun 					CI_HDRC_IMX_HSIC_SUSPEND_EVENT);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 			temp = ehci_readl(ehci, status_reg);
280*4882a593Smuzhiyun 			temp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
281*4882a593Smuzhiyun 			ehci_writel(ehci, temp, status_reg);
282*4882a593Smuzhiyun 		}
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 		set_bit(port_index, &ehci->suspended_ports);
285*4882a593Smuzhiyun 		goto done;
286*4882a593Smuzhiyun 	}
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/*
289*4882a593Smuzhiyun 	 * After resume has finished, it needs do some post resume
290*4882a593Smuzhiyun 	 * operation for some SoCs.
291*4882a593Smuzhiyun 	 */
292*4882a593Smuzhiyun 	else if (typeReq == ClearPortFeature &&
293*4882a593Smuzhiyun 		wValue == USB_PORT_FEAT_C_SUSPEND) {
294*4882a593Smuzhiyun 		/* Make sure the resume has finished, it should be finished */
295*4882a593Smuzhiyun 		if (ehci_handshake(ehci, status_reg, PORT_RESUME, 0, 25000))
296*4882a593Smuzhiyun 			ehci_err(ehci, "timeout waiting for resume\n");
297*4882a593Smuzhiyun 	}
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ehci->lock, flags);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	/* Handle the hub control events here */
302*4882a593Smuzhiyun 	return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
303*4882a593Smuzhiyun done:
304*4882a593Smuzhiyun 	spin_unlock_irqrestore(&ehci->lock, flags);
305*4882a593Smuzhiyun 	return retval;
306*4882a593Smuzhiyun }
ci_ehci_bus_suspend(struct usb_hcd * hcd)307*4882a593Smuzhiyun static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
310*4882a593Smuzhiyun 	struct device *dev = hcd->self.controller;
311*4882a593Smuzhiyun 	struct ci_hdrc *ci = dev_get_drvdata(dev);
312*4882a593Smuzhiyun 	int port;
313*4882a593Smuzhiyun 	u32 tmp;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	int ret = orig_bus_suspend(hcd);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	if (ret)
318*4882a593Smuzhiyun 		return ret;
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	port = HCS_N_PORTS(ehci->hcs_params);
321*4882a593Smuzhiyun 	while (port--) {
322*4882a593Smuzhiyun 		u32 __iomem *reg = &ehci->regs->port_status[port];
323*4882a593Smuzhiyun 		u32 portsc = ehci_readl(ehci, reg);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 		if (portsc & PORT_CONNECT) {
326*4882a593Smuzhiyun 			/*
327*4882a593Smuzhiyun 			 * For chipidea, the resume signal will be ended
328*4882a593Smuzhiyun 			 * automatically, so for remote wakeup case, the
329*4882a593Smuzhiyun 			 * usbcmd.rs may not be set before the resume has
330*4882a593Smuzhiyun 			 * ended if other resume paths consumes too much
331*4882a593Smuzhiyun 			 * time (~24ms), in that case, the SOF will not
332*4882a593Smuzhiyun 			 * send out within 3ms after resume ends, then the
333*4882a593Smuzhiyun 			 * high speed device will enter full speed mode.
334*4882a593Smuzhiyun 			 */
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 			tmp = ehci_readl(ehci, &ehci->regs->command);
337*4882a593Smuzhiyun 			tmp |= CMD_RUN;
338*4882a593Smuzhiyun 			ehci_writel(ehci, tmp, &ehci->regs->command);
339*4882a593Smuzhiyun 			/*
340*4882a593Smuzhiyun 			 * It needs a short delay between set RS bit and PHCD.
341*4882a593Smuzhiyun 			 */
342*4882a593Smuzhiyun 			usleep_range(150, 200);
343*4882a593Smuzhiyun 			/*
344*4882a593Smuzhiyun 			 * Need to clear WKCN and WKOC for imx HSIC,
345*4882a593Smuzhiyun 			 * otherwise, there will be wakeup event.
346*4882a593Smuzhiyun 			 */
347*4882a593Smuzhiyun 			if (ci->platdata->flags & CI_HDRC_IMX_IS_HSIC) {
348*4882a593Smuzhiyun 				tmp = ehci_readl(ehci, reg);
349*4882a593Smuzhiyun 				tmp &= ~(PORT_WKDISC_E | PORT_WKCONN_E);
350*4882a593Smuzhiyun 				ehci_writel(ehci, tmp, reg);
351*4882a593Smuzhiyun 			}
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 			break;
354*4882a593Smuzhiyun 		}
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	return 0;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun 
ci_hdrc_host_init(struct ci_hdrc * ci)360*4882a593Smuzhiyun int ci_hdrc_host_init(struct ci_hdrc *ci)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun 	struct ci_role_driver *rdrv;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_HC))
365*4882a593Smuzhiyun 		return -ENXIO;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL);
368*4882a593Smuzhiyun 	if (!rdrv)
369*4882a593Smuzhiyun 		return -ENOMEM;
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	rdrv->start	= host_start;
372*4882a593Smuzhiyun 	rdrv->stop	= host_stop;
373*4882a593Smuzhiyun 	rdrv->irq	= host_irq;
374*4882a593Smuzhiyun 	rdrv->name	= "host";
375*4882a593Smuzhiyun 	ci->roles[CI_ROLE_HOST] = rdrv;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	return 0;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun 
ci_hdrc_host_driver_init(void)380*4882a593Smuzhiyun void ci_hdrc_host_driver_init(void)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun 	ehci_init_driver(&ci_ehci_hc_driver, &ehci_ci_overrides);
383*4882a593Smuzhiyun 	orig_bus_suspend = ci_ehci_hc_driver.bus_suspend;
384*4882a593Smuzhiyun 	ci_ehci_hc_driver.bus_suspend = ci_ehci_bus_suspend;
385*4882a593Smuzhiyun 	ci_ehci_hc_driver.hub_control = ci_ehci_hub_control;
386*4882a593Smuzhiyun }
387