diff options
Diffstat (limited to 'drivers/usb/dwc3')
| -rw-r--r-- | drivers/usb/dwc3/core.c | 34 | ||||
| -rw-r--r-- | drivers/usb/dwc3/drd.c | 11 | ||||
| -rw-r--r-- | drivers/usb/dwc3/dwc3-pci.c | 8 | ||||
| -rw-r--r-- | drivers/usb/dwc3/gadget.c | 31 | 
4 files changed, 72 insertions, 12 deletions
| diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 1170b800acdc..d28cd1a6709b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -274,7 +274,8 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)  	reg = dwc3_readl(dwc->regs, DWC3_DCTL);  	reg |= DWC3_DCTL_CSFTRST; -	dwc3_writel(dwc->regs, DWC3_DCTL, reg); +	reg &= ~DWC3_DCTL_RUN_STOP; +	dwc3_gadget_dctl_write_safe(dwc, reg);  	/*  	 * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit @@ -1377,10 +1378,10 @@ static void dwc3_get_properties(struct dwc3 *dwc)  	u8			lpm_nyet_threshold;  	u8			tx_de_emphasis;  	u8			hird_threshold; -	u8			rx_thr_num_pkt_prd; -	u8			rx_max_burst_prd; -	u8			tx_thr_num_pkt_prd; -	u8			tx_max_burst_prd; +	u8			rx_thr_num_pkt_prd = 0; +	u8			rx_max_burst_prd = 0; +	u8			tx_thr_num_pkt_prd = 0; +	u8			tx_max_burst_prd = 0;  	u8			tx_fifo_resize_max_num;  	const char		*usb_psy_name;  	int			ret; @@ -1690,21 +1691,44 @@ static int dwc3_probe(struct platform_device *pdev)  		/*  		 * Clocks are optional, but new DT platforms should support all  		 * clocks as required by the DT-binding. +		 * Some devices have different clock names in legacy device trees, +		 * check for them to retain backwards compatibility.  		 */  		dwc->bus_clk = devm_clk_get_optional(dev, "bus_early");  		if (IS_ERR(dwc->bus_clk))  			return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),  					     "could not get bus clock\n"); +		if (dwc->bus_clk == NULL) { +			dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk"); +			if (IS_ERR(dwc->bus_clk)) +				return dev_err_probe(dev, PTR_ERR(dwc->bus_clk), +						     "could not get bus clock\n"); +		} +  		dwc->ref_clk = devm_clk_get_optional(dev, "ref");  		if (IS_ERR(dwc->ref_clk))  			return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),  					     "could not get ref clock\n"); +		if (dwc->ref_clk == NULL) { +			dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk"); +			if (IS_ERR(dwc->ref_clk)) +				return dev_err_probe(dev, PTR_ERR(dwc->ref_clk), +						     "could not get ref clock\n"); +		} +  		dwc->susp_clk = devm_clk_get_optional(dev, "suspend");  		if (IS_ERR(dwc->susp_clk))  			return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),  					     "could not get suspend clock\n"); + +		if (dwc->susp_clk == NULL) { +			dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk"); +			if (IS_ERR(dwc->susp_clk)) +				return dev_err_probe(dev, PTR_ERR(dwc->susp_clk), +						     "could not get suspend clock\n"); +		}  	}  	ret = reset_control_deassert(dwc->reset); diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c index b60b5f7b6dff..8cad9e7d3368 100644 --- a/drivers/usb/dwc3/drd.c +++ b/drivers/usb/dwc3/drd.c @@ -584,16 +584,15 @@ int dwc3_drd_init(struct dwc3 *dwc)  {  	int ret, irq; +	if (ROLE_SWITCH && +	    device_property_read_bool(dwc->dev, "usb-role-switch")) +		return dwc3_setup_role_switch(dwc); +  	dwc->edev = dwc3_get_extcon(dwc);  	if (IS_ERR(dwc->edev))  		return PTR_ERR(dwc->edev); -	if (ROLE_SWITCH && -	    device_property_read_bool(dwc->dev, "usb-role-switch")) { -		ret = dwc3_setup_role_switch(dwc); -		if (ret < 0) -			return ret; -	} else if (dwc->edev) { +	if (dwc->edev) {  		dwc->edev_nb.notifier_call = dwc3_drd_notifier;  		ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,  					       &dwc->edev_nb); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 33f657d83246..2e19e0e4ea53 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -45,6 +45,8 @@  #define PCI_DEVICE_ID_INTEL_ADLM		0x54ee  #define PCI_DEVICE_ID_INTEL_ADLS		0x7ae1  #define PCI_DEVICE_ID_INTEL_RPLS		0x7a61 +#define PCI_DEVICE_ID_INTEL_MTLP		0x7ec1 +#define PCI_DEVICE_ID_INTEL_MTL			0x7e7e  #define PCI_DEVICE_ID_INTEL_TGL			0x9a15  #define PCI_DEVICE_ID_AMD_MR			0x163a @@ -456,6 +458,12 @@ static const struct pci_device_id dwc3_pci_id_table[] = {  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS),  	  (kernel_ulong_t) &dwc3_pci_intel_swnode, }, +	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLP), +	  (kernel_ulong_t) &dwc3_pci_intel_swnode, }, + +	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL), +	  (kernel_ulong_t) &dwc3_pci_intel_swnode, }, +  	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL),  	  (kernel_ulong_t) &dwc3_pci_intel_swnode, }, diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ab725d2262d6..0b9c2493844a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3274,6 +3274,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,  		const struct dwc3_event_depevt *event,  		struct dwc3_request *req, int status)  { +	int request_status;  	int ret;  	if (req->request.num_mapped_sgs) @@ -3294,7 +3295,35 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,  		req->needs_extra_trb = false;  	} -	dwc3_gadget_giveback(dep, req, status); +	/* +	 * The event status only reflects the status of the TRB with IOC set. +	 * For the requests that don't set interrupt on completion, the driver +	 * needs to check and return the status of the completed TRBs associated +	 * with the request. Use the status of the last TRB of the request. +	 */ +	if (req->request.no_interrupt) { +		struct dwc3_trb *trb; + +		trb = dwc3_ep_prev_trb(dep, dep->trb_dequeue); +		switch (DWC3_TRB_SIZE_TRBSTS(trb->size)) { +		case DWC3_TRBSTS_MISSED_ISOC: +			/* Isoc endpoint only */ +			request_status = -EXDEV; +			break; +		case DWC3_TRB_STS_XFER_IN_PROG: +			/* Applicable when End Transfer with ForceRM=0 */ +		case DWC3_TRBSTS_SETUP_PENDING: +			/* Control endpoint only */ +		case DWC3_TRBSTS_OK: +		default: +			request_status = 0; +			break; +		} +	} else { +		request_status = status; +	} + +	dwc3_gadget_giveback(dep, req, request_status);  out:  	return ret; |