linux/drivers/usb/cdns3/core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Cadence USBSS DRD Driver.
   4 *
   5 * Copyright (C) 2018-2019 Cadence.
   6 * Copyright (C) 2017-2018 NXP
   7 * Copyright (C) 2019 Texas Instruments
   8 *
   9 * Author: Peter Chen <peter.chen@nxp.com>
  10 *         Pawel Laszczak <pawell@cadence.com>
  11 *         Roger Quadros <rogerq@ti.com>
  12 */
  13
  14#include <linux/dma-mapping.h>
  15#include <linux/module.h>
  16#include <linux/kernel.h>
  17#include <linux/platform_device.h>
  18#include <linux/interrupt.h>
  19#include <linux/io.h>
  20#include <linux/pm_runtime.h>
  21
  22#include "gadget.h"
  23#include "core.h"
  24#include "host-export.h"
  25#include "gadget-export.h"
  26#include "drd.h"
  27
  28static int cdns3_idle_init(struct cdns3 *cdns);
  29
  30static int cdns3_role_start(struct cdns3 *cdns, enum usb_role role)
  31{
  32        int ret;
  33
  34        if (WARN_ON(role > USB_ROLE_DEVICE))
  35                return 0;
  36
  37        mutex_lock(&cdns->mutex);
  38        cdns->role = role;
  39        mutex_unlock(&cdns->mutex);
  40
  41        if (!cdns->roles[role])
  42                return -ENXIO;
  43
  44        if (cdns->roles[role]->state == CDNS3_ROLE_STATE_ACTIVE)
  45                return 0;
  46
  47        mutex_lock(&cdns->mutex);
  48        ret = cdns->roles[role]->start(cdns);
  49        if (!ret)
  50                cdns->roles[role]->state = CDNS3_ROLE_STATE_ACTIVE;
  51        mutex_unlock(&cdns->mutex);
  52
  53        return ret;
  54}
  55
  56static void cdns3_role_stop(struct cdns3 *cdns)
  57{
  58        enum usb_role role = cdns->role;
  59
  60        if (WARN_ON(role > USB_ROLE_DEVICE))
  61                return;
  62
  63        if (cdns->roles[role]->state == CDNS3_ROLE_STATE_INACTIVE)
  64                return;
  65
  66        mutex_lock(&cdns->mutex);
  67        cdns->roles[role]->stop(cdns);
  68        cdns->roles[role]->state = CDNS3_ROLE_STATE_INACTIVE;
  69        mutex_unlock(&cdns->mutex);
  70}
  71
  72static void cdns3_exit_roles(struct cdns3 *cdns)
  73{
  74        cdns3_role_stop(cdns);
  75        cdns3_drd_exit(cdns);
  76}
  77
  78/**
  79 * cdns3_core_init_role - initialize role of operation
  80 * @cdns: Pointer to cdns3 structure
  81 *
  82 * Returns 0 on success otherwise negative errno
  83 */
  84static int cdns3_core_init_role(struct cdns3 *cdns)
  85{
  86        struct device *dev = cdns->dev;
  87        enum usb_dr_mode best_dr_mode;
  88        enum usb_dr_mode dr_mode;
  89        int ret;
  90
  91        dr_mode = usb_get_dr_mode(dev);
  92        cdns->role = USB_ROLE_NONE;
  93
  94        /*
  95         * If driver can't read mode by means of usb_get_dr_mode function then
  96         * chooses mode according with Kernel configuration. This setting
  97         * can be restricted later depending on strap pin configuration.
  98         */
  99        if (dr_mode == USB_DR_MODE_UNKNOWN) {
 100                if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) &&
 101                    IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
 102                        dr_mode = USB_DR_MODE_OTG;
 103                else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST))
 104                        dr_mode = USB_DR_MODE_HOST;
 105                else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET))
 106                        dr_mode = USB_DR_MODE_PERIPHERAL;
 107        }
 108
 109        /*
 110         * At this point cdns->dr_mode contains strap configuration.
 111         * Driver try update this setting considering kernel configuration
 112         */
 113        best_dr_mode = cdns->dr_mode;
 114
 115        ret = cdns3_idle_init(cdns);
 116        if (ret)
 117                return ret;
 118
 119        if (dr_mode == USB_DR_MODE_OTG) {
 120                best_dr_mode = cdns->dr_mode;
 121        } else if (cdns->dr_mode == USB_DR_MODE_OTG) {
 122                best_dr_mode = dr_mode;
 123        } else if (cdns->dr_mode != dr_mode) {
 124                dev_err(dev, "Incorrect DRD configuration\n");
 125                return -EINVAL;
 126        }
 127
 128        dr_mode = best_dr_mode;
 129
 130        if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
 131                ret = cdns3_host_init(cdns);
 132                if (ret) {
 133                        dev_err(dev, "Host initialization failed with %d\n",
 134                                ret);
 135                        goto err;
 136                }
 137        }
 138
 139        if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
 140                ret = cdns3_gadget_init(cdns);
 141                if (ret) {
 142                        dev_err(dev, "Device initialization failed with %d\n",
 143                                ret);
 144                        goto err;
 145                }
 146        }
 147
 148        cdns->dr_mode = dr_mode;
 149
 150        ret = cdns3_drd_update_mode(cdns);
 151        if (ret)
 152                goto err;
 153
 154        /* Initialize idle role to start with */
 155        ret = cdns3_role_start(cdns, USB_ROLE_NONE);
 156        if (ret)
 157                goto err;
 158
 159        switch (cdns->dr_mode) {
 160        case USB_DR_MODE_OTG:
 161                ret = cdns3_hw_role_switch(cdns);
 162                if (ret)
 163                        goto err;
 164                break;
 165        case USB_DR_MODE_PERIPHERAL:
 166                ret = cdns3_role_start(cdns, USB_ROLE_DEVICE);
 167                if (ret)
 168                        goto err;
 169                break;
 170        case USB_DR_MODE_HOST:
 171                ret = cdns3_role_start(cdns, USB_ROLE_HOST);
 172                if (ret)
 173                        goto err;
 174                break;
 175        default:
 176                ret = -EINVAL;
 177                goto err;
 178        }
 179
 180        return 0;
 181err:
 182        cdns3_exit_roles(cdns);
 183        return ret;
 184}
 185
 186/**
 187 * cdns3_hw_role_state_machine  - role switch state machine based on hw events.
 188 * @cdns: Pointer to controller structure.
 189 *
 190 * Returns next role to be entered based on hw events.
 191 */
 192static enum usb_role cdns3_hw_role_state_machine(struct cdns3 *cdns)
 193{
 194        enum usb_role role = USB_ROLE_NONE;
 195        int id, vbus;
 196
 197        if (cdns->dr_mode != USB_DR_MODE_OTG) {
 198                if (cdns3_is_host(cdns))
 199                        role = USB_ROLE_HOST;
 200                if (cdns3_is_device(cdns))
 201                        role = USB_ROLE_DEVICE;
 202
 203                return role;
 204        }
 205
 206        id = cdns3_get_id(cdns);
 207        vbus = cdns3_get_vbus(cdns);
 208
 209        /*
 210         * Role change state machine
 211         * Inputs: ID, VBUS
 212         * Previous state: cdns->role
 213         * Next state: role
 214         */
 215        role = cdns->role;
 216
 217        switch (role) {
 218        case USB_ROLE_NONE:
 219                /*
 220                 * Driver treats USB_ROLE_NONE synonymous to IDLE state from
 221                 * controller specification.
 222                 */
 223                if (!id)
 224                        role = USB_ROLE_HOST;
 225                else if (vbus)
 226                        role = USB_ROLE_DEVICE;
 227                break;
 228        case USB_ROLE_HOST: /* from HOST, we can only change to NONE */
 229                if (id)
 230                        role = USB_ROLE_NONE;
 231                break;
 232        case USB_ROLE_DEVICE: /* from GADGET, we can only change to NONE*/
 233                if (!vbus)
 234                        role = USB_ROLE_NONE;
 235                break;
 236        }
 237
 238        dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role);
 239
 240        return role;
 241}
 242
 243static int cdns3_idle_role_start(struct cdns3 *cdns)
 244{
 245        return 0;
 246}
 247
 248static void cdns3_idle_role_stop(struct cdns3 *cdns)
 249{
 250        /* Program Lane swap and bring PHY out of RESET */
 251        phy_reset(cdns->usb3_phy);
 252}
 253
 254static int cdns3_idle_init(struct cdns3 *cdns)
 255{
 256        struct cdns3_role_driver *rdrv;
 257
 258        rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL);
 259        if (!rdrv)
 260                return -ENOMEM;
 261
 262        rdrv->start = cdns3_idle_role_start;
 263        rdrv->stop = cdns3_idle_role_stop;
 264        rdrv->state = CDNS3_ROLE_STATE_INACTIVE;
 265        rdrv->suspend = NULL;
 266        rdrv->resume = NULL;
 267        rdrv->name = "idle";
 268
 269        cdns->roles[USB_ROLE_NONE] = rdrv;
 270
 271        return 0;
 272}
 273
 274/**
 275 * cdns3_hw_role_switch - switch roles based on HW state
 276 * @cdns: controller
 277 */
 278int cdns3_hw_role_switch(struct cdns3 *cdns)
 279{
 280        enum usb_role real_role, current_role;
 281        int ret = 0;
 282
 283        /* Depends on role switch class */
 284        if (cdns->role_sw)
 285                return 0;
 286
 287        pm_runtime_get_sync(cdns->dev);
 288
 289        current_role = cdns->role;
 290        real_role = cdns3_hw_role_state_machine(cdns);
 291
 292        /* Do nothing if nothing changed */
 293        if (current_role == real_role)
 294                goto exit;
 295
 296        cdns3_role_stop(cdns);
 297
 298        dev_dbg(cdns->dev, "Switching role %d -> %d", current_role, real_role);
 299
 300        ret = cdns3_role_start(cdns, real_role);
 301        if (ret) {
 302                /* Back to current role */
 303                dev_err(cdns->dev, "set %d has failed, back to %d\n",
 304                        real_role, current_role);
 305                ret = cdns3_role_start(cdns, current_role);
 306                if (ret)
 307                        dev_err(cdns->dev, "back to %d failed too\n",
 308                                current_role);
 309        }
 310exit:
 311        pm_runtime_put_sync(cdns->dev);
 312        return ret;
 313}
 314
 315/**
 316 * cdsn3_role_get - get current role of controller.
 317 *
 318 * @sw: pointer to USB role switch structure
 319 *
 320 * Returns role
 321 */
 322static enum usb_role cdns3_role_get(struct usb_role_switch *sw)
 323{
 324        struct cdns3 *cdns = usb_role_switch_get_drvdata(sw);
 325
 326        return cdns->role;
 327}
 328
 329/**
 330 * cdns3_role_set - set current role of controller.
 331 *
 332 * @sw: pointer to USB role switch structure
 333 * @role: the previous role
 334 * Handles below events:
 335 * - Role switch for dual-role devices
 336 * - USB_ROLE_GADGET <--> USB_ROLE_NONE for peripheral-only devices
 337 */
 338static int cdns3_role_set(struct usb_role_switch *sw, enum usb_role role)
 339{
 340        struct cdns3 *cdns = usb_role_switch_get_drvdata(sw);
 341        int ret = 0;
 342
 343        pm_runtime_get_sync(cdns->dev);
 344
 345        if (cdns->role == role)
 346                goto pm_put;
 347
 348        if (cdns->dr_mode == USB_DR_MODE_HOST) {
 349                switch (role) {
 350                case USB_ROLE_NONE:
 351                case USB_ROLE_HOST:
 352                        break;
 353                default:
 354                        goto pm_put;
 355                }
 356        }
 357
 358        if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) {
 359                switch (role) {
 360                case USB_ROLE_NONE:
 361                case USB_ROLE_DEVICE:
 362                        break;
 363                default:
 364                        goto pm_put;
 365                }
 366        }
 367
 368        cdns3_role_stop(cdns);
 369        ret = cdns3_role_start(cdns, role);
 370        if (ret)
 371                dev_err(cdns->dev, "set role %d has failed\n", role);
 372
 373pm_put:
 374        pm_runtime_put_sync(cdns->dev);
 375        return ret;
 376}
 377
 378static int set_phy_power_on(struct cdns3 *cdns)
 379{
 380        int ret;
 381
 382        ret = phy_power_on(cdns->usb2_phy);
 383        if (ret)
 384                return ret;
 385
 386        ret = phy_power_on(cdns->usb3_phy);
 387        if (ret)
 388                phy_power_off(cdns->usb2_phy);
 389
 390        return ret;
 391}
 392
 393static void set_phy_power_off(struct cdns3 *cdns)
 394{
 395        phy_power_off(cdns->usb3_phy);
 396        phy_power_off(cdns->usb2_phy);
 397}
 398
 399/**
 400 * cdns3_wakeup_irq - interrupt handler for wakeup events
 401 * @irq: irq number for cdns3 core device
 402 * @data: structure of cdns3
 403 *
 404 * Returns IRQ_HANDLED or IRQ_NONE
 405 */
 406static irqreturn_t cdns3_wakeup_irq(int irq, void *data)
 407{
 408        struct cdns3 *cdns = data;
 409
 410        if (cdns->in_lpm) {
 411                disable_irq_nosync(irq);
 412                cdns->wakeup_pending = true;
 413                if ((cdns->role == USB_ROLE_HOST) && cdns->host_dev)
 414                        pm_request_resume(&cdns->host_dev->dev);
 415
 416                return IRQ_HANDLED;
 417        }
 418
 419        return IRQ_NONE;
 420}
 421
 422/**
 423 * cdns3_probe - probe for cdns3 core device
 424 * @pdev: Pointer to cdns3 core platform device
 425 *
 426 * Returns 0 on success otherwise negative errno
 427 */
 428static int cdns3_probe(struct platform_device *pdev)
 429{
 430        struct device *dev = &pdev->dev;
 431        struct resource *res;
 432        struct cdns3 *cdns;
 433        void __iomem *regs;
 434        int ret;
 435
 436        ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 437        if (ret) {
 438                dev_err(dev, "error setting dma mask: %d\n", ret);
 439                return ret;
 440        }
 441
 442        cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL);
 443        if (!cdns)
 444                return -ENOMEM;
 445
 446        cdns->dev = dev;
 447        cdns->pdata = dev_get_platdata(dev);
 448
 449        platform_set_drvdata(pdev, cdns);
 450
 451        res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "host");
 452        if (!res) {
 453                dev_err(dev, "missing host IRQ\n");
 454                return -ENODEV;
 455        }
 456
 457        cdns->xhci_res[0] = *res;
 458
 459        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xhci");
 460        if (!res) {
 461                dev_err(dev, "couldn't get xhci resource\n");
 462                return -ENXIO;
 463        }
 464
 465        cdns->xhci_res[1] = *res;
 466
 467        cdns->dev_irq = platform_get_irq_byname(pdev, "peripheral");
 468        if (cdns->dev_irq < 0)
 469                return cdns->dev_irq;
 470
 471        regs = devm_platform_ioremap_resource_byname(pdev, "dev");
 472        if (IS_ERR(regs))
 473                return PTR_ERR(regs);
 474        cdns->dev_regs  = regs;
 475
 476        cdns->otg_irq = platform_get_irq_byname(pdev, "otg");
 477        if (cdns->otg_irq < 0)
 478                return cdns->otg_irq;
 479
 480        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otg");
 481        if (!res) {
 482                dev_err(dev, "couldn't get otg resource\n");
 483                return -ENXIO;
 484        }
 485
 486        cdns->phyrst_a_enable = device_property_read_bool(dev, "cdns,phyrst-a-enable");
 487
 488        cdns->otg_res = *res;
 489
 490        cdns->wakeup_irq = platform_get_irq_byname_optional(pdev, "wakeup");
 491        if (cdns->wakeup_irq == -EPROBE_DEFER)
 492                return cdns->wakeup_irq;
 493        else if (cdns->wakeup_irq == 0)
 494                return -EINVAL;
 495
 496        if (cdns->wakeup_irq < 0) {
 497                dev_dbg(dev, "couldn't get wakeup irq\n");
 498                cdns->wakeup_irq = 0x0;
 499        }
 500
 501        mutex_init(&cdns->mutex);
 502
 503        cdns->usb2_phy = devm_phy_optional_get(dev, "cdns3,usb2-phy");
 504        if (IS_ERR(cdns->usb2_phy))
 505                return PTR_ERR(cdns->usb2_phy);
 506
 507        ret = phy_init(cdns->usb2_phy);
 508        if (ret)
 509                return ret;
 510
 511        cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy");
 512        if (IS_ERR(cdns->usb3_phy))
 513                return PTR_ERR(cdns->usb3_phy);
 514
 515        ret = phy_init(cdns->usb3_phy);
 516        if (ret)
 517                goto err1;
 518
 519        ret = set_phy_power_on(cdns);
 520        if (ret)
 521                goto err2;
 522
 523        if (device_property_read_bool(dev, "usb-role-switch")) {
 524                struct usb_role_switch_desc sw_desc = { };
 525
 526                sw_desc.set = cdns3_role_set;
 527                sw_desc.get = cdns3_role_get;
 528                sw_desc.allow_userspace_control = true;
 529                sw_desc.driver_data = cdns;
 530                sw_desc.fwnode = dev->fwnode;
 531
 532                cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
 533                if (IS_ERR(cdns->role_sw)) {
 534                        ret = PTR_ERR(cdns->role_sw);
 535                        dev_warn(dev, "Unable to register Role Switch\n");
 536                        goto err3;
 537                }
 538        }
 539
 540        if (cdns->wakeup_irq) {
 541                ret = devm_request_irq(cdns->dev, cdns->wakeup_irq,
 542                                                cdns3_wakeup_irq,
 543                                                IRQF_SHARED,
 544                                                dev_name(cdns->dev), cdns);
 545
 546                if (ret) {
 547                        dev_err(cdns->dev, "couldn't register wakeup irq handler\n");
 548                        goto err4;
 549                }
 550        }
 551
 552        ret = cdns3_drd_init(cdns);
 553        if (ret)
 554                goto err4;
 555
 556        ret = cdns3_core_init_role(cdns);
 557        if (ret)
 558                goto err4;
 559
 560        spin_lock_init(&cdns->lock);
 561        device_set_wakeup_capable(dev, true);
 562        pm_runtime_set_active(dev);
 563        pm_runtime_enable(dev);
 564        if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)))
 565                pm_runtime_forbid(dev);
 566
 567        /*
 568         * The controller needs less time between bus and controller suspend,
 569         * and we also needs a small delay to avoid frequently entering low
 570         * power mode.
 571         */
 572        pm_runtime_set_autosuspend_delay(dev, 20);
 573        pm_runtime_mark_last_busy(dev);
 574        pm_runtime_use_autosuspend(dev);
 575        dev_dbg(dev, "Cadence USB3 core: probe succeed\n");
 576
 577        return 0;
 578err4:
 579        cdns3_drd_exit(cdns);
 580        if (cdns->role_sw)
 581                usb_role_switch_unregister(cdns->role_sw);
 582err3:
 583        set_phy_power_off(cdns);
 584err2:
 585        phy_exit(cdns->usb3_phy);
 586err1:
 587        phy_exit(cdns->usb2_phy);
 588
 589        return ret;
 590}
 591
 592/**
 593 * cdns3_remove - unbind drd driver and clean up
 594 * @pdev: Pointer to Linux platform device
 595 *
 596 * Returns 0 on success otherwise negative errno
 597 */
 598static int cdns3_remove(struct platform_device *pdev)
 599{
 600        struct cdns3 *cdns = platform_get_drvdata(pdev);
 601
 602        pm_runtime_get_sync(&pdev->dev);
 603        pm_runtime_disable(&pdev->dev);
 604        pm_runtime_put_noidle(&pdev->dev);
 605        cdns3_exit_roles(cdns);
 606        usb_role_switch_unregister(cdns->role_sw);
 607        set_phy_power_off(cdns);
 608        phy_exit(cdns->usb2_phy);
 609        phy_exit(cdns->usb3_phy);
 610        return 0;
 611}
 612
 613#ifdef CONFIG_PM
 614
 615static int cdns3_set_platform_suspend(struct device *dev,
 616                bool suspend, bool wakeup)
 617{
 618        struct cdns3 *cdns = dev_get_drvdata(dev);
 619        int ret = 0;
 620
 621        if (cdns->pdata && cdns->pdata->platform_suspend)
 622                ret = cdns->pdata->platform_suspend(dev, suspend, wakeup);
 623
 624        return ret;
 625}
 626
 627static int cdns3_controller_suspend(struct device *dev, pm_message_t msg)
 628{
 629        struct cdns3 *cdns = dev_get_drvdata(dev);
 630        bool wakeup;
 631        unsigned long flags;
 632
 633        if (cdns->in_lpm)
 634                return 0;
 635
 636        if (PMSG_IS_AUTO(msg))
 637                wakeup = true;
 638        else
 639                wakeup = device_may_wakeup(dev);
 640
 641        cdns3_set_platform_suspend(cdns->dev, true, wakeup);
 642        set_phy_power_off(cdns);
 643        spin_lock_irqsave(&cdns->lock, flags);
 644        cdns->in_lpm = true;
 645        spin_unlock_irqrestore(&cdns->lock, flags);
 646        dev_dbg(cdns->dev, "%s ends\n", __func__);
 647
 648        return 0;
 649}
 650
 651static int cdns3_controller_resume(struct device *dev, pm_message_t msg)
 652{
 653        struct cdns3 *cdns = dev_get_drvdata(dev);
 654        int ret;
 655        unsigned long flags;
 656
 657        if (!cdns->in_lpm)
 658                return 0;
 659
 660        ret = set_phy_power_on(cdns);
 661        if (ret)
 662                return ret;
 663
 664        cdns3_set_platform_suspend(cdns->dev, false, false);
 665
 666        spin_lock_irqsave(&cdns->lock, flags);
 667        if (cdns->roles[cdns->role]->resume && !PMSG_IS_AUTO(msg))
 668                cdns->roles[cdns->role]->resume(cdns, false);
 669
 670        cdns->in_lpm = false;
 671        spin_unlock_irqrestore(&cdns->lock, flags);
 672        if (cdns->wakeup_pending) {
 673                cdns->wakeup_pending = false;
 674                enable_irq(cdns->wakeup_irq);
 675        }
 676        dev_dbg(cdns->dev, "%s ends\n", __func__);
 677
 678        return ret;
 679}
 680
 681static int cdns3_runtime_suspend(struct device *dev)
 682{
 683        return cdns3_controller_suspend(dev, PMSG_AUTO_SUSPEND);
 684}
 685
 686static int cdns3_runtime_resume(struct device *dev)
 687{
 688        return cdns3_controller_resume(dev, PMSG_AUTO_RESUME);
 689}
 690#ifdef CONFIG_PM_SLEEP
 691
 692static int cdns3_suspend(struct device *dev)
 693{
 694        struct cdns3 *cdns = dev_get_drvdata(dev);
 695        unsigned long flags;
 696
 697        if (pm_runtime_status_suspended(dev))
 698                pm_runtime_resume(dev);
 699
 700        if (cdns->roles[cdns->role]->suspend) {
 701                spin_lock_irqsave(&cdns->lock, flags);
 702                cdns->roles[cdns->role]->suspend(cdns, false);
 703                spin_unlock_irqrestore(&cdns->lock, flags);
 704        }
 705
 706        return cdns3_controller_suspend(dev, PMSG_SUSPEND);
 707}
 708
 709static int cdns3_resume(struct device *dev)
 710{
 711        int ret;
 712
 713        ret = cdns3_controller_resume(dev, PMSG_RESUME);
 714        if (ret)
 715                return ret;
 716
 717        pm_runtime_disable(dev);
 718        pm_runtime_set_active(dev);
 719        pm_runtime_enable(dev);
 720
 721        return ret;
 722}
 723#endif /* CONFIG_PM_SLEEP */
 724#endif /* CONFIG_PM */
 725
 726static const struct dev_pm_ops cdns3_pm_ops = {
 727        SET_SYSTEM_SLEEP_PM_OPS(cdns3_suspend, cdns3_resume)
 728        SET_RUNTIME_PM_OPS(cdns3_runtime_suspend, cdns3_runtime_resume, NULL)
 729};
 730
 731#ifdef CONFIG_OF
 732static const struct of_device_id of_cdns3_match[] = {
 733        { .compatible = "cdns,usb3" },
 734        { },
 735};
 736MODULE_DEVICE_TABLE(of, of_cdns3_match);
 737#endif
 738
 739static struct platform_driver cdns3_driver = {
 740        .probe          = cdns3_probe,
 741        .remove         = cdns3_remove,
 742        .driver         = {
 743                .name   = "cdns-usb3",
 744                .of_match_table = of_match_ptr(of_cdns3_match),
 745                .pm     = &cdns3_pm_ops,
 746        },
 747};
 748
 749module_platform_driver(cdns3_driver);
 750
 751MODULE_ALIAS("platform:cdns3");
 752MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>");
 753MODULE_LICENSE("GPL v2");
 754MODULE_DESCRIPTION("Cadence USB3 DRD Controller Driver");
 755