Skip to content

Commit

Permalink
Merge tag 'usb-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of USB driver fixes for reported problems for
  4.17-rc3.

  The "largest" here is a number of phy core changes for reported
  problems with the -rc1 release. There's also the usual musb and xhci
  fixes, as well as new device id updates. There are also some usbip
  fixes for reported problems as more people start to use that code with
  containers.

  All of these have been in linux-next with no reported issues, except
  the last few new device ids, which are "obviously correct" :)"

* tag 'usb-4.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (26 commits)
  USB: musb: dsps: drop duplicate phy initialisation
  USB: musb: host: prevent core phy initialisation
  usb: core: phy: add the SPDX-License-Identifier and include guard
  xhci: Fix Kernel oops in xhci dbgtty
  usb: select USB_COMMON for usb role switch config
  usb: core: phy: add missing forward declaration for "struct device"
  usb: core: phy: make it a no-op if CONFIG_GENERIC_PHY is disabled
  usb: core: use phy_exit during suspend if wake up is not supported
  usb: core: split usb_phy_roothub_{init,alloc}
  usb: core: phy: fix return value of usb_phy_roothub_exit()
  usb: typec: ucsi: Increase command completion timeout value
  Revert "xhci: plat: Register shutdown for xhci_plat"
  usb: core: Add quirk for HP v222w 16GB Mini
  Documentation: typec.rst: Use literal-block element with ascii art
  usb: typec: ucsi: fix tracepoint related build error
  usbip: usbip_event: fix to not print kernel pointer address
  usbip: usbip_host: fix to hold parent lock for device_attach() calls
  usbip: vhci_hcd: Fix usb device and sockfd leaks
  usbip: vhci_hcd: check rhport before using in vhci_hub_control()
  USB: Increment wakeup count on remote wakeup.
  ...
  • Loading branch information
torvalds committed Apr 27, 2018
2 parents 7ff5000 + 573a094 commit 1993cbf
Show file tree
Hide file tree
Showing 24 changed files with 185 additions and 61 deletions.
5 changes: 4 additions & 1 deletion Documentation/devicetree/bindings/usb/usb-xhci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ Required properties:
- interrupts: one XHCI interrupt should be described here.

Optional properties:
- clocks: reference to a clock
- clocks: reference to the clocks
- clock-names: mandatory if there is a second clock, in this case
the name must be "core" for the first clock and "reg" for the
second one
- usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
- usb3-lpm-capable: determines if platform is USB3 LPM capable
- quirk-broken-port-ped: set if the controller has broken port disable mechanism
Expand Down
2 changes: 1 addition & 1 deletion Documentation/driver-api/usb/typec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ If the connector is dual-role capable, there may also be a switch for the data
role. USB Type-C Connector Class does not supply separate API for them. The
port drivers can use USB Role Class API with those.

Illustration of the muxes behind a connector that supports an alternate mode:
Illustration of the muxes behind a connector that supports an alternate mode::

------------------------
| Connector |
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -207,5 +207,6 @@ config USB_ULPI_BUS

config USB_ROLE_SWITCH
tristate
select USB_COMMON

endif # USB_SUPPORT
19 changes: 13 additions & 6 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
hcd->state = HC_STATE_SUSPENDED;

if (!PMSG_IS_AUTO(msg))
usb_phy_roothub_power_off(hcd->phy_roothub);
usb_phy_roothub_suspend(hcd->self.sysdev,
hcd->phy_roothub);

/* Did we race with a root-hub wakeup event? */
if (rhdev->do_remote_wakeup) {
Expand Down Expand Up @@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
}

if (!PMSG_IS_AUTO(msg)) {
status = usb_phy_roothub_power_on(hcd->phy_roothub);
status = usb_phy_roothub_resume(hcd->self.sysdev,
hcd->phy_roothub);
if (status)
return status;
}
Expand Down Expand Up @@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
}
} else {
hcd->state = old_state;
usb_phy_roothub_power_off(hcd->phy_roothub);
usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub);
dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
"resume", status);
if (status != -ESHUTDOWN)
Expand Down Expand Up @@ -2377,6 +2379,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)

spin_lock_irqsave (&hcd_root_hub_lock, flags);
if (hcd->rh_registered) {
pm_wakeup_event(&hcd->self.root_hub->dev, 0);
set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
queue_work(pm_wq, &hcd->wakeup_work);
}
Expand Down Expand Up @@ -2758,12 +2761,16 @@ int usb_add_hcd(struct usb_hcd *hcd,
}

if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev);
if (IS_ERR(hcd->phy_roothub)) {
retval = PTR_ERR(hcd->phy_roothub);
goto err_phy_roothub_init;
goto err_phy_roothub_alloc;
}

retval = usb_phy_roothub_init(hcd->phy_roothub);
if (retval)
goto err_phy_roothub_alloc;

retval = usb_phy_roothub_power_on(hcd->phy_roothub);
if (retval)
goto err_usb_phy_roothub_power_on;
Expand Down Expand Up @@ -2936,7 +2943,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
usb_phy_roothub_power_off(hcd->phy_roothub);
err_usb_phy_roothub_power_on:
usb_phy_roothub_exit(hcd->phy_roothub);
err_phy_roothub_init:
err_phy_roothub_alloc:
if (hcd->remove_phy && hcd->usb_phy) {
usb_phy_shutdown(hcd->usb_phy);
usb_put_phy(hcd->usb_phy);
Expand Down
10 changes: 9 additions & 1 deletion drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,12 +653,17 @@ void usb_wakeup_notification(struct usb_device *hdev,
unsigned int portnum)
{
struct usb_hub *hub;
struct usb_port *port_dev;

if (!hdev)
return;

hub = usb_hub_to_struct_hub(hdev);
if (hub) {
port_dev = hub->ports[portnum - 1];
if (port_dev && port_dev->child)
pm_wakeup_event(&port_dev->child->dev, 0);

set_bit(portnum, hub->wakeup_bits);
kick_hub_wq(hub);
}
Expand Down Expand Up @@ -3434,8 +3439,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)

/* Skip the initial Clear-Suspend step for a remote wakeup */
status = hub_port_status(hub, port1, &portstatus, &portchange);
if (status == 0 && !port_is_suspended(hub, portstatus))
if (status == 0 && !port_is_suspended(hub, portstatus)) {
if (portchange & USB_PORT_STAT_C_SUSPEND)
pm_wakeup_event(&udev->dev, 0);
goto SuspendCleared;
}

/* see 7.1.7.7; affects power usage, but not budgeting */
if (hub_is_superspeed(hub->hdev))
Expand Down
93 changes: 66 additions & 27 deletions drivers/usb/core/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,6 @@ struct usb_phy_roothub {
struct list_head list;
};

static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
{
struct usb_phy_roothub *roothub_entry;

roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
if (!roothub_entry)
return ERR_PTR(-ENOMEM);

INIT_LIST_HEAD(&roothub_entry->list);

return roothub_entry;
}

static int usb_phy_roothub_add_phy(struct device *dev, int index,
struct list_head *list)
{
Expand All @@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index,
return PTR_ERR(phy);
}

roothub_entry = usb_phy_roothub_alloc(dev);
if (IS_ERR(roothub_entry))
return PTR_ERR(roothub_entry);
roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
if (!roothub_entry)
return -ENOMEM;

INIT_LIST_HEAD(&roothub_entry->list);

roothub_entry->phy = phy;

Expand All @@ -56,28 +45,44 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index,
return 0;
}

struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
{
struct usb_phy_roothub *phy_roothub;
struct usb_phy_roothub *roothub_entry;
struct list_head *head;
int i, num_phys, err;

if (!IS_ENABLED(CONFIG_GENERIC_PHY))
return NULL;

num_phys = of_count_phandle_with_args(dev->of_node, "phys",
"#phy-cells");
if (num_phys <= 0)
return NULL;

phy_roothub = usb_phy_roothub_alloc(dev);
if (IS_ERR(phy_roothub))
return phy_roothub;
phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL);
if (!phy_roothub)
return ERR_PTR(-ENOMEM);

INIT_LIST_HEAD(&phy_roothub->list);

for (i = 0; i < num_phys; i++) {
err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list);
if (err)
goto err_out;
return ERR_PTR(err);
}

return phy_roothub;
}
EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc);

int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub)
{
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) {
Expand All @@ -86,14 +91,13 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
goto err_exit_phys;
}

return phy_roothub;
return 0;

err_exit_phys:
list_for_each_entry_continue_reverse(roothub_entry, head, list)
phy_exit(roothub_entry->phy);

err_out:
return ERR_PTR(err);
return err;
}
EXPORT_SYMBOL_GPL(usb_phy_roothub_init);

Expand All @@ -111,7 +115,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub)
list_for_each_entry(roothub_entry, head, list) {
err = phy_exit(roothub_entry->phy);
if (err)
ret = ret;
ret = err;
}

return ret;
Expand Down Expand Up @@ -156,3 +160,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub)
phy_power_off(roothub_entry->phy);
}
EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off);

int usb_phy_roothub_suspend(struct device *controller_dev,
struct usb_phy_roothub *phy_roothub)
{
usb_phy_roothub_power_off(phy_roothub);

/* keep the PHYs initialized so the device can wake up the system */
if (device_may_wakeup(controller_dev))
return 0;

return usb_phy_roothub_exit(phy_roothub);
}
EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend);

int usb_phy_roothub_resume(struct device *controller_dev,
struct usb_phy_roothub *phy_roothub)
{
int err;

/* if the device can't wake up the system _exit was called */
if (!device_may_wakeup(controller_dev)) {
err = usb_phy_roothub_init(phy_roothub);
if (err)
return err;
}

err = usb_phy_roothub_power_on(phy_roothub);

/* undo _init if _power_on failed */
if (err && !device_may_wakeup(controller_dev))
usb_phy_roothub_exit(phy_roothub);

return err;
}
EXPORT_SYMBOL_GPL(usb_phy_roothub_resume);
22 changes: 21 additions & 1 deletion drivers/usb/core/phy.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* USB roothub wrapper
*
* Copyright (C) 2018 Martin Blumenstingl <[email protected]>
*/

#ifndef __USB_CORE_PHY_H_
#define __USB_CORE_PHY_H_

struct device;
struct usb_phy_roothub;

struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev);
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_power_on(struct usb_phy_roothub *phy_roothub);
void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub);

int usb_phy_roothub_suspend(struct device *controller_dev,
struct usb_phy_roothub *phy_roothub);
int usb_phy_roothub_resume(struct device *controller_dev,
struct usb_phy_roothub *phy_roothub);

#endif /* __USB_CORE_PHY_H_ */
3 changes: 3 additions & 0 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x03f0, 0x0701), .driver_info =
USB_QUIRK_STRING_FETCH_255 },

/* HP v222w 16GB Mini USB Drive */
{ USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },

/* Creative SB Audigy 2 NX */
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },

Expand Down
8 changes: 5 additions & 3 deletions drivers/usb/host/xhci-dbgtty.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,11 @@ int xhci_dbc_tty_register_driver(struct xhci_hcd *xhci)

void xhci_dbc_tty_unregister_driver(void)
{
tty_unregister_driver(dbc_tty_driver);
put_tty_driver(dbc_tty_driver);
dbc_tty_driver = NULL;
if (dbc_tty_driver) {
tty_unregister_driver(dbc_tty_driver);
put_tty_driver(dbc_tty_driver);
dbc_tty_driver = NULL;
}
}

static void dbc_rx_push(unsigned long _port)
Expand Down
5 changes: 4 additions & 1 deletion drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
xhci->quirks |= XHCI_AMD_PLL_FIX;

if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43bb)
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
(pdev->device == 0x15e0 ||
pdev->device == 0x15e1 ||
pdev->device == 0x43bb))
xhci->quirks |= XHCI_SUSPEND_DELAY;

if (pdev->vendor == PCI_VENDOR_ID_AMD)
Expand Down
Loading

0 comments on commit 1993cbf

Please sign in to comment.