Skip to content

Commit

Permalink
Merge tag 'usb-5.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of small USB driver fixes for 5.11-rc3.

  Include in here are:

   - USB gadget driver fixes for reported issues

   - new usb-serial driver ids

   - dma from stack bugfixes

   - typec bugfixes

   - dwc3 bugfixes

   - xhci driver bugfixes

   - other small misc usb driver bugfixes

  All of these have been in linux-next with no reported issues"

* tag 'usb-5.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (35 commits)
  usb: dwc3: gadget: Clear wait flag on dequeue
  usb: typec: Send uevent for num_altmodes update
  usb: typec: Fix copy paste error for NVIDIA alt-mode description
  usb: gadget: enable super speed plus
  kcov, usb: hide in_serving_softirq checks in __usb_hcd_giveback_urb
  usb: uas: Add PNY USB Portable SSD to unusual_uas
  usb: gadget: configfs: Preserve function ordering after bind failure
  usb: gadget: select CONFIG_CRC32
  usb: gadget: core: change the comment for usb_gadget_connect
  usb: gadget: configfs: Fix use-after-free issue with udc_name
  usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup
  usb: usbip: vhci_hcd: protect shift size
  USB: usblp: fix DMA to stack
  USB: serial: iuu_phoenix: fix DMA from stack
  USB: serial: option: add LongSung M5710 module support
  USB: serial: option: add Quectel EM160R-GL
  USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug
  usb: gadget: f_uac2: reset wMaxPacketSize
  usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression
  usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one
  ...
  • Loading branch information
torvalds committed Jan 10, 2021
2 parents 4ad9a28 + a5c7682 commit 28318f5
Show file tree
Hide file tree
Showing 33 changed files with 267 additions and 225 deletions.
6 changes: 5 additions & 1 deletion Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ maintainers:

properties:
compatible:
items:
oneOf:
- const: ti,j721e-usb
- const: ti,am64-usb
- items:
- const: ti,j721e-usb
- const: ti,am64-usb

reg:
description: module registers
Expand Down
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3883,7 +3883,7 @@ F: drivers/mtd/nand/raw/cadence-nand-controller.c
CADENCE USB3 DRD IP DRIVER
M: Peter Chen <[email protected]>
M: Pawel Laszczak <[email protected]>
M: Roger Quadros <rogerq@ti.com>
R: Roger Quadros <rogerq@kernel.org>
R: Aswath Govindraju <[email protected]>
L: [email protected]
S: Maintained
Expand Down
6 changes: 5 additions & 1 deletion drivers/usb/chipidea/ci_hdrc_imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
misc_pdev = of_find_device_by_node(args.np);
of_node_put(args.np);

if (!misc_pdev || !platform_get_drvdata(misc_pdev))
if (!misc_pdev)
return ERR_PTR(-EPROBE_DEFER);

if (!platform_get_drvdata(misc_pdev)) {
put_device(&misc_pdev->dev);
return ERR_PTR(-EPROBE_DEFER);
}
data->dev = &misc_pdev->dev;

/*
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/class/cdc-acm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,10 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x04d8, 0xfd08),
.driver_info = IGNORE_DEVICE,
},

{ USB_DEVICE(0x04d8, 0xf58b),
.driver_info = IGNORE_DEVICE,
},
#endif

/*Samsung phone in firmware update mode */
Expand Down
16 changes: 13 additions & 3 deletions drivers/usb/class/cdc-wdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
if (!desc->resp_count || !--desc->resp_count)
goto out;

if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
rv = -ENODEV;
goto out;
}
if (test_bit(WDM_RESETTING, &desc->flags)) {
rv = -EIO;
goto out;
}

set_bit(WDM_RESPONDING, &desc->flags);
spin_unlock_irq(&desc->iuspin);
rv = usb_submit_urb(desc->response, GFP_KERNEL);
spin_lock_irq(&desc->iuspin);
if (rv) {
dev_err(&desc->intf->dev,
"usb_submit_urb failed with result %d\n", rv);
if (!test_bit(WDM_DISCONNECTING, &desc->flags))
dev_err(&desc->intf->dev,
"usb_submit_urb failed with result %d\n", rv);

/* make sure the next notification trigger a submit */
clear_bit(WDM_RESPONDING, &desc->flags);
Expand Down Expand Up @@ -1027,9 +1037,9 @@ static void wdm_disconnect(struct usb_interface *intf)
wake_up_all(&desc->wait);
mutex_lock(&desc->rlock);
mutex_lock(&desc->wlock);
kill_urbs(desc);
cancel_work_sync(&desc->rxwork);
cancel_work_sync(&desc->service_outs_intr);
kill_urbs(desc);
mutex_unlock(&desc->wlock);
mutex_unlock(&desc->rlock);

Expand Down
21 changes: 19 additions & 2 deletions drivers/usb/class/usblp.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,25 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i
#define usblp_reset(usblp)\
usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)

#define usblp_hp_channel_change_request(usblp, channel, buffer) \
usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1)
static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel)
{
u8 *buf;
int ret;

buf = kzalloc(1, GFP_KERNEL);
if (!buf)
return -ENOMEM;

ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST,
USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE,
channel, buf, 1);
if (ret == 0)
*new_channel = buf[0];

kfree(buf);

return ret;
}

/*
* See the description for usblp_select_alts() below for the usage
Expand Down
8 changes: 3 additions & 5 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1649,14 +1649,12 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
urb->status = status;
/*
* This function can be called in task context inside another remote
* coverage collection section, but KCOV doesn't support that kind of
* coverage collection section, but kcov doesn't support that kind of
* recursion yet. Only collect coverage in softirq context for now.
*/
if (in_serving_softirq())
kcov_remote_start_usb((u64)urb->dev->bus->busnum);
kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
urb->complete(urb);
if (in_serving_softirq())
kcov_remote_stop();
kcov_remote_stop_softirq();

usb_anchor_resume_wakeups(anchor);
atomic_dec(&urb->use_count);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc3/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@

/* Global USB2 PHY Vendor Control Register */
#define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25)
#define DWC3_GUSB2PHYACC_DONE BIT(24)
#define DWC3_GUSB2PHYACC_BUSY BIT(23)
#define DWC3_GUSB2PHYACC_WRITE BIT(22)
#define DWC3_GUSB2PHYACC_ADDR(n) (n << 16)
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/dwc3/dwc3-meson-g12a.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)

ret = priv->drvdata->setup_regmaps(priv, base);
if (ret)
return ret;
goto err_disable_clks;

if (priv->vbus) {
ret = regulator_enable(priv->vbus);
Expand Down
16 changes: 5 additions & 11 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
list_for_each_entry_safe(r, t, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(r);

dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;

goto out;
}
}
Expand Down Expand Up @@ -2083,6 +2085,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)

static void dwc3_gadget_disable_irq(struct dwc3 *dwc);
static void __dwc3_gadget_stop(struct dwc3 *dwc);
static int __dwc3_gadget_start(struct dwc3 *dwc);

static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
{
Expand Down Expand Up @@ -2145,6 +2148,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
dwc->ev_buf->length;
}
} else {
__dwc3_gadget_start(dwc);
}

ret = dwc3_gadget_run_stop(dwc, is_on, false);
Expand Down Expand Up @@ -2319,10 +2324,6 @@ static int dwc3_gadget_start(struct usb_gadget *g,
}

dwc->gadget_driver = driver;

if (pm_runtime_active(dwc->dev))
__dwc3_gadget_start(dwc);

spin_unlock_irqrestore(&dwc->lock, flags);

return 0;
Expand All @@ -2348,13 +2349,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
unsigned long flags;

spin_lock_irqsave(&dwc->lock, flags);

if (pm_runtime_suspended(dwc->dev))
goto out;

__dwc3_gadget_stop(dwc);

out:
dwc->gadget_driver = NULL;
spin_unlock_irqrestore(&dwc->lock, flags);

Expand Down
38 changes: 21 additions & 17 deletions drivers/usb/dwc3/ulpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* Author: Heikki Krogerus <[email protected]>
*/

#include <linux/delay.h>
#include <linux/time64.h>
#include <linux/ulpi/regs.h>

#include "core.h"
Expand All @@ -17,14 +19,28 @@
DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \
DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a))

static int dwc3_ulpi_busyloop(struct dwc3 *dwc)
#define DWC3_ULPI_BASE_DELAY DIV_ROUND_UP(NSEC_PER_SEC, 60000000L)

static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read)
{
unsigned int count = 1000;
unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY;
unsigned int count = 10000;
u32 reg;

if (addr >= ULPI_EXT_VENDOR_SPECIFIC)
ns += DWC3_ULPI_BASE_DELAY;

if (read)
ns += DWC3_ULPI_BASE_DELAY;

reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY)
usleep_range(1000, 1200);

while (count--) {
ndelay(ns);
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
if (!(reg & DWC3_GUSB2PHYACC_BUSY))
if (reg & DWC3_GUSB2PHYACC_DONE)
return 0;
cpu_relax();
}
Expand All @@ -38,16 +54,10 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr)
u32 reg;
int ret;

reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
}

reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);

ret = dwc3_ulpi_busyloop(dwc);
ret = dwc3_ulpi_busyloop(dwc, addr, true);
if (ret)
return ret;

Expand All @@ -61,17 +71,11 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val)
struct dwc3 *dwc = dev_get_drvdata(dev);
u32 reg;

reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
}

reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
reg |= DWC3_GUSB2PHYACC_WRITE | val;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);

return dwc3_ulpi_busyloop(dwc);
return dwc3_ulpi_busyloop(dwc, addr, false);
}

static const struct ulpi_ops dwc3_ulpi_ops = {
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/gadget/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM
depends on NET
select USB_U_ETHER
select USB_F_NCM
select CRC32
help
NCM is an advanced protocol for Ethernet encapsulation, allows
grouping of several ethernet frames into one USB transfer and
Expand Down Expand Up @@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM
depends on NET
select USB_U_ETHER
select USB_F_EEM
select CRC32
help
CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
and therefore can be supported by more hardware. Technically ECM and
Expand Down
10 changes: 8 additions & 2 deletions drivers/usb/gadget/composite.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_function *function)

spin_lock_irqsave(&cdev->lock, flags);

if (cdev->deactivations == 0)
if (cdev->deactivations == 0) {
spin_unlock_irqrestore(&cdev->lock, flags);
status = usb_gadget_deactivate(cdev->gadget);
spin_lock_irqsave(&cdev->lock, flags);
}
if (status == 0)
cdev->deactivations++;

Expand Down Expand Up @@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function)
status = -EINVAL;
else {
cdev->deactivations--;
if (cdev->deactivations == 0)
if (cdev->deactivations == 0) {
spin_unlock_irqrestore(&cdev->lock, flags);
status = usb_gadget_activate(cdev->gadget);
spin_lock_irqsave(&cdev->lock, flags);
}
}

spin_unlock_irqrestore(&cdev->lock, flags);
Expand Down
19 changes: 13 additions & 6 deletions drivers/usb/gadget/configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,16 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,

static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
{
char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
struct gadget_info *gi = to_gadget_info(item);
char *udc_name;
int ret;

mutex_lock(&gi->lock);
udc_name = gi->composite.gadget_driver.udc_name;
ret = sprintf(page, "%s\n", udc_name ?: "");
mutex_unlock(&gi->lock);

return sprintf(page, "%s\n", udc_name ?: "");
return ret;
}

static int unregister_gadget(struct gadget_info *gi)
Expand Down Expand Up @@ -1248,9 +1255,9 @@ static void purge_configs_funcs(struct gadget_info *gi)

cfg = container_of(c, struct config_usb_cfg, c);

list_for_each_entry_safe(f, tmp, &c->functions, list) {
list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) {

list_move_tail(&f->list, &cfg->func_list);
list_move(&f->list, &cfg->func_list);
if (f->unbind) {
dev_dbg(&gi->cdev.gadget->dev,
"unbind function '%s'/%p\n",
Expand Down Expand Up @@ -1536,7 +1543,7 @@ static const struct usb_gadget_driver configfs_driver_template = {
.suspend = configfs_composite_suspend,
.resume = configfs_composite_resume,

.max_speed = USB_SPEED_SUPER,
.max_speed = USB_SPEED_SUPER_PLUS,
.driver = {
.owner = THIS_MODULE,
.name = "configfs-gadget",
Expand Down Expand Up @@ -1576,7 +1583,7 @@ static struct config_group *gadgets_make(
gi->composite.unbind = configfs_do_nothing;
gi->composite.suspend = NULL;
gi->composite.resume = NULL;
gi->composite.max_speed = USB_SPEED_SUPER;
gi->composite.max_speed = USB_SPEED_SUPER_PLUS;

spin_lock_init(&gi->spinlock);
mutex_init(&gi->lock);
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/gadget/function/f_printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,7 @@ static int printer_func_bind(struct usb_configuration *c,
printer_req_free(dev->in_ep, req);
}

usb_free_all_descriptors(f);
return ret;

}
Expand Down
Loading

0 comments on commit 28318f5

Please sign in to comment.