0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/of_platform.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/pm_runtime.h>
0012 #include <linux/usb/chipidea.h>
0013 #include <linux/usb/of.h>
0014 #include <linux/clk.h>
0015 #include <linux/pinctrl/consumer.h>
0016 #include <linux/pm_qos.h>
0017
0018 #include "ci.h"
0019 #include "ci_hdrc_imx.h"
0020
0021 struct ci_hdrc_imx_platform_flag {
0022 unsigned int flags;
0023 };
0024
0025 static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
0026 .flags = CI_HDRC_TURN_VBUS_EARLY_ON |
0027 CI_HDRC_DISABLE_STREAMING,
0028 };
0029
0030 static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
0031 .flags = CI_HDRC_DISABLE_STREAMING,
0032 };
0033
0034 static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
0035 .flags = CI_HDRC_IMX28_WRITE_FIX |
0036 CI_HDRC_TURN_VBUS_EARLY_ON |
0037 CI_HDRC_DISABLE_STREAMING,
0038 };
0039
0040 static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
0041 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
0042 CI_HDRC_TURN_VBUS_EARLY_ON |
0043 CI_HDRC_DISABLE_STREAMING,
0044 };
0045
0046 static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
0047 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
0048 CI_HDRC_TURN_VBUS_EARLY_ON |
0049 CI_HDRC_DISABLE_HOST_STREAMING,
0050 };
0051
0052 static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
0053 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
0054 CI_HDRC_TURN_VBUS_EARLY_ON |
0055 CI_HDRC_DISABLE_HOST_STREAMING,
0056 };
0057
0058 static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
0059 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
0060 CI_HDRC_TURN_VBUS_EARLY_ON |
0061 CI_HDRC_DISABLE_DEVICE_STREAMING,
0062 };
0063
0064 static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
0065 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
0066 };
0067
0068 static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
0069 .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
0070 CI_HDRC_PMQOS,
0071 };
0072
0073 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
0074 { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
0075 { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
0076 { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
0077 { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
0078 { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
0079 { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
0080 { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
0081 { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
0082 { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
0083 { }
0084 };
0085 MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
0086
0087 struct ci_hdrc_imx_data {
0088 struct usb_phy *phy;
0089 struct platform_device *ci_pdev;
0090 struct clk *clk;
0091 struct imx_usbmisc_data *usbmisc_data;
0092 bool supports_runtime_pm;
0093 bool override_phy_control;
0094 bool in_lpm;
0095 struct pinctrl *pinctrl;
0096 struct pinctrl_state *pinctrl_hsic_active;
0097 struct regulator *hsic_pad_regulator;
0098
0099 bool need_three_clks;
0100 struct clk *clk_ipg;
0101 struct clk *clk_ahb;
0102 struct clk *clk_per;
0103
0104 struct pm_qos_request pm_qos_req;
0105 const struct ci_hdrc_imx_platform_flag *plat_data;
0106 };
0107
0108
0109
0110 static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
0111 {
0112 struct platform_device *misc_pdev;
0113 struct device_node *np = dev->of_node;
0114 struct of_phandle_args args;
0115 struct imx_usbmisc_data *data;
0116 int ret;
0117
0118
0119
0120
0121
0122 if (!of_get_property(np, "fsl,usbmisc", NULL))
0123 return NULL;
0124
0125 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0126 if (!data)
0127 return ERR_PTR(-ENOMEM);
0128
0129 ret = of_parse_phandle_with_args(np, "fsl,usbmisc", "#index-cells",
0130 0, &args);
0131 if (ret) {
0132 dev_err(dev, "Failed to parse property fsl,usbmisc, errno %d\n",
0133 ret);
0134 return ERR_PTR(ret);
0135 }
0136
0137 data->index = args.args[0];
0138
0139 misc_pdev = of_find_device_by_node(args.np);
0140 of_node_put(args.np);
0141
0142 if (!misc_pdev)
0143 return ERR_PTR(-EPROBE_DEFER);
0144
0145 if (!platform_get_drvdata(misc_pdev)) {
0146 put_device(&misc_pdev->dev);
0147 return ERR_PTR(-EPROBE_DEFER);
0148 }
0149 data->dev = &misc_pdev->dev;
0150
0151
0152
0153
0154
0155 if (of_find_property(np, "disable-over-current", NULL)) {
0156 data->disable_oc = 1;
0157 } else if (of_find_property(np, "over-current-active-high", NULL)) {
0158 data->oc_pol_active_low = 0;
0159 data->oc_pol_configured = 1;
0160 } else if (of_find_property(np, "over-current-active-low", NULL)) {
0161 data->oc_pol_active_low = 1;
0162 data->oc_pol_configured = 1;
0163 } else {
0164 dev_warn(dev, "No over current polarity defined\n");
0165 }
0166
0167 data->pwr_pol = of_property_read_bool(np, "power-active-high");
0168 data->evdo = of_property_read_bool(np, "external-vbus-divider");
0169
0170 if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
0171 data->ulpi = 1;
0172
0173 of_property_read_u32(np, "samsung,picophy-pre-emp-curr-control",
0174 &data->emp_curr_control);
0175 of_property_read_u32(np, "samsung,picophy-dc-vol-level-adjust",
0176 &data->dc_vol_level_adjust);
0177
0178 return data;
0179 }
0180
0181
0182 static int imx_get_clks(struct device *dev)
0183 {
0184 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0185 int ret = 0;
0186
0187 data->clk_ipg = devm_clk_get(dev, "ipg");
0188 if (IS_ERR(data->clk_ipg)) {
0189
0190 data->clk = devm_clk_get(dev, NULL);
0191 if (IS_ERR(data->clk)) {
0192 ret = PTR_ERR(data->clk);
0193 dev_err(dev,
0194 "Failed to get clks, err=%ld,%ld\n",
0195 PTR_ERR(data->clk), PTR_ERR(data->clk_ipg));
0196 return ret;
0197 }
0198 return ret;
0199 }
0200
0201 data->clk_ahb = devm_clk_get(dev, "ahb");
0202 if (IS_ERR(data->clk_ahb)) {
0203 ret = PTR_ERR(data->clk_ahb);
0204 dev_err(dev,
0205 "Failed to get ahb clock, err=%d\n", ret);
0206 return ret;
0207 }
0208
0209 data->clk_per = devm_clk_get(dev, "per");
0210 if (IS_ERR(data->clk_per)) {
0211 ret = PTR_ERR(data->clk_per);
0212 dev_err(dev,
0213 "Failed to get per clock, err=%d\n", ret);
0214 return ret;
0215 }
0216
0217 data->need_three_clks = true;
0218 return ret;
0219 }
0220
0221 static int imx_prepare_enable_clks(struct device *dev)
0222 {
0223 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0224 int ret = 0;
0225
0226 if (data->need_three_clks) {
0227 ret = clk_prepare_enable(data->clk_ipg);
0228 if (ret) {
0229 dev_err(dev,
0230 "Failed to prepare/enable ipg clk, err=%d\n",
0231 ret);
0232 return ret;
0233 }
0234
0235 ret = clk_prepare_enable(data->clk_ahb);
0236 if (ret) {
0237 dev_err(dev,
0238 "Failed to prepare/enable ahb clk, err=%d\n",
0239 ret);
0240 clk_disable_unprepare(data->clk_ipg);
0241 return ret;
0242 }
0243
0244 ret = clk_prepare_enable(data->clk_per);
0245 if (ret) {
0246 dev_err(dev,
0247 "Failed to prepare/enable per clk, err=%d\n",
0248 ret);
0249 clk_disable_unprepare(data->clk_ahb);
0250 clk_disable_unprepare(data->clk_ipg);
0251 return ret;
0252 }
0253 } else {
0254 ret = clk_prepare_enable(data->clk);
0255 if (ret) {
0256 dev_err(dev,
0257 "Failed to prepare/enable clk, err=%d\n",
0258 ret);
0259 return ret;
0260 }
0261 }
0262
0263 return ret;
0264 }
0265
0266 static void imx_disable_unprepare_clks(struct device *dev)
0267 {
0268 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0269
0270 if (data->need_three_clks) {
0271 clk_disable_unprepare(data->clk_per);
0272 clk_disable_unprepare(data->clk_ahb);
0273 clk_disable_unprepare(data->clk_ipg);
0274 } else {
0275 clk_disable_unprepare(data->clk);
0276 }
0277 }
0278
0279 static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
0280 {
0281 struct device *dev = ci->dev->parent;
0282 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0283 int ret = 0;
0284 struct imx_usbmisc_data *mdata = data->usbmisc_data;
0285
0286 switch (event) {
0287 case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
0288 if (data->pinctrl) {
0289 ret = pinctrl_select_state(data->pinctrl,
0290 data->pinctrl_hsic_active);
0291 if (ret)
0292 dev_err(dev,
0293 "hsic_active select failed, err=%d\n",
0294 ret);
0295 }
0296 break;
0297 case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
0298 ret = imx_usbmisc_hsic_set_connect(mdata);
0299 if (ret)
0300 dev_err(dev,
0301 "hsic_set_connect failed, err=%d\n", ret);
0302 break;
0303 case CI_HDRC_CONTROLLER_VBUS_EVENT:
0304 if (ci->vbus_active)
0305 ret = imx_usbmisc_charger_detection(mdata, true);
0306 else
0307 ret = imx_usbmisc_charger_detection(mdata, false);
0308 if (ci->usb_phy)
0309 schedule_work(&ci->usb_phy->chg_work);
0310 break;
0311 default:
0312 break;
0313 }
0314
0315 return ret;
0316 }
0317
0318 static int ci_hdrc_imx_probe(struct platform_device *pdev)
0319 {
0320 struct ci_hdrc_imx_data *data;
0321 struct ci_hdrc_platform_data pdata = {
0322 .name = dev_name(&pdev->dev),
0323 .capoffset = DEF_CAPOFFSET,
0324 .notify_event = ci_hdrc_imx_notify_event,
0325 };
0326 int ret;
0327 const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
0328 struct device_node *np = pdev->dev.of_node;
0329 struct device *dev = &pdev->dev;
0330
0331 imx_platform_flag = of_device_get_match_data(&pdev->dev);
0332
0333 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
0334 if (!data)
0335 return -ENOMEM;
0336
0337 data->plat_data = imx_platform_flag;
0338 pdata.flags |= imx_platform_flag->flags;
0339 platform_set_drvdata(pdev, data);
0340 data->usbmisc_data = usbmisc_get_init_data(dev);
0341 if (IS_ERR(data->usbmisc_data))
0342 return PTR_ERR(data->usbmisc_data);
0343
0344 if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
0345 && data->usbmisc_data) {
0346 pdata.flags |= CI_HDRC_IMX_IS_HSIC;
0347 data->usbmisc_data->hsic = 1;
0348 data->pinctrl = devm_pinctrl_get(dev);
0349 if (PTR_ERR(data->pinctrl) == -ENODEV)
0350 data->pinctrl = NULL;
0351 else if (IS_ERR(data->pinctrl))
0352 return dev_err_probe(dev, PTR_ERR(data->pinctrl),
0353 "pinctrl get failed\n");
0354
0355 data->hsic_pad_regulator =
0356 devm_regulator_get_optional(dev, "hsic");
0357 if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
0358
0359 data->hsic_pad_regulator = NULL;
0360 } else if (IS_ERR(data->hsic_pad_regulator))
0361 return dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator),
0362 "Get HSIC pad regulator error\n");
0363
0364 if (data->hsic_pad_regulator) {
0365 ret = regulator_enable(data->hsic_pad_regulator);
0366 if (ret) {
0367 dev_err(dev,
0368 "Failed to enable HSIC pad regulator\n");
0369 return ret;
0370 }
0371 }
0372 }
0373
0374
0375 if (data->pinctrl) {
0376 struct pinctrl_state *pinctrl_hsic_idle;
0377
0378 pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
0379 if (IS_ERR(pinctrl_hsic_idle)) {
0380 dev_err(dev,
0381 "pinctrl_hsic_idle lookup failed, err=%ld\n",
0382 PTR_ERR(pinctrl_hsic_idle));
0383 return PTR_ERR(pinctrl_hsic_idle);
0384 }
0385
0386 ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
0387 if (ret) {
0388 dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
0389 return ret;
0390 }
0391
0392 data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
0393 "active");
0394 if (IS_ERR(data->pinctrl_hsic_active)) {
0395 dev_err(dev,
0396 "pinctrl_hsic_active lookup failed, err=%ld\n",
0397 PTR_ERR(data->pinctrl_hsic_active));
0398 return PTR_ERR(data->pinctrl_hsic_active);
0399 }
0400 }
0401
0402 if (pdata.flags & CI_HDRC_PMQOS)
0403 cpu_latency_qos_add_request(&data->pm_qos_req, 0);
0404
0405 ret = imx_get_clks(dev);
0406 if (ret)
0407 goto disable_hsic_regulator;
0408
0409 ret = imx_prepare_enable_clks(dev);
0410 if (ret)
0411 goto disable_hsic_regulator;
0412
0413 data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
0414 if (IS_ERR(data->phy)) {
0415 ret = PTR_ERR(data->phy);
0416 if (ret != -ENODEV)
0417 goto err_clk;
0418 data->phy = devm_usb_get_phy_by_phandle(dev, "phys", 0);
0419 if (IS_ERR(data->phy)) {
0420 ret = PTR_ERR(data->phy);
0421 if (ret == -ENODEV)
0422 data->phy = NULL;
0423 else
0424 goto err_clk;
0425 }
0426 }
0427
0428 pdata.usb_phy = data->phy;
0429 if (data->usbmisc_data)
0430 data->usbmisc_data->usb_phy = data->phy;
0431
0432 if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
0433 of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
0434 of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
0435 pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
0436 data->override_phy_control = true;
0437 usb_phy_init(pdata.usb_phy);
0438 }
0439
0440 if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
0441 data->supports_runtime_pm = true;
0442
0443 ret = imx_usbmisc_init(data->usbmisc_data);
0444 if (ret) {
0445 dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
0446 goto err_clk;
0447 }
0448
0449 data->ci_pdev = ci_hdrc_add_device(dev,
0450 pdev->resource, pdev->num_resources,
0451 &pdata);
0452 if (IS_ERR(data->ci_pdev)) {
0453 ret = PTR_ERR(data->ci_pdev);
0454 dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
0455 goto err_clk;
0456 }
0457
0458 if (data->usbmisc_data) {
0459 if (!IS_ERR(pdata.id_extcon.edev) ||
0460 of_property_read_bool(np, "usb-role-switch"))
0461 data->usbmisc_data->ext_id = 1;
0462
0463 if (!IS_ERR(pdata.vbus_extcon.edev) ||
0464 of_property_read_bool(np, "usb-role-switch"))
0465 data->usbmisc_data->ext_vbus = 1;
0466
0467
0468 data->usbmisc_data->available_role =
0469 ci_hdrc_query_available_role(data->ci_pdev);
0470 }
0471
0472 ret = imx_usbmisc_init_post(data->usbmisc_data);
0473 if (ret) {
0474 dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
0475 goto disable_device;
0476 }
0477
0478 if (data->supports_runtime_pm) {
0479 pm_runtime_set_active(dev);
0480 pm_runtime_enable(dev);
0481 }
0482
0483 device_set_wakeup_capable(dev, true);
0484
0485 return 0;
0486
0487 disable_device:
0488 ci_hdrc_remove_device(data->ci_pdev);
0489 err_clk:
0490 imx_disable_unprepare_clks(dev);
0491 disable_hsic_regulator:
0492 if (data->hsic_pad_regulator)
0493
0494 regulator_disable(data->hsic_pad_regulator);
0495 if (pdata.flags & CI_HDRC_PMQOS)
0496 cpu_latency_qos_remove_request(&data->pm_qos_req);
0497 data->ci_pdev = NULL;
0498 return ret;
0499 }
0500
0501 static int ci_hdrc_imx_remove(struct platform_device *pdev)
0502 {
0503 struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev);
0504
0505 if (data->supports_runtime_pm) {
0506 pm_runtime_get_sync(&pdev->dev);
0507 pm_runtime_disable(&pdev->dev);
0508 pm_runtime_put_noidle(&pdev->dev);
0509 }
0510 if (data->ci_pdev)
0511 ci_hdrc_remove_device(data->ci_pdev);
0512 if (data->override_phy_control)
0513 usb_phy_shutdown(data->phy);
0514 if (data->ci_pdev) {
0515 imx_disable_unprepare_clks(&pdev->dev);
0516 if (data->plat_data->flags & CI_HDRC_PMQOS)
0517 cpu_latency_qos_remove_request(&data->pm_qos_req);
0518 if (data->hsic_pad_regulator)
0519 regulator_disable(data->hsic_pad_regulator);
0520 }
0521
0522 return 0;
0523 }
0524
0525 static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
0526 {
0527 ci_hdrc_imx_remove(pdev);
0528 }
0529
0530 static int __maybe_unused imx_controller_suspend(struct device *dev)
0531 {
0532 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0533 int ret = 0;
0534
0535 dev_dbg(dev, "at %s\n", __func__);
0536
0537 ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
0538 if (ret) {
0539 dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
0540 return ret;
0541 }
0542
0543 imx_disable_unprepare_clks(dev);
0544 if (data->plat_data->flags & CI_HDRC_PMQOS)
0545 cpu_latency_qos_remove_request(&data->pm_qos_req);
0546
0547 data->in_lpm = true;
0548
0549 return 0;
0550 }
0551
0552 static int __maybe_unused imx_controller_resume(struct device *dev)
0553 {
0554 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0555 int ret = 0;
0556
0557 dev_dbg(dev, "at %s\n", __func__);
0558
0559 if (!data->in_lpm) {
0560 WARN_ON(1);
0561 return 0;
0562 }
0563
0564 if (data->plat_data->flags & CI_HDRC_PMQOS)
0565 cpu_latency_qos_add_request(&data->pm_qos_req, 0);
0566
0567 ret = imx_prepare_enable_clks(dev);
0568 if (ret)
0569 return ret;
0570
0571 data->in_lpm = false;
0572
0573 ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
0574 if (ret) {
0575 dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
0576 goto clk_disable;
0577 }
0578
0579 ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
0580 if (ret) {
0581 dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
0582 goto hsic_set_clk_fail;
0583 }
0584
0585 return 0;
0586
0587 hsic_set_clk_fail:
0588 imx_usbmisc_set_wakeup(data->usbmisc_data, true);
0589 clk_disable:
0590 imx_disable_unprepare_clks(dev);
0591 return ret;
0592 }
0593
0594 static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
0595 {
0596 int ret;
0597
0598 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0599
0600 if (data->in_lpm)
0601
0602 return 0;
0603
0604 if (device_may_wakeup(dev)) {
0605 ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
0606 if (ret) {
0607 dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n",
0608 ret);
0609 return ret;
0610 }
0611 }
0612
0613 ret = imx_controller_suspend(dev);
0614 if (ret)
0615 return ret;
0616
0617 pinctrl_pm_select_sleep_state(dev);
0618 return ret;
0619 }
0620
0621 static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
0622 {
0623 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0624 int ret;
0625
0626 pinctrl_pm_select_default_state(dev);
0627 ret = imx_controller_resume(dev);
0628 if (!ret && data->supports_runtime_pm) {
0629 pm_runtime_disable(dev);
0630 pm_runtime_set_active(dev);
0631 pm_runtime_enable(dev);
0632 }
0633
0634 return ret;
0635 }
0636
0637 static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev)
0638 {
0639 struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
0640 int ret;
0641
0642 if (data->in_lpm) {
0643 WARN_ON(1);
0644 return 0;
0645 }
0646
0647 ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
0648 if (ret) {
0649 dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
0650 return ret;
0651 }
0652
0653 return imx_controller_suspend(dev);
0654 }
0655
0656 static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev)
0657 {
0658 return imx_controller_resume(dev);
0659 }
0660
0661 static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
0662 SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
0663 SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
0664 ci_hdrc_imx_runtime_resume, NULL)
0665 };
0666 static struct platform_driver ci_hdrc_imx_driver = {
0667 .probe = ci_hdrc_imx_probe,
0668 .remove = ci_hdrc_imx_remove,
0669 .shutdown = ci_hdrc_imx_shutdown,
0670 .driver = {
0671 .name = "imx_usb",
0672 .of_match_table = ci_hdrc_imx_dt_ids,
0673 .pm = &ci_hdrc_imx_pm_ops,
0674 },
0675 };
0676
0677 module_platform_driver(ci_hdrc_imx_driver);
0678
0679 MODULE_ALIAS("platform:imx-usb");
0680 MODULE_LICENSE("GPL");
0681 MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
0682 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
0683 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");