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