xref: /linux/drivers/usb/chipidea/ci_hdrc_imx.c (revision 22c55fb9eb92395d999b8404d73e58540d11bdd8)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2012 Freescale Semiconductor, Inc.
4  * Copyright 2025 NXP
5  * Copyright (C) 2012 Marek Vasut <marex@denx.de>
6  * on behalf of DENX Software Engineering GmbH
7  */
8 
9 #include <linux/module.h>
10 #include <linux/irq.h>
11 #include <linux/of.h>
12 #include <linux/of_platform.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/usb/chipidea.h>
16 #include <linux/usb/of.h>
17 #include <linux/clk.h>
18 #include <linux/pinctrl/consumer.h>
19 #include <linux/pm_qos.h>
20 
21 #include "ci.h"
22 #include "ci_hdrc_imx.h"
23 
24 struct ci_hdrc_imx_platform_flag {
25 	unsigned int flags;
26 };
27 
28 static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
29 	.flags = CI_HDRC_TURN_VBUS_EARLY_ON |
30 		CI_HDRC_DISABLE_STREAMING,
31 };
32 
33 static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
34 	.flags = CI_HDRC_DISABLE_STREAMING,
35 };
36 
37 static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
38 	.flags = CI_HDRC_IMX28_WRITE_FIX |
39 		CI_HDRC_TURN_VBUS_EARLY_ON |
40 		CI_HDRC_DISABLE_STREAMING,
41 };
42 
43 static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
44 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
45 		CI_HDRC_TURN_VBUS_EARLY_ON |
46 		CI_HDRC_DISABLE_STREAMING,
47 };
48 
49 static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
50 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
51 		CI_HDRC_TURN_VBUS_EARLY_ON |
52 		CI_HDRC_DISABLE_HOST_STREAMING,
53 };
54 
55 static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
56 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
57 		CI_HDRC_TURN_VBUS_EARLY_ON |
58 		CI_HDRC_DISABLE_HOST_STREAMING,
59 };
60 
61 static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
62 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
63 		CI_HDRC_TURN_VBUS_EARLY_ON |
64 		CI_HDRC_DISABLE_DEVICE_STREAMING,
65 };
66 
67 static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
68 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
69 };
70 
71 static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
72 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
73 		CI_HDRC_HAS_PORTSC_PEC_MISSED |
74 		CI_HDRC_PMQOS,
75 };
76 
77 static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = {
78 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
79 		CI_HDRC_HAS_PORTSC_PEC_MISSED,
80 };
81 
82 static const struct ci_hdrc_imx_platform_flag s32g_usb_data = {
83 	.flags = CI_HDRC_DISABLE_HOST_STREAMING,
84 };
85 
86 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
87 	{ .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
88 	{ .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
89 	{ .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
90 	{ .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
91 	{ .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
92 	{ .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
93 	{ .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
94 	{ .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
95 	{ .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
96 	{ .compatible = "fsl,imx8ulp-usb", .data = &imx8ulp_usb_data},
97 	{ .compatible = "nxp,s32g2-usb", .data = &s32g_usb_data},
98 	{ /* sentinel */ }
99 };
100 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
101 
102 struct ci_hdrc_imx_data {
103 	struct usb_phy *phy;
104 	struct platform_device *ci_pdev;
105 	struct clk *clk;
106 	struct clk *clk_wakeup;
107 	struct imx_usbmisc_data *usbmisc_data;
108 	int wakeup_irq;
109 	bool supports_runtime_pm;
110 	bool override_phy_control;
111 	bool in_lpm;
112 	struct pinctrl *pinctrl;
113 	struct pinctrl_state *pinctrl_hsic_active;
114 	struct regulator *hsic_pad_regulator;
115 	/* SoC before i.mx6 (except imx23/imx28) needs three clks */
116 	bool need_three_clks;
117 	struct clk *clk_ipg;
118 	struct clk *clk_ahb;
119 	struct clk *clk_per;
120 	/* --------------------------------- */
121 	struct pm_qos_request pm_qos_req;
122 	const struct ci_hdrc_imx_platform_flag *plat_data;
123 };
124 
125 /* Common functions shared by usbmisc drivers */
126 
127 static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
128 {
129 	struct platform_device *misc_pdev;
130 	struct device_node *np = dev->of_node;
131 	struct of_phandle_args args;
132 	struct imx_usbmisc_data *data;
133 	int ret;
134 
135 	/*
136 	 * In case the fsl,usbmisc property is not present this device doesn't
137 	 * need usbmisc. Return NULL (which is no error here)
138 	 */
139 	if (!of_property_present(np, "fsl,usbmisc"))
140 		return NULL;
141 
142 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
143 	if (!data)
144 		return ERR_PTR(-ENOMEM);
145 
146 	ret = of_parse_phandle_with_args(np, "fsl,usbmisc", "#index-cells",
147 					0, &args);
148 	if (ret) {
149 		dev_err(dev, "Failed to parse property fsl,usbmisc, errno %d\n",
150 			ret);
151 		return ERR_PTR(ret);
152 	}
153 
154 	data->index = args.args[0];
155 
156 	misc_pdev = of_find_device_by_node(args.np);
157 	of_node_put(args.np);
158 
159 	if (!misc_pdev)
160 		return ERR_PTR(-EPROBE_DEFER);
161 
162 	if (!platform_get_drvdata(misc_pdev)) {
163 		put_device(&misc_pdev->dev);
164 		return ERR_PTR(-EPROBE_DEFER);
165 	}
166 	data->dev = &misc_pdev->dev;
167 
168 	/*
169 	 * Check the various over current related properties. If over current
170 	 * detection is disabled we're not interested in the polarity.
171 	 */
172 	if (of_property_read_bool(np, "disable-over-current")) {
173 		data->disable_oc = 1;
174 	} else if (of_property_read_bool(np, "over-current-active-high")) {
175 		data->oc_pol_active_low = 0;
176 		data->oc_pol_configured = 1;
177 	} else if (of_property_read_bool(np, "over-current-active-low")) {
178 		data->oc_pol_active_low = 1;
179 		data->oc_pol_configured = 1;
180 	} else {
181 		dev_warn(dev, "No over current polarity defined\n");
182 	}
183 
184 	data->pwr_pol = of_property_read_bool(np, "power-active-high");
185 	data->evdo = of_property_read_bool(np, "external-vbus-divider");
186 
187 	if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
188 		data->ulpi = 1;
189 
190 	if (of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control",
191 			&data->emp_curr_control))
192 		data->emp_curr_control = -1;
193 	if (of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust",
194 			&data->dc_vol_level_adjust))
195 		data->dc_vol_level_adjust = -1;
196 	if (of_property_read_u32(np, "fsl,picophy-rise-fall-time-adjust",
197 			&data->rise_fall_time_adjust))
198 		data->rise_fall_time_adjust = -1;
199 
200 	return data;
201 }
202 
203 /* End of common functions shared by usbmisc drivers*/
204 static int imx_get_clks(struct device *dev)
205 {
206 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
207 	int ret = 0;
208 
209 	data->clk_ipg = devm_clk_get(dev, "ipg");
210 	if (IS_ERR(data->clk_ipg)) {
211 		/* If the platform only needs one primary clock */
212 		data->clk = devm_clk_get(dev, NULL);
213 		if (IS_ERR(data->clk)) {
214 			ret = PTR_ERR(data->clk);
215 			dev_err(dev,
216 				"Failed to get clks, err=%ld,%ld\n",
217 				PTR_ERR(data->clk), PTR_ERR(data->clk_ipg));
218 			return ret;
219 		}
220 		/* Get wakeup clock. Not all of the platforms need to
221 		 * handle this clock. So make it optional.
222 		 */
223 		data->clk_wakeup = devm_clk_get_optional(dev, "usb_wakeup");
224 		if (IS_ERR(data->clk_wakeup))
225 			ret = dev_err_probe(dev, PTR_ERR(data->clk_wakeup),
226 					"Failed to get wakeup clk\n");
227 		return ret;
228 	}
229 
230 	data->clk_ahb = devm_clk_get(dev, "ahb");
231 	if (IS_ERR(data->clk_ahb)) {
232 		ret = PTR_ERR(data->clk_ahb);
233 		dev_err(dev,
234 			"Failed to get ahb clock, err=%d\n", ret);
235 		return ret;
236 	}
237 
238 	data->clk_per = devm_clk_get(dev, "per");
239 	if (IS_ERR(data->clk_per)) {
240 		ret = PTR_ERR(data->clk_per);
241 		dev_err(dev,
242 			"Failed to get per clock, err=%d\n", ret);
243 		return ret;
244 	}
245 
246 	data->need_three_clks = true;
247 	return ret;
248 }
249 
250 static int imx_prepare_enable_clks(struct device *dev)
251 {
252 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
253 	int ret = 0;
254 
255 	if (data->need_three_clks) {
256 		ret = clk_prepare_enable(data->clk_ipg);
257 		if (ret) {
258 			dev_err(dev,
259 				"Failed to prepare/enable ipg clk, err=%d\n",
260 				ret);
261 			return ret;
262 		}
263 
264 		ret = clk_prepare_enable(data->clk_ahb);
265 		if (ret) {
266 			dev_err(dev,
267 				"Failed to prepare/enable ahb clk, err=%d\n",
268 				ret);
269 			clk_disable_unprepare(data->clk_ipg);
270 			return ret;
271 		}
272 
273 		ret = clk_prepare_enable(data->clk_per);
274 		if (ret) {
275 			dev_err(dev,
276 				"Failed to prepare/enable per clk, err=%d\n",
277 				ret);
278 			clk_disable_unprepare(data->clk_ahb);
279 			clk_disable_unprepare(data->clk_ipg);
280 			return ret;
281 		}
282 	} else {
283 		ret = clk_prepare_enable(data->clk);
284 		if (ret) {
285 			dev_err(dev,
286 				"Failed to prepare/enable clk, err=%d\n",
287 				ret);
288 			return ret;
289 		}
290 	}
291 
292 	return ret;
293 }
294 
295 static void imx_disable_unprepare_clks(struct device *dev)
296 {
297 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
298 
299 	if (data->need_three_clks) {
300 		clk_disable_unprepare(data->clk_per);
301 		clk_disable_unprepare(data->clk_ahb);
302 		clk_disable_unprepare(data->clk_ipg);
303 	} else {
304 		clk_disable_unprepare(data->clk);
305 	}
306 }
307 
308 static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
309 {
310 	struct device *dev = ci->dev->parent;
311 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
312 	int ret = 0;
313 	struct imx_usbmisc_data *mdata = data->usbmisc_data;
314 
315 	switch (event) {
316 	case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
317 		if (data->pinctrl) {
318 			ret = pinctrl_select_state(data->pinctrl,
319 					data->pinctrl_hsic_active);
320 			if (ret)
321 				dev_err(dev,
322 					"hsic_active select failed, err=%d\n",
323 					ret);
324 		}
325 		break;
326 	case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
327 		ret = imx_usbmisc_hsic_set_connect(mdata);
328 		if (ret)
329 			dev_err(dev,
330 				"hsic_set_connect failed, err=%d\n", ret);
331 		break;
332 	case CI_HDRC_CONTROLLER_VBUS_EVENT:
333 		if (ci->vbus_active)
334 			ret = imx_usbmisc_charger_detection(mdata, true);
335 		else
336 			ret = imx_usbmisc_charger_detection(mdata, false);
337 		if (ci->usb_phy)
338 			schedule_work(&ci->usb_phy->chg_work);
339 		break;
340 	case CI_HDRC_CONTROLLER_PULLUP_EVENT:
341 		if (ci->role == CI_ROLE_GADGET)
342 			imx_usbmisc_pullup(data->usbmisc_data,
343 					   ci->gadget.connected);
344 		break;
345 	default:
346 		break;
347 	}
348 
349 	return ret;
350 }
351 
352 static irqreturn_t ci_wakeup_irq_handler(int irq, void *data)
353 {
354 	struct ci_hdrc_imx_data *imx_data = data;
355 
356 	disable_irq_nosync(irq);
357 	pm_runtime_resume(&imx_data->ci_pdev->dev);
358 
359 	return IRQ_HANDLED;
360 }
361 
362 static void ci_hdrc_imx_disable_regulator(void *arg)
363 {
364 	struct ci_hdrc_imx_data *data = arg;
365 
366 	regulator_disable(data->hsic_pad_regulator);
367 }
368 
369 static int ci_hdrc_imx_probe(struct platform_device *pdev)
370 {
371 	struct ci_hdrc_imx_data *data;
372 	struct ci_hdrc_platform_data pdata = {
373 		.name		= dev_name(&pdev->dev),
374 		.capoffset	= DEF_CAPOFFSET,
375 		.flags		= CI_HDRC_HAS_SHORT_PKT_LIMIT,
376 		.notify_event	= ci_hdrc_imx_notify_event,
377 	};
378 	int ret;
379 	const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
380 	struct device_node *np = pdev->dev.of_node;
381 	struct device *dev = &pdev->dev;
382 
383 	imx_platform_flag = of_device_get_match_data(&pdev->dev);
384 
385 	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
386 	if (!data)
387 		return -ENOMEM;
388 
389 	data->plat_data = imx_platform_flag;
390 	pdata.flags |= imx_platform_flag->flags;
391 	platform_set_drvdata(pdev, data);
392 	data->usbmisc_data = usbmisc_get_init_data(dev);
393 	if (IS_ERR(data->usbmisc_data))
394 		return PTR_ERR(data->usbmisc_data);
395 
396 	if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
397 		&& data->usbmisc_data) {
398 		pdata.flags |= CI_HDRC_IMX_IS_HSIC;
399 		data->usbmisc_data->hsic = 1;
400 		data->pinctrl = devm_pinctrl_get(dev);
401 		if (PTR_ERR(data->pinctrl) == -ENODEV)
402 			data->pinctrl = NULL;
403 		else if (IS_ERR(data->pinctrl)) {
404 			ret = dev_err_probe(dev, PTR_ERR(data->pinctrl),
405 					     "pinctrl get failed\n");
406 			goto err_put;
407 		}
408 
409 		data->hsic_pad_regulator =
410 				devm_regulator_get_optional(dev, "hsic");
411 		if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
412 			/* no pad regulator is needed */
413 			data->hsic_pad_regulator = NULL;
414 		} else if (IS_ERR(data->hsic_pad_regulator)) {
415 			ret = dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator),
416 					     "Get HSIC pad regulator error\n");
417 			goto err_put;
418 		}
419 
420 		if (data->hsic_pad_regulator) {
421 			ret = regulator_enable(data->hsic_pad_regulator);
422 			if (ret) {
423 				dev_err(dev,
424 					"Failed to enable HSIC pad regulator\n");
425 				goto err_put;
426 			}
427 			ret = devm_add_action_or_reset(dev,
428 					ci_hdrc_imx_disable_regulator, data);
429 			if (ret) {
430 				dev_err(dev,
431 					"Failed to add regulator devm action\n");
432 				goto err_put;
433 			}
434 		}
435 	}
436 
437 	/* HSIC pinctrl handling */
438 	if (data->pinctrl) {
439 		struct pinctrl_state *pinctrl_hsic_idle;
440 
441 		pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
442 		if (IS_ERR(pinctrl_hsic_idle)) {
443 			dev_err(dev,
444 				"pinctrl_hsic_idle lookup failed, err=%ld\n",
445 					PTR_ERR(pinctrl_hsic_idle));
446 			ret = PTR_ERR(pinctrl_hsic_idle);
447 			goto err_put;
448 		}
449 
450 		ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
451 		if (ret) {
452 			dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
453 			goto err_put;
454 		}
455 
456 		data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
457 								"active");
458 		if (IS_ERR(data->pinctrl_hsic_active)) {
459 			dev_err(dev,
460 				"pinctrl_hsic_active lookup failed, err=%ld\n",
461 					PTR_ERR(data->pinctrl_hsic_active));
462 			ret = PTR_ERR(data->pinctrl_hsic_active);
463 			goto err_put;
464 		}
465 	}
466 
467 	if (pdata.flags & CI_HDRC_PMQOS)
468 		cpu_latency_qos_add_request(&data->pm_qos_req, 0);
469 
470 	ret = imx_get_clks(dev);
471 	if (ret)
472 		goto qos_remove_request;
473 
474 	ret = imx_prepare_enable_clks(dev);
475 	if (ret)
476 		goto qos_remove_request;
477 
478 	ret = clk_prepare_enable(data->clk_wakeup);
479 	if (ret)
480 		goto err_wakeup_clk;
481 
482 	data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
483 	if (IS_ERR(data->phy)) {
484 		ret = PTR_ERR(data->phy);
485 		if (ret != -ENODEV) {
486 			dev_err_probe(dev, ret, "Failed to parse fsl,usbphy\n");
487 			goto err_clk;
488 		}
489 		data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
490 		if (IS_ERR(data->phy)) {
491 			ret = PTR_ERR(data->phy);
492 			if (ret == -ENODEV) {
493 				data->phy = NULL;
494 			} else {
495 				dev_err_probe(dev, ret, "Failed to parse phys\n");
496 				goto err_clk;
497 			}
498 		}
499 	}
500 
501 	pdata.usb_phy = data->phy;
502 	if (data->usbmisc_data)
503 		data->usbmisc_data->usb_phy = data->phy;
504 
505 	if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
506 	     of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
507 	    of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
508 		pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
509 		data->override_phy_control = true;
510 		ret = usb_phy_init(pdata.usb_phy);
511 		if (ret) {
512 			dev_err(dev, "Failed to init phy\n");
513 			goto err_clk;
514 		}
515 	}
516 
517 	if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
518 		data->supports_runtime_pm = true;
519 
520 	data->wakeup_irq = platform_get_irq_optional(pdev, 1);
521 	if (data->wakeup_irq > 0) {
522 		ret = devm_request_threaded_irq(dev, data->wakeup_irq,
523 						NULL, ci_wakeup_irq_handler,
524 						IRQF_ONESHOT | IRQF_NO_AUTOEN,
525 						pdata.name, data);
526 		if (ret)
527 			goto err_clk;
528 	}
529 
530 	ret = imx_usbmisc_init(data->usbmisc_data);
531 	if (ret) {
532 		dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
533 		goto phy_shutdown;
534 	}
535 
536 	data->ci_pdev = ci_hdrc_add_device(dev,
537 				pdev->resource, pdev->num_resources,
538 				&pdata);
539 	if (IS_ERR(data->ci_pdev)) {
540 		ret = PTR_ERR(data->ci_pdev);
541 		dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
542 		goto phy_shutdown;
543 	}
544 
545 	if (data->usbmisc_data) {
546 		if (!IS_ERR(pdata.id_extcon.edev) ||
547 		    of_property_read_bool(np, "usb-role-switch"))
548 			data->usbmisc_data->ext_id = 1;
549 
550 		if (!IS_ERR(pdata.vbus_extcon.edev) ||
551 		    of_property_read_bool(np, "usb-role-switch"))
552 			data->usbmisc_data->ext_vbus = 1;
553 
554 		/* usbmisc needs to know dr mode to choose wakeup setting */
555 		data->usbmisc_data->available_role =
556 			ci_hdrc_query_available_role(data->ci_pdev);
557 	}
558 
559 	ret = imx_usbmisc_init_post(data->usbmisc_data);
560 	if (ret) {
561 		dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
562 		goto disable_device;
563 	}
564 
565 	if (data->supports_runtime_pm) {
566 		pm_runtime_set_active(dev);
567 		pm_runtime_enable(dev);
568 	}
569 
570 	device_set_wakeup_capable(dev, true);
571 
572 	return 0;
573 
574 disable_device:
575 	ci_hdrc_remove_device(data->ci_pdev);
576 phy_shutdown:
577 	if (data->override_phy_control)
578 		usb_phy_shutdown(data->phy);
579 err_clk:
580 	clk_disable_unprepare(data->clk_wakeup);
581 err_wakeup_clk:
582 	imx_disable_unprepare_clks(dev);
583 qos_remove_request:
584 	if (pdata.flags & CI_HDRC_PMQOS)
585 		cpu_latency_qos_remove_request(&data->pm_qos_req);
586 	data->ci_pdev = NULL;
587 err_put:
588 	if (data->usbmisc_data)
589 		put_device(data->usbmisc_data->dev);
590 	return ret;
591 }
592 
593 static void ci_hdrc_imx_remove(struct platform_device *pdev)
594 {
595 	struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev);
596 
597 	if (data->supports_runtime_pm) {
598 		pm_runtime_get_sync(&pdev->dev);
599 		pm_runtime_disable(&pdev->dev);
600 		pm_runtime_put_noidle(&pdev->dev);
601 	}
602 	if (data->ci_pdev)
603 		ci_hdrc_remove_device(data->ci_pdev);
604 	if (data->override_phy_control)
605 		usb_phy_shutdown(data->phy);
606 	if (data->ci_pdev) {
607 		imx_disable_unprepare_clks(&pdev->dev);
608 		clk_disable_unprepare(data->clk_wakeup);
609 		if (data->plat_data->flags & CI_HDRC_PMQOS)
610 			cpu_latency_qos_remove_request(&data->pm_qos_req);
611 	}
612 	if (data->usbmisc_data)
613 		put_device(data->usbmisc_data->dev);
614 }
615 
616 static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
617 {
618 	ci_hdrc_imx_remove(pdev);
619 }
620 
621 static int imx_controller_suspend(struct device *dev,
622 						 pm_message_t msg)
623 {
624 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
625 	int ret = 0;
626 
627 	dev_dbg(dev, "at %s\n", __func__);
628 
629 	ret = imx_usbmisc_suspend(data->usbmisc_data,
630 				  PMSG_IS_AUTO(msg) || device_may_wakeup(dev));
631 	if (ret) {
632 		dev_err(dev,
633 			"usbmisc suspend failed, ret=%d\n", ret);
634 		return ret;
635 	}
636 
637 	imx_disable_unprepare_clks(dev);
638 
639 	if (data->wakeup_irq > 0)
640 		enable_irq(data->wakeup_irq);
641 
642 	if (data->plat_data->flags & CI_HDRC_PMQOS)
643 		cpu_latency_qos_remove_request(&data->pm_qos_req);
644 
645 	data->in_lpm = true;
646 
647 	return 0;
648 }
649 
650 static int imx_controller_resume(struct device *dev,
651 						pm_message_t msg)
652 {
653 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
654 	int ret = 0;
655 
656 	dev_dbg(dev, "at %s\n", __func__);
657 
658 	if (!data->in_lpm) {
659 		WARN_ON(1);
660 		return 0;
661 	}
662 
663 	if (data->plat_data->flags & CI_HDRC_PMQOS)
664 		cpu_latency_qos_add_request(&data->pm_qos_req, 0);
665 
666 	if (data->wakeup_irq > 0 &&
667 	    !irqd_irq_disabled(irq_get_irq_data(data->wakeup_irq)))
668 		disable_irq_nosync(data->wakeup_irq);
669 
670 	ret = imx_prepare_enable_clks(dev);
671 	if (ret)
672 		return ret;
673 
674 	data->in_lpm = false;
675 
676 	ret = imx_usbmisc_resume(data->usbmisc_data,
677 				 PMSG_IS_AUTO(msg) || device_may_wakeup(dev));
678 	if (ret) {
679 		dev_err(dev, "usbmisc resume failed, ret=%d\n", ret);
680 		goto clk_disable;
681 	}
682 
683 	return 0;
684 
685 clk_disable:
686 	imx_disable_unprepare_clks(dev);
687 	return ret;
688 }
689 
690 static int ci_hdrc_imx_suspend(struct device *dev)
691 {
692 	int ret;
693 
694 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
695 
696 	if (data->in_lpm)
697 		/* The core's suspend doesn't run */
698 		return 0;
699 
700 	ret = imx_controller_suspend(dev, PMSG_SUSPEND);
701 	if (ret)
702 		return ret;
703 
704 	pinctrl_pm_select_sleep_state(dev);
705 
706 	if (data->wakeup_irq > 0 && device_may_wakeup(dev))
707 		enable_irq_wake(data->wakeup_irq);
708 
709 	return ret;
710 }
711 
712 static int ci_hdrc_imx_resume(struct device *dev)
713 {
714 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
715 	int ret;
716 
717 	if (data->wakeup_irq > 0 && device_may_wakeup(dev))
718 		disable_irq_wake(data->wakeup_irq);
719 
720 	pinctrl_pm_select_default_state(dev);
721 	ret = imx_controller_resume(dev, PMSG_RESUME);
722 	if (!ret && data->supports_runtime_pm) {
723 		pm_runtime_disable(dev);
724 		pm_runtime_set_active(dev);
725 		pm_runtime_enable(dev);
726 	}
727 
728 	return ret;
729 }
730 
731 static int ci_hdrc_imx_runtime_suspend(struct device *dev)
732 {
733 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
734 
735 	if (data->in_lpm) {
736 		WARN_ON(1);
737 		return 0;
738 	}
739 
740 	return imx_controller_suspend(dev, PMSG_AUTO_SUSPEND);
741 }
742 
743 static int ci_hdrc_imx_runtime_resume(struct device *dev)
744 {
745 	return imx_controller_resume(dev, PMSG_AUTO_RESUME);
746 }
747 
748 static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
749 	SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
750 	RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend, ci_hdrc_imx_runtime_resume, NULL)
751 };
752 static struct platform_driver ci_hdrc_imx_driver = {
753 	.probe = ci_hdrc_imx_probe,
754 	.remove = ci_hdrc_imx_remove,
755 	.shutdown = ci_hdrc_imx_shutdown,
756 	.driver = {
757 		.name = "imx_usb",
758 		.of_match_table = ci_hdrc_imx_dt_ids,
759 		.pm = pm_ptr(&ci_hdrc_imx_pm_ops),
760 	 },
761 };
762 
763 module_platform_driver(ci_hdrc_imx_driver);
764 
765 MODULE_ALIAS("platform:imx-usb");
766 MODULE_LICENSE("GPL");
767 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
768 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
769 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
770