| .. | .. |
|---|
| 73 | 73 | #include <linux/prefetch.h> |
|---|
| 74 | 74 | #include <linux/platform_device.h> |
|---|
| 75 | 75 | #include <linux/io.h> |
|---|
| 76 | +#include <linux/iopoll.h> |
|---|
| 76 | 77 | #include <linux/dma-mapping.h> |
|---|
| 77 | 78 | #include <linux/usb.h> |
|---|
| 78 | 79 | #include <linux/usb/of.h> |
|---|
| .. | .. |
|---|
| 452 | 453 | return hw_ep->musb->io.write_fifo(hw_ep, len, src); |
|---|
| 453 | 454 | } |
|---|
| 454 | 455 | |
|---|
| 456 | +static u8 musb_read_devctl(struct musb *musb) |
|---|
| 457 | +{ |
|---|
| 458 | + return musb_readb(musb->mregs, MUSB_DEVCTL); |
|---|
| 459 | +} |
|---|
| 460 | + |
|---|
| 461 | +/** |
|---|
| 462 | + * musb_set_host - set and initialize host mode |
|---|
| 463 | + * @musb: musb controller driver data |
|---|
| 464 | + * |
|---|
| 465 | + * At least some musb revisions need to enable devctl session bit in |
|---|
| 466 | + * peripheral mode to switch to host mode. Initializes things to host |
|---|
| 467 | + * mode and sets A_IDLE. SoC glue needs to advance state further |
|---|
| 468 | + * based on phy provided VBUS state. |
|---|
| 469 | + * |
|---|
| 470 | + * Note that the SoC glue code may need to wait for musb to settle |
|---|
| 471 | + * on enable before calling this to avoid babble. |
|---|
| 472 | + */ |
|---|
| 473 | +int musb_set_host(struct musb *musb) |
|---|
| 474 | +{ |
|---|
| 475 | + int error = 0; |
|---|
| 476 | + u8 devctl; |
|---|
| 477 | + |
|---|
| 478 | + if (!musb) |
|---|
| 479 | + return -EINVAL; |
|---|
| 480 | + |
|---|
| 481 | + devctl = musb_read_devctl(musb); |
|---|
| 482 | + if (!(devctl & MUSB_DEVCTL_BDEVICE)) { |
|---|
| 483 | + dev_info(musb->controller, |
|---|
| 484 | + "%s: already in host mode: %02x\n", |
|---|
| 485 | + __func__, devctl); |
|---|
| 486 | + goto init_data; |
|---|
| 487 | + } |
|---|
| 488 | + |
|---|
| 489 | + devctl |= MUSB_DEVCTL_SESSION; |
|---|
| 490 | + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
|---|
| 491 | + |
|---|
| 492 | + error = readx_poll_timeout(musb_read_devctl, musb, devctl, |
|---|
| 493 | + !(devctl & MUSB_DEVCTL_BDEVICE), 5000, |
|---|
| 494 | + 1000000); |
|---|
| 495 | + if (error) { |
|---|
| 496 | + dev_err(musb->controller, "%s: could not set host: %02x\n", |
|---|
| 497 | + __func__, devctl); |
|---|
| 498 | + |
|---|
| 499 | + return error; |
|---|
| 500 | + } |
|---|
| 501 | + |
|---|
| 502 | +init_data: |
|---|
| 503 | + musb->is_active = 1; |
|---|
| 504 | + musb->xceiv->otg->state = OTG_STATE_A_IDLE; |
|---|
| 505 | + MUSB_HST_MODE(musb); |
|---|
| 506 | + |
|---|
| 507 | + return error; |
|---|
| 508 | +} |
|---|
| 509 | +EXPORT_SYMBOL_GPL(musb_set_host); |
|---|
| 510 | + |
|---|
| 511 | +/** |
|---|
| 512 | + * musb_set_peripheral - set and initialize peripheral mode |
|---|
| 513 | + * @musb: musb controller driver data |
|---|
| 514 | + * |
|---|
| 515 | + * Clears devctl session bit and initializes things for peripheral |
|---|
| 516 | + * mode and sets B_IDLE. SoC glue needs to advance state further |
|---|
| 517 | + * based on phy provided VBUS state. |
|---|
| 518 | + */ |
|---|
| 519 | +int musb_set_peripheral(struct musb *musb) |
|---|
| 520 | +{ |
|---|
| 521 | + int error = 0; |
|---|
| 522 | + u8 devctl; |
|---|
| 523 | + |
|---|
| 524 | + if (!musb) |
|---|
| 525 | + return -EINVAL; |
|---|
| 526 | + |
|---|
| 527 | + devctl = musb_read_devctl(musb); |
|---|
| 528 | + if (devctl & MUSB_DEVCTL_BDEVICE) { |
|---|
| 529 | + dev_info(musb->controller, |
|---|
| 530 | + "%s: already in peripheral mode: %02x\n", |
|---|
| 531 | + __func__, devctl); |
|---|
| 532 | + |
|---|
| 533 | + goto init_data; |
|---|
| 534 | + } |
|---|
| 535 | + |
|---|
| 536 | + devctl &= ~MUSB_DEVCTL_SESSION; |
|---|
| 537 | + musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
|---|
| 538 | + |
|---|
| 539 | + error = readx_poll_timeout(musb_read_devctl, musb, devctl, |
|---|
| 540 | + devctl & MUSB_DEVCTL_BDEVICE, 5000, |
|---|
| 541 | + 1000000); |
|---|
| 542 | + if (error) { |
|---|
| 543 | + dev_err(musb->controller, "%s: could not set peripheral: %02x\n", |
|---|
| 544 | + __func__, devctl); |
|---|
| 545 | + |
|---|
| 546 | + return error; |
|---|
| 547 | + } |
|---|
| 548 | + |
|---|
| 549 | +init_data: |
|---|
| 550 | + musb->is_active = 0; |
|---|
| 551 | + musb->xceiv->otg->state = OTG_STATE_B_IDLE; |
|---|
| 552 | + MUSB_DEV_MODE(musb); |
|---|
| 553 | + |
|---|
| 554 | + return error; |
|---|
| 555 | +} |
|---|
| 556 | +EXPORT_SYMBOL_GPL(musb_set_peripheral); |
|---|
| 557 | + |
|---|
| 455 | 558 | /*-------------------------------------------------------------------------*/ |
|---|
| 456 | 559 | |
|---|
| 457 | 560 | /* for high speed test mode; see USB 2.0 spec 7.1.20 */ |
|---|
| .. | .. |
|---|
| 749 | 852 | case OTG_STATE_B_IDLE: |
|---|
| 750 | 853 | if (!musb->is_active) |
|---|
| 751 | 854 | break; |
|---|
| 752 | | - /* fall through */ |
|---|
| 855 | + fallthrough; |
|---|
| 753 | 856 | case OTG_STATE_B_PERIPHERAL: |
|---|
| 754 | 857 | musb_g_suspend(musb); |
|---|
| 755 | 858 | musb->is_active = musb->g.b_hnp_enable; |
|---|
| .. | .. |
|---|
| 869 | 972 | case OTG_STATE_A_PERIPHERAL: |
|---|
| 870 | 973 | musb_hnp_stop(musb); |
|---|
| 871 | 974 | musb_root_disconnect(musb); |
|---|
| 872 | | - /* FALLTHROUGH */ |
|---|
| 975 | + fallthrough; |
|---|
| 873 | 976 | case OTG_STATE_B_WAIT_ACON: |
|---|
| 874 | | - /* FALLTHROUGH */ |
|---|
| 875 | 977 | case OTG_STATE_B_PERIPHERAL: |
|---|
| 876 | 978 | case OTG_STATE_B_IDLE: |
|---|
| 877 | 979 | musb_g_disconnect(musb); |
|---|
| .. | .. |
|---|
| 906 | 1008 | switch (musb->xceiv->otg->state) { |
|---|
| 907 | 1009 | case OTG_STATE_A_SUSPEND: |
|---|
| 908 | 1010 | musb_g_reset(musb); |
|---|
| 909 | | - /* FALLTHROUGH */ |
|---|
| 1011 | + fallthrough; |
|---|
| 910 | 1012 | case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ |
|---|
| 911 | 1013 | /* never use invalid T(a_wait_bcon) */ |
|---|
| 912 | 1014 | musb_dbg(musb, "HNP: in %s, %d msec timeout", |
|---|
| .. | .. |
|---|
| 927 | 1029 | break; |
|---|
| 928 | 1030 | case OTG_STATE_B_IDLE: |
|---|
| 929 | 1031 | musb->xceiv->otg->state = OTG_STATE_B_PERIPHERAL; |
|---|
| 930 | | - /* FALLTHROUGH */ |
|---|
| 1032 | + fallthrough; |
|---|
| 931 | 1033 | case OTG_STATE_B_PERIPHERAL: |
|---|
| 932 | 1034 | musb_g_reset(musb); |
|---|
| 933 | 1035 | break; |
|---|
| .. | .. |
|---|
| 947 | 1049 | * @param musb instance pointer |
|---|
| 948 | 1050 | * @param int_usb register contents |
|---|
| 949 | 1051 | * @param devctl |
|---|
| 950 | | - * @param power |
|---|
| 951 | 1052 | */ |
|---|
| 952 | 1053 | |
|---|
| 953 | 1054 | static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, |
|---|
| .. | .. |
|---|
| 1369 | 1470 | switch (fifo_mode) { |
|---|
| 1370 | 1471 | default: |
|---|
| 1371 | 1472 | fifo_mode = 0; |
|---|
| 1372 | | - /* FALLTHROUGH */ |
|---|
| 1473 | + fallthrough; |
|---|
| 1373 | 1474 | case 0: |
|---|
| 1374 | 1475 | cfg = mode_0_cfg; |
|---|
| 1375 | 1476 | n = ARRAY_SIZE(mode_0_cfg); |
|---|
| .. | .. |
|---|
| 1534 | 1635 | } else { |
|---|
| 1535 | 1636 | musb->is_multipoint = 0; |
|---|
| 1536 | 1637 | type = ""; |
|---|
| 1537 | | -#ifndef CONFIG_USB_OTG_BLACKLIST_HUB |
|---|
| 1538 | | - pr_err("%s: kernel must blacklist external hubs\n", |
|---|
| 1539 | | - musb_driver_name); |
|---|
| 1540 | | -#endif |
|---|
| 1638 | + if (IS_ENABLED(CONFIG_USB) && |
|---|
| 1639 | + !IS_ENABLED(CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB)) { |
|---|
| 1640 | + pr_err("%s: kernel must disable external hubs, please fix the configuration\n", |
|---|
| 1641 | + musb_driver_name); |
|---|
| 1642 | + } |
|---|
| 1541 | 1643 | } |
|---|
| 1542 | 1644 | |
|---|
| 1543 | 1645 | /* log release info */ |
|---|
| .. | .. |
|---|
| 1692 | 1794 | EXPORT_SYMBOL_GPL(musb_interrupt); |
|---|
| 1693 | 1795 | |
|---|
| 1694 | 1796 | #ifndef CONFIG_MUSB_PIO_ONLY |
|---|
| 1695 | | -static bool use_dma = 1; |
|---|
| 1797 | +static bool use_dma = true; |
|---|
| 1696 | 1798 | |
|---|
| 1697 | 1799 | /* "modprobe ... use_dma=0" etc */ |
|---|
| 1698 | 1800 | module_param(use_dma, bool, 0644); |
|---|
| .. | .. |
|---|
| 1757 | 1859 | { |
|---|
| 1758 | 1860 | struct musb *musb = dev_to_musb(dev); |
|---|
| 1759 | 1861 | unsigned long flags; |
|---|
| 1760 | | - int ret = -EINVAL; |
|---|
| 1862 | + int ret; |
|---|
| 1761 | 1863 | |
|---|
| 1762 | 1864 | spin_lock_irqsave(&musb->lock, flags); |
|---|
| 1763 | 1865 | ret = sprintf(buf, "%s\n", usb_otg_state_string(musb->xceiv->otg->state)); |
|---|
| .. | .. |
|---|
| 1865 | 1967 | } |
|---|
| 1866 | 1968 | static DEVICE_ATTR_WO(srp); |
|---|
| 1867 | 1969 | |
|---|
| 1868 | | -static struct attribute *musb_attributes[] = { |
|---|
| 1970 | +static struct attribute *musb_attrs[] = { |
|---|
| 1869 | 1971 | &dev_attr_mode.attr, |
|---|
| 1870 | 1972 | &dev_attr_vbus.attr, |
|---|
| 1871 | 1973 | &dev_attr_srp.attr, |
|---|
| 1872 | 1974 | NULL |
|---|
| 1873 | 1975 | }; |
|---|
| 1874 | | - |
|---|
| 1875 | | -static const struct attribute_group musb_attr_group = { |
|---|
| 1876 | | - .attrs = musb_attributes, |
|---|
| 1877 | | -}; |
|---|
| 1976 | +ATTRIBUTE_GROUPS(musb); |
|---|
| 1878 | 1977 | |
|---|
| 1879 | 1978 | #define MUSB_QUIRK_B_INVALID_VBUS_91 (MUSB_DEVCTL_BDEVICE | \ |
|---|
| 1880 | 1979 | (2 << MUSB_DEVCTL_VBUS_SHIFT) | \ |
|---|
| .. | .. |
|---|
| 1910 | 2009 | schedule_delayed_work(&musb->irq_work, |
|---|
| 1911 | 2010 | msecs_to_jiffies(1000)); |
|---|
| 1912 | 2011 | musb->quirk_retries--; |
|---|
| 1913 | | - break; |
|---|
| 1914 | 2012 | } |
|---|
| 1915 | | - /* fall through */ |
|---|
| 2013 | + break; |
|---|
| 1916 | 2014 | case MUSB_QUIRK_B_INVALID_VBUS_91: |
|---|
| 1917 | 2015 | if (musb->quirk_retries && !musb->flush_irq_work) { |
|---|
| 1918 | 2016 | musb_dbg(musb, |
|---|
| .. | .. |
|---|
| 1922 | 2020 | musb->quirk_retries--; |
|---|
| 1923 | 2021 | return; |
|---|
| 1924 | 2022 | } |
|---|
| 1925 | | - /* fall through */ |
|---|
| 2023 | + fallthrough; |
|---|
| 1926 | 2024 | case MUSB_QUIRK_A_DISCONNECT_19: |
|---|
| 1927 | 2025 | if (musb->quirk_retries && !musb->flush_irq_work) { |
|---|
| 1928 | 2026 | musb_dbg(musb, |
|---|
| .. | .. |
|---|
| 1971 | 2069 | struct musb *musb = container_of(data, struct musb, irq_work.work); |
|---|
| 1972 | 2070 | int error; |
|---|
| 1973 | 2071 | |
|---|
| 1974 | | - error = pm_runtime_get_sync(musb->controller); |
|---|
| 2072 | + error = pm_runtime_resume_and_get(musb->controller); |
|---|
| 1975 | 2073 | if (error < 0) { |
|---|
| 1976 | 2074 | dev_err(musb->controller, "Could not enable: %i\n", error); |
|---|
| 1977 | 2075 | |
|---|
| .. | .. |
|---|
| 2085 | 2183 | * probe(), where things may be partially set up, as well as rmmod |
|---|
| 2086 | 2184 | * cleanup after everything's been de-activated. |
|---|
| 2087 | 2185 | */ |
|---|
| 2088 | | - |
|---|
| 2089 | | -#ifdef CONFIG_SYSFS |
|---|
| 2090 | | - sysfs_remove_group(&musb->controller->kobj, &musb_attr_group); |
|---|
| 2091 | | -#endif |
|---|
| 2092 | 2186 | |
|---|
| 2093 | 2187 | if (musb->nIrq >= 0) { |
|---|
| 2094 | 2188 | if (musb->irq_wake) |
|---|
| .. | .. |
|---|
| 2463 | 2557 | |
|---|
| 2464 | 2558 | musb_init_debugfs(musb); |
|---|
| 2465 | 2559 | |
|---|
| 2466 | | - status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); |
|---|
| 2467 | | - if (status) |
|---|
| 2468 | | - goto fail5; |
|---|
| 2469 | | - |
|---|
| 2470 | 2560 | musb->is_initialized = 1; |
|---|
| 2471 | 2561 | pm_runtime_mark_last_busy(musb->controller); |
|---|
| 2472 | 2562 | pm_runtime_put_autosuspend(musb->controller); |
|---|
| 2473 | 2563 | |
|---|
| 2474 | 2564 | return 0; |
|---|
| 2475 | | - |
|---|
| 2476 | | -fail5: |
|---|
| 2477 | | - musb_exit_debugfs(musb); |
|---|
| 2478 | | - |
|---|
| 2479 | | - musb_gadget_cleanup(musb); |
|---|
| 2480 | | - musb_host_cleanup(musb); |
|---|
| 2481 | 2565 | |
|---|
| 2482 | 2566 | fail3: |
|---|
| 2483 | 2567 | cancel_delayed_work_sync(&musb->irq_work); |
|---|
| .. | .. |
|---|
| 2521 | 2605 | { |
|---|
| 2522 | 2606 | struct device *dev = &pdev->dev; |
|---|
| 2523 | 2607 | int irq = platform_get_irq_byname(pdev, "mc"); |
|---|
| 2524 | | - struct resource *iomem; |
|---|
| 2525 | 2608 | void __iomem *base; |
|---|
| 2526 | 2609 | |
|---|
| 2527 | 2610 | if (irq <= 0) |
|---|
| 2528 | 2611 | return -ENODEV; |
|---|
| 2529 | 2612 | |
|---|
| 2530 | | - iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 2531 | | - base = devm_ioremap_resource(dev, iomem); |
|---|
| 2613 | + base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 2532 | 2614 | if (IS_ERR(base)) |
|---|
| 2533 | 2615 | return PTR_ERR(base); |
|---|
| 2534 | 2616 | |
|---|
| .. | .. |
|---|
| 2875 | 2957 | |
|---|
| 2876 | 2958 | static struct platform_driver musb_driver = { |
|---|
| 2877 | 2959 | .driver = { |
|---|
| 2878 | | - .name = (char *)musb_driver_name, |
|---|
| 2960 | + .name = musb_driver_name, |
|---|
| 2879 | 2961 | .bus = &platform_bus_type, |
|---|
| 2880 | 2962 | .pm = MUSB_DEV_PM_OPS, |
|---|
| 2963 | + .dev_groups = musb_groups, |
|---|
| 2881 | 2964 | }, |
|---|
| 2882 | 2965 | .probe = musb_probe, |
|---|
| 2883 | 2966 | .remove = musb_remove, |
|---|