mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 16:49:22 +00:00
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
15 changed files with 87 additions and 35 deletions
|
@ -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 cdnsp_device *pdev = gadget_to_cdnsp(gadget);
|
||||||
struct cdns *cdns = dev_get_drvdata(pdev->dev);
|
struct cdns *cdns = dev_get_drvdata(pdev->dev);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
trace_cdnsp_pullup(is_on);
|
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) {
|
if (!is_on) {
|
||||||
cdnsp_reset_device(pdev);
|
cdnsp_reset_device(pdev);
|
||||||
cdns_clear_vbus(cdns);
|
cdns_clear_vbus(cdns);
|
||||||
} else {
|
} else {
|
||||||
cdns_set_vbus(cdns);
|
cdns_set_vbus(cdns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&pdev->lock, flags);
|
||||||
|
enable_irq(cdns->dev_irq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1029,6 +1029,8 @@ static void cdnsp_process_ctrl_td(struct cdnsp_device *pdev,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*status = 0;
|
||||||
|
|
||||||
cdnsp_finish_td(pdev, td, event, pep, status);
|
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);
|
spin_lock_irqsave(&pdev->lock, flags);
|
||||||
|
|
||||||
if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) {
|
if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) {
|
||||||
|
/*
|
||||||
|
* 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);
|
cdnsp_died(pdev);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&pdev->lock, flags);
|
spin_unlock_irqrestore(&pdev->lock, flags);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,9 @@ DECLARE_EVENT_CLASS(cdnsp_log_ep,
|
||||||
__entry->first_prime_det = pep->stream_info.first_prime_det;
|
__entry->first_prime_det = pep->stream_info.first_prime_det;
|
||||||
__entry->drbls_count = pep->stream_info.drbls_count;
|
__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",
|
"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->enabled, __entry->num_streams, __entry->td_count,
|
||||||
__entry->first_prime_det, __entry->drbls_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_DEVICE(0x1532, 0x0116), .driver_info =
|
||||||
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
|
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) */
|
/* Lenovo Powered USB-C Travel Hub (4X90S92381, RTL8153 GigE) */
|
||||||
{ USB_DEVICE(0x17ef, 0x721e), .driver_info = USB_QUIRK_NO_LPM },
|
{ 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_IDEN;
|
||||||
ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
|
ggpio |= GGPIO_STM32_OTG_GCCFG_VBDEN;
|
||||||
dwc2_writel(hsotg, ggpio, GGPIO);
|
dwc2_writel(hsotg, ggpio, GGPIO);
|
||||||
|
|
||||||
|
/* ID/VBUS detection startup time */
|
||||||
|
usleep_range(5000, 7000);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = dwc2_drd_init(hsotg);
|
retval = dwc2_drd_init(hsotg);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include <linux/pci_ids.h>
|
#include <linux/pci_ids.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/iopoll.h>
|
|
||||||
#include <asm/pci-direct.h>
|
#include <asm/pci-direct.h>
|
||||||
#include <asm/fixmap.h>
|
#include <asm/fixmap.h>
|
||||||
#include <linux/bcd.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;
|
u32 result;
|
||||||
|
|
||||||
return readl_poll_timeout_atomic(ptr, result,
|
/* Can not use readl_poll_timeout_atomic() for early boot things */
|
||||||
((result & mask) == done),
|
do {
|
||||||
delay, wait);
|
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)
|
static void __init xdbc_bios_handoff(void)
|
||||||
|
|
|
@ -1680,14 +1680,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||||
u8 endp;
|
u8 endp;
|
||||||
|
|
||||||
if (w_length > USB_COMP_EP0_BUFSIZ) {
|
if (w_length > USB_COMP_EP0_BUFSIZ) {
|
||||||
if (ctrl->bRequestType == USB_DIR_OUT) {
|
if (ctrl->bRequestType & USB_DIR_IN) {
|
||||||
goto done;
|
|
||||||
} else {
|
|
||||||
/* Cast away the const, we are going to overwrite on purpose. */
|
/* Cast away the const, we are going to overwrite on purpose. */
|
||||||
__le16 *temp = (__le16 *)&ctrl->wLength;
|
__le16 *temp = (__le16 *)&ctrl->wLength;
|
||||||
|
|
||||||
*temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
|
*temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
|
||||||
w_length = USB_COMP_EP0_BUFSIZ;
|
w_length = USB_COMP_EP0_BUFSIZ;
|
||||||
|
} else {
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
|
#include <linux/etherdevice.h>
|
||||||
|
|
||||||
#include "u_ether.h"
|
#include "u_ether.h"
|
||||||
|
|
||||||
|
@ -863,19 +864,23 @@ int gether_register_netdev(struct net_device *net)
|
||||||
{
|
{
|
||||||
struct eth_dev *dev;
|
struct eth_dev *dev;
|
||||||
struct usb_gadget *g;
|
struct usb_gadget *g;
|
||||||
struct sockaddr sa;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!net->dev.parent)
|
if (!net->dev.parent)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
dev = netdev_priv(net);
|
dev = netdev_priv(net);
|
||||||
g = dev->gadget;
|
g = dev->gadget;
|
||||||
|
|
||||||
|
net->addr_assign_type = NET_ADDR_RANDOM;
|
||||||
|
eth_hw_addr_set(net, dev->dev_mac);
|
||||||
|
|
||||||
status = register_netdev(net);
|
status = register_netdev(net);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
|
dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
|
||||||
return status;
|
return status;
|
||||||
} else {
|
} else {
|
||||||
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
|
INFO(dev, "HOST MAC %pM\n", dev->host_mac);
|
||||||
|
INFO(dev, "MAC %pM\n", dev->dev_mac);
|
||||||
|
|
||||||
/* two kinds of host-initiated state changes:
|
/* two kinds of host-initiated state changes:
|
||||||
* - iff DATA transfer is active, carrier is "on"
|
* - iff DATA transfer is active, carrier is "on"
|
||||||
|
@ -883,15 +888,6 @@ int gether_register_netdev(struct net_device *net)
|
||||||
*/
|
*/
|
||||||
netif_carrier_off(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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,14 +346,14 @@ static int dbgp_setup(struct usb_gadget *gadget,
|
||||||
u16 len = 0;
|
u16 len = 0;
|
||||||
|
|
||||||
if (length > DBGP_REQ_LEN) {
|
if (length > DBGP_REQ_LEN) {
|
||||||
if (ctrl->bRequestType == USB_DIR_OUT) {
|
if (ctrl->bRequestType & USB_DIR_IN) {
|
||||||
return err;
|
|
||||||
} else {
|
|
||||||
/* Cast away the const, we are going to overwrite on purpose. */
|
/* Cast away the const, we are going to overwrite on purpose. */
|
||||||
__le16 *temp = (__le16 *)&ctrl->wLength;
|
__le16 *temp = (__le16 *)&ctrl->wLength;
|
||||||
|
|
||||||
*temp = cpu_to_le16(DBGP_REQ_LEN);
|
*temp = cpu_to_le16(DBGP_REQ_LEN);
|
||||||
length = 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);
|
u16 w_length = le16_to_cpu(ctrl->wLength);
|
||||||
|
|
||||||
if (w_length > RBUF_SIZE) {
|
if (w_length > RBUF_SIZE) {
|
||||||
if (ctrl->bRequestType == USB_DIR_OUT) {
|
if (ctrl->bRequestType & USB_DIR_IN) {
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
/* Cast away the const, we are going to overwrite on purpose. */
|
/* Cast away the const, we are going to overwrite on purpose. */
|
||||||
__le16 *temp = (__le16 *)&ctrl->wLength;
|
__le16 *temp = (__le16 *)&ctrl->wLength;
|
||||||
|
|
||||||
*temp = cpu_to_le16(RBUF_SIZE);
|
*temp = cpu_to_le16(RBUF_SIZE);
|
||||||
w_length = 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);
|
ret = xhci_check_bandwidth(hcd, udev);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
INIT_LIST_HEAD(&mtk->bw_ep_chk_list);
|
list_del_init(&mtk->bw_ep_chk_list);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 0x161e
|
#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_5 0x15d6
|
||||||
#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 0x15d7
|
#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_1042_XHCI 0x1042
|
||||||
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
|
#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_3 ||
|
||||||
pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 ||
|
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_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;
|
xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
|
||||||
|
|
||||||
if (xhci->quirks & XHCI_RESET_ON_RESUME)
|
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 */
|
/* 2 banks of GPIO - One for the pins taken from each serial port */
|
||||||
if (intf_num == 0) {
|
if (intf_num == 0) {
|
||||||
|
priv->gc.ngpio = 2;
|
||||||
|
|
||||||
if (mode.eci == CP210X_PIN_MODE_MODEM) {
|
if (mode.eci == CP210X_PIN_MODE_MODEM) {
|
||||||
/* mark all GPIOs of this interface as reserved */
|
/* mark all GPIOs of this interface as reserved */
|
||||||
priv->gpio_altfunc = 0xff;
|
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) &
|
priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
|
||||||
CP210X_ECI_GPIO_MODE_MASK) >>
|
CP210X_ECI_GPIO_MODE_MASK) >>
|
||||||
CP210X_ECI_GPIO_MODE_OFFSET);
|
CP210X_ECI_GPIO_MODE_OFFSET);
|
||||||
priv->gc.ngpio = 2;
|
|
||||||
} else if (intf_num == 1) {
|
} else if (intf_num == 1) {
|
||||||
|
priv->gc.ngpio = 3;
|
||||||
|
|
||||||
if (mode.sci == CP210X_PIN_MODE_MODEM) {
|
if (mode.sci == CP210X_PIN_MODE_MODEM) {
|
||||||
/* mark all GPIOs of this interface as reserved */
|
/* mark all GPIOs of this interface as reserved */
|
||||||
priv->gpio_altfunc = 0xff;
|
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) &
|
priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) &
|
||||||
CP210X_SCI_GPIO_MODE_MASK) >>
|
CP210X_SCI_GPIO_MODE_MASK) >>
|
||||||
CP210X_SCI_GPIO_MODE_OFFSET);
|
CP210X_SCI_GPIO_MODE_OFFSET);
|
||||||
priv->gc.ngpio = 3;
|
|
||||||
} else {
|
} else {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1219,6 +1219,14 @@ static const struct usb_device_id option_ids[] = {
|
||||||
.driver_info = NCTRL(2) | RSVD(3) },
|
.driver_info = NCTRL(2) | RSVD(3) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */
|
||||||
.driver_info = NCTRL(0) | RSVD(1) },
|
.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),
|
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
||||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||||
|
|
|
@ -324,6 +324,7 @@ struct tcpm_port {
|
||||||
|
|
||||||
bool attached;
|
bool attached;
|
||||||
bool connected;
|
bool connected;
|
||||||
|
bool registered;
|
||||||
bool pd_supported;
|
bool pd_supported;
|
||||||
enum typec_port_type port_type;
|
enum typec_port_type port_type;
|
||||||
|
|
||||||
|
@ -6291,6 +6292,7 @@ static enum hrtimer_restart state_machine_timer_handler(struct hrtimer *timer)
|
||||||
{
|
{
|
||||||
struct tcpm_port *port = container_of(timer, struct tcpm_port, state_machine_timer);
|
struct tcpm_port *port = container_of(timer, struct tcpm_port, state_machine_timer);
|
||||||
|
|
||||||
|
if (port->registered)
|
||||||
kthread_queue_work(port->wq, &port->state_machine);
|
kthread_queue_work(port->wq, &port->state_machine);
|
||||||
return HRTIMER_NORESTART;
|
return HRTIMER_NORESTART;
|
||||||
}
|
}
|
||||||
|
@ -6299,6 +6301,7 @@ 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);
|
struct tcpm_port *port = container_of(timer, struct tcpm_port, vdm_state_machine_timer);
|
||||||
|
|
||||||
|
if (port->registered)
|
||||||
kthread_queue_work(port->wq, &port->vdm_state_machine);
|
kthread_queue_work(port->wq, &port->vdm_state_machine);
|
||||||
return HRTIMER_NORESTART;
|
return HRTIMER_NORESTART;
|
||||||
}
|
}
|
||||||
|
@ -6307,6 +6310,7 @@ static enum hrtimer_restart enable_frs_timer_handler(struct hrtimer *timer)
|
||||||
{
|
{
|
||||||
struct tcpm_port *port = container_of(timer, struct tcpm_port, enable_frs_timer);
|
struct tcpm_port *port = container_of(timer, struct tcpm_port, enable_frs_timer);
|
||||||
|
|
||||||
|
if (port->registered)
|
||||||
kthread_queue_work(port->wq, &port->enable_frs);
|
kthread_queue_work(port->wq, &port->enable_frs);
|
||||||
return HRTIMER_NORESTART;
|
return HRTIMER_NORESTART;
|
||||||
}
|
}
|
||||||
|
@ -6315,6 +6319,7 @@ static enum hrtimer_restart send_discover_timer_handler(struct hrtimer *timer)
|
||||||
{
|
{
|
||||||
struct tcpm_port *port = container_of(timer, struct tcpm_port, send_discover_timer);
|
struct tcpm_port *port = container_of(timer, struct tcpm_port, send_discover_timer);
|
||||||
|
|
||||||
|
if (port->registered)
|
||||||
kthread_queue_work(port->wq, &port->send_discover_work);
|
kthread_queue_work(port->wq, &port->send_discover_work);
|
||||||
return HRTIMER_NORESTART;
|
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,
|
typec_port_register_altmodes(port->typec_port,
|
||||||
&tcpm_altmode_ops, port,
|
&tcpm_altmode_ops, port,
|
||||||
port->port_altmode, ALTMODE_DISCOVERY_MAX);
|
port->port_altmode, ALTMODE_DISCOVERY_MAX);
|
||||||
|
port->registered = true;
|
||||||
|
|
||||||
mutex_lock(&port->lock);
|
mutex_lock(&port->lock);
|
||||||
tcpm_init(port);
|
tcpm_init(port);
|
||||||
|
@ -6424,6 +6430,9 @@ void tcpm_unregister_port(struct tcpm_port *port)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
port->registered = false;
|
||||||
|
kthread_destroy_worker(port->wq);
|
||||||
|
|
||||||
hrtimer_cancel(&port->send_discover_timer);
|
hrtimer_cancel(&port->send_discover_timer);
|
||||||
hrtimer_cancel(&port->enable_frs_timer);
|
hrtimer_cancel(&port->enable_frs_timer);
|
||||||
hrtimer_cancel(&port->vdm_state_machine_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);
|
typec_unregister_port(port->typec_port);
|
||||||
usb_role_switch_put(port->role_sw);
|
usb_role_switch_put(port->role_sw);
|
||||||
tcpm_debugfs_exit(port);
|
tcpm_debugfs_exit(port);
|
||||||
kthread_destroy_worker(port->wq);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(tcpm_unregister_port);
|
EXPORT_SYMBOL_GPL(tcpm_unregister_port);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue