linux/drivers/usb/chipidea/ci_hdrc_imx.c
<<
>>
Prefs
   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/of_platform.h>
  10#include <linux/platform_device.h>
  11#include <linux/pm_runtime.h>
  12#include <linux/usb/chipidea.h>
  13#include <linux/usb/of.h>
  14#include <linux/clk.h>
  15#include <linux/pinctrl/consumer.h>
  16#include <linux/pm_qos.h>
  17
  18#include "ci.h"
  19#include "ci_hdrc_imx.h"
  20
  21struct ci_hdrc_imx_platform_flag {
  22        unsigned int flags;
  23};
  24
  25static const struct ci_hdrc_imx_platform_flag imx23_usb_data = {
  26        .flags = CI_HDRC_TURN_VBUS_EARLY_ON |
  27                CI_HDRC_DISABLE_STREAMING,
  28};
  29
  30static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
  31        .flags = CI_HDRC_DISABLE_STREAMING,
  32};
  33
  34static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
  35        .flags = CI_HDRC_IMX28_WRITE_FIX |
  36                CI_HDRC_TURN_VBUS_EARLY_ON |
  37                CI_HDRC_DISABLE_STREAMING,
  38};
  39
  40static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
  41        .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
  42                CI_HDRC_TURN_VBUS_EARLY_ON |
  43                CI_HDRC_DISABLE_STREAMING,
  44};
  45
  46static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
  47        .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
  48                CI_HDRC_TURN_VBUS_EARLY_ON |
  49                CI_HDRC_DISABLE_HOST_STREAMING,
  50};
  51
  52static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
  53        .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
  54                CI_HDRC_TURN_VBUS_EARLY_ON |
  55                CI_HDRC_DISABLE_HOST_STREAMING,
  56};
  57
  58static const struct ci_hdrc_imx_platform_flag imx6ul_usb_data = {
  59        .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
  60                CI_HDRC_TURN_VBUS_EARLY_ON,
  61};
  62
  63static const struct ci_hdrc_imx_platform_flag imx7d_usb_data = {
  64        .flags = CI_HDRC_SUPPORTS_RUNTIME_PM,
  65};
  66
  67static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = {
  68        .flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
  69                CI_HDRC_PMQOS,
  70};
  71
  72static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
  73        { .compatible = "fsl,imx23-usb", .data = &imx23_usb_data},
  74        { .compatible = "fsl,imx28-usb", .data = &imx28_usb_data},
  75        { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data},
  76        { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data},
  77        { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data},
  78        { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data},
  79        { .compatible = "fsl,imx6ul-usb", .data = &imx6ul_usb_data},
  80        { .compatible = "fsl,imx7d-usb", .data = &imx7d_usb_data},
  81        { .compatible = "fsl,imx7ulp-usb", .data = &imx7ulp_usb_data},
  82        { /* sentinel */ }
  83};
  84MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids);
  85
  86struct ci_hdrc_imx_data {
  87        struct usb_phy *phy;
  88        struct platform_device *ci_pdev;
  89        struct clk *clk;
  90        struct imx_usbmisc_data *usbmisc_data;
  91        bool supports_runtime_pm;
  92        bool override_phy_control;
  93        bool in_lpm;
  94        struct pinctrl *pinctrl;
  95        struct pinctrl_state *pinctrl_hsic_active;
  96        struct regulator *hsic_pad_regulator;
  97        /* SoC before i.mx6 (except imx23/imx28) needs three clks */
  98        bool need_three_clks;
  99        struct clk *clk_ipg;
 100        struct clk *clk_ahb;
 101        struct clk *clk_per;
 102        /* --------------------------------- */
 103        struct pm_qos_request pm_qos_req;
 104        const struct ci_hdrc_imx_platform_flag *plat_data;
 105};
 106
 107/* Common functions shared by usbmisc drivers */
 108
 109static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
 110{
 111        struct platform_device *misc_pdev;
 112        struct device_node *np = dev->of_node;
 113        struct of_phandle_args args;
 114        struct imx_usbmisc_data *data;
 115        int ret;
 116
 117        /*
 118         * In case the fsl,usbmisc property is not present this device doesn't
 119         * need usbmisc. Return NULL (which is no error here)
 120         */
 121        if (!of_get_property(np, "fsl,usbmisc", NULL))
 122                return NULL;
 123
 124        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 125        if (!data)
 126                return ERR_PTR(-ENOMEM);
 127
 128        ret = of_parse_phandle_with_args(np, "fsl,usbmisc", "#index-cells",
 129                                        0, &args);
 130        if (ret) {
 131                dev_err(dev, "Failed to parse property fsl,usbmisc, errno %d\n",
 132                        ret);
 133                return ERR_PTR(ret);
 134        }
 135
 136        data->index = args.args[0];
 137
 138        misc_pdev = of_find_device_by_node(args.np);
 139        of_node_put(args.np);
 140
 141        if (!misc_pdev || !platform_get_drvdata(misc_pdev))
 142                return ERR_PTR(-EPROBE_DEFER);
 143
 144        data->dev = &misc_pdev->dev;
 145
 146        /*
 147         * Check the various over current related properties. If over current
 148         * detection is disabled we're not interested in the polarity.
 149         */
 150        if (of_find_property(np, "disable-over-current", NULL)) {
 151                data->disable_oc = 1;
 152        } else if (of_find_property(np, "over-current-active-high", NULL)) {
 153                data->oc_pol_active_low = 0;
 154                data->oc_pol_configured = 1;
 155        } else if (of_find_property(np, "over-current-active-low", NULL)) {
 156                data->oc_pol_active_low = 1;
 157                data->oc_pol_configured = 1;
 158        } else {
 159                dev_warn(dev, "No over current polarity defined\n");
 160        }
 161
 162        data->pwr_pol = of_property_read_bool(np, "power-active-high");
 163        data->evdo = of_property_read_bool(np, "external-vbus-divider");
 164
 165        if (of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI)
 166                data->ulpi = 1;
 167
 168        return data;
 169}
 170
 171/* End of common functions shared by usbmisc drivers*/
 172static int imx_get_clks(struct device *dev)
 173{
 174        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 175        int ret = 0;
 176
 177        data->clk_ipg = devm_clk_get(dev, "ipg");
 178        if (IS_ERR(data->clk_ipg)) {
 179                /* If the platform only needs one clocks */
 180                data->clk = devm_clk_get(dev, NULL);
 181                if (IS_ERR(data->clk)) {
 182                        ret = PTR_ERR(data->clk);
 183                        dev_err(dev,
 184                                "Failed to get clks, err=%ld,%ld\n",
 185                                PTR_ERR(data->clk), PTR_ERR(data->clk_ipg));
 186                        return ret;
 187                }
 188                return ret;
 189        }
 190
 191        data->clk_ahb = devm_clk_get(dev, "ahb");
 192        if (IS_ERR(data->clk_ahb)) {
 193                ret = PTR_ERR(data->clk_ahb);
 194                dev_err(dev,
 195                        "Failed to get ahb clock, err=%d\n", ret);
 196                return ret;
 197        }
 198
 199        data->clk_per = devm_clk_get(dev, "per");
 200        if (IS_ERR(data->clk_per)) {
 201                ret = PTR_ERR(data->clk_per);
 202                dev_err(dev,
 203                        "Failed to get per clock, err=%d\n", ret);
 204                return ret;
 205        }
 206
 207        data->need_three_clks = true;
 208        return ret;
 209}
 210
 211static int imx_prepare_enable_clks(struct device *dev)
 212{
 213        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 214        int ret = 0;
 215
 216        if (data->need_three_clks) {
 217                ret = clk_prepare_enable(data->clk_ipg);
 218                if (ret) {
 219                        dev_err(dev,
 220                                "Failed to prepare/enable ipg clk, err=%d\n",
 221                                ret);
 222                        return ret;
 223                }
 224
 225                ret = clk_prepare_enable(data->clk_ahb);
 226                if (ret) {
 227                        dev_err(dev,
 228                                "Failed to prepare/enable ahb clk, err=%d\n",
 229                                ret);
 230                        clk_disable_unprepare(data->clk_ipg);
 231                        return ret;
 232                }
 233
 234                ret = clk_prepare_enable(data->clk_per);
 235                if (ret) {
 236                        dev_err(dev,
 237                                "Failed to prepare/enable per clk, err=%d\n",
 238                                ret);
 239                        clk_disable_unprepare(data->clk_ahb);
 240                        clk_disable_unprepare(data->clk_ipg);
 241                        return ret;
 242                }
 243        } else {
 244                ret = clk_prepare_enable(data->clk);
 245                if (ret) {
 246                        dev_err(dev,
 247                                "Failed to prepare/enable clk, err=%d\n",
 248                                ret);
 249                        return ret;
 250                }
 251        }
 252
 253        return ret;
 254}
 255
 256static void imx_disable_unprepare_clks(struct device *dev)
 257{
 258        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 259
 260        if (data->need_three_clks) {
 261                clk_disable_unprepare(data->clk_per);
 262                clk_disable_unprepare(data->clk_ahb);
 263                clk_disable_unprepare(data->clk_ipg);
 264        } else {
 265                clk_disable_unprepare(data->clk);
 266        }
 267}
 268
 269static int ci_hdrc_imx_notify_event(struct ci_hdrc *ci, unsigned int event)
 270{
 271        struct device *dev = ci->dev->parent;
 272        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 273        int ret = 0;
 274
 275        switch (event) {
 276        case CI_HDRC_IMX_HSIC_ACTIVE_EVENT:
 277                ret = pinctrl_select_state(data->pinctrl,
 278                                data->pinctrl_hsic_active);
 279                if (ret)
 280                        dev_err(dev, "hsic_active select failed, err=%d\n",
 281                                ret);
 282                break;
 283        case CI_HDRC_IMX_HSIC_SUSPEND_EVENT:
 284                ret = imx_usbmisc_hsic_set_connect(data->usbmisc_data);
 285                if (ret)
 286                        dev_err(dev,
 287                                "hsic_set_connect failed, err=%d\n", ret);
 288                break;
 289        default:
 290                break;
 291        }
 292
 293        return ret;
 294}
 295
 296static int ci_hdrc_imx_probe(struct platform_device *pdev)
 297{
 298        struct ci_hdrc_imx_data *data;
 299        struct ci_hdrc_platform_data pdata = {
 300                .name           = dev_name(&pdev->dev),
 301                .capoffset      = DEF_CAPOFFSET,
 302                .notify_event   = ci_hdrc_imx_notify_event,
 303        };
 304        int ret;
 305        const struct of_device_id *of_id;
 306        const struct ci_hdrc_imx_platform_flag *imx_platform_flag;
 307        struct device_node *np = pdev->dev.of_node;
 308        struct device *dev = &pdev->dev;
 309        struct pinctrl_state *pinctrl_hsic_idle;
 310
 311        of_id = of_match_device(ci_hdrc_imx_dt_ids, dev);
 312        if (!of_id)
 313                return -ENODEV;
 314
 315        imx_platform_flag = of_id->data;
 316
 317        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 318        if (!data)
 319                return -ENOMEM;
 320
 321        data->plat_data = imx_platform_flag;
 322        pdata.flags |= imx_platform_flag->flags;
 323        platform_set_drvdata(pdev, data);
 324        data->usbmisc_data = usbmisc_get_init_data(dev);
 325        if (IS_ERR(data->usbmisc_data))
 326                return PTR_ERR(data->usbmisc_data);
 327
 328        if ((of_usb_get_phy_mode(dev->of_node) == USBPHY_INTERFACE_MODE_HSIC)
 329                && data->usbmisc_data) {
 330                pdata.flags |= CI_HDRC_IMX_IS_HSIC;
 331                data->usbmisc_data->hsic = 1;
 332                data->pinctrl = devm_pinctrl_get(dev);
 333                if (IS_ERR(data->pinctrl)) {
 334                        dev_err(dev, "pinctrl get failed, err=%ld\n",
 335                                        PTR_ERR(data->pinctrl));
 336                        return PTR_ERR(data->pinctrl);
 337                }
 338
 339                pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
 340                if (IS_ERR(pinctrl_hsic_idle)) {
 341                        dev_err(dev,
 342                                "pinctrl_hsic_idle lookup failed, err=%ld\n",
 343                                        PTR_ERR(pinctrl_hsic_idle));
 344                        return PTR_ERR(pinctrl_hsic_idle);
 345                }
 346
 347                ret = pinctrl_select_state(data->pinctrl, pinctrl_hsic_idle);
 348                if (ret) {
 349                        dev_err(dev, "hsic_idle select failed, err=%d\n", ret);
 350                        return ret;
 351                }
 352
 353                data->pinctrl_hsic_active = pinctrl_lookup_state(data->pinctrl,
 354                                                                "active");
 355                if (IS_ERR(data->pinctrl_hsic_active)) {
 356                        dev_err(dev,
 357                                "pinctrl_hsic_active lookup failed, err=%ld\n",
 358                                        PTR_ERR(data->pinctrl_hsic_active));
 359                        return PTR_ERR(data->pinctrl_hsic_active);
 360                }
 361
 362                data->hsic_pad_regulator = devm_regulator_get(dev, "hsic");
 363                if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) {
 364                        return -EPROBE_DEFER;
 365                } else if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
 366                        /* no pad regualator is needed */
 367                        data->hsic_pad_regulator = NULL;
 368                } else if (IS_ERR(data->hsic_pad_regulator)) {
 369                        dev_err(dev, "Get HSIC pad regulator error: %ld\n",
 370                                        PTR_ERR(data->hsic_pad_regulator));
 371                        return PTR_ERR(data->hsic_pad_regulator);
 372                }
 373
 374                if (data->hsic_pad_regulator) {
 375                        ret = regulator_enable(data->hsic_pad_regulator);
 376                        if (ret) {
 377                                dev_err(dev,
 378                                        "Failed to enable HSIC pad regulator\n");
 379                                return ret;
 380                        }
 381                }
 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
 388        ret = imx_get_clks(dev);
 389        if (ret)
 390                goto disable_hsic_regulator;
 391
 392        ret = imx_prepare_enable_clks(dev);
 393        if (ret)
 394                goto disable_hsic_regulator;
 395
 396        data->phy = devm_usb_get_phy_by_phandle(dev, "fsl,usbphy", 0);
 397        if (IS_ERR(data->phy)) {
 398                ret = PTR_ERR(data->phy);
 399                /* Return -EINVAL if no usbphy is available */
 400                if (ret == -ENODEV)
 401                        data->phy = NULL;
 402                else
 403                        goto err_clk;
 404        }
 405
 406        pdata.usb_phy = data->phy;
 407
 408        if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
 409             of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
 410            of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
 411                pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
 412                data->override_phy_control = true;
 413                usb_phy_init(pdata.usb_phy);
 414        }
 415
 416        if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
 417                data->supports_runtime_pm = true;
 418
 419        ret = imx_usbmisc_init(data->usbmisc_data);
 420        if (ret) {
 421                dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
 422                goto err_clk;
 423        }
 424
 425        data->ci_pdev = ci_hdrc_add_device(dev,
 426                                pdev->resource, pdev->num_resources,
 427                                &pdata);
 428        if (IS_ERR(data->ci_pdev)) {
 429                ret = PTR_ERR(data->ci_pdev);
 430                if (ret != -EPROBE_DEFER)
 431                        dev_err(dev, "ci_hdrc_add_device failed, err=%d\n",
 432                                        ret);
 433                goto err_clk;
 434        }
 435
 436        ret = imx_usbmisc_init_post(data->usbmisc_data);
 437        if (ret) {
 438                dev_err(dev, "usbmisc post failed, ret=%d\n", ret);
 439                goto disable_device;
 440        }
 441
 442        if (data->supports_runtime_pm) {
 443                pm_runtime_set_active(dev);
 444                pm_runtime_enable(dev);
 445        }
 446
 447        device_set_wakeup_capable(dev, true);
 448
 449        return 0;
 450
 451disable_device:
 452        ci_hdrc_remove_device(data->ci_pdev);
 453err_clk:
 454        imx_disable_unprepare_clks(dev);
 455disable_hsic_regulator:
 456        if (data->hsic_pad_regulator)
 457                /* don't overwrite original ret (cf. EPROBE_DEFER) */
 458                regulator_disable(data->hsic_pad_regulator);
 459        if (pdata.flags & CI_HDRC_PMQOS)
 460                pm_qos_remove_request(&data->pm_qos_req);
 461        data->ci_pdev = NULL;
 462        return ret;
 463}
 464
 465static int ci_hdrc_imx_remove(struct platform_device *pdev)
 466{
 467        struct ci_hdrc_imx_data *data = platform_get_drvdata(pdev);
 468
 469        if (data->supports_runtime_pm) {
 470                pm_runtime_get_sync(&pdev->dev);
 471                pm_runtime_disable(&pdev->dev);
 472                pm_runtime_put_noidle(&pdev->dev);
 473        }
 474        if (data->ci_pdev)
 475                ci_hdrc_remove_device(data->ci_pdev);
 476        if (data->override_phy_control)
 477                usb_phy_shutdown(data->phy);
 478        if (data->ci_pdev) {
 479                imx_disable_unprepare_clks(&pdev->dev);
 480                if (data->plat_data->flags & CI_HDRC_PMQOS)
 481                        pm_qos_remove_request(&data->pm_qos_req);
 482                if (data->hsic_pad_regulator)
 483                        regulator_disable(data->hsic_pad_regulator);
 484        }
 485
 486        return 0;
 487}
 488
 489static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
 490{
 491        ci_hdrc_imx_remove(pdev);
 492}
 493
 494static int __maybe_unused imx_controller_suspend(struct device *dev)
 495{
 496        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 497        int ret = 0;
 498
 499        dev_dbg(dev, "at %s\n", __func__);
 500
 501        ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, false);
 502        if (ret) {
 503                dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
 504                return ret;
 505        }
 506
 507        imx_disable_unprepare_clks(dev);
 508        if (data->plat_data->flags & CI_HDRC_PMQOS)
 509                pm_qos_remove_request(&data->pm_qos_req);
 510
 511        data->in_lpm = true;
 512
 513        return 0;
 514}
 515
 516static int __maybe_unused imx_controller_resume(struct device *dev)
 517{
 518        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 519        int ret = 0;
 520
 521        dev_dbg(dev, "at %s\n", __func__);
 522
 523        if (!data->in_lpm) {
 524                WARN_ON(1);
 525                return 0;
 526        }
 527
 528        if (data->plat_data->flags & CI_HDRC_PMQOS)
 529                pm_qos_add_request(&data->pm_qos_req,
 530                        PM_QOS_CPU_DMA_LATENCY, 0);
 531
 532        ret = imx_prepare_enable_clks(dev);
 533        if (ret)
 534                return ret;
 535
 536        data->in_lpm = false;
 537
 538        ret = imx_usbmisc_set_wakeup(data->usbmisc_data, false);
 539        if (ret) {
 540                dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
 541                goto clk_disable;
 542        }
 543
 544        ret = imx_usbmisc_hsic_set_clk(data->usbmisc_data, true);
 545        if (ret) {
 546                dev_err(dev, "usbmisc hsic_set_clk failed, ret=%d\n", ret);
 547                goto hsic_set_clk_fail;
 548        }
 549
 550        return 0;
 551
 552hsic_set_clk_fail:
 553        imx_usbmisc_set_wakeup(data->usbmisc_data, true);
 554clk_disable:
 555        imx_disable_unprepare_clks(dev);
 556        return ret;
 557}
 558
 559static int __maybe_unused ci_hdrc_imx_suspend(struct device *dev)
 560{
 561        int ret;
 562
 563        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 564
 565        if (data->in_lpm)
 566                /* The core's suspend doesn't run */
 567                return 0;
 568
 569        if (device_may_wakeup(dev)) {
 570                ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
 571                if (ret) {
 572                        dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n",
 573                                        ret);
 574                        return ret;
 575                }
 576        }
 577
 578        return imx_controller_suspend(dev);
 579}
 580
 581static int __maybe_unused ci_hdrc_imx_resume(struct device *dev)
 582{
 583        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 584        int ret;
 585
 586        ret = imx_controller_resume(dev);
 587        if (!ret && data->supports_runtime_pm) {
 588                pm_runtime_disable(dev);
 589                pm_runtime_set_active(dev);
 590                pm_runtime_enable(dev);
 591        }
 592
 593        return ret;
 594}
 595
 596static int __maybe_unused ci_hdrc_imx_runtime_suspend(struct device *dev)
 597{
 598        struct ci_hdrc_imx_data *data = dev_get_drvdata(dev);
 599        int ret;
 600
 601        if (data->in_lpm) {
 602                WARN_ON(1);
 603                return 0;
 604        }
 605
 606        ret = imx_usbmisc_set_wakeup(data->usbmisc_data, true);
 607        if (ret) {
 608                dev_err(dev, "usbmisc set_wakeup failed, ret=%d\n", ret);
 609                return ret;
 610        }
 611
 612        return imx_controller_suspend(dev);
 613}
 614
 615static int __maybe_unused ci_hdrc_imx_runtime_resume(struct device *dev)
 616{
 617        return imx_controller_resume(dev);
 618}
 619
 620static const struct dev_pm_ops ci_hdrc_imx_pm_ops = {
 621        SET_SYSTEM_SLEEP_PM_OPS(ci_hdrc_imx_suspend, ci_hdrc_imx_resume)
 622        SET_RUNTIME_PM_OPS(ci_hdrc_imx_runtime_suspend,
 623                        ci_hdrc_imx_runtime_resume, NULL)
 624};
 625static struct platform_driver ci_hdrc_imx_driver = {
 626        .probe = ci_hdrc_imx_probe,
 627        .remove = ci_hdrc_imx_remove,
 628        .shutdown = ci_hdrc_imx_shutdown,
 629        .driver = {
 630                .name = "imx_usb",
 631                .of_match_table = ci_hdrc_imx_dt_ids,
 632                .pm = &ci_hdrc_imx_pm_ops,
 633         },
 634};
 635
 636module_platform_driver(ci_hdrc_imx_driver);
 637
 638MODULE_ALIAS("platform:imx-usb");
 639MODULE_LICENSE("GPL");
 640MODULE_DESCRIPTION("CI HDRC i.MX USB binding");
 641MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
 642MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
 643