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