diff options
author | Peter Chen <peter.chen@nxp.com> | 2019-04-27 22:35:31 -0400 |
---|---|---|
committer | Peter Chen <peter.chen@nxp.com> | 2019-06-14 05:39:43 -0400 |
commit | d1609c312d42f3bdfe7df9d4dd9d5b2c7ace90f4 (patch) | |
tree | a2f1bff97772544cb9586bcac6b6b98acab8dfa2 | |
parent | 8ea5b2abd07e2280a332bd9c1a7f4dd15b9b6c13 (diff) |
usb: chipidea: imx: add imx7ulp support
In this commit, we add CI_HDRC_PMQOS to avoid system entering idle,
at imx7ulp, if the system enters idle, the DMA will stop, so the USB
transfer can't work at this case.
Signed-off-by: Peter Chen <peter.chen@nxp.com>
-rw-r--r-- | drivers/usb/chipidea/ci_hdrc_imx.c | 28 | ||||
-rw-r--r-- | drivers/usb/chipidea/usbmisc_imx.c | 4 | ||||
-rw-r--r-- | include/linux/usb/chipidea.h | 1 |
3 files changed, 32 insertions, 1 deletions
diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index ceec8d5985d4..a76708501236 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/usb/of.h> | 13 | #include <linux/usb/of.h> |
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/pinctrl/consumer.h> | 15 | #include <linux/pinctrl/consumer.h> |
16 | #include <linux/pm_qos.h> | ||
16 | 17 | ||
17 | #include "ci.h" | 18 | #include "ci.h" |
18 | #include "ci_hdrc_imx.h" | 19 | #include "ci_hdrc_imx.h" |
@@ -63,6 +64,11 @@ static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = { | |||
63 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, | 64 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, |
64 | }; | 65 | }; |
65 | 66 | ||
67 | static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = { | ||
68 | .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | | ||
69 | CI_HDRC_PMQOS, | ||
70 | }; | ||
71 | |||
66 | static const struct of_device_id ci_hdrc_imx_dt_ids[] = { | 72 | static const struct of_device_id ci_hdrc_imx_dt_ids[] = { |
67 | { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, | 73 | { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data}, |
68 | { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, | 74 | { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data}, |
@@ -72,6 +78,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = { | |||
72 | { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data}, | 78 | { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data}, |
73 | { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data}, | 79 | { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data}, |
74 | { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, | 80 | { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data}, |
81 | { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data}, | ||
75 | { /* sentinel */ } | 82 | { /* sentinel */ } |
76 | }; | 83 | }; |
77 | MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); | 84 | MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); |
@@ -93,6 +100,8 @@ struct ci_hdrc_imx_data { | |||
93 | struct clk *clk_ahb; | 100 | struct clk *clk_ahb; |
94 | struct clk *clk_per; | 101 | struct clk *clk_per; |
95 | /* --------------------------------- */ | 102 | /* --------------------------------- */ |
103 | struct pm_qos_request pm_qos_req; | ||
104 | const struct ci_hdrc_imx_platform_flag *plat_data; | ||
96 | }; | 105 | }; |
97 | 106 | ||
98 | /* Common functions shared by usbmisc drivers */ | 107 | /* Common functions shared by usbmisc drivers */ |
@@ -309,6 +318,8 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) | |||
309 | if (!data) | 318 | if (!data) |
310 | return -ENOMEM; | 319 | return -ENOMEM; |
311 | 320 | ||
321 | data->plat_data = imx_platform_flag; | ||
322 | pdata.flags |= imx_platform_flag->flags; | ||
312 | platform_set_drvdata(pdev, data); | 323 | platform_set_drvdata(pdev, data); |
313 | data->usbmisc_data = usbmisc_get_init_data(dev); | 324 | data->usbmisc_data = usbmisc_get_init_data(dev); |
314 | if (IS_ERR(data->usbmisc_data)) | 325 | if (IS_ERR(data->usbmisc_data)) |
@@ -369,6 +380,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) | |||
369 | } | 380 | } |
370 | } | 381 | } |
371 | } | 382 | } |
383 | |||
384 | if (pdata.flags & CI_HDRC_PMQOS) | ||
385 | pm_qos_add_request(&data->pm_qos_req, | ||
386 | PM_QOS_CPU_DMA_LATENCY, 0); | ||
387 | |||
372 | ret = imx_get_clks(dev); | 388 | ret = imx_get_clks(dev); |
373 | if (ret) | 389 | if (ret) |
374 | goto disable_hsic_regulator; | 390 | goto disable_hsic_regulator; |
@@ -396,7 +412,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) | |||
396 | usb_phy_init(pdata.usb_phy); | 412 | usb_phy_init(pdata.usb_phy); |
397 | } | 413 | } |
398 | 414 | ||
399 | pdata.flags |= imx_platform_flag->flags; | ||
400 | if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM) | 415 | if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM) |
401 | data->supports_runtime_pm = true; | 416 | data->supports_runtime_pm = true; |
402 | 417 | ||
@@ -439,6 +454,8 @@ err_clk: | |||
439 | disable_hsic_regulator: | 454 | disable_hsic_regulator: |
440 | if (data->hsic_pad_regulator) | 455 | if (data->hsic_pad_regulator) |
441 | ret = regulator_disable(data->hsic_pad_regulator); | 456 | ret = regulator_disable(data->hsic_pad_regulator); |
457 | if (pdata.flags & CI_HDRC_PMQOS) | ||
458 | pm_qos_remove_request(&data->pm_qos_req); | ||
442 | return ret; | 459 | return ret; |
443 | } | 460 | } |
444 | 461 | ||
@@ -455,6 +472,8 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) | |||
455 | if (data->override_phy_control) | 472 | if (data->override_phy_control) |
456 | usb_phy_shutdown(data->phy); | 473 | usb_phy_shutdown(data->phy); |
457 | imx_disable_unprepare_clks(&pdev->dev); | 474 | imx_disable_unprepare_clks(&pdev->dev); |
475 | if (data->plat_data->flags & CI_HDRC_PMQOS) | ||
476 | pm_qos_remove_request(&data->pm_qos_req); | ||
458 | if (data->hsic_pad_regulator) | 477 | if (data->hsic_pad_regulator) |
459 | regulator_disable(data->hsic_pad_regulator); | 478 | regulator_disable(data->hsic_pad_regulator); |
460 | 479 | ||
@@ -480,6 +499,9 @@ static int __maybe_unused imx_controller_suspend(struct device *dev) | |||
480 | } | 499 | } |
481 | 500 | ||
482 | imx_disable_unprepare_clks(dev); | 501 | imx_disable_unprepare_clks(dev); |
502 | if (data->plat_data->flags & CI_HDRC_PMQOS) | ||
503 | pm_qos_remove_request(&data->pm_qos_req); | ||
504 | |||
483 | data->in_lpm = true; | 505 | data->in_lpm = true; |
484 | 506 | ||
485 | return 0; | 507 | return 0; |
@@ -497,6 +519,10 @@ static int __maybe_unused imx_controller_resume(struct device *dev) | |||
497 | return 0; | 519 | return 0; |
498 | } | 520 | } |
499 | 521 | ||
522 | if (data->plat_data->flags & CI_HDRC_PMQOS) | ||
523 | pm_qos_add_request(&data->pm_qos_req, | ||
524 | PM_QOS_CPU_DMA_LATENCY, 0); | ||
525 | |||
500 | ret = imx_prepare_enable_clks(dev); | 526 | ret = imx_prepare_enable_clks(dev); |
501 | if (ret) | 527 | if (ret) |
502 | return ret; | 528 | return ret; |
diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index d8b67e150b12..b7a5727d0c8a 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c | |||
@@ -763,6 +763,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = { | |||
763 | .compatible = "fsl,imx7d-usbmisc", | 763 | .compatible = "fsl,imx7d-usbmisc", |
764 | .data = &imx7d_usbmisc_ops, | 764 | .data = &imx7d_usbmisc_ops, |
765 | }, | 765 | }, |
766 | { | ||
767 | .compatible = "fsl,imx7ulp-usbmisc", | ||
768 | .data = &imx7d_usbmisc_ops, | ||
769 | }, | ||
766 | { /* sentinel */ } | 770 | { /* sentinel */ } |
767 | }; | 771 | }; |
768 | MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); | 772 | MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); |
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 911e05af671e..edd89b7c8f18 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h | |||
@@ -61,6 +61,7 @@ struct ci_hdrc_platform_data { | |||
61 | #define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */ | 61 | #define CI_HDRC_OVERRIDE_PHY_CONTROL BIT(12) /* Glue layer manages phy */ |
62 | #define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13) | 62 | #define CI_HDRC_REQUIRES_ALIGNED_DMA BIT(13) |
63 | #define CI_HDRC_IMX_IS_HSIC BIT(14) | 63 | #define CI_HDRC_IMX_IS_HSIC BIT(14) |
64 | #define CI_HDRC_PMQOS BIT(15) | ||
64 | enum usb_dr_mode dr_mode; | 65 | enum usb_dr_mode dr_mode; |
65 | #define CI_HDRC_CONTROLLER_RESET_EVENT 0 | 66 | #define CI_HDRC_CONTROLLER_RESET_EVENT 0 |
66 | #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 | 67 | #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 |