diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
| -rw-r--r-- | drivers/usb/host/xhci.c | 46 | 
1 files changed, 28 insertions, 18 deletions
| diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1975016f46bf..ca9385d22f68 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -20,7 +20,6 @@  #include "xhci.h"  #include "xhci-trace.h" -#include "xhci-mtk.h"  #include "xhci-debugfs.h"  #include "xhci-dbgcap.h" @@ -228,6 +227,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)  	struct device *dev = xhci_to_hcd(xhci)->self.sysdev;  	int err, i;  	u64 val; +	u32 intrs;  	/*  	 * Some Renesas controllers get into a weird state if they are @@ -266,7 +266,10 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)  	if (upper_32_bits(val))  		xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); -	for (i = 0; i < HCS_MAX_INTRS(xhci->hcs_params1); i++) { +	intrs = min_t(u32, HCS_MAX_INTRS(xhci->hcs_params1), +		      ARRAY_SIZE(xhci->run_regs->ir_set)); + +	for (i = 0; i < intrs; i++) {  		struct xhci_intr_reg __iomem *ir;  		ir = &xhci->run_regs->ir_set[i]; @@ -1428,6 +1431,7 @@ unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc)  			(usb_endpoint_dir_in(desc) ? 1 : 0) - 1;  	return index;  } +EXPORT_SYMBOL_GPL(xhci_get_endpoint_index);  /* The reverse operation to xhci_get_endpoint_index. Calculate the USB endpoint   * address from the XHCI endpoint index. @@ -1860,8 +1864,8 @@ err_giveback:   * disabled, so there's no need for mutual exclusion to protect   * the xhci->devs[slot_id] structure.   */ -static int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -		struct usb_host_endpoint *ep) +int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, +		       struct usb_host_endpoint *ep)  {  	struct xhci_hcd *xhci;  	struct xhci_container_ctx *in_ctx, *out_ctx; @@ -1921,9 +1925,6 @@ static int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,  	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); -	if (xhci->quirks & XHCI_MTK_HOST) -		xhci_mtk_drop_ep_quirk(hcd, udev, ep); -  	xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",  			(unsigned int) ep->desc.bEndpointAddress,  			udev->slot_id, @@ -1931,6 +1932,7 @@ static int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,  			(unsigned int) new_add_flags);  	return 0;  } +EXPORT_SYMBOL_GPL(xhci_drop_endpoint);  /* Add an endpoint to a new possible bandwidth configuration for this device.   * Only one call to this function is allowed per endpoint before @@ -1945,8 +1947,8 @@ static int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,   * configuration or alt setting is installed in the device, so there's no need   * for mutual exclusion to protect the xhci->devs[slot_id] structure.   */ -static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, -		struct usb_host_endpoint *ep) +int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, +		      struct usb_host_endpoint *ep)  {  	struct xhci_hcd *xhci;  	struct xhci_container_ctx *in_ctx; @@ -2020,15 +2022,6 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,  		return -ENOMEM;  	} -	if (xhci->quirks & XHCI_MTK_HOST) { -		ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); -		if (ret < 0) { -			xhci_ring_free(xhci, virt_dev->eps[ep_index].new_ring); -			virt_dev->eps[ep_index].new_ring = NULL; -			return ret; -		} -	} -  	ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs);  	new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); @@ -2053,6 +2046,7 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,  			(unsigned int) new_add_flags);  	return 0;  } +EXPORT_SYMBOL_GPL(xhci_add_endpoint);  static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)  { @@ -3086,6 +3080,7 @@ command_cleanup:  	return ret;  } +EXPORT_SYMBOL_GPL(xhci_check_bandwidth);  void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  { @@ -3110,6 +3105,7 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  	}  	xhci_zero_in_ctx(xhci, virt_dev);  } +EXPORT_SYMBOL_GPL(xhci_reset_bandwidth);  static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,  		struct xhci_container_ctx *in_ctx, @@ -3269,6 +3265,14 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,  	/* config ep command clears toggle if add and drop ep flags are set */  	ctrl_ctx = xhci_get_input_control_ctx(cfg_cmd->in_ctx); +	if (!ctrl_ctx) { +		spin_unlock_irqrestore(&xhci->lock, flags); +		xhci_free_command(xhci, cfg_cmd); +		xhci_warn(xhci, "%s: Could not get input context, bad type.\n", +				__func__); +		goto cleanup; +	} +  	xhci_setup_input_ctx_for_config_ep(xhci, cfg_cmd->in_ctx, vdev->out_ctx,  					   ctrl_ctx, ep_flag, ep_flag);  	xhci_endpoint_copy(xhci, cfg_cmd->in_ctx, vdev->out_ctx, ep_index); @@ -5234,10 +5238,12 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)  			hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;  			hcd->self.root_hub->rx_lanes = 2;  			hcd->self.root_hub->tx_lanes = 2; +			hcd->self.root_hub->ssp_rate = USB_SSP_GEN_2x2;  			break;  		case 1:  			hcd->speed = HCD_USB31;  			hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; +			hcd->self.root_hub->ssp_rate = USB_SSP_GEN_2x1;  			break;  		}  		xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n", @@ -5436,6 +5442,10 @@ void xhci_init_driver(struct hc_driver *drv,  			drv->reset = over->reset;  		if (over->start)  			drv->start = over->start; +		if (over->add_endpoint) +			drv->add_endpoint = over->add_endpoint; +		if (over->drop_endpoint) +			drv->drop_endpoint = over->drop_endpoint;  		if (over->check_bandwidth)  			drv->check_bandwidth = over->check_bandwidth;  		if (over->reset_bandwidth) | 
