mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 12:24:34 +08:00
USB fixes for 5.11-rc3
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. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCX/sKZg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ynVlgCgtLrjhpvxkW/TegCp3kuvsI7Kj0UAniYFwZG1 1KKr2rrignh3vLMmkCAp =IR1N -----END PGP SIGNATURE----- Merge tag 'usb-5.11-rc3' 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 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 ...
This commit is contained in:
commit
28318f5350
@ -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
|
||||
|
@ -3883,7 +3883,7 @@ F: drivers/mtd/nand/raw/cadence-nand-controller.c
|
||||
CADENCE USB3 DRD IP DRIVER
|
||||
M: Peter Chen <peter.chen@nxp.com>
|
||||
M: Pawel Laszczak <pawell@cadence.com>
|
||||
M: Roger Quadros <rogerq@ti.com>
|
||||
R: Roger Quadros <rogerq@kernel.org>
|
||||
R: Aswath Govindraju <a-govindraju@ti.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
@ -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);
|
||||
@ -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;
|
||||
@ -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);
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
* Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time64.h>
|
||||
#include <linux/ulpi/regs.h>
|
||||
|
||||
#include "core.h"
|
||||
@ -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();
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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 = {
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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++;
|
||||
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
return sprintf(page, "%s\n", udc_name ?: "");
|
||||
mutex_lock(&gi->lock);
|
||||
udc_name = gi->composite.gadget_driver.udc_name;
|
||||
ret = sprintf(page, "%s\n", udc_name ?: "");
|
||||
mutex_unlock(&gi->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int unregister_gadget(struct gadget_info *gi)
|
||||
@ -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",
|
||||
@ -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",
|
||||
@ -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);
|
||||
|
@ -1162,6 +1162,7 @@ fail_tx_reqs:
|
||||
printer_req_free(dev->in_ep, req);
|
||||
}
|
||||
|
||||
usb_free_all_descriptors(f);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1023),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1023),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
@ -444,12 +444,28 @@ struct cntrl_range_lay3 {
|
||||
__le32 dRES;
|
||||
} __packed;
|
||||
|
||||
static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
struct usb_endpoint_descriptor *ep_desc,
|
||||
unsigned int factor, bool is_playback)
|
||||
enum usb_device_speed speed, bool is_playback)
|
||||
{
|
||||
int chmask, srate, ssize;
|
||||
u16 max_packet_size;
|
||||
u16 max_size_bw, max_size_ep;
|
||||
unsigned int factor;
|
||||
|
||||
switch (speed) {
|
||||
case USB_SPEED_FULL:
|
||||
max_size_ep = 1023;
|
||||
factor = 1000;
|
||||
break;
|
||||
|
||||
case USB_SPEED_HIGH:
|
||||
max_size_ep = 1024;
|
||||
factor = 8000;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_playback) {
|
||||
chmask = uac2_opts->p_chmask;
|
||||
@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
ssize = uac2_opts->c_ssize;
|
||||
}
|
||||
|
||||
max_packet_size = num_channels(chmask) * ssize *
|
||||
max_size_bw = num_channels(chmask) * ssize *
|
||||
DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
|
||||
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
|
||||
le16_to_cpu(ep_desc->wMaxPacketSize)));
|
||||
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
|
||||
max_size_ep));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use macro to overcome line length limitation */
|
||||
@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
}
|
||||
|
||||
/* Calculate wMaxPacketSize according to audio bandwidth */
|
||||
set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
|
||||
set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
|
||||
set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
|
||||
set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
|
||||
ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (EPOUT_EN(uac2_opts)) {
|
||||
agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
|
||||
|
@ -45,9 +45,10 @@
|
||||
#define UETH__VERSION "29-May-2008"
|
||||
|
||||
/* Experiments show that both Linux and Windows hosts allow up to 16k
|
||||
* frame sizes. Set the max size to 15k+52 to prevent allocating 32k
|
||||
* frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k
|
||||
* blocks and still have efficient handling. */
|
||||
#define GETHER_MAX_ETH_FRAME_LEN 15412
|
||||
#define GETHER_MAX_MTU_SIZE 15412
|
||||
#define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN)
|
||||
|
||||
struct eth_dev {
|
||||
/* lock is held while accessing port_usb
|
||||
@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
|
||||
|
||||
/* MTU range: 14 - 15412 */
|
||||
net->min_mtu = ETH_HLEN;
|
||||
net->max_mtu = GETHER_MAX_ETH_FRAME_LEN;
|
||||
net->max_mtu = GETHER_MAX_MTU_SIZE;
|
||||
|
||||
dev->gadget = g;
|
||||
SET_NETDEV_DEV(net, &g->dev);
|
||||
@ -848,7 +849,7 @@ struct net_device *gether_setup_name_default(const char *netname)
|
||||
|
||||
/* MTU range: 14 - 15412 */
|
||||
net->min_mtu = ETH_HLEN;
|
||||
net->max_mtu = GETHER_MAX_ETH_FRAME_LEN;
|
||||
net->max_mtu = GETHER_MAX_MTU_SIZE;
|
||||
|
||||
return net;
|
||||
}
|
||||
|
@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
|
||||
struct usb_descriptor_header *usb_desc;
|
||||
|
||||
usb_desc = usb_otg_descriptor_alloc(gadget);
|
||||
if (!usb_desc)
|
||||
if (!usb_desc) {
|
||||
status = -ENOMEM;
|
||||
goto fail_string_ids;
|
||||
}
|
||||
usb_otg_descriptor_init(gadget, usb_desc);
|
||||
otg_desc[0] = usb_desc;
|
||||
otg_desc[1] = NULL;
|
||||
|
@ -90,7 +90,7 @@ config USB_BCM63XX_UDC
|
||||
|
||||
config USB_FSL_USB2
|
||||
tristate "Freescale Highspeed USB DR Peripheral Controller"
|
||||
depends on FSL_SOC || ARCH_MXC
|
||||
depends on FSL_SOC
|
||||
help
|
||||
Some of Freescale PowerPC and i.MX processors have a High Speed
|
||||
Dual-Role(DR) USB controller, which supports device mode.
|
||||
|
@ -23,7 +23,6 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
|
||||
obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o
|
||||
obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
|
||||
fsl_usb2_udc-y := fsl_udc_core.o
|
||||
fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o
|
||||
obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o
|
||||
obj-$(CONFIG_USB_M66592) += m66592-udc.o
|
||||
obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o
|
||||
|
@ -659,8 +659,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect);
|
||||
*
|
||||
* Enables the D+ (or potentially D-) pullup. The host will start
|
||||
* enumerating this gadget when the pullup is active and a VBUS session
|
||||
* is active (the link is powered). This pullup is always enabled unless
|
||||
* usb_gadget_disconnect() has been used to disable it.
|
||||
* is active (the link is powered).
|
||||
*
|
||||
* Returns zero on success, else negative errno.
|
||||
*/
|
||||
|
@ -2118,9 +2118,21 @@ static int dummy_hub_control(
|
||||
dum_hcd->port_status &= ~USB_PORT_STAT_POWER;
|
||||
set_link_state(dum_hcd);
|
||||
break;
|
||||
default:
|
||||
case USB_PORT_FEAT_ENABLE:
|
||||
case USB_PORT_FEAT_C_ENABLE:
|
||||
case USB_PORT_FEAT_C_SUSPEND:
|
||||
/* Not allowed for USB-3 */
|
||||
if (hcd->speed == HCD_USB3)
|
||||
goto error;
|
||||
fallthrough;
|
||||
case USB_PORT_FEAT_C_CONNECTION:
|
||||
case USB_PORT_FEAT_C_RESET:
|
||||
dum_hcd->port_status &= ~(1 << wValue);
|
||||
set_link_state(dum_hcd);
|
||||
break;
|
||||
default:
|
||||
/* Disallow INDICATOR and C_OVER_CURRENT */
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case GetHubDescriptor:
|
||||
@ -2281,18 +2293,17 @@ static int dummy_hub_control(
|
||||
*/
|
||||
dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50);
|
||||
fallthrough;
|
||||
case USB_PORT_FEAT_C_CONNECTION:
|
||||
case USB_PORT_FEAT_C_RESET:
|
||||
case USB_PORT_FEAT_C_ENABLE:
|
||||
case USB_PORT_FEAT_C_SUSPEND:
|
||||
/* Not allowed for USB-3, and ignored for USB-2 */
|
||||
if (hcd->speed == HCD_USB3)
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
if (hcd->speed == HCD_USB3) {
|
||||
if ((dum_hcd->port_status &
|
||||
USB_SS_PORT_STAT_POWER) != 0) {
|
||||
dum_hcd->port_status |= (1 << wValue);
|
||||
}
|
||||
} else
|
||||
if ((dum_hcd->port_status &
|
||||
USB_PORT_STAT_POWER) != 0) {
|
||||
dum_hcd->port_status |= (1 << wValue);
|
||||
}
|
||||
set_link_state(dum_hcd);
|
||||
/* Disallow TEST, INDICATOR, and C_OVER_CURRENT */
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case GetPortErrorCount:
|
||||
|
@ -1,122 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2009
|
||||
* Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
|
||||
*
|
||||
* Description:
|
||||
* Helper routines for i.MX3x SoCs from Freescale, needed by the fsl_usb2_udc.c
|
||||
* driver to function correctly on these systems.
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "fsl_usb2_udc.h"
|
||||
|
||||
static struct clk *mxc_ahb_clk;
|
||||
static struct clk *mxc_per_clk;
|
||||
static struct clk *mxc_ipg_clk;
|
||||
|
||||
/* workaround ENGcm09152 for i.MX35 */
|
||||
#define MX35_USBPHYCTRL_OFFSET 0x600
|
||||
#define USBPHYCTRL_OTGBASE_OFFSET 0x8
|
||||
#define USBPHYCTRL_EVDO (1 << 23)
|
||||
|
||||
int fsl_udc_clk_init(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_usb2_platform_data *pdata;
|
||||
unsigned long freq;
|
||||
int ret;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
|
||||
mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg");
|
||||
if (IS_ERR(mxc_ipg_clk)) {
|
||||
dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n");
|
||||
return PTR_ERR(mxc_ipg_clk);
|
||||
}
|
||||
|
||||
mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb");
|
||||
if (IS_ERR(mxc_ahb_clk)) {
|
||||
dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n");
|
||||
return PTR_ERR(mxc_ahb_clk);
|
||||
}
|
||||
|
||||
mxc_per_clk = devm_clk_get(&pdev->dev, "per");
|
||||
if (IS_ERR(mxc_per_clk)) {
|
||||
dev_err(&pdev->dev, "clk_get(\"per\") failed\n");
|
||||
return PTR_ERR(mxc_per_clk);
|
||||
}
|
||||
|
||||
clk_prepare_enable(mxc_ipg_clk);
|
||||
clk_prepare_enable(mxc_ahb_clk);
|
||||
clk_prepare_enable(mxc_per_clk);
|
||||
|
||||
/* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
|
||||
if (!strcmp(pdev->id_entry->name, "imx-udc-mx27")) {
|
||||
freq = clk_get_rate(mxc_per_clk);
|
||||
if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
|
||||
(freq < 59999000 || freq > 60001000)) {
|
||||
dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
|
||||
ret = -EINVAL;
|
||||
goto eclkrate;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
eclkrate:
|
||||
clk_disable_unprepare(mxc_ipg_clk);
|
||||
clk_disable_unprepare(mxc_ahb_clk);
|
||||
clk_disable_unprepare(mxc_per_clk);
|
||||
mxc_per_clk = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fsl_udc_clk_finalize(struct platform_device *pdev)
|
||||
{
|
||||
struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
int ret = 0;
|
||||
|
||||
/* workaround ENGcm09152 for i.MX35 */
|
||||
if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
|
||||
unsigned int v;
|
||||
struct resource *res = platform_get_resource
|
||||
(pdev, IORESOURCE_MEM, 0);
|
||||
void __iomem *phy_regs = ioremap(res->start +
|
||||
MX35_USBPHYCTRL_OFFSET, 512);
|
||||
if (!phy_regs) {
|
||||
dev_err(&pdev->dev, "ioremap for phy address fails\n");
|
||||
ret = -EINVAL;
|
||||
goto ioremap_err;
|
||||
}
|
||||
|
||||
v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
|
||||
writel(v | USBPHYCTRL_EVDO,
|
||||
phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
|
||||
|
||||
iounmap(phy_regs);
|
||||
}
|
||||
|
||||
|
||||
ioremap_err:
|
||||
/* ULPI transceivers don't need usbpll */
|
||||
if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
|
||||
clk_disable_unprepare(mxc_per_clk);
|
||||
mxc_per_clk = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsl_udc_clk_release(void)
|
||||
{
|
||||
if (mxc_per_clk)
|
||||
clk_disable_unprepare(mxc_per_clk);
|
||||
clk_disable_unprepare(mxc_ahb_clk);
|
||||
clk_disable_unprepare(mxc_ipg_clk);
|
||||
}
|
@ -4770,19 +4770,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,
|
||||
{
|
||||
unsigned long long timeout_ns;
|
||||
|
||||
/* Prevent U1 if service interval is shorter than U1 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) {
|
||||
dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (xhci->quirks & XHCI_INTEL_HOST)
|
||||
timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc);
|
||||
else
|
||||
timeout_ns = udev->u1_params.sel;
|
||||
|
||||
/* Prevent U1 if service interval is shorter than U1 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= timeout_ns) {
|
||||
dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* The U1 timeout is encoded in 1us intervals.
|
||||
* Don't return a timeout of zero, because that's USB3_LPM_DISABLED.
|
||||
*/
|
||||
@ -4834,19 +4834,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,
|
||||
{
|
||||
unsigned long long timeout_ns;
|
||||
|
||||
/* Prevent U2 if service interval is shorter than U2 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) {
|
||||
dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (xhci->quirks & XHCI_INTEL_HOST)
|
||||
timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc);
|
||||
else
|
||||
timeout_ns = udev->u2_params.sel;
|
||||
|
||||
/* Prevent U2 if service interval is shorter than U2 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= timeout_ns) {
|
||||
dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* The U2 timeout is encoded in 256us intervals */
|
||||
timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000);
|
||||
/* If the necessary timeout value is bigger than what we can set in the
|
||||
|
@ -496,6 +496,9 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
|
||||
timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
|
||||
finish_wait(&dev->waitq, &wait);
|
||||
|
||||
/* make sure URB is idle after timeout or (spurious) CMD_ACK */
|
||||
usb_kill_urb(dev->cntl_urb);
|
||||
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
|
||||
if (retval < 0) {
|
||||
|
@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port)
|
||||
struct device *dev = &port->dev;
|
||||
int i;
|
||||
int status;
|
||||
u8 rxcmd = IUU_UART_RX;
|
||||
u8 *rxcmd;
|
||||
struct iuu_private *priv = usb_get_serial_port_data(port);
|
||||
|
||||
if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
|
||||
return -EIO;
|
||||
|
||||
rxcmd = kmalloc(1, GFP_KERNEL);
|
||||
if (!rxcmd)
|
||||
return -ENOMEM;
|
||||
|
||||
rxcmd[0] = IUU_UART_RX;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
status = bulk_immediate(port, &rxcmd, 1);
|
||||
status = bulk_immediate(port, rxcmd, 1);
|
||||
if (status != IUU_OPERATION_OK) {
|
||||
dev_dbg(dev, "%s - uart_flush_write error\n", __func__);
|
||||
return status;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
status = read_immediate(port, &priv->len, 1);
|
||||
if (status != IUU_OPERATION_OK) {
|
||||
dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
|
||||
return status;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (priv->len > 0) {
|
||||
@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port)
|
||||
status = read_immediate(port, priv->buf, priv->len);
|
||||
if (status != IUU_OPERATION_OK) {
|
||||
dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
|
||||
return status;
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__);
|
||||
iuu_led(port, 0, 0xF000, 0, 0xFF);
|
||||
|
||||
out_free:
|
||||
kfree(rxcmd);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
|
||||
.driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
|
||||
@ -2057,6 +2059,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */
|
||||
.driver_info = RSVD(6) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
|
||||
{ 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, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
|
||||
|
@ -90,6 +90,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_BROKEN_FUA),
|
||||
|
||||
/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
|
||||
UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
|
||||
"PNY",
|
||||
"Pro Elite SSD",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_NO_ATA_1X),
|
||||
|
||||
/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
|
||||
UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
|
||||
"PNY",
|
||||
|
@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE
|
||||
to enable support for VirtualLink devices with NVIDIA GPUs.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called typec_displayport.
|
||||
module will be called typec_nvidia.
|
||||
|
||||
endmenu
|
||||
|
@ -766,6 +766,7 @@ int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmod
|
||||
return ret;
|
||||
|
||||
sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes");
|
||||
kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -923,6 +924,7 @@ int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes)
|
||||
return ret;
|
||||
|
||||
sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes");
|
||||
kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -207,10 +207,21 @@ static int
|
||||
pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp)
|
||||
{
|
||||
u8 msg[2] = { };
|
||||
int ret;
|
||||
|
||||
msg[0] = PMC_USB_DP_HPD;
|
||||
msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
|
||||
|
||||
/* Configure HPD first if HPD,IRQ comes together */
|
||||
if (!IOM_PORT_HPD_ASSERTED(port->iom_status) &&
|
||||
dp->status & DP_STATUS_IRQ_HPD &&
|
||||
dp->status & DP_STATUS_HPD_STATE) {
|
||||
msg[1] = PMC_USB_DP_HPD_LVL;
|
||||
ret = pmc_usb_command(port, msg, sizeof(msg));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dp->status & DP_STATUS_IRQ_HPD)
|
||||
msg[1] = PMC_USB_DP_HPD_IRQ;
|
||||
|
||||
|
@ -396,6 +396,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
default:
|
||||
usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n",
|
||||
wValue);
|
||||
if (wValue >= 32)
|
||||
goto error;
|
||||
vhci_hcd->port_status[rhport] &= ~(1 << wValue);
|
||||
break;
|
||||
}
|
||||
|
@ -52,6 +52,25 @@ static inline void kcov_remote_start_usb(u64 id)
|
||||
kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id));
|
||||
}
|
||||
|
||||
/*
|
||||
* The softirq flavor of kcov_remote_*() functions is introduced as a temporary
|
||||
* work around for kcov's lack of nested remote coverage sections support in
|
||||
* task context. Adding suport for nested sections is tracked in:
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=210337
|
||||
*/
|
||||
|
||||
static inline void kcov_remote_start_usb_softirq(u64 id)
|
||||
{
|
||||
if (in_serving_softirq())
|
||||
kcov_remote_start_usb(id);
|
||||
}
|
||||
|
||||
static inline void kcov_remote_stop_softirq(void)
|
||||
{
|
||||
if (in_serving_softirq())
|
||||
kcov_remote_stop();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline void kcov_task_init(struct task_struct *t) {}
|
||||
@ -66,6 +85,8 @@ static inline u64 kcov_common_handle(void)
|
||||
}
|
||||
static inline void kcov_remote_start_common(u64 id) {}
|
||||
static inline void kcov_remote_start_usb(u64 id) {}
|
||||
static inline void kcov_remote_start_usb_softirq(u64 id) {}
|
||||
static inline void kcov_remote_stop_softirq(void) {}
|
||||
|
||||
#endif /* CONFIG_KCOV */
|
||||
#endif /* _LINUX_KCOV_H */
|
||||
|
Loading…
Reference in New Issue
Block a user