mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 15:14:18 +08:00
USB driver fixes for 5.14-rc5
Here are some small USB driver fixes for 5.14-rc5. They resolve a number of small reported issues, including: - cdnsp driver fixes - usb serial driver fixes and device id updates - usb gadget hid fixes - usb host driver fixes - usb dwc3 driver fixes - other usb gadget driver fixes All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYQ+/ow8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymdLACeMlXNPA5S/YJd+vak0Oer1mjNQWkAoJAZKLEN bvN1v5wYjPs0mIFJUwj0 =xb57 -----END PGP SIGNATURE----- Merge tag 'usb-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB driver fixes from Greg KH: "Here are some small USB driver fixes for 5.14-rc5. They resolve a number of small reported issues, including: - cdnsp driver fixes - usb serial driver fixes and device id updates - usb gadget hid fixes - usb host driver fixes - usb dwc3 driver fixes - other usb gadget driver fixes All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (21 commits) usb: typec: tcpm: Keep other events when receiving FRS and Sourcing_vbus events usb: dwc3: gadget: Avoid runtime resume if disabling pullup usb: dwc3: gadget: Use list_replace_init() before traversing lists USB: serial: ftdi_sio: add device ID for Auto-M3 OP-COM v2 USB: serial: pl2303: fix GT type detection USB: serial: option: add Telit FD980 composition 0x1056 USB: serial: pl2303: fix HX type detection USB: serial: ch341: fix character loss at high transfer rates usb: cdnsp: Fix the IMAN_IE_SET and IMAN_IE_CLEAR macro usb: cdnsp: Fixed issue with ZLP usb: cdnsp: Fix incorrect supported maximum speed usb: cdns3: Fixed incorrect gadget state usb: gadget: f_hid: idle uses the highest byte for duration Revert "thunderbolt: Hide authorized attribute if router does not support PCIe tunnels" usb: otg-fsm: Fix hrtimer list corruption usb: host: ohci-at91: suspend/resume ports after/before OHCI accesses usb: musb: Fix suspend and resume issues for PHYs on I2C and SPI usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers usb: gadget: f_hid: fixed NULL pointer dereference usb: gadget: remove leaked entry from udc driver list ...
This commit is contained in:
commit
6a65554767
@ -1875,18 +1875,6 @@ static struct attribute *switch_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static bool has_port(const struct tb_switch *sw, enum tb_port_type type)
|
||||
{
|
||||
const struct tb_port *port;
|
||||
|
||||
tb_switch_for_each_port(sw, port) {
|
||||
if (!port->disabled && port->config.type == type)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static umode_t switch_attr_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int n)
|
||||
{
|
||||
@ -1895,8 +1883,7 @@ static umode_t switch_attr_is_visible(struct kobject *kobj,
|
||||
|
||||
if (attr == &dev_attr_authorized.attr) {
|
||||
if (sw->tb->security_level == TB_SECURITY_NOPCIE ||
|
||||
sw->tb->security_level == TB_SECURITY_DPONLY ||
|
||||
!has_port(sw, TB_TYPE_PCIE_UP))
|
||||
sw->tb->security_level == TB_SECURITY_DPONLY)
|
||||
return 0;
|
||||
} else if (attr == &dev_attr_device.attr) {
|
||||
if (!sw->device)
|
||||
|
@ -731,6 +731,7 @@ static int cdns3_gadget_ep0_queue(struct usb_ep *ep,
|
||||
request->actual = 0;
|
||||
priv_dev->status_completion_no_call = true;
|
||||
priv_dev->pending_status_request = request;
|
||||
usb_gadget_set_state(&priv_dev->gadget, USB_STATE_CONFIGURED);
|
||||
spin_unlock_irqrestore(&priv_dev->lock, flags);
|
||||
|
||||
/*
|
||||
|
@ -1882,7 +1882,7 @@ static int __cdnsp_gadget_init(struct cdns *cdns)
|
||||
pdev->gadget.name = "cdnsp-gadget";
|
||||
pdev->gadget.speed = USB_SPEED_UNKNOWN;
|
||||
pdev->gadget.sg_supported = 1;
|
||||
pdev->gadget.max_speed = USB_SPEED_SUPER_PLUS;
|
||||
pdev->gadget.max_speed = max_speed;
|
||||
pdev->gadget.lpm_capable = 1;
|
||||
|
||||
pdev->setup_buf = kzalloc(CDNSP_EP0_SETUP_SIZE, GFP_KERNEL);
|
||||
|
@ -383,8 +383,8 @@ struct cdnsp_intr_reg {
|
||||
#define IMAN_IE BIT(1)
|
||||
#define IMAN_IP BIT(0)
|
||||
/* bits 2:31 need to be preserved */
|
||||
#define IMAN_IE_SET(p) (((p) & IMAN_IE) | 0x2)
|
||||
#define IMAN_IE_CLEAR(p) (((p) & IMAN_IE) & ~(0x2))
|
||||
#define IMAN_IE_SET(p) ((p) | IMAN_IE)
|
||||
#define IMAN_IE_CLEAR(p) ((p) & ~IMAN_IE)
|
||||
|
||||
/* IMOD - Interrupter Moderation Register - irq_control bitmasks. */
|
||||
/*
|
||||
|
@ -1932,15 +1932,13 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
|
||||
}
|
||||
|
||||
if (enqd_len + trb_buff_len >= full_len) {
|
||||
if (need_zero_pkt && zero_len_trb) {
|
||||
zero_len_trb = true;
|
||||
} else {
|
||||
field &= ~TRB_CHAIN;
|
||||
field |= TRB_IOC;
|
||||
more_trbs_coming = false;
|
||||
need_zero_pkt = false;
|
||||
preq->td.last_trb = ring->enqueue;
|
||||
}
|
||||
if (need_zero_pkt)
|
||||
zero_len_trb = !zero_len_trb;
|
||||
|
||||
field &= ~TRB_CHAIN;
|
||||
field |= TRB_IOC;
|
||||
more_trbs_coming = false;
|
||||
preq->td.last_trb = ring->enqueue;
|
||||
}
|
||||
|
||||
/* Only set interrupt on short packet for OUT endpoints. */
|
||||
@ -1955,7 +1953,7 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
|
||||
length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
|
||||
TRB_INTR_TARGET(0);
|
||||
|
||||
cdnsp_queue_trb(pdev, ring, more_trbs_coming | need_zero_pkt,
|
||||
cdnsp_queue_trb(pdev, ring, more_trbs_coming | zero_len_trb,
|
||||
lower_32_bits(send_addr),
|
||||
upper_32_bits(send_addr),
|
||||
length_field,
|
||||
|
@ -2324,17 +2324,10 @@ static void usbtmc_interrupt(struct urb *urb)
|
||||
dev_err(dev, "overflow with length %d, actual length is %d\n",
|
||||
data->iin_wMaxPacketSize, urb->actual_length);
|
||||
fallthrough;
|
||||
case -ECONNRESET:
|
||||
case -ENOENT:
|
||||
case -ESHUTDOWN:
|
||||
case -EILSEQ:
|
||||
case -ETIME:
|
||||
case -EPIPE:
|
||||
default:
|
||||
/* urb terminated, clean up */
|
||||
dev_dbg(dev, "urb terminated, status: %d\n", status);
|
||||
return;
|
||||
default:
|
||||
dev_err(dev, "unknown status received: %d\n", status);
|
||||
}
|
||||
exit:
|
||||
rv = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
|
@ -193,7 +193,11 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm)
|
||||
if (!fsm->host_req_flag)
|
||||
return;
|
||||
|
||||
INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work);
|
||||
if (!fsm->hnp_work_inited) {
|
||||
INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work);
|
||||
fsm->hnp_work_inited = true;
|
||||
}
|
||||
|
||||
schedule_delayed_work(&fsm->hnp_polling_work,
|
||||
msecs_to_jiffies(T_HOST_REQ_POLL));
|
||||
}
|
||||
|
@ -1741,9 +1741,13 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
|
||||
{
|
||||
struct dwc3_request *req;
|
||||
struct dwc3_request *tmp;
|
||||
struct list_head local;
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
|
||||
list_for_each_entry_safe(req, tmp, &dep->cancelled_list, list) {
|
||||
restart:
|
||||
list_replace_init(&dep->cancelled_list, &local);
|
||||
|
||||
list_for_each_entry_safe(req, tmp, &local, list) {
|
||||
dwc3_gadget_ep_skip_trbs(dep, req);
|
||||
switch (req->status) {
|
||||
case DWC3_REQUEST_STATUS_DISCONNECTED:
|
||||
@ -1761,6 +1765,9 @@ static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!list_empty(&dep->cancelled_list))
|
||||
goto restart;
|
||||
}
|
||||
|
||||
static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
|
||||
@ -2249,6 +2256,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid issuing a runtime resume if the device is already in the
|
||||
* suspended state during gadget disconnect. DWC3 gadget was already
|
||||
* halted/stopped during runtime suspend.
|
||||
*/
|
||||
if (!is_on) {
|
||||
pm_runtime_barrier(dwc->dev);
|
||||
if (pm_runtime_suspended(dwc->dev))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the return value for successful resume, or error. For a
|
||||
* successful resume, the DWC3 runtime PM resume routine will handle
|
||||
@ -2958,8 +2976,12 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
|
||||
{
|
||||
struct dwc3_request *req;
|
||||
struct dwc3_request *tmp;
|
||||
struct list_head local;
|
||||
|
||||
list_for_each_entry_safe(req, tmp, &dep->started_list, list) {
|
||||
restart:
|
||||
list_replace_init(&dep->started_list, &local);
|
||||
|
||||
list_for_each_entry_safe(req, tmp, &local, list) {
|
||||
int ret;
|
||||
|
||||
ret = dwc3_gadget_ep_cleanup_completed_request(dep, event,
|
||||
@ -2967,6 +2989,9 @@ static void dwc3_gadget_ep_cleanup_completed_requests(struct dwc3_ep *dep,
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!list_empty(&dep->started_list))
|
||||
goto restart;
|
||||
}
|
||||
|
||||
static bool dwc3_gadget_ep_should_continue(struct dwc3_ep *dep)
|
||||
|
@ -41,6 +41,7 @@ struct f_hidg {
|
||||
unsigned char bInterfaceSubClass;
|
||||
unsigned char bInterfaceProtocol;
|
||||
unsigned char protocol;
|
||||
unsigned char idle;
|
||||
unsigned short report_desc_length;
|
||||
char *report_desc;
|
||||
unsigned short report_length;
|
||||
@ -338,6 +339,11 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
|
||||
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
|
||||
if (!hidg->req) {
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
#define WRITE_COND (!hidg->write_pending)
|
||||
try_again:
|
||||
/* write queue */
|
||||
@ -358,8 +364,14 @@ try_again:
|
||||
count = min_t(unsigned, count, hidg->report_length);
|
||||
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
status = copy_from_user(req->buf, buffer, count);
|
||||
|
||||
if (!req) {
|
||||
ERROR(hidg->func.config->cdev, "hidg->req is NULL\n");
|
||||
status = -ESHUTDOWN;
|
||||
goto release_write_pending;
|
||||
}
|
||||
|
||||
status = copy_from_user(req->buf, buffer, count);
|
||||
if (status != 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"copy_from_user error\n");
|
||||
@ -387,15 +399,18 @@ try_again:
|
||||
|
||||
spin_unlock_irqrestore(&hidg->write_spinlock, flags);
|
||||
|
||||
status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
|
||||
if (status < 0) {
|
||||
ERROR(hidg->func.config->cdev,
|
||||
"usb_ep_queue error on int endpoint %zd\n", status);
|
||||
if (!hidg->in_ep->enabled) {
|
||||
ERROR(hidg->func.config->cdev, "in_ep is disabled\n");
|
||||
status = -ESHUTDOWN;
|
||||
goto release_write_pending;
|
||||
} else {
|
||||
status = count;
|
||||
}
|
||||
|
||||
status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC);
|
||||
if (status < 0)
|
||||
goto release_write_pending;
|
||||
else
|
||||
status = count;
|
||||
|
||||
return status;
|
||||
release_write_pending:
|
||||
spin_lock_irqsave(&hidg->write_spinlock, flags);
|
||||
@ -523,6 +538,14 @@ static int hidg_setup(struct usb_function *f,
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_GET_IDLE):
|
||||
VDBG(cdev, "get_idle\n");
|
||||
length = min_t(unsigned int, length, 1);
|
||||
((u8 *) req->buf)[0] = hidg->idle;
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_SET_REPORT):
|
||||
VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength);
|
||||
@ -546,6 +569,14 @@ static int hidg_setup(struct usb_function *f,
|
||||
goto stall;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_SET_IDLE):
|
||||
VDBG(cdev, "set_idle\n");
|
||||
length = 0;
|
||||
hidg->idle = value >> 8;
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8
|
||||
| USB_REQ_GET_DESCRIPTOR):
|
||||
switch (value >> 8) {
|
||||
@ -773,6 +804,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
|
||||
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
|
||||
hidg->protocol = HID_REPORT_PROTOCOL;
|
||||
hidg->idle = 1;
|
||||
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_ss_in_comp_desc.wBytesPerInterval =
|
||||
cpu_to_le16(hidg->report_length);
|
||||
|
@ -1255,12 +1255,14 @@ static int max3420_probe(struct spi_device *spi)
|
||||
err = devm_request_irq(&spi->dev, irq, max3420_irq_handler, 0,
|
||||
"max3420", udc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto del_gadget;
|
||||
|
||||
udc->thread_task = kthread_create(max3420_thread, udc,
|
||||
"max3420-thread");
|
||||
if (IS_ERR(udc->thread_task))
|
||||
return PTR_ERR(udc->thread_task);
|
||||
if (IS_ERR(udc->thread_task)) {
|
||||
err = PTR_ERR(udc->thread_task);
|
||||
goto del_gadget;
|
||||
}
|
||||
|
||||
irq = of_irq_get_byname(spi->dev.of_node, "vbus");
|
||||
if (irq <= 0) { /* no vbus irq implies self-powered design */
|
||||
@ -1280,10 +1282,14 @@ static int max3420_probe(struct spi_device *spi)
|
||||
err = devm_request_irq(&spi->dev, irq,
|
||||
max3420_vbus_handler, 0, "vbus", udc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto del_gadget;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
del_gadget:
|
||||
usb_del_gadget_udc(&udc->gadget);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int max3420_remove(struct spi_device *spi)
|
||||
|
@ -611,8 +611,6 @@ ohci_hcd_at91_drv_suspend(struct device *dev)
|
||||
if (ohci_at91->wakeup)
|
||||
enable_irq_wake(hcd->irq);
|
||||
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1);
|
||||
|
||||
ret = ohci_suspend(hcd, ohci_at91->wakeup);
|
||||
if (ret) {
|
||||
if (ohci_at91->wakeup)
|
||||
@ -632,7 +630,10 @@ ohci_hcd_at91_drv_suspend(struct device *dev)
|
||||
/* flush the writes */
|
||||
(void) ohci_readl (ohci, &ohci->regs->control);
|
||||
msleep(1);
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1);
|
||||
at91_stop_clock(ohci_at91);
|
||||
} else {
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -644,6 +645,8 @@ ohci_hcd_at91_drv_resume(struct device *dev)
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
|
||||
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0);
|
||||
|
||||
if (ohci_at91->wakeup)
|
||||
disable_irq_wake(hcd->irq);
|
||||
else
|
||||
@ -651,8 +654,6 @@ ohci_hcd_at91_drv_resume(struct device *dev)
|
||||
|
||||
ohci_resume(hcd, false);
|
||||
|
||||
ohci_at91_port_suspend(ohci_at91->sfr_regmap, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ struct omap2430_glue {
|
||||
struct device *control_otghs;
|
||||
unsigned int is_runtime_suspended:1;
|
||||
unsigned int needs_resume:1;
|
||||
unsigned int phy_suspended:1;
|
||||
};
|
||||
#define glue_to_musb(g) platform_get_drvdata(g->musb)
|
||||
|
||||
@ -458,8 +459,10 @@ static int omap2430_runtime_suspend(struct device *dev)
|
||||
|
||||
omap2430_low_level_exit(musb);
|
||||
|
||||
phy_power_off(musb->phy);
|
||||
phy_exit(musb->phy);
|
||||
if (!glue->phy_suspended) {
|
||||
phy_power_off(musb->phy);
|
||||
phy_exit(musb->phy);
|
||||
}
|
||||
|
||||
glue->is_runtime_suspended = 1;
|
||||
|
||||
@ -474,8 +477,10 @@ static int omap2430_runtime_resume(struct device *dev)
|
||||
if (!musb)
|
||||
return 0;
|
||||
|
||||
phy_init(musb->phy);
|
||||
phy_power_on(musb->phy);
|
||||
if (!glue->phy_suspended) {
|
||||
phy_init(musb->phy);
|
||||
phy_power_on(musb->phy);
|
||||
}
|
||||
|
||||
omap2430_low_level_init(musb);
|
||||
musb_writel(musb->mregs, OTG_INTERFSEL,
|
||||
@ -489,7 +494,21 @@ static int omap2430_runtime_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* I2C and SPI PHYs need to be suspended before the glue layer */
|
||||
static int omap2430_suspend(struct device *dev)
|
||||
{
|
||||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
struct musb *musb = glue_to_musb(glue);
|
||||
|
||||
phy_power_off(musb->phy);
|
||||
phy_exit(musb->phy);
|
||||
glue->phy_suspended = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Glue layer needs to be suspended after musb_suspend() */
|
||||
static int omap2430_suspend_late(struct device *dev)
|
||||
{
|
||||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
|
||||
@ -501,7 +520,7 @@ static int omap2430_suspend(struct device *dev)
|
||||
return omap2430_runtime_suspend(dev);
|
||||
}
|
||||
|
||||
static int omap2430_resume(struct device *dev)
|
||||
static int omap2430_resume_early(struct device *dev)
|
||||
{
|
||||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
|
||||
@ -513,10 +532,24 @@ static int omap2430_resume(struct device *dev)
|
||||
return omap2430_runtime_resume(dev);
|
||||
}
|
||||
|
||||
static int omap2430_resume(struct device *dev)
|
||||
{
|
||||
struct omap2430_glue *glue = dev_get_drvdata(dev);
|
||||
struct musb *musb = glue_to_musb(glue);
|
||||
|
||||
phy_init(musb->phy);
|
||||
phy_power_on(musb->phy);
|
||||
glue->phy_suspended = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops omap2430_pm_ops = {
|
||||
.runtime_suspend = omap2430_runtime_suspend,
|
||||
.runtime_resume = omap2430_runtime_resume,
|
||||
.suspend = omap2430_suspend,
|
||||
.suspend_late = omap2430_suspend_late,
|
||||
.resume_early = omap2430_resume_early,
|
||||
.resume = omap2430_resume,
|
||||
};
|
||||
|
||||
|
@ -851,6 +851,7 @@ static struct usb_serial_driver ch341_device = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ch341-uart",
|
||||
},
|
||||
.bulk_in_size = 512,
|
||||
.id_table = id_table,
|
||||
.num_ports = 1,
|
||||
.open = ch341_open,
|
||||
|
@ -219,6 +219,7 @@ static const struct usb_device_id id_table_combined[] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_AUTO_M3_OP_COM_V2_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
|
||||
{ USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
|
||||
|
@ -159,6 +159,9 @@
|
||||
/* Vardaan Enterprises Serial Interface VEUSB422R3 */
|
||||
#define FTDI_VARDAAN_PID 0xF070
|
||||
|
||||
/* Auto-M3 Ltd. - OP-COM USB V2 - OBD interface Adapter */
|
||||
#define FTDI_AUTO_M3_OP_COM_V2_PID 0x4f50
|
||||
|
||||
/*
|
||||
* Xsens Technologies BV products (http://www.xsens.com).
|
||||
*/
|
||||
|
@ -1203,6 +1203,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1055, 0xff), /* Telit FN980 (PCIe) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ 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),
|
||||
|
@ -418,24 +418,34 @@ static int pl2303_detect_type(struct usb_serial *serial)
|
||||
bcdDevice = le16_to_cpu(desc->bcdDevice);
|
||||
bcdUSB = le16_to_cpu(desc->bcdUSB);
|
||||
|
||||
switch (bcdDevice) {
|
||||
case 0x100:
|
||||
/*
|
||||
* Assume it's an HXN-type if the device doesn't support the old read
|
||||
* request value.
|
||||
*/
|
||||
if (bcdUSB == 0x200 && !pl2303_supports_hx_status(serial))
|
||||
return TYPE_HXN;
|
||||
switch (bcdUSB) {
|
||||
case 0x110:
|
||||
switch (bcdDevice) {
|
||||
case 0x300:
|
||||
return TYPE_HX;
|
||||
case 0x400:
|
||||
return TYPE_HXD;
|
||||
default:
|
||||
return TYPE_HX;
|
||||
}
|
||||
break;
|
||||
case 0x300:
|
||||
if (bcdUSB == 0x200)
|
||||
case 0x200:
|
||||
switch (bcdDevice) {
|
||||
case 0x100:
|
||||
case 0x305:
|
||||
/*
|
||||
* Assume it's an HXN-type if the device doesn't
|
||||
* support the old read request value.
|
||||
*/
|
||||
if (!pl2303_supports_hx_status(serial))
|
||||
return TYPE_HXN;
|
||||
break;
|
||||
case 0x300:
|
||||
return TYPE_TA;
|
||||
|
||||
return TYPE_HX;
|
||||
case 0x400:
|
||||
return TYPE_HXD;
|
||||
case 0x500:
|
||||
return TYPE_TB;
|
||||
case 0x500:
|
||||
return TYPE_TB;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dev_err(&serial->interface->dev,
|
||||
|
@ -5369,7 +5369,7 @@ EXPORT_SYMBOL_GPL(tcpm_pd_hard_reset);
|
||||
void tcpm_sink_frs(struct tcpm_port *port)
|
||||
{
|
||||
spin_lock(&port->pd_event_lock);
|
||||
port->pd_events = TCPM_FRS_EVENT;
|
||||
port->pd_events |= TCPM_FRS_EVENT;
|
||||
spin_unlock(&port->pd_event_lock);
|
||||
kthread_queue_work(port->wq, &port->event_work);
|
||||
}
|
||||
@ -5378,7 +5378,7 @@ EXPORT_SYMBOL_GPL(tcpm_sink_frs);
|
||||
void tcpm_sourcing_vbus(struct tcpm_port *port)
|
||||
{
|
||||
spin_lock(&port->pd_event_lock);
|
||||
port->pd_events = TCPM_SOURCING_VBUS;
|
||||
port->pd_events |= TCPM_SOURCING_VBUS;
|
||||
spin_unlock(&port->pd_event_lock);
|
||||
kthread_queue_work(port->wq, &port->event_work);
|
||||
}
|
||||
|
@ -196,6 +196,7 @@ struct otg_fsm {
|
||||
struct mutex lock;
|
||||
u8 *host_req_flag;
|
||||
struct delayed_work hnp_polling_work;
|
||||
bool hnp_work_inited;
|
||||
bool state_changed;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user