diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 1 | ||||
-rw-r--r-- | drivers/usb/core/devio.c | 144 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 6 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.c | 29 | ||||
-rw-r--r-- | drivers/usb/dwc3/core.h | 8 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/epautoconf.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_uac2.c | 16 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/goku_udc.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/ehci-atmel.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/ehci-mv.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-platform.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 3 | ||||
-rw-r--r-- | drivers/usb/musb/mediatek.c | 1 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 5 | ||||
-rw-r--r-- | drivers/usb/typec/hd3ss3220.c | 8 | ||||
-rw-r--r-- | drivers/usb/typec/tipd/core.c | 9 |
19 files changed, 206 insertions, 64 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 4e2f1552f4b7..1a84b24d199f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1851,7 +1851,6 @@ static const struct usb_device_id acm_ids[] = { { NOKIA_PCSUITE_ACM_INFO(0x0071), }, /* Nokia N82 */ { NOKIA_PCSUITE_ACM_INFO(0x04F0), }, /* Nokia N95 & N95-3 NAM */ { NOKIA_PCSUITE_ACM_INFO(0x0070), }, /* Nokia N95 8GB */ - { NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */ { NOKIA_PCSUITE_ACM_INFO(0x0099), }, /* Nokia 6210 Navigator, RM-367 */ { NOKIA_PCSUITE_ACM_INFO(0x0128), }, /* Nokia 6210 Navigator, RM-419 */ { NOKIA_PCSUITE_ACM_INFO(0x008f), }, /* Nokia 6220 Classic */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 9618ba622a2d..fa66e6e58792 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -32,6 +32,7 @@ #include <linux/usb.h> #include <linux/usbdevice_fs.h> #include <linux/usb/hcd.h> /* for usbcore internals */ +#include <linux/usb/quirks.h> #include <linux/cdev.h> #include <linux/notifier.h> #include <linux/security.h> @@ -1102,14 +1103,55 @@ static int usbdev_release(struct inode *inode, struct file *file) return 0; } +static void usbfs_blocking_completion(struct urb *urb) +{ + complete((struct completion *) urb->context); +} + +/* + * Much like usb_start_wait_urb, but returns status separately from + * actual_length and uses a killable wait. + */ +static int usbfs_start_wait_urb(struct urb *urb, int timeout, + unsigned int *actlen) +{ + DECLARE_COMPLETION_ONSTACK(ctx); + unsigned long expire; + int rc; + + urb->context = &ctx; + urb->complete = usbfs_blocking_completion; + *actlen = 0; + rc = usb_submit_urb(urb, GFP_KERNEL); + if (unlikely(rc)) + return rc; + + expire = (timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT); + rc = wait_for_completion_killable_timeout(&ctx, expire); + if (rc <= 0) { + usb_kill_urb(urb); + *actlen = urb->actual_length; + if (urb->status != -ENOENT) + ; /* Completed before it was killed */ + else if (rc < 0) + return -EINTR; + else + return -ETIMEDOUT; + } + *actlen = urb->actual_length; + return urb->status; +} + static int do_proc_control(struct usb_dev_state *ps, struct usbdevfs_ctrltransfer *ctrl) { struct usb_device *dev = ps->dev; unsigned int tmo; unsigned char *tbuf; - unsigned wLength; + unsigned int wLength, actlen; int i, pipe, ret; + struct urb *urb = NULL; + struct usb_ctrlrequest *dr = NULL; ret = check_ctrlrecip(ps, ctrl->bRequestType, ctrl->bRequest, ctrl->wIndex); @@ -1122,51 +1164,63 @@ static int do_proc_control(struct usb_dev_state *ps, sizeof(struct usb_ctrlrequest)); if (ret) return ret; + + ret = -ENOMEM; tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!tbuf) { - ret = -ENOMEM; + if (!tbuf) goto done; - } + urb = usb_alloc_urb(0, GFP_NOIO); + if (!urb) + goto done; + dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); + if (!dr) + goto done; + + dr->bRequestType = ctrl->bRequestType; + dr->bRequest = ctrl->bRequest; + dr->wValue = cpu_to_le16(ctrl->wValue); + dr->wIndex = cpu_to_le16(ctrl->wIndex); + dr->wLength = cpu_to_le16(ctrl->wLength); + tmo = ctrl->timeout; snoop(&dev->dev, "control urb: bRequestType=%02x " "bRequest=%02x wValue=%04x " "wIndex=%04x wLength=%04x\n", ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex, ctrl->wLength); - if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) { + + if ((ctrl->bRequestType & USB_DIR_IN) && wLength) { pipe = usb_rcvctrlpipe(dev, 0); - snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0); + usb_fill_control_urb(urb, dev, pipe, (unsigned char *) dr, tbuf, + wLength, NULL, NULL); + snoop_urb(dev, NULL, pipe, wLength, tmo, SUBMIT, NULL, 0); usb_unlock_device(dev); - i = usb_control_msg(dev, pipe, ctrl->bRequest, - ctrl->bRequestType, ctrl->wValue, ctrl->wIndex, - tbuf, ctrl->wLength, tmo); + i = usbfs_start_wait_urb(urb, tmo, &actlen); usb_lock_device(dev); - snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, - tbuf, max(i, 0)); - if ((i > 0) && ctrl->wLength) { - if (copy_to_user(ctrl->data, tbuf, i)) { + snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen); + if (!i && actlen) { + if (copy_to_user(ctrl->data, tbuf, actlen)) { ret = -EFAULT; - goto done; + goto recv_fault; } } } else { - if (ctrl->wLength) { - if (copy_from_user(tbuf, ctrl->data, ctrl->wLength)) { + if (wLength) { + if (copy_from_user(tbuf, ctrl->data, wLength)) { ret = -EFAULT; goto done; } } pipe = usb_sndctrlpipe(dev, 0); - snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, - tbuf, ctrl->wLength); + usb_fill_control_urb(urb, dev, pipe, (unsigned char *) dr, tbuf, + wLength, NULL, NULL); + snoop_urb(dev, NULL, pipe, wLength, tmo, SUBMIT, tbuf, wLength); usb_unlock_device(dev); - i = usb_control_msg(dev, pipe, ctrl->bRequest, - ctrl->bRequestType, ctrl->wValue, ctrl->wIndex, - tbuf, ctrl->wLength, tmo); + i = usbfs_start_wait_urb(urb, tmo, &actlen); usb_lock_device(dev); - snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0); + snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0); } if (i < 0 && i != -EPIPE) { dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " @@ -1174,8 +1228,15 @@ static int do_proc_control(struct usb_dev_state *ps, current->comm, ctrl->bRequestType, ctrl->bRequest, ctrl->wLength, i); } - ret = i; + ret = (i < 0 ? i : actlen); + + recv_fault: + /* Linger a bit, prior to the next control message. */ + if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) + msleep(200); done: + kfree(dr); + usb_free_urb(urb); free_page((unsigned long) tbuf); usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) + sizeof(struct usb_ctrlrequest)); @@ -1195,10 +1256,11 @@ static int do_proc_bulk(struct usb_dev_state *ps, struct usbdevfs_bulktransfer *bulk) { struct usb_device *dev = ps->dev; - unsigned int tmo, len1, pipe; - int len2; + unsigned int tmo, len1, len2, pipe; unsigned char *tbuf; int i, ret; + struct urb *urb = NULL; + struct usb_host_endpoint *ep; ret = findintfep(ps->dev, bulk->ep); if (ret < 0) @@ -1206,14 +1268,17 @@ static int do_proc_bulk(struct usb_dev_state *ps, ret = checkintf(ps, ret); if (ret) return ret; + + len1 = bulk->len; + if (len1 < 0 || len1 >= (INT_MAX - sizeof(struct urb))) + return -EINVAL; + if (bulk->ep & USB_DIR_IN) pipe = usb_rcvbulkpipe(dev, bulk->ep & 0x7f); else pipe = usb_sndbulkpipe(dev, bulk->ep & 0x7f); - if (!usb_maxpacket(dev, pipe, !(bulk->ep & USB_DIR_IN))) - return -EINVAL; - len1 = bulk->len; - if (len1 >= (INT_MAX - sizeof(struct urb))) + ep = usb_pipe_endpoint(dev, pipe); + if (!ep || !usb_endpoint_maxp(&ep->desc)) return -EINVAL; ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); if (ret) @@ -1223,17 +1288,29 @@ static int do_proc_bulk(struct usb_dev_state *ps, * len1 can be almost arbitrarily large. Don't WARN if it's * too big, just fail the request. */ + ret = -ENOMEM; tbuf = kmalloc(len1, GFP_KERNEL | __GFP_NOWARN); - if (!tbuf) { - ret = -ENOMEM; + if (!tbuf) + goto done; + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) goto done; + + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { + pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); + usb_fill_int_urb(urb, dev, pipe, tbuf, len1, + NULL, NULL, ep->desc.bInterval); + } else { + usb_fill_bulk_urb(urb, dev, pipe, tbuf, len1, NULL, NULL); } + tmo = bulk->timeout; if (bulk->ep & 0x80) { snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); usb_unlock_device(dev); - i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); + i = usbfs_start_wait_urb(urb, tmo, &len2); usb_lock_device(dev); snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, tbuf, len2); @@ -1253,12 +1330,13 @@ static int do_proc_bulk(struct usb_dev_state *ps, snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); usb_unlock_device(dev); - i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); + i = usbfs_start_wait_urb(urb, tmo, &len2); usb_lock_device(dev); snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0); } ret = (i < 0 ? i : len2); done: + usb_free_urb(urb); kfree(tbuf); usbfs_decrease_memory_usage(len1 + sizeof(struct urb)); return ret; diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 7ee6e4cc0d89..a3311e937847 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2732,14 +2732,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, hcd->irq = irqnum; dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum, (hcd->driver->flags & HCD_MEMORY) ? - "io mem" : "io base", - (unsigned long long)hcd->rsrc_start); + "io mem" : "io port", + (unsigned long long)hcd->rsrc_start); } else { hcd->irq = 0; if (hcd->rsrc_start) dev_info(hcd->self.controller, "%s 0x%08llx\n", (hcd->driver->flags & HCD_MEMORY) ? - "io mem" : "io base", + "io mem" : "io port", (unsigned long long)hcd->rsrc_start); } return 0; diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 0104a80b185e..643239d7d370 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -26,6 +26,7 @@ #include <linux/acpi.h> #include <linux/pinctrl/consumer.h> #include <linux/reset.h> +#include <linux/bitfield.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> @@ -336,6 +337,29 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc) } /** + * dwc3_ref_clk_period - Reference clock period configuration + * Default reference clock period depends on hardware + * configuration. For systems with reference clock that differs + * from the default, this will set clock period in DWC3_GUCTL + * register. + * @dwc: Pointer to our controller context structure + * @ref_clk_per: reference clock period in ns + */ +static void dwc3_ref_clk_period(struct dwc3 *dwc) +{ + u32 reg; + + if (dwc->ref_clk_per == 0) + return; + + reg = dwc3_readl(dwc->regs, DWC3_GUCTL); + reg &= ~DWC3_GUCTL_REFCLKPER_MASK; + reg |= FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, dwc->ref_clk_per); + dwc3_writel(dwc->regs, DWC3_GUCTL, reg); +} + + +/** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure * @evt: Pointer to event buffer to be freed @@ -1007,6 +1031,9 @@ static int dwc3_core_init(struct dwc3 *dwc) /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc); + /* Adjust Reference Clock Period */ + dwc3_ref_clk_period(dwc); + dwc3_set_incr_burst_type(dwc); usb_phy_set_suspend(dwc->usb2_phy, 0); @@ -1389,6 +1416,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) &dwc->hsphy_interface); device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj); + device_property_read_u32(dev, "snps,ref-clock-period-ns", + &dwc->ref_clk_per); dwc->dis_metastability_quirk = device_property_read_bool(dev, "snps,dis_metastability_quirk"); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5612bfdf37da..ee854697c300 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -387,6 +387,10 @@ #define DWC3_GFLADJ_30MHZ_SDBND_SEL BIT(7) #define DWC3_GFLADJ_30MHZ_MASK 0x3f +/* Global User Control Register*/ +#define DWC3_GUCTL_REFCLKPER_MASK 0xffc00000 +#define DWC3_GUCTL_REFCLKPER_SEL 22 + /* Global User Control Register 2 */ #define DWC3_GUCTL2_RST_ACTBITLATER BIT(14) @@ -970,6 +974,7 @@ struct dwc3_scratchpad_array { * @regs: base address for our registers * @regs_size: address space size * @fladj: frame length adjustment + * @ref_clk_per: reference clock period configuration * @irq_gadget: peripheral controller's IRQ number * @otg_irq: IRQ number for OTG IRQs * @current_otg_role: current role of operation while using the OTG block @@ -1027,6 +1032,7 @@ struct dwc3_scratchpad_array { * @tx_fifo_resize_max_num: max number of fifos allocated during txfifo resize * @hsphy_interface: "utmi" or "ulpi" * @connected: true when we're connected to a host, false otherwise + * @softconnect: true when gadget connect is called, false when disconnect runs * @delayed_status: true when gadget driver asks for delayed status * @ep0_bounced: true when we used bounce buffer * @ep0_expect_in: true when we expect a DATA IN transfer @@ -1149,6 +1155,7 @@ struct dwc3 { struct power_supply *usb_psy; u32 fladj; + u32 ref_clk_per; u32 irq_gadget; u32 otg_irq; u32 current_otg_role; @@ -1246,6 +1253,7 @@ struct dwc3 { const char *hsphy_interface; unsigned connected:1; + unsigned softconnect:1; unsigned delayed_status:1; unsigned ep0_bounced:1; unsigned ep0_expect_in:1; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 804b50548163..32e01885b211 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2418,7 +2418,7 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) int ret; is_on = !!is_on; - + dwc->softconnect = is_on; /* * Per databook, when we want to stop the gadget, if a control transfer * is still in process, complete it and get the core into setup phase. @@ -4352,7 +4352,7 @@ int dwc3_gadget_resume(struct dwc3 *dwc) { int ret; - if (!dwc->gadget_driver) + if (!dwc->gadget_driver || !dwc->softconnect) return 0; ret = __dwc3_gadget_start(dwc); diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 1eb4fa2e623f..ed5a92c474e5 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -181,7 +181,7 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig); * This function can be used during function bind for endpoints obtained * from usb_ep_autoconfig(). It unclaims endpoint claimed by * usb_ep_autoconfig() to make it available for other functions. Endpoint - * which was released is no longer invalid and shouldn't be used in + * which was released is no longer valid and shouldn't be used in * context of function which released it. */ void usb_ep_autoconfig_release(struct usb_ep *ep) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index be864560bfea..d5a4f60bdcb9 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -754,15 +754,15 @@ static void setup_headers(struct f_uac2_opts *opts, headers[i++] = USBDHDR(&out_clk_src_desc); headers[i++] = USBDHDR(&usb_out_it_desc); - if (FUOUT_EN(opts)) - headers[i++] = USBDHDR(out_feature_unit_desc); - } + if (FUOUT_EN(opts)) + headers[i++] = USBDHDR(out_feature_unit_desc); + } if (EPIN_EN(opts)) { headers[i++] = USBDHDR(&io_in_it_desc); - if (FUIN_EN(opts)) - headers[i++] = USBDHDR(in_feature_unit_desc); + if (FUIN_EN(opts)) + headers[i++] = USBDHDR(in_feature_unit_desc); headers[i++] = USBDHDR(&usb_in_ot_desc); } @@ -770,10 +770,10 @@ static void setup_headers(struct f_uac2_opts *opts, if (EPOUT_EN(opts)) headers[i++] = USBDHDR(&io_out_ot_desc); - if (FUOUT_EN(opts) || FUIN_EN(opts)) - headers[i++] = USBDHDR(ep_int_desc); + if (FUOUT_EN(opts) || FUIN_EN(opts)) + headers[i++] = USBDHDR(ep_int_desc); - if (EPOUT_EN(opts)) { + if (EPOUT_EN(opts)) { headers[i++] = USBDHDR(&std_as_out_if0_desc); headers[i++] = USBDHDR(&std_as_out_if1_desc); headers[i++] = USBDHDR(&as_out_hdr_desc); diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index 3e1267d38774..3757a772a55e 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -553,12 +553,12 @@ static int start_dma(struct goku_ep *ep, struct goku_request *req) master &= ~MST_R_BITS; if (unlikely(req->req.length == 0)) - master = MST_RD_ENA | MST_RD_EOPB; + master |= MST_RD_ENA | MST_RD_EOPB; else if ((req->req.length % ep->ep.maxpacket) != 0 || req->req.zero) - master = MST_RD_ENA | MST_EOPB_ENA; + master |= MST_RD_ENA | MST_EOPB_ENA; else - master = MST_RD_ENA | MST_EOPB_DIS; + master |= MST_RD_ENA | MST_EOPB_DIS; ep->dev->int_enable |= INT_MSTRDEND; diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index e893467d659c..05d41fd65f25 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -18,6 +18,8 @@ #include <linux/platform_device.h> #include <linux/usb.h> #include <linux/usb/hcd.h> +#include <linux/usb/phy.h> +#include <linux/usb/of.h> #include "ehci.h" @@ -25,6 +27,9 @@ static const char hcd_name[] = "ehci-atmel"; +#define EHCI_INSNREG(index) ((index) * 4 + 0x90) +#define EHCI_INSNREG08_HSIC_EN BIT(2) + /* interface and function clocks */ #define hcd_to_atmel_ehci_priv(h) \ ((struct atmel_ehci_priv *)hcd_to_ehci(h)->priv) @@ -154,6 +159,9 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev) goto fail_add_hcd; device_wakeup_enable(hcd->self.controller); + if (of_usb_get_phy_mode(pdev->dev.of_node) == USBPHY_INTERFACE_MODE_HSIC) + writel(EHCI_INSNREG08_HSIC_EN, hcd->regs + EHCI_INSNREG(8)); + return retval; fail_add_hcd: diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1776c05d0a48..144080321629 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -635,7 +635,16 @@ static int ehci_run (struct usb_hcd *hcd) /* Wait until HC become operational */ ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ msleep(5); - rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000); + + /* For Aspeed, STS_HALT also depends on ASS/PSS status. + * Check CMD_RUN instead. + */ + if (ehci->is_aspeed) + rc = ehci_handshake(ehci, &ehci->regs->command, CMD_RUN, + 1, 100 * 1000); + else + rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, + 0, 100 * 1000); up_write(&ehci_cf_port_reset_rwsem); diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 8fd27249ad25..fa46d217dd10 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -258,8 +258,6 @@ static int mv_ehci_remove(struct platform_device *pdev) return 0; } -MODULE_ALIAS("mv-ehci"); - static const struct platform_device_id ehci_id_table[] = { {"pxa-u2oehci", 0}, {"pxa-sph", 0}, diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index c70f2d0b4aaf..c3dc906274d9 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -297,6 +297,12 @@ static int ehci_platform_probe(struct platform_device *dev) "has-transaction-translator")) hcd->has_tt = 1; + if (of_device_is_compatible(dev->dev.of_node, + "aspeed,ast2500-ehci") || + of_device_is_compatible(dev->dev.of_node, + "aspeed,ast2600-ehci")) + ehci->is_aspeed = 1; + if (soc_device_match(quirk_poll_match)) priv->quirk_poll = true; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 80bb823aa9fe..fdd073cc053b 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -219,6 +219,7 @@ struct ehci_hcd { /* one per controller */ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ unsigned spurious_oc:1; + unsigned is_aspeed:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1f5e69314a17..666b1c665188 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -191,8 +191,7 @@ static int ohci_urb_enqueue ( } /* allocate the private part of the URB */ - urb_priv = kzalloc (sizeof (urb_priv_t) + size * sizeof (struct td *), - mem_flags); + urb_priv = kzalloc(struct_size(urb_priv, td, size), mem_flags); if (!urb_priv) return -ENOMEM; INIT_LIST_HEAD (&urb_priv->pending); diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c index 6b92d037d8fc..f5d97eb84cb5 100644 --- a/drivers/usb/musb/mediatek.c +++ b/drivers/usb/musb/mediatek.c @@ -185,6 +185,7 @@ static int mtk_otg_switch_init(struct mtk_glue *glue) role_sx_desc.set = musb_usb_role_sx_set; role_sx_desc.get = musb_usb_role_sx_get; + role_sx_desc.allow_userspace_control = true; role_sx_desc.fwnode = dev_fwnode(glue->dev); role_sx_desc.driver_data = glue; glue->role_sw = usb_role_switch_register(glue->dev, &role_sx_desc); diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index c968ecda42aa..7ed4cc348d99 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1104,6 +1104,11 @@ static int tusb_musb_init(struct musb *musb) /* dma address for async dma */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + pr_debug("no async dma resource?\n"); + ret = -ENODEV; + goto done; + } musb->async = mem->start; /* dma address for sync dma */ diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index f633ec15b1a1..cd47c3597e19 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -125,11 +125,9 @@ static irqreturn_t hd3ss3220_irq(struct hd3ss3220 *hd3ss3220) int err; hd3ss3220_set_role(hd3ss3220); - err = regmap_update_bits_base(hd3ss3220->regmap, - HD3SS3220_REG_CN_STAT_CTRL, - HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS, - HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS, - NULL, false, true); + err = regmap_write_bits(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, + HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS, + HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS); if (err < 0) return IRQ_NONE; diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 21b3ae25c76d..93e56291f0cf 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -117,13 +117,13 @@ tps6598x_block_read(struct tps6598x *tps, u8 reg, void *val, size_t len) u8 data[TPS_MAX_LEN + 1]; int ret; - if (WARN_ON(len + 1 > sizeof(data))) + if (len + 1 > sizeof(data)) return -EINVAL; if (!tps->i2c_protocol) return regmap_raw_read(tps->regmap, reg, val, len); - ret = regmap_raw_read(tps->regmap, reg, data, sizeof(data)); + ret = regmap_raw_read(tps->regmap, reg, data, len + 1); if (ret) return ret; @@ -139,13 +139,16 @@ static int tps6598x_block_write(struct tps6598x *tps, u8 reg, { u8 data[TPS_MAX_LEN + 1]; + if (len + 1 > sizeof(data)) + return -EINVAL; + if (!tps->i2c_protocol) return regmap_raw_write(tps->regmap, reg, val, len); data[0] = len; memcpy(&data[1], val, len); - return regmap_raw_write(tps->regmap, reg, data, sizeof(data)); + return regmap_raw_write(tps->regmap, reg, data, len + 1); } static inline int tps6598x_read16(struct tps6598x *tps, u8 reg, u16 *val) |