Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright 2012 Freescale Semiconductor, Inc.
0004  * Copyright (C) 2012 Marek Vasut <marex@denx.de>
0005  * on behalf of DENX Software Engineering GmbH
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     { /* sentinel */ }
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     /* SoC before i.mx6 (except imx23/imx28) needs three clks */
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 /* Common functions shared by usbmisc drivers */
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      * In case the fsl,usbmisc property is not present this device doesn't
0120      * need usbmisc. Return NULL (which is no error here)
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      * Check the various over current related properties. If over current
0153      * detection is disabled we're not interested in the polarity.
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 /* End of common functions shared by usbmisc drivers*/
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         /* If the platform only needs one clocks */
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             /* no pad regualator is needed */
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     /* HSIC pinctrl handling */
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         /* usbmisc needs to know dr mode to choose wakeup setting */
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         /* don't overwrite original ret (cf. EPROBE_DEFER) */
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         /* The core's suspend doesn't run */
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>");