Skip to content

Commit

Permalink
Merge tag 'usb-5.16-rc6' 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 small USB driver fixes for reported problems.
  They include:

   - dwc2 driver fixes

   - xhci driver fixes

   - cdnsp driver fixes

   - typec driver fix

   - gadget u_ether driver fix

   - new quirk additions

   - usb gadget endpoint calculation fix

   - usb serial new device ids

   - revert of a xhci-dbg change that broke early debug booting

  All changes, except for the revert, have been in linux-next with no
  reported problems. The revert was from yesterday, and it was reported
  by the developers affected that it resolved their problem"

* tag 'usb-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  Revert "usb: early: convert to readl_poll_timeout_atomic()"
  usb: typec: tcpm: fix tcpm unregister port but leave a pending timer
  usb: cdnsp: Fix lack of spin_lock_irqsave/spin_lock_restore
  USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04)
  usb: xhci: Extend support for runtime power management for AMD's Yellow carp.
  usb: dwc2: fix STM ID/VBUS detection startup delay in dwc2_driver_probe
  USB: gadget: bRequestType is a bitfield, not a enum
  USB: serial: option: add Telit FN990 compositions
  USB: serial: cp210x: fix CP2105 GPIO registration
  usb: cdnsp: Fix incorrect status for control request
  usb: cdnsp: Fix issue in cdnsp_log_ep trace event
  usb: cdnsp: Fix incorrect calling of cdnsp_died function
  usb: xhci-mtk: fix list_del warning when enable list debug
  usb: gadget: u_ether: fix race in setting MAC address in setup phase
  • Loading branch information
Linus Torvalds committed Dec 18, 2021
2 parents 0f03adc + c4d936e commit fb7d082
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 35 deletions.
12 changes: 12 additions & 0 deletions drivers/usb/cdns3/cdnsp-gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1541,15 +1541,27 @@ static int cdnsp_gadget_pullup(struct usb_gadget *gadget, int is_on)
{
struct cdnsp_device *pdev = gadget_to_cdnsp(gadget);
struct cdns *cdns = dev_get_drvdata(pdev->dev);
unsigned long flags;

trace_cdnsp_pullup(is_on);

/*
* Disable events handling while controller is being
* enabled/disabled.
*/
disable_irq(cdns->dev_irq);
spin_lock_irqsave(&pdev->lock, flags);

if (!is_on) {
cdnsp_reset_device(pdev);
cdns_clear_vbus(cdns);
} else {
cdns_set_vbus(cdns);
}

spin_unlock_irqrestore(&pdev->lock, flags);
enable_irq(cdns->dev_irq);

return 0;
}

Expand Down
11 changes: 10 additions & 1 deletion drivers/usb/cdns3/cdnsp-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,8 @@ static void cdnsp_process_ctrl_td(struct cdnsp_device *pdev,
return;
}

*status = 0;

cdnsp_finish_td(pdev, td, event, pep, status);
}

Expand Down Expand Up @@ -1523,7 +1525,14 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data)
spin_lock_irqsave(&pdev->lock, flags);

if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) {
cdnsp_died(pdev);
/*
* While removing or stopping driver there may still be deferred
* not handled interrupt which should not be treated as error.
* Driver should simply ignore it.
*/
if (pdev->gadget_driver)
cdnsp_died(pdev);

spin_unlock_irqrestore(&pdev->lock, flags);
return IRQ_HANDLED;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/cdns3/cdnsp-trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ DECLARE_EVENT_CLASS(cdnsp_log_ep,
__entry->first_prime_det = pep->stream_info.first_prime_det;
__entry->drbls_count = pep->stream_info.drbls_count;
),
TP_printk("%s: SID: %08x ep state: %x stream: enabled: %d num %d "
TP_printk("%s: SID: %08x, ep state: %x, stream: enabled: %d num %d "
"tds %d, first prime: %d drbls %d",
__get_str(name), __entry->state, __entry->stream_id,
__get_str(name), __entry->stream_id, __entry->state,
__entry->enabled, __entry->num_streams, __entry->td_count,
__entry->first_prime_det, __entry->drbls_count)
);
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/core/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x1532, 0x0116), .driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },

/* Lenovo USB-C to Ethernet Adapter RTL8153-04 */
{ USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },

/* Lenovo Powered USB-C Travel Hub (4X90S92381, RTL8153 GigE) */
{ USB_DEVICE(0x17ef, 0x721e), .driver_info = USB_QUIRK_NO_LPM },

Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/dwc2/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,9 @@ static int dwc2_driver_probe(struct platform_device *dev)
ggpio |= GGPIO_STM32_OTG_GCCFG_IDEN;
ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
dwc2_writel(hsotg, ggpio, GGPIO);

/* ID/VBUS detection startup time */
usleep_range(5000, 7000);
}

retval = dwc2_drd_init(hsotg);
Expand Down
15 changes: 11 additions & 4 deletions drivers/usb/early/xhci-dbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <linux/pci_ids.h>
#include <linux/memblock.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <asm/pci-direct.h>
#include <asm/fixmap.h>
#include <linux/bcd.h>
Expand Down Expand Up @@ -136,9 +135,17 @@ static int handshake(void __iomem *ptr, u32 mask, u32 done, int wait, int delay)
{
u32 result;

return readl_poll_timeout_atomic(ptr, result,
((result & mask) == done),
delay, wait);
/* Can not use readl_poll_timeout_atomic() for early boot things */
do {
result = readl(ptr);
result &= mask;
if (result == done)
return 0;
udelay(delay);
wait -= delay;
} while (wait > 0);

return -ETIMEDOUT;
}

static void __init xdbc_bios_handoff(void)
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -1680,14 +1680,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
u8 endp;

if (w_length > USB_COMP_EP0_BUFSIZ) {
if (ctrl->bRequestType == USB_DIR_OUT) {
goto done;
} else {
if (ctrl->bRequestType & USB_DIR_IN) {
/* Cast away the const, we are going to overwrite on purpose. */
__le16 *temp = (__le16 *)&ctrl->wLength;

*temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
w_length = USB_COMP_EP0_BUFSIZ;
} else {
goto done;
}
}

Expand Down
16 changes: 6 additions & 10 deletions drivers/usb/gadget/function/u_ether.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/etherdevice.h>

#include "u_ether.h"

Expand Down Expand Up @@ -863,35 +864,30 @@ int gether_register_netdev(struct net_device *net)
{
struct eth_dev *dev;
struct usb_gadget *g;
struct sockaddr sa;
int status;

if (!net->dev.parent)
return -EINVAL;
dev = netdev_priv(net);
g = dev->gadget;

net->addr_assign_type = NET_ADDR_RANDOM;
eth_hw_addr_set(net, dev->dev_mac);

status = register_netdev(net);
if (status < 0) {
dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
return status;
} else {
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
INFO(dev, "MAC %pM\n", dev->dev_mac);

/* two kinds of host-initiated state changes:
* - iff DATA transfer is active, carrier is "on"
* - tx queueing enabled if open *and* carrier is "on"
*/
netif_carrier_off(net);
}
sa.sa_family = net->type;
memcpy(sa.sa_data, dev->dev_mac, ETH_ALEN);
rtnl_lock();
status = dev_set_mac_address(net, &sa, NULL);
rtnl_unlock();
if (status)
pr_warn("cannot set self ethernet address: %d\n", status);
else
INFO(dev, "MAC %pM\n", dev->dev_mac);

return status;
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/legacy/dbgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,14 +346,14 @@ static int dbgp_setup(struct usb_gadget *gadget,
u16 len = 0;

if (length > DBGP_REQ_LEN) {
if (ctrl->bRequestType == USB_DIR_OUT) {
return err;
} else {
if (ctrl->bRequestType & USB_DIR_IN) {
/* Cast away the const, we are going to overwrite on purpose. */
__le16 *temp = (__le16 *)&ctrl->wLength;

*temp = cpu_to_le16(DBGP_REQ_LEN);
length = DBGP_REQ_LEN;
} else {
return err;
}
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/legacy/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1334,14 +1334,14 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
u16 w_length = le16_to_cpu(ctrl->wLength);

if (w_length > RBUF_SIZE) {
if (ctrl->bRequestType == USB_DIR_OUT) {
return value;
} else {
if (ctrl->bRequestType & USB_DIR_IN) {
/* Cast away the const, we are going to overwrite on purpose. */
__le16 *temp = (__le16 *)&ctrl->wLength;

*temp = cpu_to_le16(RBUF_SIZE);
w_length = RBUF_SIZE;
} else {
return value;
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/xhci-mtk-sch.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ int xhci_mtk_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)

ret = xhci_check_bandwidth(hcd, udev);
if (!ret)
INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
list_del_init(&mtk->bw_ep_chk_list);

return ret;
}
Expand Down
6 changes: 5 additions & 1 deletion drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 0x161e
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 0x15d6
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 0x15d7
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 0x161c
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8 0x161f

#define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
Expand Down Expand Up @@ -330,7 +332,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 ||
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 ||
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 ||
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6))
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 ||
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 ||
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8))
xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;

if (xhci->quirks & XHCI_RESET_ON_RESUME)
Expand Down
6 changes: 4 additions & 2 deletions drivers/usb/serial/cp210x.c
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,8 @@ static int cp2105_gpioconf_init(struct usb_serial *serial)

/* 2 banks of GPIO - One for the pins taken from each serial port */
if (intf_num == 0) {
priv->gc.ngpio = 2;

if (mode.eci == CP210X_PIN_MODE_MODEM) {
/* mark all GPIOs of this interface as reserved */
priv->gpio_altfunc = 0xff;
Expand All @@ -1645,8 +1647,9 @@ static int cp2105_gpioconf_init(struct usb_serial *serial)
priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
CP210X_ECI_GPIO_MODE_MASK) >>
CP210X_ECI_GPIO_MODE_OFFSET);
priv->gc.ngpio = 2;
} else if (intf_num == 1) {
priv->gc.ngpio = 3;

if (mode.sci == CP210X_PIN_MODE_MODEM) {
/* mark all GPIOs of this interface as reserved */
priv->gpio_altfunc = 0xff;
Expand All @@ -1657,7 +1660,6 @@ static int cp2105_gpioconf_init(struct usb_serial *serial)
priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
CP210X_SCI_GPIO_MODE_MASK) >>
CP210X_SCI_GPIO_MODE_OFFSET);
priv->gc.ngpio = 3;
} else {
return -ENODEV;
}
Expand Down
8 changes: 8 additions & 0 deletions drivers/usb/serial/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,14 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
Expand Down
18 changes: 13 additions & 5 deletions drivers/usb/typec/tcpm/tcpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ struct tcpm_port {

bool attached;
bool connected;
bool registered;
bool pd_supported;
enum typec_port_type port_type;

Expand Down Expand Up @@ -6291,31 +6292,35 @@ static enum hrtimer_restart state_machine_timer_handler(struct hrtimer *timer)
{
struct tcpm_port *port = container_of(timer, struct tcpm_port, state_machine_timer);

kthread_queue_work(port->wq, &port->state_machine);
if (port->registered)
kthread_queue_work(port->wq, &port->state_machine);
return HRTIMER_NORESTART;
}

static enum hrtimer_restart vdm_state_machine_timer_handler(struct hrtimer *timer)
{
struct tcpm_port *port = container_of(timer, struct tcpm_port, vdm_state_machine_timer);

kthread_queue_work(port->wq, &port->vdm_state_machine);
if (port->registered)
kthread_queue_work(port->wq, &port->vdm_state_machine);
return HRTIMER_NORESTART;
}

static enum hrtimer_restart enable_frs_timer_handler(struct hrtimer *timer)
{
struct tcpm_port *port = container_of(timer, struct tcpm_port, enable_frs_timer);

kthread_queue_work(port->wq, &port->enable_frs);
if (port->registered)
kthread_queue_work(port->wq, &port->enable_frs);
return HRTIMER_NORESTART;
}

static enum hrtimer_restart send_discover_timer_handler(struct hrtimer *timer)
{
struct tcpm_port *port = container_of(timer, struct tcpm_port, send_discover_timer);

kthread_queue_work(port->wq, &port->send_discover_work);
if (port->registered)
kthread_queue_work(port->wq, &port->send_discover_work);
return HRTIMER_NORESTART;
}

Expand Down Expand Up @@ -6403,6 +6408,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
typec_port_register_altmodes(port->typec_port,
&tcpm_altmode_ops, port,
port->port_altmode, ALTMODE_DISCOVERY_MAX);
port->registered = true;

mutex_lock(&port->lock);
tcpm_init(port);
Expand All @@ -6424,6 +6430,9 @@ void tcpm_unregister_port(struct tcpm_port *port)
{
int i;

port->registered = false;
kthread_destroy_worker(port->wq);

hrtimer_cancel(&port->send_discover_timer);
hrtimer_cancel(&port->enable_frs_timer);
hrtimer_cancel(&port->vdm_state_machine_timer);
Expand All @@ -6435,7 +6444,6 @@ void tcpm_unregister_port(struct tcpm_port *port)
typec_unregister_port(port->typec_port);
usb_role_switch_put(port->role_sw);
tcpm_debugfs_exit(port);
kthread_destroy_worker(port->wq);
}
EXPORT_SYMBOL_GPL(tcpm_unregister_port);

Expand Down

0 comments on commit fb7d082

Please sign in to comment.