USB fixes for 6.14-rc3
Here are some small USB driver fixes, and new device ids, for 6.14-rc3. Lots of tiny stuff for reported problems, including: - new device ids and quirks - usb hub crash fix found by syzbot - dwc2 driver fix - dwc3 driver fixes - uvc gadget driver fix - cdc-acm driver fixes for a variety of different issues - other tiny bugfixes Almost all of these have been in linux-next this week, and all have passed 0-day testing. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZ7H/9Q8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ym9YgCeIG0YNJa3Bb8gVQOnNwbOXzSpt84AniHDxqW9 EMqZy36ZYzee04t1wR0b =La/t -----END PGP SIGNATURE----- Merge tag 'usb-6.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB fixes from Greg KH: "Here are some small USB driver fixes, and new device ids, for 6.14-rc3. Lots of tiny stuff for reported problems, including: - new device ids and quirks - usb hub crash fix found by syzbot - dwc2 driver fix - dwc3 driver fixes - uvc gadget driver fix - cdc-acm driver fixes for a variety of different issues - other tiny bugfixes Almost all of these have been in linux-next this week, and all have passed 0-day testing" * tag 'usb-6.14-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (25 commits) usb: typec: tcpm: PSSourceOffTimer timeout in PR_Swap enters ERROR_RECOVERY usb: roles: set switch registered flag early on usb: gadget: uvc: Fix unstarted kthread worker USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist usb: gadget: core: flush gadget workqueue after device removal USB: gadget: f_midi: f_midi_complete to call queue_work usb: core: fix pipe creation for get_bMaxPacketSize0 usb: dwc3: Fix timeout issue during controller enter/exit from halt state USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk usb: cdc-acm: Fix handling of oversized fragments usb: cdc-acm: Check control transfer buffer size before access usb: xhci: Restore xhci_pci support for Renesas HCs USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI USB: serial: option: drop MeiG Smart defines USB: serial: option: fix Telit Cinterion FN990A name USB: serial: option: add Telit Cinterion FN990B compositions USB: serial: option: add MeiG Smart SLM828 usb: gadget: f_midi: fix MIDI Streaming descriptor lengths usb: dwc2: gadget: remove of_node reference upon udc_stop ...
This commit is contained in:
commit
6bfcc5fb2f
16 changed files with 139 additions and 45 deletions
|
@ -371,7 +371,7 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
|
||||||
static void acm_ctrl_irq(struct urb *urb)
|
static void acm_ctrl_irq(struct urb *urb)
|
||||||
{
|
{
|
||||||
struct acm *acm = urb->context;
|
struct acm *acm = urb->context;
|
||||||
struct usb_cdc_notification *dr = urb->transfer_buffer;
|
struct usb_cdc_notification *dr;
|
||||||
unsigned int current_size = urb->actual_length;
|
unsigned int current_size = urb->actual_length;
|
||||||
unsigned int expected_size, copy_size, alloc_size;
|
unsigned int expected_size, copy_size, alloc_size;
|
||||||
int retval;
|
int retval;
|
||||||
|
@ -398,14 +398,25 @@ static void acm_ctrl_irq(struct urb *urb)
|
||||||
|
|
||||||
usb_mark_last_busy(acm->dev);
|
usb_mark_last_busy(acm->dev);
|
||||||
|
|
||||||
if (acm->nb_index)
|
if (acm->nb_index == 0) {
|
||||||
|
/*
|
||||||
|
* The first chunk of a message must contain at least the
|
||||||
|
* notification header with the length field, otherwise we
|
||||||
|
* can't get an expected_size.
|
||||||
|
*/
|
||||||
|
if (current_size < sizeof(struct usb_cdc_notification)) {
|
||||||
|
dev_dbg(&acm->control->dev, "urb too short\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
dr = urb->transfer_buffer;
|
||||||
|
} else {
|
||||||
dr = (struct usb_cdc_notification *)acm->notification_buffer;
|
dr = (struct usb_cdc_notification *)acm->notification_buffer;
|
||||||
|
}
|
||||||
/* size = notification-header + (optional) data */
|
/* size = notification-header + (optional) data */
|
||||||
expected_size = sizeof(struct usb_cdc_notification) +
|
expected_size = sizeof(struct usb_cdc_notification) +
|
||||||
le16_to_cpu(dr->wLength);
|
le16_to_cpu(dr->wLength);
|
||||||
|
|
||||||
if (current_size < expected_size) {
|
if (acm->nb_index != 0 || current_size < expected_size) {
|
||||||
/* notification is transmitted fragmented, reassemble */
|
/* notification is transmitted fragmented, reassemble */
|
||||||
if (acm->nb_size < expected_size) {
|
if (acm->nb_size < expected_size) {
|
||||||
u8 *new_buffer;
|
u8 *new_buffer;
|
||||||
|
@ -1727,13 +1738,16 @@ static const struct usb_device_id acm_ids[] = {
|
||||||
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
|
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
|
||||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||||
},
|
},
|
||||||
{ USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */
|
{ USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */
|
||||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||||
},
|
},
|
||||||
{ USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */
|
{ USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */
|
||||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||||
},
|
},
|
||||||
{ USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */
|
{ USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */
|
||||||
|
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||||
|
},
|
||||||
|
{ USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */
|
||||||
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
.driver_info = DISABLE_ECHO, /* Don't echo banner */
|
||||||
},
|
},
|
||||||
{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
|
{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */
|
||||||
|
|
|
@ -1848,6 +1848,17 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||||
desc = intf->cur_altsetting;
|
desc = intf->cur_altsetting;
|
||||||
hdev = interface_to_usbdev(intf);
|
hdev = interface_to_usbdev(intf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The USB 2.0 spec prohibits hubs from having more than one
|
||||||
|
* configuration or interface, and we rely on this prohibition.
|
||||||
|
* Refuse to accept a device that violates it.
|
||||||
|
*/
|
||||||
|
if (hdev->descriptor.bNumConfigurations > 1 ||
|
||||||
|
hdev->actconfig->desc.bNumInterfaces > 1) {
|
||||||
|
dev_err(&intf->dev, "Invalid hub with more than one config or interface\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set default autosuspend delay as 0 to speedup bus suspend,
|
* Set default autosuspend delay as 0 to speedup bus suspend,
|
||||||
* based on the below considerations:
|
* based on the below considerations:
|
||||||
|
@ -4698,7 +4709,6 @@ void usb_ep0_reinit(struct usb_device *udev)
|
||||||
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
|
EXPORT_SYMBOL_GPL(usb_ep0_reinit);
|
||||||
|
|
||||||
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
|
#define usb_sndaddr0pipe() (PIPE_CONTROL << 30)
|
||||||
#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN)
|
|
||||||
|
|
||||||
static int hub_set_address(struct usb_device *udev, int devnum)
|
static int hub_set_address(struct usb_device *udev, int devnum)
|
||||||
{
|
{
|
||||||
|
@ -4804,7 +4814,7 @@ static int get_bMaxPacketSize0(struct usb_device *udev,
|
||||||
for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) {
|
for (i = 0; i < GET_MAXPACKET0_TRIES; ++i) {
|
||||||
/* Start with invalid values in case the transfer fails */
|
/* Start with invalid values in case the transfer fails */
|
||||||
buf->bDescriptorType = buf->bMaxPacketSize0 = 0;
|
buf->bDescriptorType = buf->bMaxPacketSize0 = 0;
|
||||||
rc = usb_control_msg(udev, usb_rcvaddr0pipe(),
|
rc = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
||||||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||||
USB_DT_DEVICE << 8, 0,
|
USB_DT_DEVICE << 8, 0,
|
||||||
buf, size,
|
buf, size,
|
||||||
|
|
|
@ -435,6 +435,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||||
{ USB_DEVICE(0x0c45, 0x7056), .driver_info =
|
{ USB_DEVICE(0x0c45, 0x7056), .driver_info =
|
||||||
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
|
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
|
||||||
|
|
||||||
|
/* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */
|
||||||
|
{ USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
/* Action Semiconductor flash disk */
|
/* Action Semiconductor flash disk */
|
||||||
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
|
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
|
||||||
USB_QUIRK_STRING_FETCH_255 },
|
USB_QUIRK_STRING_FETCH_255 },
|
||||||
|
@ -525,6 +528,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||||
/* Blackmagic Design UltraStudio SDI */
|
/* Blackmagic Design UltraStudio SDI */
|
||||||
{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
|
{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
|
/* Teclast disk */
|
||||||
|
{ USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM },
|
||||||
|
|
||||||
/* Hauppauge HVR-950q */
|
/* Hauppauge HVR-950q */
|
||||||
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
|
||||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||||
|
|
|
@ -4615,6 +4615,7 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
|
||||||
spin_lock_irqsave(&hsotg->lock, flags);
|
spin_lock_irqsave(&hsotg->lock, flags);
|
||||||
|
|
||||||
hsotg->driver = NULL;
|
hsotg->driver = NULL;
|
||||||
|
hsotg->gadget.dev.of_node = NULL;
|
||||||
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
|
||||||
hsotg->enabled = 0;
|
hsotg->enabled = 0;
|
||||||
|
|
||||||
|
|
|
@ -717,6 +717,7 @@ struct dwc3_event_buffer {
|
||||||
/**
|
/**
|
||||||
* struct dwc3_ep - device side endpoint representation
|
* struct dwc3_ep - device side endpoint representation
|
||||||
* @endpoint: usb endpoint
|
* @endpoint: usb endpoint
|
||||||
|
* @nostream_work: work for handling bulk NoStream
|
||||||
* @cancelled_list: list of cancelled requests for this endpoint
|
* @cancelled_list: list of cancelled requests for this endpoint
|
||||||
* @pending_list: list of pending requests for this endpoint
|
* @pending_list: list of pending requests for this endpoint
|
||||||
* @started_list: list of started requests on this endpoint
|
* @started_list: list of started requests on this endpoint
|
||||||
|
|
|
@ -2629,10 +2629,38 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
u32 timeout = 2000;
|
u32 timeout = 2000;
|
||||||
|
u32 saved_config = 0;
|
||||||
|
|
||||||
if (pm_runtime_suspended(dwc->dev))
|
if (pm_runtime_suspended(dwc->dev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When operating in USB 2.0 speeds (HS/FS), ensure that
|
||||||
|
* GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY are cleared before starting
|
||||||
|
* or stopping the controller. This resolves timeout issues that occur
|
||||||
|
* during frequent role switches between host and device modes.
|
||||||
|
*
|
||||||
|
* Save and clear these settings, then restore them after completing the
|
||||||
|
* controller start or stop sequence.
|
||||||
|
*
|
||||||
|
* This solution was discovered through experimentation as it is not
|
||||||
|
* mentioned in the dwc3 programming guide. It has been tested on an
|
||||||
|
* Exynos platforms.
|
||||||
|
*/
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
||||||
|
if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
|
||||||
|
saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
|
||||||
|
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg & DWC3_GUSB2PHYCFG_ENBLSLPM) {
|
||||||
|
saved_config |= DWC3_GUSB2PHYCFG_ENBLSLPM;
|
||||||
|
reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saved_config)
|
||||||
|
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
||||||
|
|
||||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||||
if (is_on) {
|
if (is_on) {
|
||||||
if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
|
if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) {
|
||||||
|
@ -2660,6 +2688,12 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
|
||||||
reg &= DWC3_DSTS_DEVCTRLHLT;
|
reg &= DWC3_DSTS_DEVCTRLHLT;
|
||||||
} while (--timeout && !(!is_on ^ !reg));
|
} while (--timeout && !(!is_on ^ !reg));
|
||||||
|
|
||||||
|
if (saved_config) {
|
||||||
|
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
|
||||||
|
reg |= saved_config;
|
||||||
|
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
|
||||||
|
}
|
||||||
|
|
||||||
if (!timeout)
|
if (!timeout)
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req)
|
||||||
/* Our transmit completed. See if there's more to go.
|
/* Our transmit completed. See if there's more to go.
|
||||||
* f_midi_transmit eats req, don't queue it again. */
|
* f_midi_transmit eats req, don't queue it again. */
|
||||||
req->length = 0;
|
req->length = 0;
|
||||||
f_midi_transmit(midi);
|
queue_work(system_highpri_wq, &midi->work);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -907,6 +907,15 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||||
|
|
||||||
status = -ENODEV;
|
status = -ENODEV;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset wMaxPacketSize with maximum packet size of FS bulk transfer before
|
||||||
|
* endpoint claim. This ensures that the wMaxPacketSize does not exceed the
|
||||||
|
* limit during bind retries where configured dwc3 TX/RX FIFO's maxpacket
|
||||||
|
* size of 512 bytes for IN/OUT endpoints in support HS speed only.
|
||||||
|
*/
|
||||||
|
bulk_in_desc.wMaxPacketSize = cpu_to_le16(64);
|
||||||
|
bulk_out_desc.wMaxPacketSize = cpu_to_le16(64);
|
||||||
|
|
||||||
/* allocate instance-specific endpoints */
|
/* allocate instance-specific endpoints */
|
||||||
midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc);
|
midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc);
|
||||||
if (!midi->in_ep)
|
if (!midi->in_ep)
|
||||||
|
@ -1000,11 +1009,11 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* configure the endpoint descriptors ... */
|
/* configure the endpoint descriptors ... */
|
||||||
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
|
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
|
||||||
ms_out_desc.bNumEmbMIDIJack = midi->in_ports;
|
ms_out_desc.bNumEmbMIDIJack = midi->out_ports;
|
||||||
|
|
||||||
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
|
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
|
||||||
ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
|
ms_in_desc.bNumEmbMIDIJack = midi->in_ports;
|
||||||
|
|
||||||
/* ... and add them to the list */
|
/* ... and add them to the list */
|
||||||
endpoint_descriptor_index = i;
|
endpoint_descriptor_index = i;
|
||||||
|
|
|
@ -818,7 +818,7 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Allocate a kthread for asynchronous hw submit handler. */
|
/* Allocate a kthread for asynchronous hw submit handler. */
|
||||||
video->kworker = kthread_create_worker(0, "UVCG");
|
video->kworker = kthread_run_worker(0, "UVCG");
|
||||||
if (IS_ERR(video->kworker)) {
|
if (IS_ERR(video->kworker)) {
|
||||||
uvcg_err(&video->uvc->func, "failed to create UVCG kworker\n");
|
uvcg_err(&video->uvc->func, "failed to create UVCG kworker\n");
|
||||||
return PTR_ERR(video->kworker);
|
return PTR_ERR(video->kworker);
|
||||||
|
|
|
@ -1543,8 +1543,8 @@ void usb_del_gadget(struct usb_gadget *gadget)
|
||||||
|
|
||||||
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
|
kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
|
||||||
sysfs_remove_link(&udc->dev.kobj, "gadget");
|
sysfs_remove_link(&udc->dev.kobj, "gadget");
|
||||||
flush_work(&gadget->work);
|
|
||||||
device_del(&gadget->dev);
|
device_del(&gadget->dev);
|
||||||
|
flush_work(&gadget->work);
|
||||||
ida_free(&gadget_id_numbers, gadget->id_number);
|
ida_free(&gadget_id_numbers, gadget->id_number);
|
||||||
cancel_work_sync(&udc->vbus_work);
|
cancel_work_sync(&udc->vbus_work);
|
||||||
device_unregister(&udc->dev);
|
device_unregister(&udc->dev);
|
||||||
|
|
|
@ -310,7 +310,7 @@ struct renesas_usb3_request {
|
||||||
struct list_head queue;
|
struct list_head queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USB3_EP_NAME_SIZE 8
|
#define USB3_EP_NAME_SIZE 16
|
||||||
struct renesas_usb3_ep {
|
struct renesas_usb3_ep {
|
||||||
struct usb_ep ep;
|
struct usb_ep ep;
|
||||||
struct renesas_usb3 *usb3;
|
struct renesas_usb3 *usb3;
|
||||||
|
|
|
@ -958,6 +958,15 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev)
|
||||||
* booting from USB disk or using a usb keyboard
|
* booting from USB disk or using a usb keyboard
|
||||||
*/
|
*/
|
||||||
hcc_params = readl(base + EHCI_HCC_PARAMS);
|
hcc_params = readl(base + EHCI_HCC_PARAMS);
|
||||||
|
|
||||||
|
/* LS7A EHCI controller doesn't have extended capabilities, the
|
||||||
|
* EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS
|
||||||
|
* register should be 0x0 but it reads as 0xa0. So clear it to
|
||||||
|
* avoid error messages on boot.
|
||||||
|
*/
|
||||||
|
if (pdev->vendor == PCI_VENDOR_ID_LOONGSON && pdev->device == 0x7a14)
|
||||||
|
hcc_params &= ~(0xffL << 8);
|
||||||
|
|
||||||
offset = (hcc_params >> 8) & 0xff;
|
offset = (hcc_params >> 8) & 0xff;
|
||||||
while (offset && --count) {
|
while (offset && --count) {
|
||||||
pci_read_config_dword(pdev, offset, &cap);
|
pci_read_config_dword(pdev, offset, &cap);
|
||||||
|
|
|
@ -653,8 +653,8 @@ put_runtime_pm:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_NS_GPL(xhci_pci_common_probe, "xhci");
|
EXPORT_SYMBOL_NS_GPL(xhci_pci_common_probe, "xhci");
|
||||||
|
|
||||||
static const struct pci_device_id pci_ids_reject[] = {
|
/* handled by xhci-pci-renesas if enabled */
|
||||||
/* handled by xhci-pci-renesas */
|
static const struct pci_device_id pci_ids_renesas[] = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0014) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0014) },
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0015) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0015) },
|
||||||
{ /* end: all zeroes */ }
|
{ /* end: all zeroes */ }
|
||||||
|
@ -662,7 +662,8 @@ static const struct pci_device_id pci_ids_reject[] = {
|
||||||
|
|
||||||
static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||||
{
|
{
|
||||||
if (pci_match_id(pci_ids_reject, dev))
|
if (IS_ENABLED(CONFIG_USB_XHCI_PCI_RENESAS) &&
|
||||||
|
pci_match_id(pci_ids_renesas, dev))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
return xhci_pci_common_probe(dev, id);
|
return xhci_pci_common_probe(dev, id);
|
||||||
|
|
|
@ -212,7 +212,7 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop)
|
||||||
if (of_property_read_u32(node, "clock-frequency", &clk_rate))
|
if (of_property_read_u32(node, "clock-frequency", &clk_rate))
|
||||||
clk_rate = 0;
|
clk_rate = 0;
|
||||||
|
|
||||||
needs_clk = of_property_read_bool(node, "clocks");
|
needs_clk = of_property_present(node, "clocks");
|
||||||
}
|
}
|
||||||
nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
|
nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
|
||||||
GPIOD_ASIS);
|
GPIOD_ASIS);
|
||||||
|
|
|
@ -387,8 +387,11 @@ usb_role_switch_register(struct device *parent,
|
||||||
dev_set_name(&sw->dev, "%s-role-switch",
|
dev_set_name(&sw->dev, "%s-role-switch",
|
||||||
desc->name ? desc->name : dev_name(parent));
|
desc->name ? desc->name : dev_name(parent));
|
||||||
|
|
||||||
|
sw->registered = true;
|
||||||
|
|
||||||
ret = device_register(&sw->dev);
|
ret = device_register(&sw->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
sw->registered = false;
|
||||||
put_device(&sw->dev);
|
put_device(&sw->dev);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
@ -399,8 +402,6 @@ usb_role_switch_register(struct device *parent,
|
||||||
dev_warn(&sw->dev, "failed to add component\n");
|
dev_warn(&sw->dev, "failed to add component\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
sw->registered = true;
|
|
||||||
|
|
||||||
/* TODO: Symlinks for the host port and the device controller. */
|
/* TODO: Symlinks for the host port and the device controller. */
|
||||||
|
|
||||||
return sw;
|
return sw;
|
||||||
|
|
|
@ -619,15 +619,6 @@ static void option_instat_callback(struct urb *urb);
|
||||||
/* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */
|
/* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */
|
||||||
#define LUAT_PRODUCT_AIR720U 0x4e00
|
#define LUAT_PRODUCT_AIR720U 0x4e00
|
||||||
|
|
||||||
/* MeiG Smart Technology products */
|
|
||||||
#define MEIGSMART_VENDOR_ID 0x2dee
|
|
||||||
/* MeiG Smart SRM815/SRM825L based on Qualcomm 315 */
|
|
||||||
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
|
|
||||||
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
|
|
||||||
#define MEIGSMART_PRODUCT_SLM320 0x4d41
|
|
||||||
/* MeiG Smart SLM770A based on ASR1803 */
|
|
||||||
#define MEIGSMART_PRODUCT_SLM770A 0x4d57
|
|
||||||
|
|
||||||
/* Device flags */
|
/* Device flags */
|
||||||
|
|
||||||
/* Highest interface number which can be used with NCTRL() and RSVD() */
|
/* Highest interface number which can be used with NCTRL() and RSVD() */
|
||||||
|
@ -1367,15 +1358,15 @@ 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) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */
|
||||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */
|
||||||
.driver_info = NCTRL(0) | RSVD(1) },
|
.driver_info = NCTRL(0) | RSVD(1) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */
|
||||||
.driver_info = NCTRL(2) | RSVD(3) },
|
.driver_info = NCTRL(2) | RSVD(3) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */
|
||||||
.driver_info = NCTRL(0) | RSVD(1) },
|
.driver_info = NCTRL(0) | RSVD(1) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */
|
||||||
.driver_info = RSVD(0) },
|
.driver_info = RSVD(0) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */
|
||||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||||
|
@ -1403,6 +1394,22 @@ static const struct usb_device_id option_ids[] = {
|
||||||
.driver_info = RSVD(0) | NCTRL(3) },
|
.driver_info = RSVD(0) | NCTRL(3) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */
|
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */
|
||||||
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x60) }, /* Telit FN990B (rmnet) */
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x40) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d0, 0x30),
|
||||||
|
.driver_info = NCTRL(5) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x60) }, /* Telit FN990B (MBIM) */
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x40) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d1, 0x30),
|
||||||
|
.driver_info = NCTRL(6) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x60) }, /* Telit FN990B (RNDIS) */
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x40) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d2, 0x30),
|
||||||
|
.driver_info = NCTRL(6) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x60) }, /* Telit FN990B (ECM) */
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x40) },
|
||||||
|
{ USB_DEVICE_INTERFACE_PROTOCOL(TELIT_VENDOR_ID, 0x10d3, 0x30),
|
||||||
|
.driver_info = NCTRL(6) },
|
||||||
{ 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),
|
||||||
|
@ -2347,6 +2354,14 @@ static const struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */
|
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */
|
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */
|
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */
|
||||||
|
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
|
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
|
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
|
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
|
||||||
|
@ -2403,12 +2418,6 @@ static const struct usb_device_id option_ids[] = {
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0, 0) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
|
|
||||||
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
|
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
|
||||||
.driver_info = NCTRL(1) },
|
.driver_info = NCTRL(1) },
|
||||||
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
|
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
|
||||||
|
|
|
@ -5591,8 +5591,7 @@ static void run_state_machine(struct tcpm_port *port)
|
||||||
tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB,
|
tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB,
|
||||||
port->pps_data.active, 0);
|
port->pps_data.active, 0);
|
||||||
tcpm_set_charge(port, false);
|
tcpm_set_charge(port, false);
|
||||||
tcpm_set_state(port, hard_reset_state(port),
|
tcpm_set_state(port, ERROR_RECOVERY, port->timings.ps_src_off_time);
|
||||||
port->timings.ps_src_off_time);
|
|
||||||
break;
|
break;
|
||||||
case PR_SWAP_SNK_SRC_SOURCE_ON:
|
case PR_SWAP_SNK_SRC_SOURCE_ON:
|
||||||
tcpm_enable_auto_vbus_discharge(port, true);
|
tcpm_enable_auto_vbus_discharge(port, true);
|
||||||
|
|
Loading…
Add table
Reference in a new issue