summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c46
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)