diff options
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/cdns3/cdnsp-ring.c | 19 | ||||
| -rw-r--r-- | drivers/usb/chipidea/udc.c | 3 | ||||
| -rw-r--r-- | drivers/usb/dwc2/hcd.c | 2 | ||||
| -rw-r--r-- | drivers/usb/dwc3/core.c | 9 | ||||
| -rw-r--r-- | drivers/usb/dwc3/dwc3-pci.c | 1 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 26 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 40 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/u_ether.c | 12 | ||||
| -rw-r--r-- | drivers/usb/gadget/function/uvc_video.c | 3 | ||||
| -rw-r--r-- | drivers/usb/gadget/legacy/raw_gadget.c | 63 | ||||
| -rw-r--r-- | drivers/usb/gadget/udc/lpc32xx_udc.c | 1 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-hub.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-pci.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 65 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.h | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/io_ti.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/io_usbvend.h | 1 | ||||
| -rw-r--r-- | drivers/usb/serial/option.c | 12 | ||||
| -rw-r--r-- | drivers/usb/serial/pl2303.c | 29 | ||||
| -rw-r--r-- | drivers/usb/typec/tcpm/Kconfig | 1 | 
20 files changed, 199 insertions, 100 deletions
diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c index e45c3d6e1536..794e413800ae 100644 --- a/drivers/usb/cdns3/cdnsp-ring.c +++ b/drivers/usb/cdns3/cdnsp-ring.c @@ -1941,13 +1941,16 @@ 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; - -			field &= ~TRB_CHAIN; -			field |= TRB_IOC; -			more_trbs_coming = false; -			preq->td.last_trb = ring->enqueue; +			if (need_zero_pkt && !zero_len_trb) { +				zero_len_trb = true; +			} else { +				zero_len_trb = false; +				field &= ~TRB_CHAIN; +				field |= TRB_IOC; +				more_trbs_coming = false; +				need_zero_pkt = false; +				preq->td.last_trb = ring->enqueue; +			}  		}  		/* Only set interrupt on short packet for OUT endpoints. */ @@ -1962,7 +1965,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 | zero_len_trb, +		cdnsp_queue_trb(pdev, ring, more_trbs_coming,  				lower_32_bits(send_addr),  				upper_32_bits(send_addr),  				length_field, diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index dc6c96e04bcf..3b8bf6daf7d0 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1048,6 +1048,9 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)  	struct ci_hdrc *ci = req->context;  	unsigned long flags; +	if (req->status < 0) +		return; +  	if (ci->setaddr) {  		hw_usb_set_address(ci, ci->address);  		ci->setaddr = false; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index f63a27d11fac..3f107a06817d 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -5190,7 +5190,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg)  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!res) {  		retval = -EINVAL; -		goto error1; +		goto error2;  	}  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index e027c0420dc3..573421984948 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1644,13 +1644,8 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)  	 * This device property is for kernel internal use only and  	 * is expected to be set by the glue code.  	 */ -	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) { -		edev = extcon_get_extcon_dev(name); -		if (!edev) -			return ERR_PTR(-EPROBE_DEFER); - -		return edev; -	} +	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) +		return extcon_get_extcon_dev(name);  	/*  	 * Try to get an extcon device from the USB PHY controller's "port" diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index ba51de7dd760..6b018048fe2e 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -127,6 +127,7 @@ static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[  	PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),  	PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),  	PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"), +	PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),  	{}  }; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 00427d108ab9..8716bece1072 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2976,6 +2976,7 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)  	struct dwc3 *dwc = dep->dwc;  	u32 mdwidth;  	int size; +	int maxpacket;  	mdwidth = dwc3_mdwidth(dwc); @@ -2988,21 +2989,24 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)  	else  		size = DWC31_GTXFIFOSIZ_TXFDEP(size); -	/* FIFO Depth is in MDWDITH bytes. Multiply */ -	size *= mdwidth; -  	/* -	 * To meet performance requirement, a minimum TxFIFO size of 3x -	 * MaxPacketSize is recommended for endpoints that support burst and a -	 * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't -	 * support burst. Use those numbers and we can calculate the max packet -	 * limit as below. +	 * maxpacket size is determined as part of the following, after assuming +	 * a mult value of one maxpacket: +	 * DWC3 revision 280A and prior: +	 * fifo_size = mult * (max_packet / mdwidth) + 1; +	 * maxpacket = mdwidth * (fifo_size - 1); +	 * +	 * DWC3 revision 290A and onwards: +	 * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1 +	 * maxpacket = mdwidth * ((fifo_size - 1) - 1) - mdwidth;  	 */ -	if (dwc->maximum_speed >= USB_SPEED_SUPER) -		size /= 3; +	if (DWC3_VER_IS_PRIOR(DWC3, 290A)) +		maxpacket = mdwidth * (size - 1);  	else -		size /= 2; +		maxpacket = mdwidth * ((size - 1) - 1) - mdwidth; +	/* Functionally, space for one max packet is sufficient */ +	size = min_t(int, maxpacket, 1024);  	usb_ep_set_maxpacket_limit(&dep->endpoint, size);  	dep->endpoint.max_streams = 16; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 4585ee3a444a..e0fa4b186ec6 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -122,8 +122,6 @@ struct ffs_ep {  	struct usb_endpoint_descriptor	*descs[3];  	u8				num; - -	int				status;	/* P: epfile->mutex */  };  struct ffs_epfile { @@ -227,6 +225,9 @@ struct ffs_io_data {  	bool use_sg;  	struct ffs_data *ffs; + +	int status; +	struct completion done;  };  struct ffs_desc_helper { @@ -707,12 +708,15 @@ static const struct file_operations ffs_ep0_operations = {  static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req)  { +	struct ffs_io_data *io_data = req->context; +  	ENTER(); -	if (req->context) { -		struct ffs_ep *ep = _ep->driver_data; -		ep->status = req->status ? req->status : req->actual; -		complete(req->context); -	} +	if (req->status) +		io_data->status = req->status; +	else +		io_data->status = req->actual; + +	complete(&io_data->done);  }  static ssize_t ffs_copy_to_iter(void *data, int data_len, struct iov_iter *iter) @@ -1050,7 +1054,6 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)  		WARN(1, "%s: data_len == -EINVAL\n", __func__);  		ret = -EINVAL;  	} else if (!io_data->aio) { -		DECLARE_COMPLETION_ONSTACK(done);  		bool interrupted = false;  		req = ep->req; @@ -1066,7 +1069,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)  		io_data->buf = data; -		req->context  = &done; +		init_completion(&io_data->done); +		req->context  = io_data;  		req->complete = ffs_epfile_io_complete;  		ret = usb_ep_queue(ep->ep, req, GFP_ATOMIC); @@ -1075,7 +1079,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)  		spin_unlock_irq(&epfile->ffs->eps_lock); -		if (wait_for_completion_interruptible(&done)) { +		if (wait_for_completion_interruptible(&io_data->done)) { +			spin_lock_irq(&epfile->ffs->eps_lock); +			if (epfile->ep != ep) { +				ret = -ESHUTDOWN; +				goto error_lock; +			}  			/*  			 * To avoid race condition with ffs_epfile_io_complete,  			 * dequeue the request first then check @@ -1083,17 +1092,18 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)  			 * condition with req->complete callback.  			 */  			usb_ep_dequeue(ep->ep, req); -			wait_for_completion(&done); -			interrupted = ep->status < 0; +			spin_unlock_irq(&epfile->ffs->eps_lock); +			wait_for_completion(&io_data->done); +			interrupted = io_data->status < 0;  		}  		if (interrupted)  			ret = -EINTR; -		else if (io_data->read && ep->status > 0) -			ret = __ffs_epfile_read_data(epfile, data, ep->status, +		else if (io_data->read && io_data->status > 0) +			ret = __ffs_epfile_read_data(epfile, data, io_data->status,  						     &io_data->data);  		else -			ret = ep->status; +			ret = io_data->status;  		goto error_mutex;  	} else if (!(req = usb_ep_alloc_request(ep->ep, GFP_ATOMIC))) {  		ret = -ENOMEM; diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 6f5d45ef2e39..f51694f29de9 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -775,9 +775,13 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,  	dev->qmult = qmult;  	snprintf(net->name, sizeof(net->name), "%s%%d", netname); -	if (get_ether_addr(dev_addr, addr)) +	if (get_ether_addr(dev_addr, addr)) { +		net->addr_assign_type = NET_ADDR_RANDOM;  		dev_warn(&g->dev,  			"using random %s ethernet address\n", "self"); +	} else { +		net->addr_assign_type = NET_ADDR_SET; +	}  	eth_hw_addr_set(net, addr);  	if (get_ether_addr(host_addr, dev->host_mac))  		dev_warn(&g->dev, @@ -844,6 +848,10 @@ struct net_device *gether_setup_name_default(const char *netname)  	eth_random_addr(dev->dev_mac);  	pr_warn("using random %s ethernet address\n", "self"); + +	/* by default we always have a random MAC address */ +	net->addr_assign_type = NET_ADDR_RANDOM; +  	eth_random_addr(dev->host_mac);  	pr_warn("using random %s ethernet address\n", "host"); @@ -871,7 +879,6 @@ int gether_register_netdev(struct net_device *net)  	dev = netdev_priv(net);  	g = dev->gadget; -	net->addr_assign_type = NET_ADDR_RANDOM;  	eth_hw_addr_set(net, dev->dev_mac);  	status = register_netdev(net); @@ -912,6 +919,7 @@ int gether_set_dev_addr(struct net_device *net, const char *dev_addr)  	if (get_ether_addr(dev_addr, new_addr))  		return -EINVAL;  	memcpy(dev->dev_mac, new_addr, ETH_ALEN); +	net->addr_assign_type = NET_ADDR_SET;  	return 0;  }  EXPORT_SYMBOL_GPL(gether_set_dev_addr); diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index a9bb4553db84..d42bb3346745 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -424,6 +424,9 @@ static void uvcg_video_pump(struct work_struct *work)  			uvcg_queue_cancel(queue, 0);  			break;  		} + +		/* Endpoint now owns the request */ +		req = NULL;  		video->req_int_count++;  	} diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index 241740024c50..2acece16b890 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -11,6 +11,7 @@  #include <linux/ctype.h>  #include <linux/debugfs.h>  #include <linux/delay.h> +#include <linux/idr.h>  #include <linux/kref.h>  #include <linux/miscdevice.h>  #include <linux/module.h> @@ -36,6 +37,9 @@ MODULE_LICENSE("GPL");  /*----------------------------------------------------------------------*/ +static DEFINE_IDA(driver_id_numbers); +#define DRIVER_DRIVER_NAME_LENGTH_MAX	32 +  #define RAW_EVENT_QUEUE_SIZE	16  struct raw_event_queue { @@ -161,6 +165,9 @@ struct raw_dev {  	/* Reference to misc device: */  	struct device			*dev; +	/* Make driver names unique */ +	int				driver_id_number; +  	/* Protected by lock: */  	enum dev_state			state;  	bool				gadget_registered; @@ -189,6 +196,7 @@ static struct raw_dev *dev_new(void)  	spin_lock_init(&dev->lock);  	init_completion(&dev->ep0_done);  	raw_event_queue_init(&dev->queue); +	dev->driver_id_number = -1;  	return dev;  } @@ -199,6 +207,9 @@ static void dev_free(struct kref *kref)  	kfree(dev->udc_name);  	kfree(dev->driver.udc_name); +	kfree(dev->driver.driver.name); +	if (dev->driver_id_number >= 0) +		ida_free(&driver_id_numbers, dev->driver_id_number);  	if (dev->req) {  		if (dev->ep0_urb_queued)  			usb_ep_dequeue(dev->gadget->ep0, dev->req); @@ -419,9 +430,11 @@ out_put:  static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)  {  	int ret = 0; +	int driver_id_number;  	struct usb_raw_init arg;  	char *udc_driver_name;  	char *udc_device_name; +	char *driver_driver_name;  	unsigned long flags;  	if (copy_from_user(&arg, (void __user *)value, sizeof(arg))) @@ -440,36 +453,43 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)  		return -EINVAL;  	} +	driver_id_number = ida_alloc(&driver_id_numbers, GFP_KERNEL); +	if (driver_id_number < 0) +		return driver_id_number; + +	driver_driver_name = kmalloc(DRIVER_DRIVER_NAME_LENGTH_MAX, GFP_KERNEL); +	if (!driver_driver_name) { +		ret = -ENOMEM; +		goto out_free_driver_id_number; +	} +	snprintf(driver_driver_name, DRIVER_DRIVER_NAME_LENGTH_MAX, +				DRIVER_NAME ".%d", driver_id_number); +  	udc_driver_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL); -	if (!udc_driver_name) -		return -ENOMEM; +	if (!udc_driver_name) { +		ret = -ENOMEM; +		goto out_free_driver_driver_name; +	}  	ret = strscpy(udc_driver_name, &arg.driver_name[0],  				UDC_NAME_LENGTH_MAX); -	if (ret < 0) { -		kfree(udc_driver_name); -		return ret; -	} +	if (ret < 0) +		goto out_free_udc_driver_name;  	ret = 0;  	udc_device_name = kmalloc(UDC_NAME_LENGTH_MAX, GFP_KERNEL);  	if (!udc_device_name) { -		kfree(udc_driver_name); -		return -ENOMEM; +		ret = -ENOMEM; +		goto out_free_udc_driver_name;  	}  	ret = strscpy(udc_device_name, &arg.device_name[0],  				UDC_NAME_LENGTH_MAX); -	if (ret < 0) { -		kfree(udc_driver_name); -		kfree(udc_device_name); -		return ret; -	} +	if (ret < 0) +		goto out_free_udc_device_name;  	ret = 0;  	spin_lock_irqsave(&dev->lock, flags);  	if (dev->state != STATE_DEV_OPENED) {  		dev_dbg(dev->dev, "fail, device is not opened\n"); -		kfree(udc_driver_name); -		kfree(udc_device_name);  		ret = -EINVAL;  		goto out_unlock;  	} @@ -484,14 +504,25 @@ static int raw_ioctl_init(struct raw_dev *dev, unsigned long value)  	dev->driver.suspend = gadget_suspend;  	dev->driver.resume = gadget_resume;  	dev->driver.reset = gadget_reset; -	dev->driver.driver.name = DRIVER_NAME; +	dev->driver.driver.name = driver_driver_name;  	dev->driver.udc_name = udc_device_name;  	dev->driver.match_existing_only = 1; +	dev->driver_id_number = driver_id_number;  	dev->state = STATE_DEV_INITIALIZED; +	spin_unlock_irqrestore(&dev->lock, flags); +	return ret;  out_unlock:  	spin_unlock_irqrestore(&dev->lock, flags); +out_free_udc_device_name: +	kfree(udc_device_name); +out_free_udc_driver_name: +	kfree(udc_driver_name); +out_free_driver_driver_name: +	kfree(driver_driver_name); +out_free_driver_id_number: +	ida_free(&driver_id_numbers, driver_id_number);  	return ret;  } diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 6117ae8e7242..cea10cdb83ae 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -3016,6 +3016,7 @@ static int lpc32xx_udc_probe(struct platform_device *pdev)  	}  	udc->isp1301_i2c_client = isp1301_get_client(isp1301_node); +	of_node_put(isp1301_node);  	if (!udc->isp1301_i2c_client) {  		return -EPROBE_DEFER;  	} diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index c54f2bc23d3f..0fdc014c9401 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -652,7 +652,7 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd)   * It will release and re-aquire the lock while calling ACPI   * method.   */ -static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, +void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd,  				u16 index, bool on, unsigned long *flags)  	__must_hold(&xhci->lock)  { diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index fac9492a8bda..dce6c0ec8d34 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -61,6 +61,8 @@  #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI		0x461e  #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI		0x464e  #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI	0x51ed +#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI		0xa71e +#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI		0x7ec0  #define PCI_DEVICE_ID_AMD_RENOIR_XHCI			0x1639  #define PCI_DEVICE_ID_AMD_PROMONTORYA_4			0x43b9 @@ -269,7 +271,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  	     pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI ||  	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI ||  	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI || -	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)) +	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI || +	     pdev->device == PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI || +	     pdev->device == PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI))  		xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;  	if (pdev->vendor == PCI_VENDOR_ID_ETRON && diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f0ab63138016..65858f607437 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -611,15 +611,37 @@ static int xhci_init(struct usb_hcd *hcd)  static int xhci_run_finished(struct xhci_hcd *xhci)  { +	unsigned long	flags; +	u32		temp; + +	/* +	 * Enable interrupts before starting the host (xhci 4.2 and 5.5.2). +	 * Protect the short window before host is running with a lock +	 */ +	spin_lock_irqsave(&xhci->lock, flags); + +	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Enable interrupts"); +	temp = readl(&xhci->op_regs->command); +	temp |= (CMD_EIE); +	writel(temp, &xhci->op_regs->command); + +	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Enable primary interrupter"); +	temp = readl(&xhci->ir_set->irq_pending); +	writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending); +  	if (xhci_start(xhci)) {  		xhci_halt(xhci); +		spin_unlock_irqrestore(&xhci->lock, flags);  		return -ENODEV;  	} +  	xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;  	if (xhci->quirks & XHCI_NEC_HOST)  		xhci_ring_cmd_db(xhci); +	spin_unlock_irqrestore(&xhci->lock, flags); +  	return 0;  } @@ -668,19 +690,6 @@ int xhci_run(struct usb_hcd *hcd)  	temp |= (xhci->imod_interval / 250) & ER_IRQ_INTERVAL_MASK;  	writel(temp, &xhci->ir_set->irq_control); -	/* Set the HCD state before we enable the irqs */ -	temp = readl(&xhci->op_regs->command); -	temp |= (CMD_EIE); -	xhci_dbg_trace(xhci, trace_xhci_dbg_init, -			"// Enable interrupts, cmd = 0x%x.", temp); -	writel(temp, &xhci->op_regs->command); - -	temp = readl(&xhci->ir_set->irq_pending); -	xhci_dbg_trace(xhci, trace_xhci_dbg_init, -			"// Enabling event ring interrupter %p by writing 0x%x to irq_pending", -			xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); -	writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending); -  	if (xhci->quirks & XHCI_NEC_HOST) {  		struct xhci_command *command; @@ -782,6 +791,8 @@ static void xhci_stop(struct usb_hcd *hcd)  void xhci_shutdown(struct usb_hcd *hcd)  {  	struct xhci_hcd *xhci = hcd_to_xhci(hcd); +	unsigned long flags; +	int i;  	if (xhci->quirks & XHCI_SPURIOUS_REBOOT)  		usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); @@ -797,12 +808,21 @@ void xhci_shutdown(struct usb_hcd *hcd)  		del_timer_sync(&xhci->shared_hcd->rh_timer);  	} -	spin_lock_irq(&xhci->lock); +	spin_lock_irqsave(&xhci->lock, flags);  	xhci_halt(xhci); + +	/* Power off USB2 ports*/ +	for (i = 0; i < xhci->usb2_rhub.num_ports; i++) +		xhci_set_port_power(xhci, xhci->main_hcd, i, false, &flags); + +	/* Power off USB3 ports*/ +	for (i = 0; i < xhci->usb3_rhub.num_ports; i++) +		xhci_set_port_power(xhci, xhci->shared_hcd, i, false, &flags); +  	/* Workaround for spurious wakeups at shutdown with HSW */  	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)  		xhci_reset(xhci, XHCI_RESET_SHORT_USEC); -	spin_unlock_irq(&xhci->lock); +	spin_unlock_irqrestore(&xhci->lock, flags);  	xhci_cleanup_msix(xhci); @@ -1107,7 +1127,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  {  	u32			command, temp = 0;  	struct usb_hcd		*hcd = xhci_to_hcd(xhci); -	struct usb_hcd		*secondary_hcd;  	int			retval = 0;  	bool			comp_timer_running = false;  	bool			pending_portevent = false; @@ -1214,23 +1233,19 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  		 * first with the primary HCD, and then with the secondary HCD.  		 * If we don't do the same, the host will never be started.  		 */ -		if (!usb_hcd_is_primary_hcd(hcd)) -			secondary_hcd = hcd; -		else -			secondary_hcd = xhci->shared_hcd; -  		xhci_dbg(xhci, "Initialize the xhci_hcd\n"); -		retval = xhci_init(hcd->primary_hcd); +		retval = xhci_init(hcd);  		if (retval)  			return retval;  		comp_timer_running = true;  		xhci_dbg(xhci, "Start the primary HCD\n"); -		retval = xhci_run(hcd->primary_hcd); -		if (!retval && secondary_hcd) { +		retval = xhci_run(hcd); +		if (!retval && xhci->shared_hcd) {  			xhci_dbg(xhci, "Start the secondary HCD\n"); -			retval = xhci_run(secondary_hcd); +			retval = xhci_run(xhci->shared_hcd);  		} +  		hcd->state = HC_STATE_SUSPENDED;  		if (xhci->shared_hcd)  			xhci->shared_hcd->state = HC_STATE_SUSPENDED; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 0bd76c94a4b1..28aaf031f9a8 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2196,6 +2196,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,  int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);  int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);  struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); +void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index, +			 bool on, unsigned long *flags);  void xhci_hc_died(struct xhci_hcd *xhci); diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index a7b3c15957ba..feba2a8d1233 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -166,6 +166,7 @@ static const struct usb_device_id edgeport_2port_id_table[] = {  	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },  	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },  	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, +	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) },  	{ }  }; @@ -204,6 +205,7 @@ static const struct usb_device_id id_table_combined[] = {  	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_8S) },  	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416) },  	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_TI_EDGEPORT_416B) }, +	{ USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_E5805A) },  	{ }  }; diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h index 52cbc353051f..9a6f742ad3ab 100644 --- a/drivers/usb/serial/io_usbvend.h +++ b/drivers/usb/serial/io_usbvend.h @@ -212,6 +212,7 @@  //  // Definitions for other product IDs  #define ION_DEVICE_ID_MT4X56USB			0x1403	// OEM device +#define ION_DEVICE_ID_E5805A			0x1A01  // OEM device (rebranded Edgeport/4)  #define	GENERATION_ID_FROM_USB_PRODUCT_ID(ProductId)				\ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e60425bbf537..de59fa919540 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -252,10 +252,12 @@ static void option_instat_callback(struct urb *urb);  #define QUECTEL_PRODUCT_EG95			0x0195  #define QUECTEL_PRODUCT_BG96			0x0296  #define QUECTEL_PRODUCT_EP06			0x0306 +#define QUECTEL_PRODUCT_EM05G			0x030a  #define QUECTEL_PRODUCT_EM12			0x0512  #define QUECTEL_PRODUCT_RM500Q			0x0800  #define QUECTEL_PRODUCT_EC200S_CN		0x6002  #define QUECTEL_PRODUCT_EC200T			0x6026 +#define QUECTEL_PRODUCT_RM500K			0x7001  #define CMOTECH_VENDOR_ID			0x16d8  #define CMOTECH_PRODUCT_6001			0x6001 @@ -432,6 +434,8 @@ static void option_instat_callback(struct urb *urb);  #define CINTERION_PRODUCT_CLS8			0x00b0  #define CINTERION_PRODUCT_MV31_MBIM		0x00b3  #define CINTERION_PRODUCT_MV31_RMNET		0x00b7 +#define CINTERION_PRODUCT_MV31_2_MBIM		0x00b8 +#define CINTERION_PRODUCT_MV31_2_RMNET		0x00b9  #define CINTERION_PRODUCT_MV32_WA		0x00f1  #define CINTERION_PRODUCT_MV32_WB		0x00f2 @@ -1132,6 +1136,8 @@ static const struct usb_device_id option_ids[] = {  	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),  	  .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },  	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, +	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), +	  .driver_info = RSVD(6) | ZLP },  	{ 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) }, @@ -1145,6 +1151,7 @@ static const struct usb_device_id option_ids[] = {  	  .driver_info = ZLP },  	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },  	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },  	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },  	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, @@ -1277,6 +1284,7 @@ static const struct usb_device_id option_ids[] = {  	  .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },  	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff),	/* Telit LE910Cx (RNDIS) */  	  .driver_info = NCTRL(2) | RSVD(3) }, +	{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) },	/* Telit LE910Cx (rmnet) */  	{ USB_DEVICE(TELIT_VENDOR_ID, 0x1260),  	  .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },  	{ USB_DEVICE(TELIT_VENDOR_ID, 0x1261), @@ -1979,6 +1987,10 @@ static const struct usb_device_id option_ids[] = {  	  .driver_info = RSVD(3)},  	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),  	  .driver_info = RSVD(0)}, +	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_MBIM, 0xff), +	  .driver_info = RSVD(3)}, +	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_RMNET, 0xff), +	  .driver_info = RSVD(0)},  	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff),  	  .driver_info = RSVD(3)},  	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 3506c47e1eef..40b1ab3d284d 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -436,22 +436,27 @@ static int pl2303_detect_type(struct usb_serial *serial)  		break;  	case 0x200:  		switch (bcdDevice) { -		case 0x100: +		case 0x100:	/* GC */  		case 0x105: +			return TYPE_HXN; +		case 0x300:	/* GT / TA */ +			if (pl2303_supports_hx_status(serial)) +				return TYPE_TA; +			fallthrough;  		case 0x305: +		case 0x400:	/* GL */  		case 0x405: +			return TYPE_HXN; +		case 0x500:	/* GE / TB */ +			if (pl2303_supports_hx_status(serial)) +				return TYPE_TB; +			fallthrough; +		case 0x505: +		case 0x600:	/* GS */  		case 0x605: -			/* -			 * 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; -		case 0x500: -			return TYPE_TB; +		case 0x700:	/* GR */ +		case 0x705: +			return TYPE_HXN;  		}  		break;  	} diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig index 557f392fe24d..073fd2ea5e0b 100644 --- a/drivers/usb/typec/tcpm/Kconfig +++ b/drivers/usb/typec/tcpm/Kconfig @@ -56,7 +56,6 @@ config TYPEC_WCOVE  	tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"  	depends on ACPI  	depends on MFD_INTEL_PMC_BXT -	depends on INTEL_SOC_PMIC  	depends on BXT_WC_PMIC_OPREGION  	help  	  This driver adds support for USB Type-C on Intel Broxton platforms  | 
