diff options
Diffstat (limited to 'drivers/usb')
85 files changed, 700 insertions, 526 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 70e6c956c23c..e4b27413f528 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB device configuration # diff --git a/drivers/usb/README b/drivers/usb/README deleted file mode 100644 index 2144e7dbfa41..000000000000 --- a/drivers/usb/README +++ /dev/null @@ -1,54 +0,0 @@ -To understand all the Linux-USB framework, you'll use these resources: - - * This source code. This is necessarily an evolving work, and - includes kerneldoc that should help you get a current overview. - ("make pdfdocs", and then look at "usb.pdf" for host side and - "gadget.pdf" for peripheral side.) Also, Documentation/usb has - more information. - - * The USB 2.0 specification (from www.usb.org), with supplements - such as those for USB OTG and the various device classes. - The USB specification has a good overview chapter, and USB - peripherals conform to the widely known "Chapter 9". - - * Chip specifications for USB controllers. Examples include - host controllers (on PCs, servers, and more); peripheral - controllers (in devices with Linux firmware, like printers or - cell phones); and hard-wired peripherals like Ethernet adapters. - - * Specifications for other protocols implemented by USB peripheral - functions. Some are vendor-specific; others are vendor-neutral - but just standardized outside of the www.usb.org team. - -Here is a list of what each subdirectory here is, and what is contained in -them. - -core/ - This is for the core USB host code, including the - usbfs files and the hub class driver ("hub_wq"). - -host/ - This is for USB host controller drivers. This - includes UHCI, OHCI, EHCI, and others that might - be used with more specialized "embedded" systems. - -gadget/ - This is for USB peripheral controller drivers and - the various gadget drivers which talk to them. - - -Individual USB driver directories. A new driver should be added to the -first subdirectory in the list below that it fits into. - -image/ - This is for still image drivers, like scanners or - digital cameras. -../input/ - This is for any driver that uses the input subsystem, - like keyboard, mice, touchscreens, tablets, etc. -../media/ - This is for multimedia drivers, like video cameras, - radios, and any other drivers that talk to the v4l - subsystem. -../net/ - This is for network drivers. -serial/ - This is for USB to serial drivers. -storage/ - This is for USB mass-storage drivers. -class/ - This is for all USB device drivers that do not fit - into any of the above categories, and work for a range - of USB Class specified devices. -misc/ - This is for all USB device drivers that do not fit - into any of the above categories. diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index 0f922942a07a..989aaa3b080d 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB/ATM DSL configuration # diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index ee34e9046f7e..eb37ebfcb123 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_CHIPIDEA tristate "ChipIdea Highspeed Dual Role Controller" depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 971385fe9abc..52f3a531a82f 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Class driver configuration # diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 4d75d9a80001..4453e10b9dbb 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Core configuration # diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 7b5cb28ffb35..7bb6b1bd06c8 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -800,13 +800,11 @@ int usb_get_configuration(struct usb_device *dev) { struct device *ddev = &dev->dev; int ncfg = dev->descriptor.bNumConfigurations; - int result = 0; + int result = -ENOMEM; unsigned int cfgno, length; unsigned char *bigbuffer; struct usb_config_descriptor *desc; - cfgno = 0; - result = -ENOMEM; if (ncfg > USB_MAXCONFIG) { dev_warn(ddev, "too many configurations: %d, " "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); @@ -832,8 +830,7 @@ int usb_get_configuration(struct usb_device *dev) if (!desc) goto err2; - result = 0; - for (; cfgno < ncfg; cfgno++) { + for (cfgno = 0; cfgno < ncfg; cfgno++) { /* We grab just the first descriptor so we know how long * the whole configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, @@ -889,7 +886,6 @@ int usb_get_configuration(struct usb_device *dev) goto err; } } - result = 0; err: kfree(desc); diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index d65566341dd1..a12f2ce8df90 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1564,12 +1564,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb } for (totlen = u = 0; u < number_of_packets; u++) { /* - * arbitrary limit need for USB 3.0 - * bMaxBurst (0~15 allowed, 1~16 packets) - * bmAttributes (bit 1:0, mult 0~2, 1~3 packets) - * sizemax: 1024 * 16 * 3 = 49152 + * arbitrary limit need for USB 3.1 Gen2 + * sizemax: 96 DPs at SSP, 96 * 1024 = 98304 */ - if (isopkt[u].length > 49152) { + if (isopkt[u].length > 98304) { ret = -EINVAL; goto error; } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 53564386ed57..8987cec9549d 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1896,14 +1896,11 @@ int usb_runtime_idle(struct device *dev) return -EBUSY; } -int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); int ret = -EPERM; - if (enable && !udev->usb2_hw_lpm_allowed) - return 0; - if (hcd->driver->set_usb2_hw_lpm) { ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); if (!ret) @@ -1913,6 +1910,24 @@ int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) return ret; } +int usb_enable_usb2_hardware_lpm(struct usb_device *udev) +{ + if (!udev->usb2_hw_lpm_capable || + !udev->usb2_hw_lpm_allowed || + udev->usb2_hw_lpm_enabled) + return 0; + + return usb_set_usb2_hardware_lpm(udev, 1); +} + +int usb_disable_usb2_hardware_lpm(struct usb_device *udev) +{ + if (!udev->usb2_hw_lpm_enabled) + return 0; + + return usb_set_usb2_hardware_lpm(udev, 0); +} + #endif /* CONFIG_PM */ struct bus_type usb_bus_type = { diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index f713cecc1f41..1ac9c1e5f773 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -118,6 +118,31 @@ int usb_choose_configuration(struct usb_device *udev) continue; } + /* + * Select first configuration as default for audio so that + * devices that don't comply with UAC3 protocol are supported. + * But, still iterate through other configurations and + * select UAC3 compliant config if present. + */ + if (desc && is_audio(desc)) { + /* Always prefer the first found UAC3 config */ + if (is_uac3_config(desc)) { + best = c; + break; + } + + /* If there is no UAC3 config, prefer the first config */ + else if (i == 0) + best = c; + + /* Unconditional continue, because the rest of the code + * in the loop is irrelevant for audio devices, and + * because it can reassign best, which for audio devices + * we don't want. + */ + continue; + } + /* When the first config's first interface is one of Microsoft's * pet nonstandard Ethernet-over-USB protocols, ignore it unless * this kernel has enabled the necessary host side driver. @@ -132,25 +157,6 @@ int usb_choose_configuration(struct usb_device *udev) #endif } - /* - * Select first configuration as default for audio so that - * devices that don't comply with UAC3 protocol are supported. - * But, still iterate through other configurations and - * select UAC3 compliant config if present. - */ - if (i == 0 && num_configs > 1 && desc && is_audio(desc)) { - best = c; - continue; - } - - if (i > 0 && desc && is_audio(desc)) { - if (is_uac3_config(desc)) { - best = c; - break; - } - continue; - } - /* From the remaining configs, choose the first one whose * first interface is for a non-vendor-specific class. * Reason: Linux is more likely to have a class driver diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 015b126ce455..86f39e44f98a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2736,6 +2736,11 @@ int usb_add_hcd(struct usb_hcd *hcd, if (retval) return retval; + retval = usb_phy_roothub_set_mode(hcd->phy_roothub, + PHY_MODE_USB_HOST_SS); + if (retval) + goto err_usb_phy_roothub_power_on; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1d1e61e980f3..8d4631c81b9f 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -108,6 +108,8 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); static void hub_release(struct kref *kref); static int usb_reset_and_verify_device(struct usb_device *udev); static int hub_port_disable(struct usb_hub *hub, int port1, int set_state); +static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1, + u16 portstatus); static inline char *portspeed(struct usb_hub *hub, int portstatus) { @@ -607,6 +609,36 @@ static int hub_port_status(struct usb_hub *hub, int port1, status, change, NULL); } +static void hub_resubmit_irq_urb(struct usb_hub *hub) +{ + unsigned long flags; + int status; + + spin_lock_irqsave(&hub->irq_urb_lock, flags); + + if (hub->quiescing) { + spin_unlock_irqrestore(&hub->irq_urb_lock, flags); + return; + } + + status = usb_submit_urb(hub->urb, GFP_ATOMIC); + if (status && status != -ENODEV && status != -EPERM && + status != -ESHUTDOWN) { + dev_err(hub->intfdev, "resubmit --> %d\n", status); + mod_timer(&hub->irq_urb_retry, jiffies + HZ); + } + + spin_unlock_irqrestore(&hub->irq_urb_lock, flags); +} + +static void hub_retry_irq_urb(struct timer_list *t) +{ + struct usb_hub *hub = from_timer(hub, t, irq_urb_retry); + + hub_resubmit_irq_urb(hub); +} + + static void kick_hub_wq(struct usb_hub *hub) { struct usb_interface *intf; @@ -709,12 +741,7 @@ static void hub_irq(struct urb *urb) kick_hub_wq(hub); resubmit: - if (hub->quiescing) - return; - - status = usb_submit_urb(hub->urb, GFP_ATOMIC); - if (status != 0 && status != -ENODEV && status != -EPERM) - dev_err(hub->intfdev, "resubmit --> %d\n", status); + hub_resubmit_irq_urb(hub); } /* USB 2.0 spec Section 11.24.2.3 */ @@ -1112,6 +1139,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) USB_PORT_FEAT_ENABLE); } + /* Make sure a warm-reset request is handled by port_event */ + if (type == HUB_RESUME && + hub_port_warm_reset_required(hub, port1, portstatus)) + set_bit(port1, hub->event_bits); + /* * Add debounce if USB3 link is in polling/link training state. * Link will automatically transition to Enabled state after @@ -1264,10 +1296,13 @@ enum hub_quiescing_type { static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) { struct usb_device *hdev = hub->hdev; + unsigned long flags; int i; /* hub_wq and related activity won't re-trigger */ + spin_lock_irqsave(&hub->irq_urb_lock, flags); hub->quiescing = 1; + spin_unlock_irqrestore(&hub->irq_urb_lock, flags); if (type != HUB_SUSPEND) { /* Disconnect all the children */ @@ -1278,6 +1313,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) } /* Stop hub_wq and related activity */ + del_timer_sync(&hub->irq_urb_retry); usb_kill_urb(hub->urb); if (hub->has_indicators) cancel_delayed_work_sync(&hub->leds); @@ -1810,6 +1846,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) INIT_DELAYED_WORK(&hub->leds, led_work); INIT_DELAYED_WORK(&hub->init_work, NULL); INIT_WORK(&hub->events, hub_event); + spin_lock_init(&hub->irq_urb_lock); + timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0); usb_get_intf(intf); usb_get_dev(hdev); @@ -3220,8 +3258,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) } /* disable USB2 hardware LPM */ - if (udev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(udev, 0); + usb_disable_usb2_hardware_lpm(udev); if (usb_disable_ltm(udev)) { dev_err(&udev->dev, "Failed to disable LTM before suspend\n"); @@ -3259,8 +3296,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) usb_enable_ltm(udev); err_ltm: /* Try to enable USB2 hardware LPM again */ - if (udev->usb2_hw_lpm_capable == 1) - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); if (udev->do_remote_wakeup) (void) usb_disable_remote_wakeup(udev); @@ -3543,8 +3579,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) hub_port_logical_disconnect(hub, port1); } else { /* Try to enable USB2 hardware LPM */ - if (udev->usb2_hw_lpm_capable == 1) - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); /* Try to enable USB3 LTM */ usb_enable_ltm(udev); @@ -4435,7 +4470,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { udev->usb2_hw_lpm_allowed = 1; - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); } } @@ -5649,8 +5684,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) /* Disable USB2 hardware LPM. * It will be re-enabled by the enumeration process. */ - if (udev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(udev, 0); + usb_disable_usb2_hardware_lpm(udev); /* Disable LPM while we reset the device and reinstall the alt settings. * Device-initiated LPM, and system exit latency settings are cleared @@ -5753,7 +5787,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) done: /* Now that the alt settings are re-installed, enable LTM and LPM. */ - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); usb_unlocked_enable_lpm(udev); usb_enable_ltm(udev); usb_release_bos_descriptor(udev); diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 4accfb63f7dc..a9e24e4b8df1 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -69,6 +69,8 @@ struct usb_hub { struct delayed_work leds; struct delayed_work init_work; struct work_struct events; + spinlock_t irq_urb_lock; + struct timer_list irq_urb_retry; struct usb_port **ports; }; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index bfa5eda0cc26..4f33eb632a88 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1243,8 +1243,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev->actconfig->interface[i] = NULL; } - if (dev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(dev, 0); + usb_disable_usb2_hardware_lpm(dev); usb_unlocked_disable_lpm(dev); usb_disable_ltm(dev); diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 38b2c776c4b4..7580493b867a 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -123,6 +123,34 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub) } EXPORT_SYMBOL_GPL(usb_phy_roothub_exit); +int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub, + enum phy_mode mode) +{ + struct usb_phy_roothub *roothub_entry; + struct list_head *head; + int err; + + if (!phy_roothub) + return 0; + + head = &phy_roothub->list; + + list_for_each_entry(roothub_entry, head, list) { + err = phy_set_mode(roothub_entry->phy, mode); + if (err) + goto err_out; + } + + return 0; + +err_out: + list_for_each_entry_continue_reverse(roothub_entry, head, list) + phy_power_off(roothub_entry->phy); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_set_mode); + int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub) { struct usb_phy_roothub *roothub_entry; diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 88a3c037e9df..dad564e2d2d4 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -16,6 +16,8 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); +int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub, + enum phy_mode mode); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index ea18284dfa9a..7e88fdfe3cf5 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -528,7 +528,10 @@ static ssize_t usb2_hardware_lpm_store(struct device *dev, if (!ret) { udev->usb2_hw_lpm_allowed = value; - ret = usb_set_usb2_hardware_lpm(udev, value); + if (value) + ret = usb_enable_usb2_hardware_lpm(udev); + else + ret = usb_disable_usb2_hardware_lpm(udev); } usb_unlock_device(udev); diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index f51750bcd152..0eab79f82ce4 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -70,9 +70,8 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) { struct urb *urb; - urb = kmalloc(sizeof(struct urb) + - iso_packets * sizeof(struct usb_iso_packet_descriptor), - mem_flags); + urb = kmalloc(struct_size(urb, iso_frame_desc, iso_packets), + mem_flags); if (!urb) return NULL; usb_init_urb(urb); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 546a2219454b..d95a5358f73d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -92,7 +92,8 @@ extern int usb_remote_wakeup(struct usb_device *dev); extern int usb_runtime_suspend(struct device *dev); extern int usb_runtime_resume(struct device *dev); extern int usb_runtime_idle(struct device *dev); -extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable); +extern int usb_enable_usb2_hardware_lpm(struct usb_device *udev); +extern int usb_disable_usb2_hardware_lpm(struct usb_device *udev); #else @@ -112,7 +113,12 @@ static inline int usb_autoresume_device(struct usb_device *udev) return 0; } -static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +static inline int usb_enable_usb2_hardware_lpm(struct usb_device *udev) +{ + return 0; +} + +static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev) { return 0; } diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index b6a495e98fd8..68d095ae2865 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_DWC2 tristate "DesignWare USB2 DRD Core Support" depends on HAS_DMA diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 34d9ce20532c..2b1494460d0c 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_DWC3 tristate "DesignWare USB3 DRD Core Support" depends on (USB || USB_GADGET) && HAS_DMA diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index cb7fcd7c0ad8..c1e9ea621f41 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -78,7 +78,7 @@ static int dwc3_exynos_probe(struct platform_device *pdev) for (i = 0; i < exynos->num_clks; i++) { ret = clk_prepare_enable(exynos->clks[i]); if (ret) { - while (--i > 0) + while (i-- > 0) clk_disable_unprepare(exynos->clks[i]); return ret; } @@ -223,7 +223,7 @@ static int dwc3_exynos_resume(struct device *dev) for (i = 0; i < exynos->num_clks; i++) { ret = clk_prepare_enable(exynos->clks[i]); if (ret) { - while (--i > 0) + while (i-- > 0) clk_disable_unprepare(exynos->clks[i]); return ret; } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f2d7b744def3..e293400cc6e9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1110,7 +1110,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); unsigned int rem = length % maxp; - if (rem && usb_endpoint_dir_out(dep->endpoint.desc)) { + if ((!length || rem) && usb_endpoint_dir_out(dep->endpoint.desc)) { struct dwc3 *dwc = dep->dwc; struct dwc3_trb *trb; diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 31cce7805eb2..ec189d7855a0 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Gadget support on a system involves # (a) a peripheral controller, and diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 784bf86dad4f..d7c9e4fca895 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Gadget support on a system involves # (a) a peripheral controller, and diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 0a16cbd4e528..ef0259a950ba 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Gadget support on a system involves # (a) a peripheral controller, and diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig index c74ac25dddcd..3e88c7670b2e 100644 --- a/drivers/usb/gadget/udc/bdc/Kconfig +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_BDC_UDC tristate "Broadcom USB3.0 device controller IP driver(BDC)" depends on USB_GADGET && HAS_DMA diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 660878a19505..b77f3126580e 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c @@ -2083,7 +2083,7 @@ static irqreturn_t net2272_irq(int irq, void *_dev) #if defined(PLX_PCI_RDK2) /* see if PCI int for us by checking irqstat */ intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT); - if (!intcsr & (1 << NET2272_PCI_IRQ)) { + if (!(intcsr & (1 << NET2272_PCI_IRQ))) { spin_unlock(&dev->lock); return IRQ_NONE; } diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 16758b12a5e9..d809671c5fea 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Host Controller Drivers # @@ -69,13 +70,13 @@ config USB_XHCI_MTK If unsure, say N. config USB_XHCI_MVEBU - tristate "xHCI support for Marvell Armada 375/38x" + tristate "xHCI support for Marvell Armada 375/38x/37xx" select USB_XHCI_PLATFORM depends on HAS_IOMEM depends on ARCH_MVEBU || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller - found in Marvell Armada 375/38x ARM SOCs. + found in Marvell Armada 375/38x/37xx ARM SOCs. config USB_XHCI_RCAR tristate "xHCI support for Renesas R-Car SoCs" @@ -179,8 +180,7 @@ config XPS_USB_HCD_XILINX devices only. config USB_EHCI_FSL - tristate "Support for Freescale PPC on-chip EHCI USB controller" - depends on FSL_SOC + tristate "Support for Freescale on-chip EHCI USB controller" select USB_EHCI_ROOT_HUB_TT ---help--- Variation of ARC USB block used in some Freescale chips. diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 0a9fd2022acf..e3d0c1c25160 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/fsl_devices.h> #include <linux/of_platform.h> +#include <linux/io.h> #include "ehci.h" #include "ehci-fsl.h" @@ -50,6 +51,7 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) struct resource *res; int irq; int retval; + u32 tmp; pr_debug("initializing FSL-SOC USB Controller\n"); @@ -114,17 +116,22 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) } /* Enable USB controller, 83xx or 8536 */ - if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) - clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, 0x4); - + if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) { + tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= 0x4; + iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); + } /* * Enable UTMI phy and program PTS field in UTMI mode before asserting * controller reset for USB Controller version 2.5 */ if (pdata->has_fsl_erratum_a007792) { - clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, CTRL_UTMI_PHY_EN); + tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= CTRL_UTMI_PHY_EN; + iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); + writel(PORT_PTS_UTMI, hcd->regs + FSL_SOC_USB_PORTSC1); } @@ -174,7 +181,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, enum fsl_usb2_phy_modes phy_mode, unsigned int port_offset) { - u32 portsc; + u32 portsc, tmp; struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; struct device *dev = hcd->self.controller; @@ -192,11 +199,16 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, case FSL_USB2_PHY_ULPI: if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ - clrbits32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, - ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN); + /* turn off UTMI PHY first */ + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~(CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + + /* then turn on ULPI and enable USB controller */ + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); } portsc |= PORT_PTS_ULPI; break; @@ -210,16 +222,21 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, case FSL_USB2_PHY_UTMI_DUAL: if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, UTMI_PHY_EN); + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= UTMI_PHY_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to become stable - 10ms*/ } /* enable UTMI PHY */ - if (pdata->have_sysif_regs) - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, - CTRL_UTMI_PHY_EN); + if (pdata->have_sysif_regs) { + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= CTRL_UTMI_PHY_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + } portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: @@ -241,9 +258,12 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); - if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, USB_CTRL_USB_EN); + if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) { + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= USB_CTRL_USB_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + } return 0; } @@ -284,14 +304,9 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) return -EINVAL; if (pdata->operating_mode == FSL_USB2_MPH_HOST) { - unsigned int chip, rev, svr; - - svr = mfspr(SPRN_SVR); - chip = svr >> 16; - rev = (svr >> 4) & 0xf; /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ - if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055)) + if (pdata->has_fsl_erratum_14 == 1) ehci->has_fsl_port_bug = 1; if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 1ad72647a069..790acf3633e8 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -182,6 +182,23 @@ static int ehci_orion_drv_reset(struct usb_hcd *hcd) return ret; } +static int __maybe_unused ehci_orion_drv_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + + return ehci_suspend(hcd, device_may_wakeup(dev)); +} + +static int __maybe_unused ehci_orion_drv_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + + return ehci_resume(hcd, false); +} + +static SIMPLE_DEV_PM_OPS(ehci_orion_pm_ops, ehci_orion_drv_suspend, + ehci_orion_drv_resume); + static const struct ehci_driver_overrides orion_overrides __initconst = { .extra_priv_size = sizeof(struct orion_ehci_hcd), .reset = ehci_orion_drv_reset, @@ -257,15 +274,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) if (IS_ERR(priv->phy)) { err = PTR_ERR(priv->phy); if (err != -ENOSYS) - goto err_phy_get; - } else { - err = phy_init(priv->phy); - if (err) - goto err_phy_init; - - err = phy_power_on(priv->phy); - if (err) - goto err_phy_power_on; + goto err_dis_clk; } /* @@ -297,19 +306,12 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) - goto err_add_hcd; + goto err_dis_clk; device_wakeup_enable(hcd->self.controller); return 0; -err_add_hcd: - if (!IS_ERR(priv->phy)) - phy_power_off(priv->phy); -err_phy_power_on: - if (!IS_ERR(priv->phy)) - phy_exit(priv->phy); -err_phy_init: -err_phy_get: +err_dis_clk: if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); usb_put_hcd(hcd); @@ -327,11 +329,6 @@ static int ehci_orion_drv_remove(struct platform_device *pdev) usb_remove_hcd(hcd); - if (!IS_ERR(priv->phy)) { - phy_power_off(priv->phy); - phy_exit(priv->phy); - } - if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); @@ -354,6 +351,7 @@ static struct platform_driver ehci_orion_driver = { .driver = { .name = "orion-ehci", .of_match_table = ehci_orion_dt_ids, + .pm = &ehci_orion_pm_ops, }, }; diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 677f9d592109..4f8b8a08c914 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -225,6 +225,12 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) pdata->has_fsl_erratum_a005697 = of_property_read_bool(np, "fsl,usb_erratum-a005697"); + if (of_get_property(np, "fsl,usb_erratum_14", NULL)) + pdata->has_fsl_erratum_14 = 1; + else + pdata->has_fsl_erratum_14 = 0; + + /* * Determine whether phy_clk_valid needs to be checked * by reading property in device tree diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index ec6739ef3129..fc35a7993b7b 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -141,8 +141,11 @@ static struct regmap *at91_dt_syscon_sfr(void) struct regmap *regmap; regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); - if (IS_ERR(regmap)) - regmap = NULL; + if (IS_ERR(regmap)) { + regmap = syscon_regmap_lookup_by_compatible("microchip,sam9x60-sfr"); + if (IS_ERR(regmap)) + regmap = NULL; + } return regmap; } diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index c5e6e8d0b5ef..f06a291f05f8 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -1323,7 +1323,7 @@ static struct list_head *qh_urb_transaction(struct oxu_hcd *oxu, } /* by default, enable interrupt on urb completion */ - qtd->hw_token |= cpu_to_le32(QTD_IOC); + qtd->hw_token |= cpu_to_le32(QTD_IOC); return head; cleanup: diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 5b8a3d9530c4..934584f0a20a 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2477,7 +2477,8 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); kfree(urbq); - } urb->error_count = 0; + } + urb->error_count = 0; usb_hcd_giveback_urb(hcd, urb, status); return 0; } else if (list_empty(&endp->urb_more)) { @@ -2982,7 +2983,8 @@ static int u132_remove(struct platform_device *pdev) while (rings-- > 0) { struct u132_ring *ring = &u132->ring[rings]; u132_ring_cancel_work(u132, ring); - } while (endps-- > 0) { + } + while (endps-- > 0) { struct u132_endp *endp = u132->endp[endps]; if (endp) u132_endp_cancel_work(u132, endp); diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Makefile index 26df0138079e..859d20079df6 100644 --- a/drivers/usb/host/whci/Kbuild +++ b/drivers/usb/host/whci/Makefile @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o whci-hcd-y := \ diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 32e158568788..60651a50770f 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -13,6 +13,7 @@ #include <linux/usb/hcd.h> #include "xhci-mvebu.h" +#include "xhci.h" #define USB3_MAX_WINDOWS 4 #define USB3_WIN_CTRL(w) (0x0 + ((w) * 8)) @@ -72,3 +73,13 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) return 0; } + +int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + /* Without reset on resume, the HC won't work at all */ + xhci->quirks |= XHCI_RESET_ON_RESUME; + + return 0; +} diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h index 09791df2cec0..ca0a3a5721dd 100644 --- a/drivers/usb/host/xhci-mvebu.h +++ b/drivers/usb/host/xhci-mvebu.h @@ -12,10 +12,16 @@ struct usb_hcd; #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd); +int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd); #else static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) { return 0; } + +static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) +{ + return 0; +} #endif #endif /* __LINUX_XHCI_MVEBU_H */ diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ef09cb06212f..0ac4ec975547 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -98,6 +98,10 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = { .init_quirk = xhci_mvebu_mbus_init_quirk, }; +static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { + .init_quirk = xhci_mvebu_a3700_init_quirk, +}; + static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V1, .init_quirk = xhci_rcar_init_quirk, @@ -124,6 +128,9 @@ static const struct of_device_id usb_xhci_of_match[] = { .compatible = "marvell,armada-380-xhci", .data = &xhci_plat_marvell_armada, }, { + .compatible = "marvell,armada3700-xhci", + .data = &xhci_plat_marvell_armada3700, + }, { .compatible = "renesas,xhci-r8a7790", .data = &xhci_plat_renesas_rcar_gen2, }, { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 005e65922608..7fa58c99f126 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1455,8 +1455,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag else num_tds = 1; - urb_priv = kzalloc(sizeof(struct urb_priv) + - num_tds * sizeof(struct xhci_td), mem_flags); + urb_priv = kzalloc(struct_size(urb_priv, td, num_tds), mem_flags); if (!urb_priv) return -ENOMEM; diff --git a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig index 320d368c8dac..26c75f309da9 100644 --- a/drivers/usb/image/Kconfig +++ b/drivers/usb/image/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Imaging devices configuration # diff --git a/drivers/usb/isp1760/Kconfig b/drivers/usb/isp1760/Kconfig index c94b7d953399..b1022cc490a2 100644 --- a/drivers/usb/isp1760/Kconfig +++ b/drivers/usb/isp1760/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_ISP1760 tristate "NXP ISP 1760/1761 support" depends on USB || USB_GADGET diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 68d2f2cd17dd..be04c117fe80 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Miscellaneous driver configuration # diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 76c718ac8c78..257efacf3551 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -915,7 +915,6 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi) int bytes_read = 0; int retry_on_empty = 1; int retry_on_timeout = 3; - int empty_packets = 0; read:{ int packet_bytes = 0; int retval = usb_bulk_msg(ftdi->udev, @@ -960,31 +959,6 @@ read:{ dev_err(&ftdi->udev->dev, "error = %d with packet_bytes = %d with total %d bytes%s\n", retval, packet_bytes, bytes_read, diag); return retval; - } else if (packet_bytes == 2) { - unsigned char s0 = ftdi->bulk_in_buffer[0]; - unsigned char s1 = ftdi->bulk_in_buffer[1]; - empty_packets += 1; - if (s0 == 0x31 && s1 == 0x60) { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; - } else if (s0 == 0x31 && s1 == 0x00) { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; - } else { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; - } - } else if (packet_bytes == 1) { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; } else { if (retry_on_empty-- > 0) { goto more; diff --git a/drivers/usb/misc/sisusbvga/Kconfig b/drivers/usb/misc/sisusbvga/Kconfig index 36bc28c884ad..9b632ab24f03 100644 --- a/drivers/usb/misc/sisusbvga/Kconfig +++ b/drivers/usb/misc/sisusbvga/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config USB_SISUSBVGA tristate "USB 2.0 SVGA dongle support (Net2280/SiS315)" diff --git a/drivers/usb/misc/sisusbvga/Makefile b/drivers/usb/misc/sisusbvga/Makefile index 6ed3a638261a..6551bce68ac5 100644 --- a/drivers/usb/misc/sisusbvga/Makefile +++ b/drivers/usb/misc/sisusbvga/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga.o -sisusbvga-y := sisusb.o sisusb_init.o sisusb_con.o +sisusbvga-y := sisusb.o +sisusbvga-$(CONFIG_USB_SISUSBVGA_CON) += sisusb_con.o sisusb_init.o diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 3198d0477cf8..9560fde621ee 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -53,7 +53,7 @@ #include "sisusb.h" #include "sisusb_init.h" -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON #include <linux/font.h> #endif @@ -61,7 +61,7 @@ /* Forward declarations / clean-up routines */ -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON static int sisusb_first_vc; static int sisusb_last_vc; module_param_named(first, sisusb_first_vc, int, 0); @@ -1198,7 +1198,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, /* High level: Gfx (indexed) register access */ -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data) { return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); @@ -1272,7 +1272,7 @@ int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, /* Write/read video ram */ -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data) { return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data); @@ -2255,7 +2255,7 @@ static int sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen) } -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON /* Set up default text mode: * - Set text mode (0x03) @@ -2448,7 +2448,7 @@ void sisusb_delete(struct kref *kref) sisusb->sisusb_dev = NULL; sisusb_free_buffers(sisusb); sisusb_free_urbs(sisusb); -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON kfree(sisusb->SiS_Pr); #endif kfree(sisusb); @@ -2844,7 +2844,7 @@ static int sisusb_handle_command(struct sisusb_usb_data *sisusb, case SUCMD_HANDLETEXTMODE: retval = 0; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON /* Gfx core must be initialized, SiS_Pr must exist */ if (!sisusb->gfxinit || !sisusb->SiS_Pr) return -ENODEV; @@ -2860,7 +2860,7 @@ static int sisusb_handle_command(struct sisusb_usb_data *sisusb, #endif break; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON case SUCMD_SETMODE: /* Gfx core must be initialized, SiS_Pr must exist */ if (!sisusb->gfxinit || !sisusb->SiS_Pr) @@ -2944,7 +2944,7 @@ static long sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) x.sisusb_vramsize = sisusb->vramsize; x.sisusb_minor = sisusb->minor; x.sisusb_fbdevactive = 0; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON x.sisusb_conactive = sisusb->haveconsole ? 1 : 0; #else x.sisusb_conactive = 0; @@ -2975,7 +2975,7 @@ err_out: return retval; } -#ifdef SISUSB_NEW_CONFIG_COMPAT +#ifdef CONFIG_COMPAT static long sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { @@ -2998,7 +2998,7 @@ static const struct file_operations usb_sisusb_fops = { .read = sisusb_read, .write = sisusb_write, .llseek = sisusb_lseek, -#ifdef SISUSB_NEW_CONFIG_COMPAT +#ifdef CONFIG_COMPAT .compat_ioctl = sisusb_compat_ioctl, #endif .unlocked_ioctl = sisusb_ioctl @@ -3091,7 +3091,7 @@ static int sisusb_probe(struct usb_interface *intf, dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs); -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON /* Allocate our SiS_Pr */ sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL); if (!sisusb->SiS_Pr) { @@ -3112,7 +3112,7 @@ static int sisusb_probe(struct usb_interface *intf, if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) { int initscreen = 1; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON if (sisusb_first_vc > 0 && sisusb_last_vc > 0 && sisusb_first_vc <= sisusb_last_vc && sisusb_last_vc <= MAX_NR_CONSOLES) @@ -3134,7 +3134,7 @@ static int sisusb_probe(struct usb_interface *intf, dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); #endif -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc); #endif @@ -3160,7 +3160,7 @@ static void sisusb_disconnect(struct usb_interface *intf) if (!sisusb) return; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON sisusb_console_exit(sisusb); #endif @@ -3210,7 +3210,7 @@ static struct usb_driver sisusb_driver = { static int __init usb_sisusb_init(void) { -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON sisusb_init_concode(); #endif diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index 20f03ad0ea16..8a5e6bb07d05 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h @@ -38,17 +38,8 @@ #ifndef _SISUSB_H_ #define _SISUSB_H_ -#ifdef CONFIG_COMPAT -#define SISUSB_NEW_CONFIG_COMPAT -#endif - #include <linux/mutex.h> -/* For older kernels, support for text consoles is by default - * off. To enable text console support, change the following: - */ -/* #define CONFIG_USB_SISUSBVGA_CON */ - /* Version Information */ #define SISUSB_VERSION 0 @@ -57,10 +48,6 @@ /* Include console and mode switching code? */ -#ifdef CONFIG_USB_SISUSBVGA_CON -#define INCL_SISUSB_CON 1 -#endif - #include <linux/console.h> #include <linux/vt_kern.h> #include "sisusb_struct.h" @@ -139,7 +126,7 @@ struct sisusb_usb_data { unsigned char gfxinit; /* graphics core initialized? */ unsigned short chipid, chipvendor; unsigned short chiprevision; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON struct SiS_Private *SiS_Pr; unsigned long scrbuf; unsigned int scrbuf_size; diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index c4f017e1d17a..cd0155310fea 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -70,13 +70,6 @@ #include "sisusb.h" #include "sisusb_init.h" -#ifdef INCL_SISUSB_CON - -#define sisusbcon_writew(val, addr) (*(addr) = (val)) -#define sisusbcon_readw(addr) (*(addr)) -#define sisusbcon_memmovew(d, s, c) memmove(d, s, c) -#define sisusbcon_memcpyw(d, s, c) memcpy(d, s, c) - /* vc_data -> sisusb conversion table */ static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES]; @@ -86,9 +79,7 @@ static const struct consw sisusb_con; static inline void sisusbcon_memsetw(u16 *s, u16 c, unsigned int count) { - count /= 2; - while (count--) - sisusbcon_writew(c, s++); + memset16(s, c, count / 2); } static inline void @@ -346,25 +337,30 @@ sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count) */ while (count--) { - u16 a = sisusbcon_readw(p); - - a = ((a) & 0x88ff) | - (((a) & 0x7000) >> 4) | - (((a) & 0x0700) << 4); + u16 a = *p; - sisusbcon_writew(a, p++); + *p++ = ((a) & 0x88ff) | + (((a) & 0x7000) >> 4) | + (((a) & 0x0700) << 4); } } -#define SISUSB_VADDR(x,y) \ - ((u16 *)c->vc_origin + \ - (y) * sisusb->sisusb_num_columns + \ - (x)) +static inline void *sisusb_vaddr(const struct sisusb_usb_data *sisusb, + const struct vc_data *c, unsigned int x, unsigned int y) +{ + return (u16 *)c->vc_origin + y * sisusb->sisusb_num_columns + x; +} + +static inline unsigned long sisusb_haddr(const struct sisusb_usb_data *sisusb, + const struct vc_data *c, unsigned int x, unsigned int y) +{ + unsigned long offset = c->vc_origin - sisusb->scrbuf; -#define SISUSB_HADDR(x,y) \ - ((u16 *)(sisusb->vrambase + (c->vc_origin - sisusb->scrbuf)) + \ - (y) * sisusb->sisusb_num_columns + \ - (x)) + /* 2 bytes per each character */ + offset += 2 * (y * sisusb->sisusb_num_columns + x); + + return sisusb->vrambase + offset; +} /* Interface routine */ static void @@ -382,9 +378,8 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) return; } - - sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), - (long)SISUSB_HADDR(x, y), 2); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), + sisusb_haddr(sisusb, c, x, y), 2); mutex_unlock(&sisusb->lock); } @@ -395,8 +390,6 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, int count, int y, int x) { struct sisusb_usb_data *sisusb; - u16 *dest; - int i; sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); if (!sisusb) @@ -408,18 +401,15 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, * because the vt does this AFTER calling us. */ - dest = SISUSB_VADDR(x, y); - - for (i = count; i > 0; i--) - sisusbcon_writew(sisusbcon_readw(s++), dest++); + memcpy(sisusb_vaddr(sisusb, c, x, y), s, count * 2); if (sisusb_is_inactive(c, sisusb)) { mutex_unlock(&sisusb->lock); return; } - sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), - (long)SISUSB_HADDR(x, y), count * 2); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), + sisusb_haddr(sisusb, c, x, y), count * 2); mutex_unlock(&sisusb->lock); } @@ -446,7 +436,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) * this AFTER calling us. */ - dest = SISUSB_VADDR(x, y); + dest = sisusb_vaddr(sisusb, c, x, y); cols = sisusb->sisusb_num_columns; @@ -472,8 +462,8 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) length = ((height * cols) - x - (cols - width - x)) * 2; - sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), - (long)SISUSB_HADDR(x, y), length); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), + sisusb_haddr(sisusb, c, x, y), length); mutex_unlock(&sisusb->lock); } @@ -517,12 +507,10 @@ sisusbcon_switch(struct vc_data *c) (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); /* Restore the screen contents */ - sisusbcon_memcpyw((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, - length); + memcpy((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, length); - sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, - (long)SISUSB_HADDR(0, 0), - length); + sisusb_copy_memory(sisusb, (char *)c->vc_origin, + sisusb_haddr(sisusb, c, 0, 0), length); mutex_unlock(&sisusb->lock); @@ -556,8 +544,7 @@ sisusbcon_save_screen(struct vc_data *c) (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); /* Save the screen contents to vc's private buffer */ - sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, - length); + memcpy((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, length); mutex_unlock(&sisusb->lock); } @@ -628,10 +615,8 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) sisusbcon_memsetw((u16 *)c->vc_origin, c->vc_video_erase_char, c->vc_screenbuf_size); - sisusb_copy_memory(sisusb, - (unsigned char *)c->vc_origin, - (u32)(sisusb->vrambase + - (c->vc_origin - sisusb->scrbuf)), + sisusb_copy_memory(sisusb, (char *)c->vc_origin, + sisusb_haddr(sisusb, c, 0, 0), c->vc_screenbuf_size); sisusb->con_blanked = 1; ret = 1; @@ -796,24 +781,24 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, switch (dir) { case SM_UP: - sisusbcon_memmovew(SISUSB_VADDR(0, t), - SISUSB_VADDR(0, t + lines), + memmove(sisusb_vaddr(sisusb, c, 0, t), + sisusb_vaddr(sisusb, c, 0, t + lines), (b - t - lines) * cols * 2); - sisusbcon_memsetw(SISUSB_VADDR(0, b - lines), eattr, - lines * cols * 2); + sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, b - lines), + eattr, lines * cols * 2); break; case SM_DOWN: - sisusbcon_memmovew(SISUSB_VADDR(0, t + lines), - SISUSB_VADDR(0, t), + memmove(sisusb_vaddr(sisusb, c, 0, t + lines), + sisusb_vaddr(sisusb, c, 0, t), (b - t - lines) * cols * 2); - sisusbcon_memsetw(SISUSB_VADDR(0, t), eattr, + sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, t), eattr, lines * cols * 2); break; } - sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), - (long)SISUSB_HADDR(0, t), length); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, 0, t), + sisusb_haddr(sisusb, c, 0, t), length); mutex_unlock(&sisusb->lock); @@ -830,7 +815,6 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, int copyall = 0; unsigned long oldorigin; unsigned int delta = lines * c->vc_size_row; - u32 originoffset; /* Returning != 0 means we have done the scrolling successfully. * Returning 0 makes vt do the scrolling on its own. @@ -874,7 +858,7 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, if (c->vc_scr_end + delta >= sisusb->scrbuf + sisusb->scrbuf_size) { - sisusbcon_memcpyw((u16 *)sisusb->scrbuf, + memcpy((u16 *)sisusb->scrbuf, (u16 *)(oldorigin + delta), c->vc_screenbuf_size - delta); c->vc_origin = sisusb->scrbuf; @@ -892,12 +876,10 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, case SM_DOWN: if (oldorigin - delta < sisusb->scrbuf) { - sisusbcon_memmovew((u16 *)(sisusb->scrbuf + - sisusb->scrbuf_size - - c->vc_screenbuf_size + - delta), - (u16 *)oldorigin, - c->vc_screenbuf_size - delta); + memmove((void *)sisusb->scrbuf + sisusb->scrbuf_size - + c->vc_screenbuf_size + delta, + (u16 *)oldorigin, + c->vc_screenbuf_size - delta); c->vc_origin = sisusb->scrbuf + sisusb->scrbuf_size - c->vc_screenbuf_size; @@ -913,23 +895,21 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, break; } - originoffset = (u32)(c->vc_origin - sisusb->scrbuf); - if (copyall) sisusb_copy_memory(sisusb, (char *)c->vc_origin, - (u32)(sisusb->vrambase + originoffset), + sisusb_haddr(sisusb, c, 0, 0), c->vc_screenbuf_size); else if (dir == SM_UP) sisusb_copy_memory(sisusb, (char *)c->vc_origin + c->vc_screenbuf_size - delta, - (u32)sisusb->vrambase + originoffset + + sisusb_haddr(sisusb, c, 0, 0) + c->vc_screenbuf_size - delta, delta); else sisusb_copy_memory(sisusb, (char *)c->vc_origin, - (u32)(sisusb->vrambase + originoffset), + sisusb_haddr(sisusb, c, 0, 0), delta); c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; @@ -1534,8 +1514,3 @@ void __init sisusb_init_concode(void) for (i = 0; i < MAX_NR_CONSOLES; i++) mysisusbs[i] = NULL; } - -#endif /* INCL_CON */ - - - diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 6a30e8bd9221..66f6ab5acd97 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c @@ -44,9 +44,6 @@ #include <linux/spinlock.h> #include "sisusb.h" - -#ifdef INCL_SISUSB_CON - #include "sisusb_init.h" /*********************************************/ @@ -955,5 +952,3 @@ int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) return SiSUSBSetMode(SiS_Pr, ModeNo); } - -#endif /* INCL_SISUSB_CON */ diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index a6efb9a72939..4d72b7d1d383 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -337,10 +337,12 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, struct device *dev = hub->dev; struct device_node *np = dev->of_node; int len, err, i; - u32 property_u32 = 0; + u32 port, property_u32 = 0; const u32 *cproperty_u32; const char *cproperty_char; char str[USB251XB_STRING_BUFSIZE / 2]; + struct property *prop; + const __be32 *p; if (!np) { dev_err(dev, "failed to get ofdata\n"); @@ -539,6 +541,16 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, (wchar_t *)hub->serial, USB251XB_STRING_BUFSIZE); + /* + * The datasheet documents the register as 'Port Swap' but in real the + * register controls the USB DP/DM signal swapping for each port. + */ + hub->port_swap = USB251XB_DEF_PORT_SWAP; + of_property_for_each_u32(np, "swap-dx-lanes", prop, p, port) { + if ((port >= 0) && (port <= data->port_cnt)) + hub->port_swap |= BIT(port); + } + /* The following parameters are currently not exposed to devicetree, but * may be as soon as needed. */ @@ -546,7 +558,6 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, hub->boost_up = USB251XB_DEF_BOOST_UP; hub->boost_57 = USB251XB_DEF_BOOST_57; hub->boost_14 = USB251XB_DEF_BOOST_14; - hub->port_swap = USB251XB_DEF_PORT_SWAP; hub->port_map12 = USB251XB_DEF_PORT_MAP_12; hub->port_map34 = USB251XB_DEF_PORT_MAP_34; hub->port_map56 = USB251XB_DEF_PORT_MAP_56; diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index f723f7b8c9ac..d5141aa79dd4 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -355,11 +355,8 @@ static int usb3503_platform_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int usb3503_i2c_suspend(struct device *dev) +static int usb3503_suspend(struct usb3503 *hub) { - struct i2c_client *client = to_i2c_client(dev); - struct usb3503 *hub = i2c_get_clientdata(client); - usb3503_switch_mode(hub, USB3503_MODE_STANDBY); if (hub->clk) @@ -368,11 +365,8 @@ static int usb3503_i2c_suspend(struct device *dev) return 0; } -static int usb3503_i2c_resume(struct device *dev) +static int usb3503_resume(struct usb3503 *hub) { - struct i2c_client *client = to_i2c_client(dev); - struct usb3503 *hub = i2c_get_clientdata(client); - if (hub->clk) clk_prepare_enable(hub->clk); @@ -380,11 +374,38 @@ static int usb3503_i2c_resume(struct device *dev) return 0; } + +static int usb3503_i2c_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + return usb3503_suspend(i2c_get_clientdata(client)); +} + +static int usb3503_i2c_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + return usb3503_resume(i2c_get_clientdata(client)); +} + +static int usb3503_platform_suspend(struct device *dev) +{ + return usb3503_suspend(dev_get_drvdata(dev)); +} + +static int usb3503_platform_resume(struct device *dev) +{ + return usb3503_resume(dev_get_drvdata(dev)); +} #endif static SIMPLE_DEV_PM_OPS(usb3503_i2c_pm_ops, usb3503_i2c_suspend, usb3503_i2c_resume); +static SIMPLE_DEV_PM_OPS(usb3503_platform_pm_ops, usb3503_platform_suspend, + usb3503_platform_resume); + static const struct i2c_device_id usb3503_id[] = { { USB3503_I2C_NAME, 0 }, { } @@ -415,6 +436,7 @@ static struct platform_driver usb3503_platform_driver = { .driver = { .name = USB3503_I2C_NAME, .of_match_table = of_match_ptr(usb3503_of_match), + .pm = &usb3503_platform_pm_ops, }, .probe = usb3503_platform_probe, .remove = usb3503_platform_remove, diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig index 5c6ffa2a612e..48f1b2dadb24 100644 --- a/drivers/usb/mon/Kconfig +++ b/drivers/usb/mon/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Monitor configuration # diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index 40bbf1f53337..bcc23486c4ed 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# # For MTK USB3.0 IP config USB_MTU3 diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ad08895e78f9..f742fddc5e2c 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Dual Role (OTG-ready) Controller Drivers # for silicon based on Mentor Graphics INVENTRA designs @@ -111,9 +112,9 @@ config USB_MUSB_UX500 config USB_MUSB_JZ4740 tristate "JZ4740" depends on NOP_USB_XCEIV - depends on MACH_JZ4740 || COMPILE_TEST + depends on MIPS || COMPILE_TEST depends on USB_MUSB_GADGET - depends on USB_OTG_BLACKLIST_HUB + depends on USB=n || USB_OTG_BLACKLIST_HUB config USB_MUSB_AM335X_CHILD tristate diff --git a/drivers/usb/musb/jz4740.c b/drivers/usb/musb/jz4740.c index 04d8b2bc205a..a60627bf7be3 100644 --- a/drivers/usb/musb/jz4740.c +++ b/drivers/usb/musb/jz4740.c @@ -10,6 +10,7 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/usb/usb_phy_generic.h> @@ -188,11 +189,20 @@ static int jz4740_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id jz4740_musb_of_match[] = { + { .compatible = "ingenic,jz4740-musb" }, + {}, +}; +MODULE_DEVICE_TABLE(of, jz4740_musb_of_match); +#endif + static struct platform_driver jz4740_driver = { .probe = jz4740_probe, .remove = jz4740_remove, .driver = { .name = "musb-jz4740", + .of_match_table = of_match_ptr(jz4740_musb_of_match), }, }; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index eae8b1b1b45b..ffe462a657b1 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -452,13 +452,10 @@ void musb_g_tx(struct musb *musb, u8 epnum) } if (request) { - u8 is_dma = 0; - bool short_packet = false; trace_musb_req_tx(req); if (dma && (csr & MUSB_TXCSR_DMAENAB)) { - is_dma = 1; csr |= MUSB_TXCSR_P_WZC_BITS; csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN | MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_AUTOSET); @@ -476,16 +473,8 @@ void musb_g_tx(struct musb *musb, u8 epnum) */ if ((request->zero && request->length) && (request->length % musb_ep->packet_sz == 0) - && (request->actual == request->length)) - short_packet = true; + && (request->actual == request->length)) { - if ((musb_dma_inventra(musb) || musb_dma_ux500(musb)) && - (is_dma && (!dma->desired_mode || - (request->actual & - (musb_ep->packet_sz - 1))))) - short_packet = true; - - if (short_packet) { /* * On DMA completion, FIFO may not be * available yet... diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index b59ce9ad14ce..eb308ec35c66 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -378,7 +378,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, qh = first_qh(head); break; } - /* else: fall through */ + /* fall through */ case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_INT: @@ -1283,7 +1283,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); } - return; + return; } done: diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index a688f7f87829..5fc6825745f2 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -346,12 +346,10 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) channel->status = MUSB_DMA_STATUS_FREE; /* completed */ - if ((devctl & MUSB_DEVCTL_HM) - && (musb_channel->transmit) - && ((channel->desired_mode == 0) - || (channel->actual_len & - (musb_channel->max_packet_sz - 1))) - ) { + if (musb_channel->transmit && + (!channel->desired_mode || + (channel->actual_len % + musb_channel->max_packet_sz))) { u8 epnum = musb_channel->epnum; int offset = musb->io.ep_offset(epnum, MUSB_TXCSR); @@ -363,11 +361,14 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data) */ musb_ep_select(mbase, epnum); txcsr = musb_readw(mbase, offset); - txcsr &= ~(MUSB_TXCSR_DMAENAB + if (channel->desired_mode == 1) { + txcsr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_AUTOSET); - musb_writew(mbase, offset, txcsr); - /* Send out the packet */ - txcsr &= ~MUSB_TXCSR_DMAMODE; + musb_writew(mbase, offset, txcsr); + /* Send out the packet */ + txcsr &= ~MUSB_TXCSR_DMAMODE; + txcsr |= MUSB_TXCSR_DMAENAB; + } txcsr |= MUSB_TXCSR_TXPKTRDY; musb_writew(mbase, offset, txcsr); } diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index d7312eed6088..8c509b060c09 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Physical Layer USB driver configuration # @@ -21,7 +22,7 @@ config AB8500_USB config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM + depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM=y && PM depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't be 'y' select USB_PHY help diff --git a/drivers/usb/phy/phy-am335x.c b/drivers/usb/phy/phy-am335x.c index 27bdb7222527..f5f0568d8533 100644 --- a/drivers/usb/phy/phy-am335x.c +++ b/drivers/usb/phy/phy-am335x.c @@ -61,9 +61,6 @@ static int am335x_phy_probe(struct platform_device *pdev) if (ret) return ret; - ret = usb_add_phy_dev(&am_phy->usb_phy_gen.phy); - if (ret) - return ret; am_phy->usb_phy_gen.phy.init = am335x_init; am_phy->usb_phy_gen.phy.shutdown = am335x_shutdown; @@ -82,7 +79,7 @@ static int am335x_phy_probe(struct platform_device *pdev) device_set_wakeup_enable(dev, false); phy_ctrl_power(am_phy->phy_ctrl, am_phy->id, am_phy->dr_mode, false); - return 0; + return usb_add_phy_dev(&am_phy->usb_phy_gen.phy); } static int am335x_phy_remove(struct platform_device *pdev) diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index e4194ac94510..f8b31aa67526 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_ROLE_SWITCH tristate "USB Role Switch Support" help diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index c02873206fc1..757a7d2797eb 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index 99116af07f1d..f45d8df5cfb8 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -8,6 +8,7 @@ */ #include <linux/usb/role.h> +#include <linux/property.h> #include <linux/device.h> #include <linux/module.h> #include <linux/mutex.h> @@ -84,7 +85,12 @@ enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw) } EXPORT_SYMBOL_GPL(usb_role_switch_get_role); -static int __switch_match(struct device *dev, const void *name) +static int switch_fwnode_match(struct device *dev, const void *fwnode) +{ + return dev_fwnode(dev) == fwnode; +} + +static int switch_name_match(struct device *dev, const void *name) { return !strcmp((const char *)name, dev_name(dev)); } @@ -94,8 +100,16 @@ static void *usb_role_switch_match(struct device_connection *con, int ep, { struct device *dev; - dev = class_find_device(role_class, NULL, con->endpoint[ep], - __switch_match); + if (con->fwnode) { + if (!fwnode_property_present(con->fwnode, con->id)) + return NULL; + + dev = class_find_device(role_class, NULL, con->fwnode, + switch_fwnode_match); + } else { + dev = class_find_device(role_class, NULL, con->endpoint[ep], + switch_name_match); + } return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER); } @@ -266,6 +280,7 @@ usb_role_switch_register(struct device *parent, sw->get = desc->get; sw->dev.parent = parent; + sw->dev.fwnode = desc->fwnode; sw->dev.class = role_class; sw->dev.type = &usb_role_dev_type; dev_set_name(&sw->dev, "%s-role-switch", dev_name(parent)); diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 533f127c30ad..7d031911d04e 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Serial device configuration # diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 6fd427284b12..59aad38b490a 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Storage driver configuration # diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index edcf2be0e0eb..395cf8fb5870 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -167,6 +167,7 @@ static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) static void rio_karma_destructor(void *extra) { struct karma_data *data = (struct karma_data *) extra; + kfree(data->recv); } @@ -174,6 +175,7 @@ static int rio_karma_init(struct us_data *us) { int ret = 0; struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); + if (!data) goto out; diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index 30a847c2089d..89d9193bd1cf 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig TYPEC tristate "USB Type-C Support" diff --git a/drivers/usb/typec/altmodes/Kconfig b/drivers/usb/typec/altmodes/Kconfig index efef2a64bc51..ef2226eb7a33 100644 --- a/drivers/usb/typec/altmodes/Kconfig +++ b/drivers/usb/typec/altmodes/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "USB Type-C Alternate Mode drivers" diff --git a/drivers/usb/typec/altmodes/Makefile b/drivers/usb/typec/altmodes/Makefile index 5caf094ef71a..eda8456f1c92 100644 --- a/drivers/usb/typec/altmodes/Makefile +++ b/drivers/usb/typec/altmodes/Makefile @@ -1,2 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_TYPEC_DP_ALTMODE) += typec_displayport.o typec_displayport-y := displayport.o diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 3f06e94771a7..610d790bc9be 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -24,10 +24,6 @@ enum { DP_CONF_DUAL_D, }; -/* Helper for setting/getting the pin assignement value to the configuration */ -#define DP_CONF_SET_PIN_ASSIGN(_a_) ((_a_) << 8) -#define DP_CONF_GET_PIN_ASSIGN(_conf_) (((_conf_) & GENMASK(15, 8)) >> 8) - /* Pin assignments that use USB3.1 Gen2 signaling to carry DP protocol */ #define DP_PIN_ASSIGN_GEN2_BR_MASK (BIT(DP_PIN_ASSIGN_A) | \ BIT(DP_PIN_ASSIGN_B)) diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 5db0593ca0bd..2eb623841847 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -9,6 +9,7 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/property.h> #include <linux/slab.h> #include "bus.h" @@ -204,15 +205,32 @@ static void typec_altmode_put_partner(struct altmode *altmode) put_device(&adev->dev); } -static int __typec_port_match(struct device *dev, const void *name) +static int typec_port_fwnode_match(struct device *dev, const void *fwnode) +{ + return dev_fwnode(dev) == fwnode; +} + +static int typec_port_name_match(struct device *dev, const void *name) { return !strcmp((const char *)name, dev_name(dev)); } static void *typec_port_match(struct device_connection *con, int ep, void *data) { - return class_find_device(typec_class, NULL, con->endpoint[ep], - __typec_port_match); + struct device *dev; + + /* + * FIXME: Check does the fwnode supports the requested SVID. If it does + * we need to return ERR_PTR(-PROBE_DEFER) when there is no device. + */ + if (con->fwnode) + return class_find_device(typec_class, NULL, con->fwnode, + typec_port_fwnode_match); + + dev = class_find_device(typec_class, NULL, con->endpoint[ep], + typec_port_name_match); + + return dev ? dev : ERR_PTR(-EPROBE_DEFER); } struct typec_altmode * @@ -277,7 +295,7 @@ void typec_altmode_update_active(struct typec_altmode *adev, bool active) if (adev->active == active) return; - if (!is_typec_port(adev->dev.parent)) { + if (!is_typec_port(adev->dev.parent) && adev->dev.driver) { if (!active) module_put(adev->dev.driver->owner); else @@ -1496,11 +1514,8 @@ typec_port_register_altmode(struct typec_port *port, { struct typec_altmode *adev; struct typec_mux *mux; - char id[10]; - - sprintf(id, "id%04xm%02x", desc->svid, desc->mode); - mux = typec_mux_get(&port->dev, id); + mux = typec_mux_get(&port->dev, desc); if (IS_ERR(mux)) return ERR_CAST(mux); @@ -1593,7 +1608,7 @@ struct typec_port *typec_register_port(struct device *parent, return ERR_CAST(port->sw); } - port->mux = typec_mux_get(&port->dev, "typec-mux"); + port->mux = typec_mux_get(&port->dev, NULL); if (IS_ERR(port->mux)) { put_device(&port->dev); return ERR_CAST(port->mux); diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index d990aa510fab..a5947d98824d 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -11,6 +11,8 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/property.h> +#include <linux/slab.h> #include <linux/usb/typec_mux.h> static DEFINE_MUTEX(switch_lock); @@ -23,15 +25,25 @@ static void *typec_switch_match(struct device_connection *con, int ep, { struct typec_switch *sw; - list_for_each_entry(sw, &switch_list, entry) - if (!strcmp(con->endpoint[ep], dev_name(sw->dev))) - return sw; + if (!con->fwnode) { + list_for_each_entry(sw, &switch_list, entry) + if (!strcmp(con->endpoint[ep], dev_name(sw->dev))) + return sw; + return ERR_PTR(-EPROBE_DEFER); + } /* - * We only get called if a connection was found, tell the caller to - * wait for the switch to show up. + * With OF graph the mux node must have a boolean device property named + * "orientation-switch". */ - return ERR_PTR(-EPROBE_DEFER); + if (con->id && !fwnode_property_present(con->fwnode, con->id)) + return NULL; + + list_for_each_entry(sw, &switch_list, entry) + if (dev_fwnode(sw->dev) == con->fwnode) + return sw; + + return con->id ? ERR_PTR(-EPROBE_DEFER) : NULL; } /** @@ -48,7 +60,7 @@ struct typec_switch *typec_switch_get(struct device *dev) struct typec_switch *sw; mutex_lock(&switch_lock); - sw = device_connection_find_match(dev, "typec-switch", NULL, + sw = device_connection_find_match(dev, "orientation-switch", NULL, typec_switch_match); if (!IS_ERR_OR_NULL(sw)) { WARN_ON(!try_module_get(sw->dev->driver->owner)); @@ -112,35 +124,87 @@ EXPORT_SYMBOL_GPL(typec_switch_unregister); static void *typec_mux_match(struct device_connection *con, int ep, void *data) { + const struct typec_altmode_desc *desc = data; struct typec_mux *mux; + size_t nval; + bool match; + u16 *val; + int i; - list_for_each_entry(mux, &mux_list, entry) - if (!strcmp(con->endpoint[ep], dev_name(mux->dev))) - return mux; + if (!con->fwnode) { + list_for_each_entry(mux, &mux_list, entry) + if (!strcmp(con->endpoint[ep], dev_name(mux->dev))) + return mux; + return ERR_PTR(-EPROBE_DEFER); + } /* - * We only get called if a connection was found, tell the caller to - * wait for the switch to show up. + * Check has the identifier already been "consumed". If it + * has, no need to do any extra connection identification. */ - return ERR_PTR(-EPROBE_DEFER); + match = !con->id; + if (match) + goto find_mux; + + /* Accessory Mode muxes */ + if (!desc) { + match = fwnode_property_present(con->fwnode, "accessory"); + if (match) + goto find_mux; + return NULL; + } + + /* Alternate Mode muxes */ + nval = fwnode_property_read_u16_array(con->fwnode, "svid", NULL, 0); + if (nval <= 0) + return NULL; + + val = kcalloc(nval, sizeof(*val), GFP_KERNEL); + if (!val) + return ERR_PTR(-ENOMEM); + + nval = fwnode_property_read_u16_array(con->fwnode, "svid", val, nval); + if (nval < 0) { + kfree(val); + return ERR_PTR(nval); + } + + for (i = 0; i < nval; i++) { + match = val[i] == desc->svid; + if (match) { + kfree(val); + goto find_mux; + } + } + kfree(val); + return NULL; + +find_mux: + list_for_each_entry(mux, &mux_list, entry) + if (dev_fwnode(mux->dev) == con->fwnode) + return mux; + + return match ? ERR_PTR(-EPROBE_DEFER) : NULL; } /** * typec_mux_get - Find USB Type-C Multiplexer * @dev: The caller device - * @name: Mux identifier + * @desc: Alt Mode description * * Finds a mux linked to the caller. This function is primarily meant for the * Type-C drivers. Returns a reference to the mux on success, NULL if no * matching connection was found, or ERR_PTR(-EPROBE_DEFER) when a connection * was found but the mux has not been enumerated yet. */ -struct typec_mux *typec_mux_get(struct device *dev, const char *name) +struct typec_mux *typec_mux_get(struct device *dev, + const struct typec_altmode_desc *desc) { struct typec_mux *mux; mutex_lock(&mux_lock); - mux = device_connection_find_match(dev, name, NULL, typec_mux_match); + mux = device_connection_find_match(dev, "mode-switch", (void *)desc, + typec_mux_match); if (!IS_ERR_OR_NULL(mux)) { WARN_ON(!try_module_get(mux->dev->driver->owner)); get_device(mux->dev); diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index 9a954d2b8d8f..01ed0d5e10e8 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + menu "USB Type-C Multiplexer/DeMultiplexer Switch support" config TYPEC_MUX_PI3USB30532 diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig index f03ea8a61768..72481bbb2af3 100644 --- a/drivers/usb/typec/tcpm/Kconfig +++ b/drivers/usb/typec/tcpm/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config TYPEC_TCPM tristate "USB Type-C Port Controller Manager" depends on USB diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 4bc29b586698..0f62db091d8d 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -2297,7 +2297,8 @@ static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) pdo_pps_apdo_max_voltage(snk)); port->pps_data.max_curr = min_pps_apdo_current(src, snk); port->pps_data.out_volt = min(port->pps_data.max_volt, - port->pps_data.out_volt); + max(port->pps_data.min_volt, + port->pps_data.out_volt)); port->pps_data.op_curr = min(port->pps_data.max_curr, port->pps_data.op_curr); } @@ -4434,66 +4435,6 @@ sink: return 0; } -int tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo, - unsigned int nr_pdo) -{ - if (tcpm_validate_caps(port, pdo, nr_pdo)) - return -EINVAL; - - mutex_lock(&port->lock); - port->nr_src_pdo = tcpm_copy_pdos(port->src_pdo, pdo, nr_pdo); - switch (port->state) { - case SRC_UNATTACHED: - case SRC_ATTACH_WAIT: - case SRC_TRYWAIT: - tcpm_set_cc(port, tcpm_rp_cc(port)); - break; - case SRC_SEND_CAPABILITIES: - case SRC_NEGOTIATE_CAPABILITIES: - case SRC_READY: - case SRC_WAIT_NEW_CAPABILITIES: - tcpm_set_cc(port, tcpm_rp_cc(port)); - tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0); - break; - default: - break; - } - mutex_unlock(&port->lock); - return 0; -} -EXPORT_SYMBOL_GPL(tcpm_update_source_capabilities); - -int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo, - unsigned int nr_pdo, - unsigned int operating_snk_mw) -{ - if (tcpm_validate_caps(port, pdo, nr_pdo)) - return -EINVAL; - - mutex_lock(&port->lock); - port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, pdo, nr_pdo); - port->operating_snk_mw = operating_snk_mw; - port->update_sink_caps = true; - - switch (port->state) { - case SNK_NEGOTIATE_CAPABILITIES: - case SNK_NEGOTIATE_PPS_CAPABILITIES: - case SNK_READY: - case SNK_TRANSITION_SINK: - case SNK_TRANSITION_SINK_VBUS: - if (port->pps_data.active) - tcpm_set_state(port, SNK_NEGOTIATE_PPS_CAPABILITIES, 0); - else - tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0); - break; - default: - break; - } - mutex_unlock(&port->lock); - return 0; -} -EXPORT_SYMBOL_GPL(tcpm_update_sink_capabilities); - /* Power Supply access to expose source power information */ enum tcpm_psy_online_states { TCPM_PSY_OFFLINE = 0, @@ -4810,12 +4751,12 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) err = devm_tcpm_psy_register(port); if (err) - goto out_destroy_wq; + goto out_role_sw_put; port->typec_port = typec_register_port(port->dev, &port->typec_caps); if (IS_ERR(port->typec_port)) { err = PTR_ERR(port->typec_port); - goto out_destroy_wq; + goto out_role_sw_put; } if (tcpc->config && tcpc->config->alt_modes) { @@ -4848,8 +4789,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) tcpm_log(port, "%s: registered", dev_name(dev)); return port; -out_destroy_wq: +out_role_sw_put: usb_role_switch_put(port->role_sw); +out_destroy_wq: + tcpm_debugfs_exit(port); destroy_workqueue(port->wq); return ERR_PTR(err); } diff --git a/drivers/usb/typec/tps6598x.c b/drivers/usb/typec/tps6598x.c index 1c0033ad8738..9947c87d2a1e 100644 --- a/drivers/usb/typec/tps6598x.c +++ b/drivers/usb/typec/tps6598x.c @@ -14,6 +14,8 @@ #include <linux/usb/typec.h> /* Register offsets */ +#define TPS_REG_VID 0x00 +#define TPS_REG_MODE 0x03 #define TPS_REG_CMD1 0x08 #define TPS_REG_DATA1 0x09 #define TPS_REG_INT_EVENT1 0x14 @@ -66,6 +68,20 @@ struct tps6598x_rx_identity_reg { #define TPS_TASK_TIMEOUT 1 #define TPS_TASK_REJECTED 3 +enum { + TPS_MODE_APP, + TPS_MODE_BOOT, + TPS_MODE_BIST, + TPS_MODE_DISC, +}; + +static const char *const modes[] = { + [TPS_MODE_APP] = "APP ", + [TPS_MODE_BOOT] = "BOOT", + [TPS_MODE_BIST] = "BIST", + [TPS_MODE_DISC] = "DISC", +}; + /* Unrecognized commands will be replaced with "!CMD" */ #define INVALID_CMD(_cmd_) (_cmd_ == 0x444d4321) @@ -384,6 +400,32 @@ err_unlock: return IRQ_HANDLED; } +static int tps6598x_check_mode(struct tps6598x *tps) +{ + char mode[5] = { }; + int ret; + + ret = tps6598x_read32(tps, TPS_REG_MODE, (void *)mode); + if (ret) + return ret; + + switch (match_string(modes, ARRAY_SIZE(modes), mode)) { + case TPS_MODE_APP: + return 0; + case TPS_MODE_BOOT: + dev_warn(tps->dev, "dead-battery condition\n"); + return 0; + case TPS_MODE_BIST: + case TPS_MODE_DISC: + default: + dev_err(tps->dev, "controller in unsupported mode \"%s\"\n", + mode); + break; + } + + return -ENODEV; +} + static const struct regmap_config tps6598x_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -409,10 +451,8 @@ static int tps6598x_probe(struct i2c_client *client) if (IS_ERR(tps->regmap)) return PTR_ERR(tps->regmap); - ret = tps6598x_read32(tps, 0, &vid); - if (ret < 0) - return ret; - if (!vid) + ret = tps6598x_read32(tps, TPS_REG_VID, &vid); + if (ret < 0 || !vid) return -ENODEV; /* @@ -425,6 +465,11 @@ static int tps6598x_probe(struct i2c_client *client) if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) tps->i2c_protocol = true; + /* Make sure the controller has application firmware running */ + ret = tps6598x_check_mode(tps); + if (ret) + return ret; + ret = tps6598x_read32(tps, TPS_REG_STATUS, &status); if (ret < 0) return ret; diff --git a/drivers/usb/typec/ucsi/Kconfig b/drivers/usb/typec/ucsi/Kconfig index 78118883f96c..15c2ac7db02d 100644 --- a/drivers/usb/typec/ucsi/Kconfig +++ b/drivers/usb/typec/ucsi/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config TYPEC_UCSI tristate "USB Type-C Connector System Software Interface driver" depends on !CPU_BIG_ENDIAN diff --git a/drivers/usb/typec/ucsi/debug.h b/drivers/usb/typec/ucsi/debug.h deleted file mode 100644 index fdeff39df120..000000000000 --- a/drivers/usb/typec/ucsi/debug.h +++ /dev/null @@ -1,65 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __UCSI_DEBUG_H -#define __UCSI_DEBUG_H - -#include "ucsi.h" - -static const char * const ucsi_cmd_strs[] = { - [0] = "Unknown command", - [UCSI_PPM_RESET] = "PPM_RESET", - [UCSI_CANCEL] = "CANCEL", - [UCSI_CONNECTOR_RESET] = "CONNECTOR_RESET", - [UCSI_ACK_CC_CI] = "ACK_CC_CI", - [UCSI_SET_NOTIFICATION_ENABLE] = "SET_NOTIFICATION_ENABLE", - [UCSI_GET_CAPABILITY] = "GET_CAPABILITY", - [UCSI_GET_CONNECTOR_CAPABILITY] = "GET_CONNECTOR_CAPABILITY", - [UCSI_SET_UOM] = "SET_UOM", - [UCSI_SET_UOR] = "SET_UOR", - [UCSI_SET_PDM] = "SET_PDM", - [UCSI_SET_PDR] = "SET_PDR", - [UCSI_GET_ALTERNATE_MODES] = "GET_ALTERNATE_MODES", - [UCSI_GET_CAM_SUPPORTED] = "GET_CAM_SUPPORTED", - [UCSI_GET_CURRENT_CAM] = "GET_CURRENT_CAM", - [UCSI_SET_NEW_CAM] = "SET_NEW_CAM", - [UCSI_GET_PDOS] = "GET_PDOS", - [UCSI_GET_CABLE_PROPERTY] = "GET_CABLE_PROPERTY", - [UCSI_GET_CONNECTOR_STATUS] = "GET_CONNECTOR_STATUS", - [UCSI_GET_ERROR_STATUS] = "GET_ERROR_STATUS", -}; - -static inline const char *ucsi_cmd_str(u64 raw_cmd) -{ - u8 cmd = raw_cmd & GENMASK(7, 0); - - return ucsi_cmd_strs[(cmd >= ARRAY_SIZE(ucsi_cmd_strs)) ? 0 : cmd]; -} - -static const char * const ucsi_ack_strs[] = { - [0] = "", - [UCSI_ACK_EVENT] = "event", - [UCSI_ACK_CMD] = "command", -}; - -static inline const char *ucsi_ack_str(u8 ack) -{ - return ucsi_ack_strs[(ack >= ARRAY_SIZE(ucsi_ack_strs)) ? 0 : ack]; -} - -static inline const char *ucsi_cci_str(u32 cci) -{ - if (cci & GENMASK(7, 0)) { - if (cci & BIT(29)) - return "Event pending (ACK completed)"; - if (cci & BIT(31)) - return "Event pending (command completed)"; - return "Connector Change"; - } - if (cci & BIT(29)) - return "ACK completed"; - if (cci & BIT(31)) - return "Command completed"; - - return ""; -} - -#endif /* __UCSI_DEBUG_H */ diff --git a/drivers/usb/typec/ucsi/trace.c b/drivers/usb/typec/ucsi/trace.c index d9a6ff6e673c..ffa3b4c3f338 100644 --- a/drivers/usb/typec/ucsi/trace.c +++ b/drivers/usb/typec/ucsi/trace.c @@ -1,3 +1,62 @@ // SPDX-License-Identifier: GPL-2.0 #define CREATE_TRACE_POINTS +#include "ucsi.h" #include "trace.h" + +static const char * const ucsi_cmd_strs[] = { + [0] = "Unknown command", + [UCSI_PPM_RESET] = "PPM_RESET", + [UCSI_CANCEL] = "CANCEL", + [UCSI_CONNECTOR_RESET] = "CONNECTOR_RESET", + [UCSI_ACK_CC_CI] = "ACK_CC_CI", + [UCSI_SET_NOTIFICATION_ENABLE] = "SET_NOTIFICATION_ENABLE", + [UCSI_GET_CAPABILITY] = "GET_CAPABILITY", + [UCSI_GET_CONNECTOR_CAPABILITY] = "GET_CONNECTOR_CAPABILITY", + [UCSI_SET_UOM] = "SET_UOM", + [UCSI_SET_UOR] = "SET_UOR", + [UCSI_SET_PDM] = "SET_PDM", + [UCSI_SET_PDR] = "SET_PDR", + [UCSI_GET_ALTERNATE_MODES] = "GET_ALTERNATE_MODES", + [UCSI_GET_CAM_SUPPORTED] = "GET_CAM_SUPPORTED", + [UCSI_GET_CURRENT_CAM] = "GET_CURRENT_CAM", + [UCSI_SET_NEW_CAM] = "SET_NEW_CAM", + [UCSI_GET_PDOS] = "GET_PDOS", + [UCSI_GET_CABLE_PROPERTY] = "GET_CABLE_PROPERTY", + [UCSI_GET_CONNECTOR_STATUS] = "GET_CONNECTOR_STATUS", + [UCSI_GET_ERROR_STATUS] = "GET_ERROR_STATUS", +}; + +const char *ucsi_cmd_str(u64 raw_cmd) +{ + u8 cmd = raw_cmd & GENMASK(7, 0); + + return ucsi_cmd_strs[(cmd >= ARRAY_SIZE(ucsi_cmd_strs)) ? 0 : cmd]; +} + +static const char * const ucsi_ack_strs[] = { + [0] = "", + [UCSI_ACK_EVENT] = "event", + [UCSI_ACK_CMD] = "command", +}; + +const char *ucsi_ack_str(u8 ack) +{ + return ucsi_ack_strs[(ack >= ARRAY_SIZE(ucsi_ack_strs)) ? 0 : ack]; +} + +const char *ucsi_cci_str(u32 cci) +{ + if (cci & GENMASK(7, 0)) { + if (cci & BIT(29)) + return "Event pending (ACK completed)"; + if (cci & BIT(31)) + return "Event pending (command completed)"; + return "Connector Change"; + } + if (cci & BIT(29)) + return "ACK completed"; + if (cci & BIT(31)) + return "Command completed"; + + return ""; +} diff --git a/drivers/usb/typec/ucsi/trace.h b/drivers/usb/typec/ucsi/trace.h index d5092446ecc6..5e2906df2db7 100644 --- a/drivers/usb/typec/ucsi/trace.h +++ b/drivers/usb/typec/ucsi/trace.h @@ -7,8 +7,11 @@ #define __UCSI_TRACE_H #include <linux/tracepoint.h> -#include "ucsi.h" -#include "debug.h" + +const char *ucsi_cmd_str(u64 raw_cmd); +const char *ucsi_ack_str(u8 ack); +const char *ucsi_cci_str(u32 cci); +const char *ucsi_recipient_str(u8 recipient); DECLARE_EVENT_CLASS(ucsi_log_ack, TP_PROTO(u8 ack), diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index a20b65cb6678..2f86b28fa3da 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USBIP_CORE tristate "USB/IP support" depends on NET diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 1e592ec94ba4..f46ee1fefe02 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -702,8 +702,10 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag } vdev = &vhci_hcd->vdev[portnum-1]; - /* patch to usb_sg_init() is in 2.5.60 */ - BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); + if (!urb->transfer_buffer && urb->transfer_buffer_length) { + dev_dbg(dev, "Null URB transfer buffer\n"); + return -EINVAL; + } spin_lock_irqsave(&vhci->lock, flags); diff --git a/drivers/usb/usbip/vudc_dev.c b/drivers/usb/usbip/vudc_dev.c index 1634d8698e15..a72c17ff1c6a 100644 --- a/drivers/usb/usbip/vudc_dev.c +++ b/drivers/usb/usbip/vudc_dev.c @@ -297,7 +297,8 @@ static void vep_free_request(struct usb_ep *_ep, struct usb_request *_req) { struct vrequest *req; - if (WARN_ON(!_ep || !_req)) + /* ep is always valid here - see usb_ep_free_request() */ + if (!_req) return; req = to_vrequest(_req); diff --git a/drivers/usb/wusbcore/Kconfig b/drivers/usb/wusbcore/Kconfig index 348de1d6726e..12e89189ca7d 100644 --- a/drivers/usb/wusbcore/Kconfig +++ b/drivers/usb/wusbcore/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Wireless USB Core configuration # |