diff options
Diffstat (limited to 'drivers/usb/cdns3')
| -rw-r--r-- | drivers/usb/cdns3/cdns3-pci-wrap.c | 3 | ||||
| -rw-r--r-- | drivers/usb/cdns3/core.c | 20 | ||||
| -rw-r--r-- | drivers/usb/cdns3/ep0.c | 12 | ||||
| -rw-r--r-- | drivers/usb/cdns3/gadget.c | 8 | 
4 files changed, 38 insertions, 5 deletions
diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns3-pci-wrap.c index c41ddb61b857..b0a29efe7d31 100644 --- a/drivers/usb/cdns3/cdns3-pci-wrap.c +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c @@ -159,8 +159,9 @@ static int cdns3_pci_probe(struct pci_dev *pdev,  		wrap->plat_dev = platform_device_register_full(&plat_info);  		if (IS_ERR(wrap->plat_dev)) {  			pci_disable_device(pdev); +			err = PTR_ERR(wrap->plat_dev);  			kfree(wrap); -			return PTR_ERR(wrap->plat_dev); +			return err;  		}  	} diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 06f1e105be4e..1109dc5a4c39 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -160,10 +160,28 @@ static int cdns3_core_init_role(struct cdns3 *cdns)  	if (ret)  		goto err; -	if (cdns->dr_mode != USB_DR_MODE_OTG) { +	/* Initialize idle role to start with */ +	ret = cdns3_role_start(cdns, USB_ROLE_NONE); +	if (ret) +		goto err; + +	switch (cdns->dr_mode) { +	case USB_DR_MODE_UNKNOWN: +	case USB_DR_MODE_OTG:  		ret = cdns3_hw_role_switch(cdns);  		if (ret)  			goto err; +		break; +	case USB_DR_MODE_PERIPHERAL: +		ret = cdns3_role_start(cdns, USB_ROLE_DEVICE); +		if (ret) +			goto err; +		break; +	case USB_DR_MODE_HOST: +		ret = cdns3_role_start(cdns, USB_ROLE_HOST); +		if (ret) +			goto err; +		break;  	}  	return ret; diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c index 44f652e8b5a2..e71240b386b4 100644 --- a/drivers/usb/cdns3/ep0.c +++ b/drivers/usb/cdns3/ep0.c @@ -234,9 +234,11 @@ static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev,  static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,  				    struct usb_ctrlrequest *ctrl)  { +	struct cdns3_endpoint *priv_ep;  	__le16 *response_pkt;  	u16 usb_status = 0;  	u32 recip; +	u8 index;  	recip = ctrl->bRequestType & USB_RECIP_MASK; @@ -262,9 +264,13 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev,  	case USB_RECIP_INTERFACE:  		return cdns3_ep0_delegate_req(priv_dev, ctrl);  	case USB_RECIP_ENDPOINT: -		/* check if endpoint is stalled */ +		index = cdns3_ep_addr_to_index(ctrl->wIndex); +		priv_ep = priv_dev->eps[index]; + +		/* check if endpoint is stalled or stall is pending */  		cdns3_select_ep(priv_dev, ctrl->wIndex); -		if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts))) +		if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts)) || +		    (priv_ep->flags & EP_STALL_PENDING))  			usb_status =  BIT(USB_ENDPOINT_HALT);  		break;  	default: @@ -332,7 +338,7 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev,  			 * for sending status stage.  			 * This time should be less then 3ms.  			 */ -			usleep_range(1000, 2000); +			mdelay(1);  			cdns3_set_register_bit(&priv_dev->regs->usb_cmd,  					       USB_CMD_STMODE |  					       USB_STS_TMODE_SEL(tmode - 1)); diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 228cdc4ab886..2ca280f4c054 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -2571,6 +2571,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns)  	switch (max_speed) {  	case USB_SPEED_FULL:  		writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); +		writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf);  		break;  	case USB_SPEED_HIGH:  		writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); @@ -2662,6 +2663,13 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)  {  	int ret = 0; +	/* Ensure 32-bit DMA Mask in case we switched back from Host mode */ +	ret = dma_set_mask_and_coherent(cdns->dev, DMA_BIT_MASK(32)); +	if (ret) { +		dev_err(cdns->dev, "Failed to set dma mask: %d\n", ret); +		return ret; +	} +  	cdns3_drd_switch_gadget(cdns, 1);  	pm_runtime_get_sync(cdns->dev);  | 
