xref: /linux/drivers/usb/chipidea/ci_hdrc_imx.c (revision 8004d08330e1aa7ae797778509e864f7ac3da687)
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 
usbmisc_get_init_data(struct device * dev)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*/
imx_get_clks(struct device * dev)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 
imx_prepare_enable_clks(struct device * dev)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 
imx_disable_unprepare_clks(struct device * dev)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 
ci_hdrc_imx_notify_event(struct ci_hdrc * ci,unsigned int event)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 		    ci->gadget.speed == USB_SPEED_HIGH)
343 			imx_usbmisc_pullup(data->usbmisc_data,
344 					   ci->gadget.connected);
345 		break;
346 	default:
347 		break;
348 	}
349 
350 	return ret;
351 }
352 
ci_wakeup_irq_handler(int irq,void * data)353 static irqreturn_t ci_wakeup_irq_handler(int irq, void *data)
354 {
355 	struct ci_hdrc_imx_data *imx_data = data;
356 
357 	disable_irq_nosync(irq);
358 	pm_runtime_resume(&imx_data->ci_pdev->dev);
359 
360 	return IRQ_HANDLED;
361 }
362 
ci_hdrc_imx_disable_regulator(void * arg)363 static void ci_hdrc_imx_disable_regulator(void *arg)
364 {
365 	struct ci_hdrc_imx_data *data = arg;
366 
367 	regulator_disable(data->hsic_pad_regulator);
368 }
369 
ci_hdrc_imx_probe(struct platform_device * pdev)370 static int ci_hdrc_imx_probe(struct platform_device *pdev)
371 {
372 	struct ci_hdrc_imx_data *data;
373 	struct ci_hdrc_platform_data pdata = {
374 		.name		= dev_name(&pdev->dev),
375 		.capoffset	= DEF_CAPOFFSET,
376 		.flags		= CI_HDRC_HAS_SHORT_PKT_LIMIT,
377 		.notify_event	= ci_hdrc_imx_notify_event,
378 	};
379 	int ret;
380 	const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
381 	struct device_node *np = pdev->dev.of_node;
382 	struct device *dev = &pdev->dev;
383 
384 	imx_platform_flag = of_device_get_match_data(&pdev->dev);
385 
386 	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
387 	if (!data)
388 		return -ENOMEM;
389 
390 	data->plat_data = imx_platform_flag;
391 	pdata.flags |= imx_platform_flag->flags;
392 	platform_set_drvdata(pdev, data);
393 	data->usbmisc_data = usbmisc_get_init_data(dev);
394 	if (IS_ERR(data->usbmisc_data))
395 		return PTR_ERR(data->usbmisc_data);
396 
397 	if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
398 		&& data->usbmisc_data) {
399 		pdata.flags |= CI_HDRC_IMX_IS_HSIC;
400 		data->usbmisc_data->hsic = 1;
401 		data->pinctrl = devm_pinctrl_get(dev);
402 		if (PTR_ERR(data->pinctrl) == -ENODEV)
403 			data->pinctrl = NULL;
404 		else if (IS_ERR(data->pinctrl)) {
405 			ret = dev_err_probe(dev, PTR_ERR(data->pinctrl),
406 					     "pinctrl get failed\n");
407 			goto err_put;
408 		}
409 
410 		data->hsic_pad_regulator =
411 				devm_regulator_get_optional(dev, "hsic");
412 		if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
413 			/* no pad regulator is needed */
414 			data->hsic_pad_regulator = NULL;
415 		} else if (IS_ERR(data->hsic_pad_regulator)) {
416 			ret = dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator),
417 					     "Get HSIC pad regulator error\n");
418 			goto err_put;
419 		}
420 
421 		if (data->hsic_pad_regulator) {
422 			ret = regulator_enable(data->hsic_pad_regulator);
423 			if (ret) {
424 				dev_err(dev,
425 					"Failed to enable HSIC pad regulator\n");
426 				goto err_put;
427 			}
428 			ret = devm_add_action_or_reset(dev,
429 					ci_hdrc_imx_disable_regulator, data);
430 			if (ret) {
431 				dev_err(dev,
432 					"Failed to add regulator devm action\n");
433 				goto err_put;
434 			}
435 		}
436 	}
437 
438 	/* HSIC pinctrl handling */
439 	if (data->pinctrl) {
440 		struct pinctrl_state *pinctrl_hsic_idle;
441 
442 		pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
443 		if (IS_ERR(pinctrl_hsic_idle)) {
444 			dev_err(dev,
445 				"pinctrl_hsic_idle lookup failed, err=%ld\n",
446 					PTR_ERR(pinctrl_hsic_idle));
447 			ret = PTR_ERR(pinctrl_hsic_idle);
448 			goto err_put;
449 		}
450 
451 		ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
452 		if (ret) {
453 			dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
454 			goto err_put;
455 		}
456 
457 		data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
458 								"active");
459 		if (IS_ERR(data->pinctrl_hsic_active)) {
460 			dev_err(dev,
461 				"pinctrl_hsic_active lookup failed, err=%ld\n",
462 					PTR_ERR(data->pinctrl_hsic_active));
463 			ret = PTR_ERR(data->pinctrl_hsic_active);
464 			goto err_put;
465 		}
466 	}
467 
468 	if (pdata.flags & CI_HDRC_PMQOS)
469 		cpu_latency_qos_add_request(&data->pm_qos_req, 0);
470 
471 	ret = imx_get_clks(dev);
472 	if (ret)
473 		goto qos_remove_request;
474 
475 	ret = imx_prepare_enable_clks(dev);
476 	if (ret)
477 		goto qos_remove_request;
478 
479 	ret = clk_prepare_enable(data->clk_wakeup);
480 	if (ret)
481 		goto err_wakeup_clk;
482 
483 	data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
484 	if (IS_ERR(data->phy)) {
485 		ret = PTR_ERR(data->phy);
486 		if (ret != -ENODEV) {
487 			dev_err_probe(dev, ret, "Failed to parse fsl,usbphy\n");
488 			goto err_clk;
489 		}
490 		data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
491 		if (IS_ERR(data->phy)) {
492 			ret = PTR_ERR(data->phy);
493 			if (ret == -ENODEV) {
494 				data->phy = NULL;
495 			} else {
496 				dev_err_probe(dev, ret, "Failed to parse phys\n");
497 				goto err_clk;
498 			}
499 		}
500 	}
501 
502 	pdata.usb_phy = data->phy;
503 	if (data->usbmisc_data)
504 		data->usbmisc_data->usb_phy = data->phy;
505 
506 	if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
507 	     of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
508 	    of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
509 		pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
510 		data->override_phy_control = true;
511 		ret = usb_phy_init(pdata.usb_phy);
512 		if (ret) {
513 			dev_err(dev, "Failed to init phy\n");
514 			goto err_clk;
515 		}
516 	}
517 
518 	if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
519 		data->supports_runtime_pm = true;
520 
521 	data->wakeup_irq = platform_get_irq_optional(pdev, 1);
522 	if (data->wakeup_irq > 0) {
523 		ret = devm_request_threaded_irq(dev, data->wakeup_irq,
524 						NULL, ci_wakeup_irq_handler,
525 						IRQF_ONESHOT | IRQF_NO_AUTOEN,
526 						pdata.name, data);
527 		if (ret)
528 			goto err_clk;
529 	}
530 
531 	ret = imx_usbmisc_init(data->usbmisc_data);
532 	if (ret) {
533 		dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
534 		goto phy_shutdown;
535 	}
536 
537 	data->ci_pdev = ci_hdrc_add_device(dev,
538 				pdev->resource, pdev->num_resources,
539 				&pdata);
540 	if (IS_ERR(data->ci_pdev)) {
541 		ret = PTR_ERR(data->ci_pdev);
542 		dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
543 		goto phy_shutdown;
544 	}
545 
546 	if (data->usbmisc_data) {
547 		if (!IS_ERR(pdata.id_extcon.edev) ||
548 		    of_property_read_bool(np, "usb-role-switch"))
549 			data->usbmisc_data->ext_id = 1;
550 
551 		if (!IS_ERR(pdata.vbus_extcon.edev) ||
552 		    of_property_read_bool(np, "usb-role-switch"))
553 			data->usbmisc_data->ext_vbus = 1;
554 
555 		/* usbmisc needs to know dr mode to choose wakeup setting */
556 		data->usbmisc_data->available_role =
557 			ci_hdrc_query_available_role(data->ci_pdev);
558 	}
559 
560 	ret = imx_usbmisc_init_post(data->usbmisc_data);
561 	if (ret) {
562 		dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
563 		goto disable_device;
564 	}
565 
566 	if (data->supports_runtime_pm) {
567 		pm_runtime_set_active(dev);
568 		pm_runtime_enable(dev);
569 	}
570 
571 	device_set_wakeup_capable(dev, true);
572 
573 	return 0;
574 
575 disable_device:
576 	ci_hdrc_remove_device(data->ci_pdev);
577 phy_shutdown:
578 	if (data->override_phy_control)
579 		usb_phy_shutdown(data->phy);
580 err_clk:
581 	clk_disable_unprepare(data->clk_wakeup);
582 err_wakeup_clk:
583 	imx_disable_unprepare_clks(dev);
584 qos_remove_request:
585 	if (pdata.flags & CI_HDRC_PMQOS)
586 		cpu_latency_qos_remove_request(&data->pm_qos_req);
587 	data->ci_pdev = NULL;
588 err_put:
589 	if (data->usbmisc_data)
590 		put_device(data->usbmisc_data->dev);
591 	return ret;
592 }
593 
ci_hdrc_imx_remove(struct platform_device * pdev)594 static void ci_hdrc_imx_remove(struct platform_device *pdev)
595 {
596 	struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev);
597 
598 	if (data->supports_runtime_pm) {
599 		pm_runtime_get_sync(&pdev->dev);
600 		pm_runtime_disable(&pdev->dev);
601 		pm_runtime_put_noidle(&pdev->dev);
602 	}
603 	if (data->ci_pdev)
604 		ci_hdrc_remove_device(data->ci_pdev);
605 	if (data->override_phy_control)
606 		usb_phy_shutdown(data->phy);
607 	if (data->ci_pdev) {
608 		imx_disable_unprepare_clks(&pdev->dev);
609 		clk_disable_unprepare(data->clk_wakeup);
610 		if (data->plat_data->flags & CI_HDRC_PMQOS)
611 			cpu_latency_qos_remove_request(&data->pm_qos_req);
612 	}
613 	if (data->usbmisc_data)
614 		put_device(data->usbmisc_data->dev);
615 }
616 
ci_hdrc_imx_shutdown(struct platform_device * pdev)617 static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
618 {
619 	ci_hdrc_imx_remove(pdev);
620 }
621 
imx_controller_suspend(struct device * dev,pm_message_t msg)622 static int imx_controller_suspend(struct device *dev,
623 						 pm_message_t msg)
624 {
625 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
626 	int ret = 0;
627 
628 	dev_dbg(dev, "at %s\n", __func__);
629 
630 	ret = imx_usbmisc_suspend(data->usbmisc_data,
631 				  PMSG_IS_AUTO(msg) || device_may_wakeup(dev));
632 	if (ret) {
633 		dev_err(dev,
634 			"usbmisc suspend failed, ret=%d\n", ret);
635 		return ret;
636 	}
637 
638 	imx_disable_unprepare_clks(dev);
639 
640 	if (data->wakeup_irq > 0)
641 		enable_irq(data->wakeup_irq);
642 
643 	if (data->plat_data->flags & CI_HDRC_PMQOS)
644 		cpu_latency_qos_remove_request(&data->pm_qos_req);
645 
646 	data->in_lpm = true;
647 
648 	return 0;
649 }
650 
imx_controller_resume(struct device * dev,pm_message_t msg)651 static int imx_controller_resume(struct device *dev,
652 						pm_message_t msg)
653 {
654 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
655 	int ret = 0;
656 
657 	dev_dbg(dev, "at %s\n", __func__);
658 
659 	if (!data->in_lpm) {
660 		WARN_ON(1);
661 		return 0;
662 	}
663 
664 	if (data->plat_data->flags & CI_HDRC_PMQOS)
665 		cpu_latency_qos_add_request(&data->pm_qos_req, 0);
666 
667 	if (data->wakeup_irq > 0 &&
668 	    !irqd_irq_disabled(irq_get_irq_data(data->wakeup_irq)))
669 		disable_irq_nosync(data->wakeup_irq);
670 
671 	ret = imx_prepare_enable_clks(dev);
672 	if (ret)
673 		return ret;
674 
675 	data->in_lpm = false;
676 
677 	ret = imx_usbmisc_resume(data->usbmisc_data,
678 				 PMSG_IS_AUTO(msg) || device_may_wakeup(dev));
679 	if (ret) {
680 		dev_err(dev, "usbmisc resume failed, ret=%d\n", ret);
681 		goto clk_disable;
682 	}
683 
684 	return 0;
685 
686 clk_disable:
687 	imx_disable_unprepare_clks(dev);
688 	return ret;
689 }
690 
ci_hdrc_imx_suspend(struct device * dev)691 static int ci_hdrc_imx_suspend(struct device *dev)
692 {
693 	int ret;
694 
695 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
696 
697 	if (data->in_lpm)
698 		/* The core's suspend doesn't run */
699 		return 0;
700 
701 	ret = imx_controller_suspend(dev, PMSG_SUSPEND);
702 	if (ret)
703 		return ret;
704 
705 	pinctrl_pm_select_sleep_state(dev);
706 
707 	if (data->wakeup_irq > 0 && device_may_wakeup(dev))
708 		enable_irq_wake(data->wakeup_irq);
709 
710 	return ret;
711 }
712 
ci_hdrc_imx_resume(struct device * dev)713 static int ci_hdrc_imx_resume(struct device *dev)
714 {
715 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
716 	int ret;
717 
718 	if (data->wakeup_irq > 0 && device_may_wakeup(dev))
719 		disable_irq_wake(data->wakeup_irq);
720 
721 	pinctrl_pm_select_default_state(dev);
722 	ret = imx_controller_resume(dev, PMSG_RESUME);
723 	if (!ret && data->supports_runtime_pm) {
724 		pm_runtime_disable(dev);
725 		pm_runtime_set_active(dev);
726 		pm_runtime_enable(dev);
727 	}
728 
729 	return ret;
730 }
731 
ci_hdrc_imx_runtime_suspend(struct device * dev)732 static int ci_hdrc_imx_runtime_suspend(struct device *dev)
733 {
734 	struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
735 
736 	if (data->in_lpm) {
737 		WARN_ON(1);
738 		return 0;
739 	}
740 
741 	return imx_controller_suspend(dev, PMSG_AUTO_SUSPEND);
742 }
743 
ci_hdrc_imx_runtime_resume(struct device * dev)744 static int ci_hdrc_imx_runtime_resume(struct device *dev)
745 {
746 	return imx_controller_resume(dev, PMSG_AUTO_RESUME);
747 }
748 
749 static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
750 	SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
751 	RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend, ci_hdrc_imx_runtime_resume, NULL)
752 };
753 static struct platform_driver ci_hdrc_imx_driver = {
754 	.probe = ci_hdrc_imx_probe,
755 	.remove = ci_hdrc_imx_remove,
756 	.shutdown = ci_hdrc_imx_shutdown,
757 	.driver = {
758 		.name = "imx_usb",
759 		.of_match_table = ci_hdrc_imx_dt_ids,
760 		.pm = pm_ptr(&ci_hdrc_imx_pm_ops),
761 	 },
762 };
763 
764 module_platform_driver(ci_hdrc_imx_driver);
765 
766 MODULE_ALIAS("platform:imx-usb");
767 MODULE_LICENSE("GPL");
768 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
769 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
770 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
771