USB fixes for 5.16-rc6
Here are a number of small USB driver fixes for reported problems for 5.16-rc6. 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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYb4SyA8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ynliACgusJ0z1JblgjetgAJGnCZb8G1hwgAoK0w2kB8 U00OQSDCsE4xNqKVGeyr =L8hW -----END PGP SIGNATURE----- Merge tag 'usb-5.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
commit
fb7d082913
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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 },
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -863,19 +864,23 @@ 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"
|
||||
|
@ -883,15 +888,6 @@ int gether_register_netdev(struct net_device *net)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -324,6 +324,7 @@ struct tcpm_port {
|
|||
|
||||
bool attached;
|
||||
bool connected;
|
||||
bool registered;
|
||||
bool pd_supported;
|
||||
enum typec_port_type port_type;
|
||||
|
||||
|
@ -6291,7 +6292,8 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -6299,7 +6301,8 @@ static enum hrtimer_restart vdm_state_machine_timer_handler(struct hrtimer *time
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -6307,7 +6310,8 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -6315,7 +6319,8 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue