| .. | .. |
|---|
| 43 | 43 | #define EHCI_MAX_CLKS 4 |
|---|
| 44 | 44 | #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) |
|---|
| 45 | 45 | |
|---|
| 46 | +#define BCM_USB_FIFO_THRESHOLD 0x00800040 |
|---|
| 47 | +#define bcm_iproc_insnreg01 hostpc[0] |
|---|
| 48 | + |
|---|
| 46 | 49 | struct ehci_platform_priv { |
|---|
| 47 | 50 | struct clk *clks[EHCI_MAX_CLKS]; |
|---|
| 48 | 51 | struct reset_control *rsts; |
|---|
| .. | .. |
|---|
| 66 | 69 | ehci_writel(ehci, portsc, status_reg); |
|---|
| 67 | 70 | } |
|---|
| 68 | 71 | |
|---|
| 69 | | -static void ehci_rockchip_usic_init(struct usb_hcd *hcd) |
|---|
| 72 | +#define USIC_MICROFRAME_OFFSET 0x90 |
|---|
| 73 | +#define USIC_SCALE_DOWN_OFFSET 0xa0 |
|---|
| 74 | +#define USIC_ENABLE_OFFSET 0xb0 |
|---|
| 75 | +#define USIC_ENABLE BIT(0) |
|---|
| 76 | +#define USIC_SCALE_DOWN BIT(2) |
|---|
| 77 | +#define USIC_MICROFRAME_COUNT 0x1d4d |
|---|
| 78 | + |
|---|
| 79 | +static void ehci_usic_init(struct usb_hcd *hcd) |
|---|
| 70 | 80 | { |
|---|
| 71 | 81 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
|---|
| 72 | 82 | |
|---|
| .. | .. |
|---|
| 100 | 110 | |
|---|
| 101 | 111 | if (pdata->no_io_watchdog) |
|---|
| 102 | 112 | ehci->need_io_watchdog = 0; |
|---|
| 113 | + |
|---|
| 114 | + if (of_device_is_compatible(pdev->dev.of_node, "brcm,xgs-iproc-ehci")) |
|---|
| 115 | + ehci_writel(ehci, BCM_USB_FIFO_THRESHOLD, |
|---|
| 116 | + &ehci->regs->bcm_iproc_insnreg01); |
|---|
| 117 | + |
|---|
| 103 | 118 | return 0; |
|---|
| 104 | 119 | } |
|---|
| 105 | 120 | |
|---|
| .. | .. |
|---|
| 261 | 276 | struct ehci_platform_priv *priv; |
|---|
| 262 | 277 | struct ehci_hcd *ehci; |
|---|
| 263 | 278 | int err, irq, clk = 0; |
|---|
| 279 | + struct device *companion_dev; |
|---|
| 280 | + struct device_link *link; |
|---|
| 264 | 281 | |
|---|
| 265 | 282 | if (usb_disabled()) |
|---|
| 266 | 283 | return -ENODEV; |
|---|
| .. | .. |
|---|
| 280 | 297 | } |
|---|
| 281 | 298 | |
|---|
| 282 | 299 | irq = platform_get_irq(dev, 0); |
|---|
| 283 | | - if (irq < 0) { |
|---|
| 284 | | - dev_err(&dev->dev, "no irq provided"); |
|---|
| 300 | + if (irq < 0) |
|---|
| 285 | 301 | return irq; |
|---|
| 286 | | - } |
|---|
| 287 | 302 | |
|---|
| 288 | 303 | hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, |
|---|
| 289 | 304 | dev_name(&dev->dev)); |
|---|
| .. | .. |
|---|
| 324 | 339 | |
|---|
| 325 | 340 | if (of_machine_is_compatible("rockchip,rk3288") && |
|---|
| 326 | 341 | of_property_read_bool(dev->dev.of_node, |
|---|
| 327 | | - "rockchip-relinquish-port")) { |
|---|
| 342 | + "rockchip-relinquish-port")) |
|---|
| 328 | 343 | ehci_platform_hc_driver.relinquish_port = |
|---|
| 329 | 344 | ehci_rockchip_relinquish_port; |
|---|
| 330 | | - hcd->rk3288_relinquish_port_quirk = 1; |
|---|
| 331 | | - } |
|---|
| 332 | | - |
|---|
| 333 | | - if (of_property_read_bool(dev->dev.of_node, |
|---|
| 334 | | - "rockchip-has-usic")) |
|---|
| 335 | | - ehci->has_usic = 1; |
|---|
| 336 | 345 | |
|---|
| 337 | 346 | for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { |
|---|
| 338 | 347 | priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); |
|---|
| .. | .. |
|---|
| 404 | 413 | if (err) |
|---|
| 405 | 414 | goto err_power; |
|---|
| 406 | 415 | |
|---|
| 407 | | - if (ehci->has_usic) |
|---|
| 408 | | - ehci_rockchip_usic_init(hcd); |
|---|
| 416 | + if (of_usb_get_phy_mode(dev->dev.of_node) == USBPHY_INTERFACE_MODE_HSIC) |
|---|
| 417 | + ehci_usic_init(hcd); |
|---|
| 418 | + |
|---|
| 419 | + if (of_device_is_compatible(dev->dev.of_node, |
|---|
| 420 | + "rockchip,rk3588-ehci")) { |
|---|
| 421 | + companion_dev = usb_of_get_companion_dev(hcd->self.controller); |
|---|
| 422 | + if (companion_dev) { |
|---|
| 423 | + link = device_link_add(companion_dev, hcd->self.controller, |
|---|
| 424 | + DL_FLAG_STATELESS); |
|---|
| 425 | + put_device(companion_dev); |
|---|
| 426 | + if (!link) { |
|---|
| 427 | + dev_err(&dev->dev, "Unable to link %s\n", |
|---|
| 428 | + dev_name(companion_dev)); |
|---|
| 429 | + err = -EINVAL; |
|---|
| 430 | + goto err_power; |
|---|
| 431 | + } |
|---|
| 432 | + } |
|---|
| 433 | + } |
|---|
| 409 | 434 | |
|---|
| 410 | 435 | device_wakeup_enable(hcd->self.controller); |
|---|
| 411 | 436 | device_enable_async_suspend(hcd->self.controller); |
|---|
| .. | .. |
|---|
| 440 | 465 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
|---|
| 441 | 466 | struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); |
|---|
| 442 | 467 | struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); |
|---|
| 468 | + struct device *companion_dev; |
|---|
| 443 | 469 | int clk; |
|---|
| 444 | 470 | |
|---|
| 445 | 471 | if (priv->quirk_poll) |
|---|
| 446 | 472 | quirk_poll_end(priv); |
|---|
| 473 | + |
|---|
| 474 | + if (of_device_is_compatible(dev->dev.of_node, |
|---|
| 475 | + "rockchip,rk3588-ehci")) { |
|---|
| 476 | + companion_dev = usb_of_get_companion_dev(hcd->self.controller); |
|---|
| 477 | + if (companion_dev) { |
|---|
| 478 | + device_link_remove(companion_dev, hcd->self.controller); |
|---|
| 479 | + put_device(companion_dev); |
|---|
| 480 | + } |
|---|
| 481 | + } |
|---|
| 447 | 482 | |
|---|
| 448 | 483 | usb_remove_hcd(hcd); |
|---|
| 449 | 484 | |
|---|
| .. | .. |
|---|
| 466 | 501 | return 0; |
|---|
| 467 | 502 | } |
|---|
| 468 | 503 | |
|---|
| 469 | | -#ifdef CONFIG_PM_SLEEP |
|---|
| 470 | | -static int ehci_platform_suspend(struct device *dev) |
|---|
| 504 | +static int __maybe_unused ehci_platform_suspend(struct device *dev) |
|---|
| 471 | 505 | { |
|---|
| 472 | 506 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
|---|
| 473 | 507 | struct usb_ehci_pdata *pdata = dev_get_platdata(dev); |
|---|
| .. | .. |
|---|
| 489 | 523 | return ret; |
|---|
| 490 | 524 | } |
|---|
| 491 | 525 | |
|---|
| 492 | | -static int ehci_platform_resume(struct device *dev) |
|---|
| 526 | +static int __maybe_unused ehci_platform_resume(struct device *dev) |
|---|
| 493 | 527 | { |
|---|
| 494 | 528 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
|---|
| 495 | 529 | struct usb_ehci_pdata *pdata = dev_get_platdata(dev); |
|---|
| .. | .. |
|---|
| 505 | 539 | |
|---|
| 506 | 540 | companion_dev = usb_of_get_companion_dev(hcd->self.controller); |
|---|
| 507 | 541 | if (companion_dev) { |
|---|
| 508 | | - device_pm_wait_for_dev(hcd->self.controller, companion_dev); |
|---|
| 542 | + if (!device_is_dependent(hcd->self.controller, companion_dev)) |
|---|
| 543 | + device_pm_wait_for_dev(hcd->self.controller, companion_dev); |
|---|
| 509 | 544 | put_device(companion_dev); |
|---|
| 510 | 545 | } |
|---|
| 511 | 546 | |
|---|
| 512 | 547 | ehci_resume(hcd, priv->reset_on_resume); |
|---|
| 548 | + |
|---|
| 549 | + pm_runtime_disable(dev); |
|---|
| 550 | + pm_runtime_set_active(dev); |
|---|
| 551 | + pm_runtime_enable(dev); |
|---|
| 513 | 552 | |
|---|
| 514 | 553 | if (priv->quirk_poll) |
|---|
| 515 | 554 | quirk_poll_init(priv); |
|---|
| 516 | 555 | |
|---|
| 517 | 556 | return 0; |
|---|
| 518 | 557 | } |
|---|
| 519 | | -#endif /* CONFIG_PM_SLEEP */ |
|---|
| 520 | 558 | |
|---|
| 521 | 559 | static const struct of_device_id vt8500_ehci_ids[] = { |
|---|
| 522 | 560 | { .compatible = "via,vt8500-ehci", }, |
|---|
| .. | .. |
|---|
| 527 | 565 | }; |
|---|
| 528 | 566 | MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); |
|---|
| 529 | 567 | |
|---|
| 568 | +#ifdef CONFIG_ACPI |
|---|
| 530 | 569 | static const struct acpi_device_id ehci_acpi_match[] = { |
|---|
| 531 | 570 | { "PNP0D20", 0 }, /* EHCI controller without debug */ |
|---|
| 532 | 571 | { } |
|---|
| 533 | 572 | }; |
|---|
| 534 | 573 | MODULE_DEVICE_TABLE(acpi, ehci_acpi_match); |
|---|
| 574 | +#endif |
|---|
| 535 | 575 | |
|---|
| 536 | 576 | static const struct platform_device_id ehci_platform_table[] = { |
|---|
| 537 | 577 | { "ehci-platform", 0 }, |
|---|
| .. | .. |
|---|
| 549 | 589 | .shutdown = usb_hcd_platform_shutdown, |
|---|
| 550 | 590 | .driver = { |
|---|
| 551 | 591 | .name = "ehci-platform", |
|---|
| 552 | | - .pm = &ehci_platform_pm_ops, |
|---|
| 592 | + .pm = pm_ptr(&ehci_platform_pm_ops), |
|---|
| 553 | 593 | .of_match_table = vt8500_ehci_ids, |
|---|
| 554 | 594 | .acpi_match_table = ACPI_PTR(ehci_acpi_match), |
|---|
| 555 | 595 | } |
|---|