summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-08-05 21:13:10 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2020-08-05 21:13:10 +0200
commitecfd7940b8641da6e41ca94eba36876dc2ba827b (patch)
treeb25d042366a3b6f165abb4c9fba9b9faf1ba33f6 /drivers/usb/host
parentMerge tag 'driver-core-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/... (diff)
parentusb: common: usb-conn-gpio: Register charger (diff)
downloadlinux-ecfd7940b8641da6e41ca94eba36876dc2ba827b.tar.xz
linux-ecfd7940b8641da6e41ca94eba36876dc2ba827b.zip
Merge tag 'usb-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/Thunderbolt updates from Greg KH: "Here is the large set of USB and Thunderbolt patches for 5.9-rc1. Nothing really magic/major in here, just lots of little changes and updates: - clean up language usages in USB core and some drivers - Thunderbolt driver updates and additions - USB Gadget driver updates - dwc3 driver updates (like always...) - build with "W=1" warning fixups - mtu3 driver updates - usb-serial driver updates and device ids - typec additions and updates for new hardware - xhci debug code updates for future platforms - cdns3 driver updates - lots of other minor driver updates and fixes and cleanups All of these have been in linux-next for a while with no reported issues" * tag 'usb-5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (330 commits) usb: common: usb-conn-gpio: Register charger usb: mtu3: simplify mtu3_req_complete() usb: mtu3: clear dual mode of u3port when disable device usb: mtu3: use MTU3_EP_WEDGE flag usb: mtu3: remove useless member @busy in mtu3_ep struct usb: mtu3: remove repeated error log usb: mtu3: add ->udc_set_speed() usb: mtu3: introduce a funtion to check maximum speed usb: mtu3: clear interrupts status when disable interrupts usb: mtu3: reinitialize CSR registers usb: mtu3: fix macro for maximum number of packets usb: mtu3: remove unnecessary pointer checks usb: xhci: Fix ASMedia ASM1142 DMA addressing usb: xhci: define IDs for various ASMedia host controllers usb: musb: convert to devm_platform_ioremap_resource_byname usb: gadget: tegra-xudc: convert to devm_platform_ioremap_resource_byname usb: gadget: r8a66597: convert to devm_platform_ioremap_resource_byname usb: dwc3: convert to devm_platform_ioremap_resource_byname usb: cdns3: convert to devm_platform_ioremap_resource_byname usb: phy: am335x: convert to devm_platform_ioremap_resource_byname ...
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig4
-rw-r--r--drivers/usb/host/bcma-hcd.c4
-rw-r--r--drivers/usb/host/ehci-dbg.c2
-rw-r--r--drivers/usb/host/ehci-fsl.c6
-rw-r--r--drivers/usb/host/ehci-hcd.c4
-rw-r--r--drivers/usb/host/ehci-omap.c2
-rw-r--r--drivers/usb/host/ehci-pci.c3
-rw-r--r--drivers/usb/host/ehci-platform.c2
-rw-r--r--drivers/usb/host/ehci-q.c2
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/host/fhci-sched.c19
-rw-r--r--drivers/usb/host/fhci-tds.c11
-rw-r--r--drivers/usb/host/fotg210-hcd.c15
-rw-r--r--drivers/usb/host/imx21-hcd.c2
-rw-r--r--drivers/usb/host/isp1362-hcd.c2
-rw-r--r--drivers/usb/host/isp1362.h2
-rw-r--r--drivers/usb/host/max3421-hcd.c12
-rw-r--r--drivers/usb/host/ohci-at91.c5
-rw-r--r--drivers/usb/host/ohci-hcd.c6
-rw-r--r--drivers/usb/host/ohci-hub.c2
-rw-r--r--drivers/usb/host/ohci-omap.c144
-rw-r--r--drivers/usb/host/ohci-pci.c4
-rw-r--r--drivers/usb/host/ohci-q.c6
-rw-r--r--drivers/usb/host/ohci-s3c2410.c2
-rw-r--r--drivers/usb/host/ohci-tmio.c6
-rw-r--r--drivers/usb/host/ohci.h2
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c15
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c8
-rw-r--r--drivers/usb/host/xhci-dbgcap.c393
-rw-r--r--drivers/usb/host/xhci-dbgcap.h69
-rw-r--r--drivers/usb/host/xhci-dbgtty.c221
-rw-r--r--drivers/usb/host/xhci-debugfs.c1
-rw-r--r--drivers/usb/host/xhci-hub.c48
-rw-r--r--drivers/usb/host/xhci-mem.c37
-rw-r--r--drivers/usb/host/xhci-pci.c10
-rw-r--r--drivers/usb/host/xhci-plat.c4
-rw-r--r--drivers/usb/host/xhci-tegra.c8
-rw-r--r--drivers/usb/host/xhci.c2
-rw-r--r--drivers/usb/host/xhci.h2
40 files changed, 632 insertions, 459 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1cb3004ea7b2..ab12c4bf0ef1 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -44,10 +44,10 @@ config USB_XHCI_PCI
default y
config USB_XHCI_PCI_RENESAS
- tristate "Support for additional Renesas xHCI controller with firwmare"
+ tristate "Support for additional Renesas xHCI controller with firmware"
help
Say 'Y' to enable the support for the Renesas xHCI controller with
- firwmare. Make sure you have the firwmare for the device and
+ firmware. Make sure you have the firwmare for the device and
installed on your system for this device to work.
If unsure, say 'N'.
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
index 652fa29beb27..b1b777f33521 100644
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -168,7 +168,7 @@ static void bcma_hcd_init_chip_mips(struct bcma_device *dev)
}
}
-/**
+/*
* bcma_hcd_usb20_old_arm_init - Initialize old USB 2.0 controller on ARM
*
* Old USB 2.0 core is identified as BCMA_CORE_USB20_HOST and was introduced
@@ -261,7 +261,7 @@ static void bcma_hcd_usb20_ns_init_hc(struct bcma_device *dev)
usleep_range(1000, 2000);
}
-/**
+/*
* bcma_hcd_usb20_ns_init - Initialize Northstar USB 2.0 controller
*/
static int bcma_hcd_usb20_ns_init(struct bcma_hcd_device *bcma_hcd)
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 7619cfb06883..0b7f1edd9eec 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -823,7 +823,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
break;
case 0: /* illegal reserved capability */
cap = 0;
- /* FALLTHROUGH */
+ fallthrough;
default: /* unknown */
break;
}
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 9e9c232e896f..1e8b59ab2272 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -234,7 +234,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
break;
case FSL_USB2_PHY_UTMI_WIDE:
portsc |= PORT_PTS_PTW;
- /* fall through */
+ fallthrough;
case FSL_USB2_PHY_UTMI:
/* Presence of this node "has_fsl_erratum_a006918"
* in device-tree is used to stop USB controller
@@ -244,7 +244,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
dev_warn(dev, "USB PHY clock invalid\n");
return -EINVAL;
}
- /* fall through */
+ fallthrough;
case FSL_USB2_PHY_UTMI_DUAL:
/* PHY_CLK_VALID bit is de-featured from all controller
* versions below 2.4 and is to be checked only for
@@ -683,7 +683,7 @@ static const struct ehci_driver_overrides ehci_fsl_overrides __initconst = {
/**
* fsl_ehci_drv_remove - shutdown processing for FSL-based HCDs
- * @dev: USB Host Controller being removed
+ * @pdev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_fsl_probe().
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index cf2b7ae93b7e..6257be4110ca 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -982,7 +982,7 @@ rescan:
start_unlink_async(ehci, qh);
else
start_unlink_intr(ehci, qh);
- /* FALL THROUGH */
+ fallthrough;
case QH_STATE_COMPLETING: /* already in unlinking */
case QH_STATE_UNLINK: /* wait for hw to finish? */
case QH_STATE_UNLINK_WAIT:
@@ -999,7 +999,7 @@ idle_timeout:
qh_destroy(ehci, qh);
break;
}
- /* fall through */
+ fallthrough;
default:
/* caller was supposed to have unlinked any requests;
* that's not our job. just leak this memory.
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index fc125b3d06e7..8771a2ed6926 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -24,7 +24,6 @@
#include <linux/slab.h>
#include <linux/usb/ulpi.h>
#include <linux/pm_runtime.h>
-#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
@@ -78,6 +77,7 @@ static const struct ehci_driver_overrides ehci_omap_overrides __initconst = {
/**
* ehci_hcd_omap_probe - initialize TI-based HCDs
+ * @pdev: Pointer to this platform device's information
*
* Allocates basic resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index af3c1b9b38b2..71ec3025686f 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -124,8 +124,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
case 0x005b: /* CK804 */
case 0x00d8: /* CK8 */
case 0x00e8: /* CK8S */
- if (pci_set_consistent_dma_mask(pdev,
- DMA_BIT_MASK(31)) < 0)
+ if (dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(31)) < 0)
ehci_warn(ehci, "can't enable NVidia "
"workaround for >2GB RAM\n");
break;
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index e9a49007cce4..006c4f6188a5 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -475,11 +475,13 @@ static const struct of_device_id vt8500_ehci_ids[] = {
};
MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
+#ifdef CONFIG_ACPI
static const struct acpi_device_id ehci_acpi_match[] = {
{ "PNP0D20", 0 }, /* EHCI controller without debug */
{ }
};
MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
+#endif
static const struct platform_device_id ehci_platform_table[] = {
{ "ehci-platform", 0 },
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 8a5c9b3ebe1e..a826715ae9bd 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -874,7 +874,7 @@ qh_make (
switch (urb->dev->speed) {
case USB_SPEED_LOW:
info1 |= QH_LOW_SPEED;
- /* FALL THROUGH */
+ fallthrough;
case USB_SPEED_FULL:
/* EPS 0 means "full" */
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index da7b00a6110b..847979f265b1 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -2475,7 +2475,7 @@ restart:
ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n",
type, frame, q.ptr);
/* BUG(); */
- /* FALL THROUGH */
+ fallthrough;
case Q_TYPE_QH:
case Q_TYPE_FSTN:
/* End of the iTDs and siTDs */
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c
index 5c423f240a1f..a45ede80edfc 100644
--- a/drivers/usb/host/fhci-sched.c
+++ b/drivers/usb/host/fhci-sched.c
@@ -701,7 +701,6 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
u32 data_len = urb->transfer_buffer_length;
int urb_state = 0;
int toggle = 0;
- struct td *td;
u8 *data;
u16 cnt = 0;
@@ -770,7 +769,7 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
usb_endpoint_maxp(&urb->ep->desc)) == 0))
urb_state = US_BULK0;
while (data_len > 4096) {
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
FHCI_TA_IN,
cnt ? USB_TD_TOGGLE_CARRY :
@@ -781,7 +780,7 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
cnt++;
}
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN,
cnt ? USB_TD_TOGGLE_CARRY : toggle,
data, data_len, 0, 0, true);
@@ -789,7 +788,7 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
if (urb->transfer_flags & URB_ZERO_PACKET &&
cnt < urb_priv->num_of_tds) {
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
FHCI_TA_IN,
USB_TD_TOGGLE_CARRY, NULL, 0, 0, 0, true);
@@ -798,7 +797,7 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
break;
case FHCI_TF_INTR:
urb->start_frame = get_frame_num(fhci) + 1;
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN,
USB_TD_TOGGLE_DATA0, data, data_len,
urb->interval, urb->start_frame, true);
@@ -808,12 +807,12 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
ed->max_pkt_size = usb_endpoint_maxp(&urb->ep->desc);
/* setup stage */
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP,
USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true);
/* data stage */
if (data_len > 0) {
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
FHCI_TA_IN,
USB_TD_TOGGLE_DATA1, data, data_len, 0, 0,
@@ -822,12 +821,12 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
/* status stage */
if (data_len > 0)
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
(usb_pipeout(urb->pipe) ? FHCI_TA_IN :
FHCI_TA_OUT),
USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
else
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt++,
FHCI_TA_IN,
USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true);
@@ -844,7 +843,7 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb)
*/
frame += cnt * urb->interval;
frame &= 0x07ff;
- td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
+ fhci_td_fill(fhci, urb, urb_priv, ed, cnt,
usb_pipeout(urb->pipe) ? FHCI_TA_OUT :
FHCI_TA_IN,
USB_TD_TOGGLE_DATA0,
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
index f3308ce25043..d98fd9e1af0b 100644
--- a/drivers/usb/host/fhci-tds.c
+++ b/drivers/usb/host/fhci-tds.c
@@ -467,17 +467,15 @@ u32 fhci_host_transaction(struct fhci_usb *usb,
/* Reset the Tx BD ring */
void fhci_flush_bds(struct fhci_usb *usb)
{
- u16 extra_data;
u16 td_status;
- u32 buf;
struct usb_td __iomem *td;
struct endpoint *ep = usb->ep0;
td = ep->td_base;
while (1) {
td_status = in_be16(&td->status);
- buf = in_be32(&td->buf_ptr);
- extra_data = in_be16(&td->extra);
+ in_be32(&td->buf_ptr);
+ in_be16(&td->extra);
/* if the TD is not empty - we'll confirm it as Timeout */
if (td_status & TD_R)
@@ -524,7 +522,6 @@ void fhci_flush_actual_frame(struct fhci_usb *usb)
{
u8 mode;
u16 tb_ptr;
- u16 extra_data;
u16 td_status;
u32 buf_ptr;
struct usb_td __iomem *td;
@@ -538,7 +535,7 @@ void fhci_flush_actual_frame(struct fhci_usb *usb)
td = cpm_muram_addr(tb_ptr);
td_status = in_be16(&td->status);
buf_ptr = in_be32(&td->buf_ptr);
- extra_data = in_be16(&td->extra);
+ in_be16(&td->extra);
do {
if (td_status & TD_R) {
out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
@@ -552,7 +549,7 @@ void fhci_flush_actual_frame(struct fhci_usb *usb)
td = next_bd(ep->td_base, td, td_status);
td_status = in_be16(&td->status);
buf_ptr = in_be32(&td->buf_ptr);
- extra_data = in_be16(&td->extra);
+ in_be16(&td->extra);
} while ((td_status & TD_R) || buf_ptr);
fhci_td_transaction_confirm(usb);
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index f967adf2d8df..194df8282471 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -2807,7 +2807,7 @@ static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
switch (urb->dev->speed) {
case USB_SPEED_LOW:
info1 |= QH_LOW_SPEED;
- /* FALL THROUGH */
+ fallthrough;
case USB_SPEED_FULL:
/* EPS 0 means "full" */
@@ -4634,7 +4634,7 @@ static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
default:
fotg210_dbg(fotg210, "corrupt type %d frame %d shadow %p\n",
type, frame, q.ptr);
- /* FALL THROUGH */
+ fallthrough;
case Q_TYPE_QH:
case Q_TYPE_FSTN:
/* End of the iTDs and siTDs */
@@ -5010,7 +5010,6 @@ static int fotg210_run(struct usb_hcd *hcd)
{
struct fotg210_hcd *fotg210 = hcd_to_fotg210(hcd);
u32 temp;
- u32 hcc_params;
hcd->uses_new_polling = 1;
@@ -5033,7 +5032,7 @@ static int fotg210_run(struct usb_hcd *hcd)
* Scsi_Host.highmem_io, and so forth. It's readonly to all
* host side drivers though.
*/
- hcc_params = fotg210_readl(fotg210, &fotg210->caps->hcc_params);
+ fotg210_readl(fotg210, &fotg210->caps->hcc_params);
/*
* Philips, Intel, and maybe others need CMD_RUN before the
@@ -5412,7 +5411,7 @@ rescan:
*/
if (tmp)
start_unlink_async(fotg210, qh);
- /* FALL THROUGH */
+ fallthrough;
case QH_STATE_UNLINK: /* wait for hw to finish? */
case QH_STATE_UNLINK_WAIT:
idle_timeout:
@@ -5426,7 +5425,7 @@ idle_timeout:
qh_destroy(fotg210, qh);
break;
}
- /* fall through */
+ fallthrough;
default:
/* caller was supposed to have unlinked any requests;
* that's not our job. just leak this memory.
@@ -5558,7 +5557,7 @@ static void fotg210_init(struct fotg210_hcd *fotg210)
iowrite32(value, &fotg210->regs->otgcsr);
}
-/**
+/*
* fotg210_hcd_probe - initialize faraday FOTG210 HCDs
*
* Allocates basic resources for this USB host controller, and
@@ -5657,7 +5656,7 @@ fail_create_hcd:
return retval;
}
-/**
+/*
* fotg210_hcd_remove - shutdown processing for EHCI HCDs
* @dev: USB Host Controller being removed
*
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c
index 5835f9966204..b2716cb72471 100644
--- a/drivers/usb/host/imx21-hcd.c
+++ b/drivers/usb/host/imx21-hcd.c
@@ -224,7 +224,7 @@ static void setup_etd_dword0(struct imx21 *imx21,
((u32) maxpacket << DW0_MAXPKTSIZ));
}
-/**
+/*
* Copy buffer to data controller data memory.
* We cannot use memcpy_toio() because the hardware requires 32bit writes
*/
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index 4a3a2852523f..2cecb36d241b 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -1748,7 +1748,7 @@ static int isp1362_bus_suspend(struct usb_hcd *hcd)
isp1362_hcd->hc_control &= ~OHCI_CTRL_HCFS;
isp1362_hcd->hc_control |= OHCI_USB_RESET;
isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control);
- /* FALL THROUGH */
+ fallthrough;
case OHCI_USB_RESET:
status = -EBUSY;
pr_warn("%s: needs reinit!\n", __func__);
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index 4c49688a069d..9bbfcc3fdd3c 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -56,7 +56,7 @@ typedef const unsigned char isp1362_reg_t;
#define ISP1362_REG_NO(r) (r)
#define ISP1362_REG(name, addr, width, rw) \
-static isp1362_reg_t ISP1362_REG_##name = addr
+static isp1362_reg_t __maybe_unused ISP1362_REG_##name = addr
#define REG_ACCESS_TEST(r) do {} while (0)
#define REG_WIDTH_TEST(r, w) do {} while (0)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 8819f502b6a6..0894f6caccb2 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -11,9 +11,9 @@
*
* Based on:
* o MAX3421E datasheet
- * http://datasheets.maximintegrated.com/en/ds/MAX3421E.pdf
+ * https://datasheets.maximintegrated.com/en/ds/MAX3421E.pdf
* o MAX3421E Programming Guide
- * http://www.hdl.co.jp/ftpdata/utl-001/AN3785.pdf
+ * https://www.hdl.co.jp/ftpdata/utl-001/AN3785.pdf
* o gadget/dummy_hcd.c
* For USB HCD implementation.
* o Arduino MAX3421 driver
@@ -317,7 +317,7 @@ static const int hrsl_to_error[] = {
};
/*
- * See http://www.beyondlogic.org/usbnutshell/usb4.shtml#Control for a
+ * See https://www.beyondlogic.org/usbnutshell/usb4.shtml#Control for a
* reasonable overview of how control transfers use the the IN/OUT
* tokens.
*/
@@ -925,7 +925,7 @@ max3421_handle_error(struct usb_hcd *hcd, u8 hrsl)
spi_wr8(hcd, MAX3421_REG_HCTL,
BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT));
}
- /* FALL THROUGH */
+ fallthrough;
case MAX3421_HRSL_BADBC: /* bad byte count */
case MAX3421_HRSL_PIDERR: /* received PID is corrupted */
case MAX3421_HRSL_PKTERR: /* packet error (stuff, EOP) */
@@ -1715,7 +1715,7 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
dev_dbg(hcd->self.controller, "power-off\n");
max3421_gpout_set_value(hcd, pdata->vbus_gpout,
!pdata->vbus_active_level);
- /* FALLS THROUGH */
+ fallthrough;
default:
max3421_hcd->port_status &= ~(1 << value);
}
@@ -1768,7 +1768,7 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
break;
case USB_PORT_FEAT_RESET:
max3421_reset_port(hcd);
- /* FALLS THROUGH */
+ fallthrough;
default:
if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
!= 0)
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index b635c6a1b1a9..0487a4b0501e 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -153,7 +153,7 @@ static struct regmap *at91_dt_syscon_sfr(void)
/* always called with process context; sleeping is OK */
-/**
+/*
* usb_hcd_at91_probe - initialize AT91-based HCDs
* Context: !in_interrupt()
*
@@ -244,9 +244,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
/* may be called with controller, bus, and devices active */
-/**
+/*
* usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
- * @dev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_at91_probe(), first invoking
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 4de91653a2c7..dd37e77dae00 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -16,7 +16,7 @@
* OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller
* interfaces (though some non-x86 Intel chips use it). It supports
* smarter hardware than UHCI. A download link for the spec available
- * through the http://www.usb.org website.
+ * through the https://www.usb.org website.
*
* This file is licenced under the GPL.
*/
@@ -385,7 +385,7 @@ sanitize:
ed_free (ohci, ed);
break;
}
- /* fall through */
+ fallthrough;
default:
/* caller was supposed to have unlinked any requests;
* that's not our job. can't recover; must leak ed.
@@ -1051,7 +1051,7 @@ int ohci_restart(struct ohci_hcd *ohci)
ed->ed_next = ohci->ed_rm_list;
ed->ed_prev = NULL;
ohci->ed_rm_list = ed;
- /* FALLTHROUGH */
+ fallthrough;
case ED_UNLINK:
break;
default:
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 634f3c7bf774..44504c1751e0 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -58,7 +58,7 @@ __acquires(ohci->lock)
ohci->hc_control |= OHCI_USB_RESET;
ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
(void) ohci_readl (ohci, &ohci->regs->control);
- /* FALL THROUGH */
+ fallthrough;
case OHCI_USB_RESET:
status = -EBUSY;
ohci_dbg (ohci, "needs reinit!\n");
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index d8d35d456456..9ccdf2c216b5 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -18,7 +18,7 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
@@ -53,38 +53,29 @@
#define DRIVER_DESC "OHCI OMAP driver"
-#ifdef CONFIG_TPS65010
-#include <linux/mfd/tps65010.h>
-#else
-
-#define LOW 0
-#define HIGH 1
-
-#define GPIO1 1
-
-static inline int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
-{
- return 0;
-}
-
-#endif
-
-static struct clk *usb_host_ck;
-static struct clk *usb_dc_ck;
+struct ohci_omap_priv {
+ struct clk *usb_host_ck;
+ struct clk *usb_dc_ck;
+ struct gpio_desc *power;
+ struct gpio_desc *overcurrent;
+};
static const char hcd_name[] = "ohci-omap";
static struct hc_driver __read_mostly ohci_omap_hc_driver;
-static void omap_ohci_clock_power(int on)
+#define hcd_to_ohci_omap_priv(h) \
+ ((struct ohci_omap_priv *)hcd_to_ohci(h)->priv)
+
+static void omap_ohci_clock_power(struct ohci_omap_priv *priv, int on)
{
if (on) {
- clk_enable(usb_dc_ck);
- clk_enable(usb_host_ck);
+ clk_enable(priv->usb_dc_ck);
+ clk_enable(priv->usb_host_ck);
/* guesstimate for T5 == 1x 32K clock + APLL lock time */
udelay(100);
} else {
- clk_disable(usb_host_ck);
- clk_disable(usb_dc_ck);
+ clk_disable(priv->usb_host_ck);
+ clk_disable(priv->usb_dc_ck);
}
}
@@ -92,22 +83,22 @@ static void omap_ohci_clock_power(int on)
* Board specific gang-switched transceiver power on/off.
* NOTE: OSK supplies power from DC, not battery.
*/
-static int omap_ohci_transceiver_power(int on)
+static int omap_ohci_transceiver_power(struct ohci_omap_priv *priv, int on)
{
if (on) {
if (machine_is_omap_innovator() && cpu_is_omap1510())
__raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
| ((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL);
- else if (machine_is_omap_osk())
- tps65010_set_gpio_out_value(GPIO1, LOW);
+ else if (priv->power)
+ gpiod_set_value(priv->power, 0);
} else {
if (machine_is_omap_innovator() && cpu_is_omap1510())
__raw_writeb(__raw_readb(INNOVATOR_FPGA_CAM_USB_CONTROL)
& ~((1 << 5/*usb1*/) | (1 << 3/*usb2*/)),
INNOVATOR_FPGA_CAM_USB_CONTROL);
- else if (machine_is_omap_osk())
- tps65010_set_gpio_out_value(GPIO1, HIGH);
+ else if (priv->power)
+ gpiod_set_value(priv->power, 1);
}
return 0;
@@ -196,6 +187,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
struct omap_usb_config *config = dev_get_platdata(hcd->self.controller);
+ struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd);
int need_transceiver = (config->otg != 0);
int ret;
@@ -235,7 +227,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
}
#endif
- omap_ohci_clock_power(1);
+ omap_ohci_clock_power(priv, 1);
if (cpu_is_omap15xx()) {
omap_1510_local_bus_power(1);
@@ -266,8 +258,6 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
/* gpio9 for overcurrent detction */
omap_cfg_reg(W8_1610_GPIO9);
- gpio_request(9, "OHCI overcurrent");
- gpio_direction_input(9);
/* for paranoia's sake: disable USB.PUEN */
omap_cfg_reg(W4_USB_HIGHZ);
@@ -281,7 +271,7 @@ static int ohci_omap_reset(struct usb_hcd *hcd)
}
/* FIXME hub_wq hub requests should manage power switching */
- omap_ohci_transceiver_power(1);
+ omap_ohci_transceiver_power(priv, 1);
/* board init will have already handled HMC and mux setup.
* any external transceiver should already be initialized
@@ -305,6 +295,7 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev)
{
int retval, irq;
struct usb_hcd *hcd = 0;
+ struct ohci_omap_priv *priv;
if (pdev->num_resources != 2) {
dev_err(&pdev->dev, "invalid num_resources: %i\n",
@@ -318,34 +309,58 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev)
return -ENODEV;
}
- usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
- if (IS_ERR(usb_host_ck))
- return PTR_ERR(usb_host_ck);
+ hcd = usb_create_hcd(&ohci_omap_hc_driver, &pdev->dev,
+ dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
- if (!cpu_is_omap15xx())
- usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
- else
- usb_dc_ck = clk_get(&pdev->dev, "lb_ck");
+ hcd->rsrc_start = pdev->resource[0].start;
+ hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+ priv = hcd_to_ohci_omap_priv(hcd);
- if (IS_ERR(usb_dc_ck)) {
- clk_put(usb_host_ck);
- return PTR_ERR(usb_dc_ck);
+ /* Obtain two optional GPIO lines */
+ priv->power = devm_gpiod_get_optional(&pdev->dev, "power", GPIOD_ASIS);
+ if (IS_ERR(priv->power)) {
+ retval = PTR_ERR(priv->power);
+ goto err_put_hcd;
}
+ if (priv->power)
+ gpiod_set_consumer_name(priv->power, "OHCI power");
+ /*
+ * This "overcurrent" GPIO line isn't really used in the code,
+ * but has a designated hardware function.
+ * TODO: implement proper overcurrent handling.
+ */
+ priv->overcurrent = devm_gpiod_get_optional(&pdev->dev, "overcurrent",
+ GPIOD_IN);
+ if (IS_ERR(priv->overcurrent)) {
+ retval = PTR_ERR(priv->overcurrent);
+ goto err_put_hcd;
+ }
+ if (priv->overcurrent)
+ gpiod_set_consumer_name(priv->overcurrent, "OHCI overcurrent");
- hcd = usb_create_hcd(&ohci_omap_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
- if (!hcd) {
- retval = -ENOMEM;
- goto err0;
+ priv->usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck");
+ if (IS_ERR(priv->usb_host_ck)) {
+ retval = PTR_ERR(priv->usb_host_ck);
+ goto err_put_hcd;
+ }
+
+ if (!cpu_is_omap15xx())
+ priv->usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
+ else
+ priv->usb_dc_ck = clk_get(&pdev->dev, "lb_ck");
+
+ if (IS_ERR(priv->usb_dc_ck)) {
+ retval = PTR_ERR(priv->usb_dc_ck);
+ goto err_put_host_ck;
}
- hcd->rsrc_start = pdev->resource[0].start;
- hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
dev_dbg(&pdev->dev, "request_mem_region failed\n");
retval = -EBUSY;
- goto err1;
+ goto err_put_dc_ck;
}
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
@@ -370,11 +385,12 @@ err3:
iounmap(hcd->regs);
err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
+err_put_dc_ck:
+ clk_put(priv->usb_dc_ck);
+err_put_host_ck:
+ clk_put(priv->usb_host_ck);
+err_put_hcd:
usb_put_hcd(hcd);
-err0:
- clk_put(usb_dc_ck);
- clk_put(usb_host_ck);
return retval;
}
@@ -393,21 +409,20 @@ err0:
static int ohci_hcd_omap_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd);
dev_dbg(hcd->self.controller, "stopping USB Controller\n");
usb_remove_hcd(hcd);
- omap_ohci_clock_power(0);
+ omap_ohci_clock_power(priv, 0);
if (!IS_ERR_OR_NULL(hcd->usb_phy)) {
(void) otg_set_host(hcd->usb_phy->otg, 0);
usb_put_phy(hcd->usb_phy);
}
- if (machine_is_omap_osk())
- gpio_free(9);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ clk_put(priv->usb_dc_ck);
+ clk_put(priv->usb_host_ck);
usb_put_hcd(hcd);
- clk_put(usb_dc_ck);
- clk_put(usb_host_ck);
return 0;
}
@@ -419,6 +434,7 @@ static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd);
bool do_wakeup = device_may_wakeup(&pdev->dev);
int ret;
@@ -430,7 +446,7 @@ static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message)
if (ret)
return ret;
- omap_ohci_clock_power(0);
+ omap_ohci_clock_power(priv, 0);
return ret;
}
@@ -438,12 +454,13 @@ static int ohci_omap_resume(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct ohci_omap_priv *priv = hcd_to_ohci_omap_priv(hcd);
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
- omap_ohci_clock_power(1);
+ omap_ohci_clock_power(priv, 1);
ohci_resume(hcd, false);
return 0;
}
@@ -470,7 +487,8 @@ static struct platform_driver ohci_hcd_omap_driver = {
static const struct ohci_driver_overrides omap_overrides __initconst = {
.product_desc = "OMAP OHCI",
- .reset = ohci_omap_reset
+ .reset = ohci_omap_reset,
+ .extra_priv_size = sizeof(struct ohci_omap_priv),
};
static int __init ohci_omap_init(void)
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 585222af24ff..41efe927d8f3 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -232,10 +232,6 @@ static const struct pci_device_id ohci_pci_quirks[] = {
.driver_data = (unsigned long)ohci_quirk_qemu,
},
- /* FIXME for some of the early AMD 760 southbridges, OHCI
- * won't work at all. blacklist them.
- */
-
{},
};
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 4ccb85a67bb3..3b445312beea 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -647,7 +647,7 @@ static void td_submit_urb (
/* ... and periodic urbs have extra accounting */
periodic = ohci_to_hcd(ohci)->self.bandwidth_int_reqs++ == 0
&& ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0;
- /* FALLTHROUGH */
+ fallthrough;
case PIPE_BULK:
info = is_out
? TD_T_TOGGLE | TD_CC | TD_DP_OUT
@@ -879,11 +879,11 @@ static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc)
case TD_DATAUNDERRUN:
if ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0)
break;
- /* fallthrough */
+ fallthrough;
case TD_CC_STALL:
if (usb_pipecontrol (urb->pipe))
break;
- /* fallthrough */
+ fallthrough;
default:
ohci_dbg (ohci,
"urb %p path %s ep%d%s %08x cc %d --> status %d\n",
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index d961097c90f0..de5e570c58ba 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -343,7 +343,7 @@ ohci_hcd_s3c2410_remove(struct platform_device *dev)
return 0;
}
-/**
+/*
* ohci_hcd_s3c2410_probe - initialize S3C2410-based HCDs
* Context: !in_interrupt()
*
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index fb6f5e9ae5c6..7f857bad9e95 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -97,13 +97,13 @@ static void tmio_stop_hc(struct platform_device *dev)
switch (ohci->num_ports) {
default:
dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports);
- /* fall through */
+ fallthrough;
case 3:
pm |= CCR_PM_USBPW3;
- /* fall through */
+ fallthrough;
case 2:
pm |= CCR_PM_USBPW2;
- /* fall through */
+ fallthrough;
case 1:
pm |= CCR_PM_USBPW1;
}
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index b85a39588f9d..aac6285b37f8 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -162,7 +162,7 @@ struct td {
/* map OHCI TD status codes (CC) to errno values */
-static const int cc_to_error [16] = {
+static const int __maybe_unused cc_to_error [16] = {
/* No Error */ 0,
/* CRC Error */ -EILSEQ,
/* Bit Stuff */ -EPROTO,
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 120666a0d590..cfa7dd2cc7d3 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -1858,7 +1858,7 @@ static struct ehci_qh *qh_make(struct oxu_hcd *oxu,
switch (urb->dev->speed) {
case USB_SPEED_LOW:
info1 |= (1 << 12); /* EPS "low" */
- /* FALL THROUGH */
+ fallthrough;
case USB_SPEED_FULL:
/* EPS 0 means "full" */
@@ -2037,16 +2037,15 @@ static struct ehci_qh *qh_append_tds(struct oxu_hcd *oxu,
static int submit_async(struct oxu_hcd *oxu, struct urb *urb,
struct list_head *qtd_list, gfp_t mem_flags)
{
- struct ehci_qtd *qtd;
- int epnum;
+ int epnum = urb->ep->desc.bEndpointAddress;
unsigned long flags;
struct ehci_qh *qh = NULL;
int rc = 0;
+#ifdef OXU_URB_TRACE
+ struct ehci_qtd *qtd;
qtd = list_entry(qtd_list->next, struct ehci_qtd, qtd_list);
- epnum = urb->ep->desc.bEndpointAddress;
-#ifdef OXU_URB_TRACE
oxu_dbg(oxu, "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n",
__func__, urb->dev->devpath, urb,
epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out",
@@ -3378,7 +3377,7 @@ static int oxu_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
switch (qh->qh_state) {
case QH_STATE_LINKED:
intr_deschedule(oxu, qh);
- /* FALL THROUGH */
+ fallthrough;
case QH_STATE_IDLE:
qh_completions(oxu, qh);
break;
@@ -3450,7 +3449,7 @@ rescan:
if (!tmp)
goto nogood;
unlink_async(oxu, qh);
- /* FALL THROUGH */
+ fallthrough;
case QH_STATE_UNLINK: /* wait for hw to finish? */
idle_timeout:
spin_unlock_irqrestore(&oxu->lock, flags);
@@ -3461,7 +3460,7 @@ idle_timeout:
qh_put(qh);
break;
}
- /* fall through */
+ fallthrough;
default:
nogood:
/* caller was supposed to have unlinked any requests;
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 0b949acfa258..b8961c0381cf 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -1133,7 +1133,7 @@ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev)
}
EXPORT_SYMBOL_GPL(usb_disable_xhci_ports);
-/**
+/*
* PCI Quirks for xHCI.
*
* Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS.
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 0c03ac6b0213..63719cdf6a4e 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -475,16 +475,14 @@ static void pipe_stop(struct r8a66597 *r8a66597, struct r8a66597_pipe *pipe)
static void clear_all_buffer(struct r8a66597 *r8a66597,
struct r8a66597_pipe *pipe)
{
- u16 tmp;
-
if (!pipe || pipe->info.pipenum == 0)
return;
pipe_stop(r8a66597, pipe);
r8a66597_bset(r8a66597, ACLRM, pipe->pipectr);
- tmp = r8a66597_read(r8a66597, pipe->pipectr);
- tmp = r8a66597_read(r8a66597, pipe->pipectr);
- tmp = r8a66597_read(r8a66597, pipe->pipectr);
+ r8a66597_read(r8a66597, pipe->pipectr);
+ r8a66597_read(r8a66597, pipe->pipectr);
+ r8a66597_read(r8a66597, pipe->pipectr);
r8a66597_bclr(r8a66597, ACLRM, pipe->pipectr);
}
diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
index 93e2cca5262d..fcc5ac5ce8b1 100644
--- a/drivers/usb/host/xhci-dbgcap.c
+++ b/drivers/usb/host/xhci-dbgcap.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-/**
+/*
* xhci-dbgcap.c - xHCI debug capability support
*
* Copyright (C) 2017 Intel Corporation
@@ -14,24 +14,27 @@
#include "xhci-trace.h"
#include "xhci-dbgcap.h"
-static inline void *
-dbc_dma_alloc_coherent(struct xhci_hcd *xhci, size_t size,
- dma_addr_t *dma_handle, gfp_t flags)
+static void dbc_free_ctx(struct device *dev, struct xhci_container_ctx *ctx)
{
- void *vaddr;
-
- vaddr = dma_alloc_coherent(xhci_to_hcd(xhci)->self.sysdev,
- size, dma_handle, flags);
- return vaddr;
+ if (!ctx)
+ return;
+ dma_free_coherent(dev, ctx->size, ctx->bytes, ctx->dma);
+ kfree(ctx);
}
-static inline void
-dbc_dma_free_coherent(struct xhci_hcd *xhci, size_t size,
- void *cpu_addr, dma_addr_t dma_handle)
+/* we use only one segment for DbC rings */
+static void dbc_ring_free(struct device *dev, struct xhci_ring *ring)
{
- if (cpu_addr)
- dma_free_coherent(xhci_to_hcd(xhci)->self.sysdev,
- size, cpu_addr, dma_handle);
+ if (!ring)
+ return;
+
+ if (ring->first_seg && ring->first_seg->trbs) {
+ dma_free_coherent(dev, TRB_SEGMENT_SIZE,
+ ring->first_seg->trbs,
+ ring->first_seg->dma);
+ kfree(ring->first_seg);
+ }
+ kfree(ring);
}
static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings)
@@ -83,16 +86,14 @@ static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings)
return string_length;
}
-static void xhci_dbc_init_contexts(struct xhci_hcd *xhci, u32 string_length)
+static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length)
{
- struct xhci_dbc *dbc;
struct dbc_info_context *info;
struct xhci_ep_ctx *ep_ctx;
u32 dev_info;
dma_addr_t deq, dma;
unsigned int max_burst;
- dbc = xhci->dbc;
if (!dbc)
return;
@@ -121,7 +122,7 @@ static void xhci_dbc_init_contexts(struct xhci_hcd *xhci, u32 string_length)
ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state);
/* Set DbC context and info registers: */
- xhci_write_64(xhci, dbc->ctx->dma, &dbc->regs->dccp);
+ lo_hi_writeq(dbc->ctx->dma, &dbc->regs->dccp);
dev_info = cpu_to_le32((DBC_VENDOR_ID << 16) | DBC_PROTOCOL);
writel(dev_info, &dbc->regs->devinfo1);
@@ -134,10 +135,8 @@ static void xhci_dbc_giveback(struct dbc_request *req, int status)
__releases(&dbc->lock)
__acquires(&dbc->lock)
{
- struct dbc_ep *dep = req->dep;
- struct xhci_dbc *dbc = dep->dbc;
- struct xhci_hcd *xhci = dbc->xhci;
- struct device *dev = xhci_to_hcd(dbc->xhci)->self.sysdev;
+ struct xhci_dbc *dbc = req->dbc;
+ struct device *dev = dbc->dev;
list_del_init(&req->list_pending);
req->trb_dma = 0;
@@ -151,11 +150,11 @@ static void xhci_dbc_giveback(struct dbc_request *req, int status)
dma_unmap_single(dev,
req->dma,
req->length,
- dbc_ep_dma_direction(dep));
+ dbc_ep_dma_direction(req));
/* Give back the transfer request: */
spin_unlock(&dbc->lock);
- req->complete(xhci, req);
+ req->complete(dbc, req);
spin_lock(&dbc->lock);
}
@@ -187,18 +186,25 @@ static void xhci_dbc_flush_requests(struct xhci_dbc *dbc)
}
struct dbc_request *
-dbc_alloc_request(struct dbc_ep *dep, gfp_t gfp_flags)
+dbc_alloc_request(struct xhci_dbc *dbc, unsigned int direction, gfp_t flags)
{
struct dbc_request *req;
- req = kzalloc(sizeof(*req), gfp_flags);
+ if (direction != BULK_IN &&
+ direction != BULK_OUT)
+ return NULL;
+
+ if (!dbc)
+ return NULL;
+
+ req = kzalloc(sizeof(*req), flags);
if (!req)
return NULL;
- req->dep = dep;
+ req->dbc = dbc;
INIT_LIST_HEAD(&req->list_pending);
INIT_LIST_HEAD(&req->list_pool);
- req->direction = dep->direction;
+ req->direction = direction;
trace_xhci_dbc_alloc_request(req);
@@ -206,7 +212,7 @@ dbc_alloc_request(struct dbc_ep *dep, gfp_t gfp_flags)
}
void
-dbc_free_request(struct dbc_ep *dep, struct dbc_request *req)
+dbc_free_request(struct dbc_request *req)
{
trace_xhci_dbc_free_request(req);
@@ -242,7 +248,7 @@ static int xhci_dbc_queue_bulk_tx(struct dbc_ep *dep,
u64 addr;
union xhci_trb *trb;
unsigned int num_trbs;
- struct xhci_dbc *dbc = dep->dbc;
+ struct xhci_dbc *dbc = req->dbc;
struct xhci_ring *ring = dep->ring;
u32 length, control, cycle;
@@ -286,14 +292,12 @@ static int xhci_dbc_queue_bulk_tx(struct dbc_ep *dep,
}
static int
-dbc_ep_do_queue(struct dbc_ep *dep, struct dbc_request *req)
+dbc_ep_do_queue(struct dbc_request *req)
{
int ret;
- struct device *dev;
- struct xhci_dbc *dbc = dep->dbc;
- struct xhci_hcd *xhci = dbc->xhci;
-
- dev = xhci_to_hcd(xhci)->self.sysdev;
+ struct xhci_dbc *dbc = req->dbc;
+ struct device *dev = dbc->dev;
+ struct dbc_ep *dep = &dbc->eps[req->direction];
if (!req->length || !req->buf)
return -EINVAL;
@@ -306,13 +310,13 @@ dbc_ep_do_queue(struct dbc_ep *dep, struct dbc_request *req)
req->length,
dbc_ep_dma_direction(dep));
if (dma_mapping_error(dev, req->dma)) {
- xhci_err(xhci, "failed to map buffer\n");
+ dev_err(dbc->dev, "failed to map buffer\n");
return -EFAULT;
}
ret = xhci_dbc_queue_bulk_tx(dep, req);
if (ret) {
- xhci_err(xhci, "failed to queue trbs\n");
+ dev_err(dbc->dev, "failed to queue trbs\n");
dma_unmap_single(dev,
req->dma,
req->length,
@@ -325,16 +329,22 @@ dbc_ep_do_queue(struct dbc_ep *dep, struct dbc_request *req)
return 0;
}
-int dbc_ep_queue(struct dbc_ep *dep, struct dbc_request *req,
- gfp_t gfp_flags)
+int dbc_ep_queue(struct dbc_request *req)
{
unsigned long flags;
- struct xhci_dbc *dbc = dep->dbc;
+ struct xhci_dbc *dbc = req->dbc;
int ret = -ESHUTDOWN;
+ if (!dbc)
+ return -ENODEV;
+
+ if (req->direction != BULK_IN &&
+ req->direction != BULK_OUT)
+ return -EINVAL;
+
spin_lock_irqsave(&dbc->lock, flags);
if (dbc->state == DS_CONFIGURED)
- ret = dbc_ep_do_queue(dep, req);
+ ret = dbc_ep_do_queue(req);
spin_unlock_irqrestore(&dbc->lock, flags);
mod_delayed_work(system_wq, &dbc->event_work, 0);
@@ -344,10 +354,9 @@ int dbc_ep_queue(struct dbc_ep *dep, struct dbc_request *req,
return ret;
}
-static inline void xhci_dbc_do_eps_init(struct xhci_hcd *xhci, bool direction)
+static inline void xhci_dbc_do_eps_init(struct xhci_dbc *dbc, bool direction)
{
struct dbc_ep *dep;
- struct xhci_dbc *dbc = xhci->dbc;
dep = &dbc->eps[direction];
dep->dbc = dbc;
@@ -357,125 +366,205 @@ static inline void xhci_dbc_do_eps_init(struct xhci_hcd *xhci, bool direction)
INIT_LIST_HEAD(&dep->list_pending);
}
-static void xhci_dbc_eps_init(struct xhci_hcd *xhci)
+static void xhci_dbc_eps_init(struct xhci_dbc *dbc)
{
- xhci_dbc_do_eps_init(xhci, BULK_OUT);
- xhci_dbc_do_eps_init(xhci, BULK_IN);
+ xhci_dbc_do_eps_init(dbc, BULK_OUT);
+ xhci_dbc_do_eps_init(dbc, BULK_IN);
}
-static void xhci_dbc_eps_exit(struct xhci_hcd *xhci)
+static void xhci_dbc_eps_exit(struct xhci_dbc *dbc)
{
- struct xhci_dbc *dbc = xhci->dbc;
-
memset(dbc->eps, 0, sizeof(struct dbc_ep) * ARRAY_SIZE(dbc->eps));
}
-static int xhci_dbc_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+static int dbc_erst_alloc(struct device *dev, struct xhci_ring *evt_ring,
+ struct xhci_erst *erst, gfp_t flags)
+{
+ erst->entries = dma_alloc_coherent(dev, sizeof(struct xhci_erst_entry),
+ &erst->erst_dma_addr, flags);
+ if (!erst->entries)
+ return -ENOMEM;
+
+ erst->num_entries = 1;
+ erst->entries[0].seg_addr = cpu_to_le64(evt_ring->first_seg->dma);
+ erst->entries[0].seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
+ erst->entries[0].rsvd = 0;
+ return 0;
+}
+
+static void dbc_erst_free(struct device *dev, struct xhci_erst *erst)
+{
+ if (erst->entries)
+ dma_free_coherent(dev, sizeof(struct xhci_erst_entry),
+ erst->entries, erst->erst_dma_addr);
+ erst->entries = NULL;
+}
+
+static struct xhci_container_ctx *
+dbc_alloc_ctx(struct device *dev, gfp_t flags)
+{
+ struct xhci_container_ctx *ctx;
+
+ ctx = kzalloc(sizeof(*ctx), flags);
+ if (!ctx)
+ return NULL;
+
+ /* xhci 7.6.9, all three contexts; info, ep-out and ep-in. Each 64 bytes*/
+ ctx->size = 3 * DBC_CONTEXT_SIZE;
+ ctx->bytes = dma_alloc_coherent(dev, ctx->size, &ctx->dma, flags);
+ if (!ctx->bytes) {
+ kfree(ctx);
+ return NULL;
+ }
+ return ctx;
+}
+
+static struct xhci_ring *
+xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags)
+{
+ struct xhci_ring *ring;
+ struct xhci_segment *seg;
+ dma_addr_t dma;
+
+ ring = kzalloc(sizeof(*ring), flags);
+ if (!ring)
+ return NULL;
+
+ ring->num_segs = 1;
+ ring->type = type;
+
+ seg = kzalloc(sizeof(*seg), flags);
+ if (!seg)
+ goto seg_fail;
+
+ ring->first_seg = seg;
+ ring->last_seg = seg;
+ seg->next = seg;
+
+ seg->trbs = dma_alloc_coherent(dev, TRB_SEGMENT_SIZE, &dma, flags);
+ if (!seg->trbs)
+ goto dma_fail;
+
+ seg->dma = dma;
+
+ /* Only event ring does not use link TRB */
+ if (type != TYPE_EVENT) {
+ union xhci_trb *trb = &seg->trbs[TRBS_PER_SEGMENT - 1];
+
+ trb->link.segment_ptr = cpu_to_le64(dma);
+ trb->link.control = cpu_to_le32(LINK_TOGGLE | TRB_TYPE(TRB_LINK));
+ }
+ INIT_LIST_HEAD(&ring->td_list);
+ xhci_initialize_ring_info(ring, 1);
+ return ring;
+dma_fail:
+ kfree(seg);
+seg_fail:
+ kfree(ring);
+ return NULL;
+}
+
+static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags)
{
int ret;
dma_addr_t deq;
u32 string_length;
- struct xhci_dbc *dbc = xhci->dbc;
+ struct device *dev = dbc->dev;
/* Allocate various rings for events and transfers: */
- dbc->ring_evt = xhci_ring_alloc(xhci, 1, 1, TYPE_EVENT, 0, flags);
+ dbc->ring_evt = xhci_dbc_ring_alloc(dev, TYPE_EVENT, flags);
if (!dbc->ring_evt)
goto evt_fail;
- dbc->ring_in = xhci_ring_alloc(xhci, 1, 1, TYPE_BULK, 0, flags);
+ dbc->ring_in = xhci_dbc_ring_alloc(dev, TYPE_BULK, flags);
if (!dbc->ring_in)
goto in_fail;
- dbc->ring_out = xhci_ring_alloc(xhci, 1, 1, TYPE_BULK, 0, flags);
+ dbc->ring_out = xhci_dbc_ring_alloc(dev, TYPE_BULK, flags);
if (!dbc->ring_out)
goto out_fail;
/* Allocate and populate ERST: */
- ret = xhci_alloc_erst(xhci, dbc->ring_evt, &dbc->erst, flags);
+ ret = dbc_erst_alloc(dev, dbc->ring_evt, &dbc->erst, flags);
if (ret)
goto erst_fail;
/* Allocate context data structure: */
- dbc->ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags);
+ dbc->ctx = dbc_alloc_ctx(dev, flags); /* was sysdev, and is still */
if (!dbc->ctx)
goto ctx_fail;
/* Allocate the string table: */
dbc->string_size = sizeof(struct dbc_str_descs);
- dbc->string = dbc_dma_alloc_coherent(xhci,
- dbc->string_size,
- &dbc->string_dma,
- flags);
+ dbc->string = dma_alloc_coherent(dev, dbc->string_size,
+ &dbc->string_dma, flags);
if (!dbc->string)
goto string_fail;
/* Setup ERST register: */
writel(dbc->erst.erst_size, &dbc->regs->ersts);
- xhci_write_64(xhci, dbc->erst.erst_dma_addr, &dbc->regs->erstba);
+
+ lo_hi_writeq(dbc->erst.erst_dma_addr, &dbc->regs->erstba);
deq = xhci_trb_virt_to_dma(dbc->ring_evt->deq_seg,
dbc->ring_evt->dequeue);
- xhci_write_64(xhci, deq, &dbc->regs->erdp);
+ lo_hi_writeq(deq, &dbc->regs->erdp);
/* Setup strings and contexts: */
string_length = xhci_dbc_populate_strings(dbc->string);
- xhci_dbc_init_contexts(xhci, string_length);
+ xhci_dbc_init_contexts(dbc, string_length);
- xhci_dbc_eps_init(xhci);
+ xhci_dbc_eps_init(dbc);
dbc->state = DS_INITIALIZED;
return 0;
string_fail:
- xhci_free_container_ctx(xhci, dbc->ctx);
+ dbc_free_ctx(dev, dbc->ctx);
dbc->ctx = NULL;
ctx_fail:
- xhci_free_erst(xhci, &dbc->erst);
+ dbc_erst_free(dev, &dbc->erst);
erst_fail:
- xhci_ring_free(xhci, dbc->ring_out);
+ dbc_ring_free(dev, dbc->ring_out);
dbc->ring_out = NULL;
out_fail:
- xhci_ring_free(xhci, dbc->ring_in);
+ dbc_ring_free(dev, dbc->ring_in);
dbc->ring_in = NULL;
in_fail:
- xhci_ring_free(xhci, dbc->ring_evt);
+ dbc_ring_free(dev, dbc->ring_evt);
dbc->ring_evt = NULL;
evt_fail:
return -ENOMEM;
}
-static void xhci_dbc_mem_cleanup(struct xhci_hcd *xhci)
+static void xhci_dbc_mem_cleanup(struct xhci_dbc *dbc)
{
- struct xhci_dbc *dbc = xhci->dbc;
-
if (!dbc)
return;
- xhci_dbc_eps_exit(xhci);
+ xhci_dbc_eps_exit(dbc);
if (dbc->string) {
- dbc_dma_free_coherent(xhci,
- dbc->string_size,
- dbc->string, dbc->string_dma);
+ dma_free_coherent(dbc->dev, dbc->string_size,
+ dbc->string, dbc->string_dma);
dbc->string = NULL;
}
- xhci_free_container_ctx(xhci, dbc->ctx);
+ dbc_free_ctx(dbc->dev, dbc->ctx);
dbc->ctx = NULL;
- xhci_free_erst(xhci, &dbc->erst);
- xhci_ring_free(xhci, dbc->ring_out);
- xhci_ring_free(xhci, dbc->ring_in);
- xhci_ring_free(xhci, dbc->ring_evt);
+ dbc_erst_free(dbc->dev, &dbc->erst);
+ dbc_ring_free(dbc->dev, dbc->ring_out);
+ dbc_ring_free(dbc->dev, dbc->ring_in);
+ dbc_ring_free(dbc->dev, dbc->ring_evt);
dbc->ring_in = NULL;
dbc->ring_out = NULL;
dbc->ring_evt = NULL;
}
-static int xhci_do_dbc_start(struct xhci_hcd *xhci)
+static int xhci_do_dbc_start(struct xhci_dbc *dbc)
{
int ret;
u32 ctrl;
- struct xhci_dbc *dbc = xhci->dbc;
if (dbc->state != DS_DISABLED)
return -EINVAL;
@@ -487,7 +576,7 @@ static int xhci_do_dbc_start(struct xhci_hcd *xhci)
if (ret)
return ret;
- ret = xhci_dbc_mem_init(xhci, GFP_ATOMIC);
+ ret = xhci_dbc_mem_init(dbc, GFP_ATOMIC);
if (ret)
return ret;
@@ -505,10 +594,8 @@ static int xhci_do_dbc_start(struct xhci_hcd *xhci)
return 0;
}
-static int xhci_do_dbc_stop(struct xhci_hcd *xhci)
+static int xhci_do_dbc_stop(struct xhci_dbc *dbc)
{
- struct xhci_dbc *dbc = xhci->dbc;
-
if (dbc->state == DS_DISABLED)
return -1;
@@ -518,76 +605,81 @@ static int xhci_do_dbc_stop(struct xhci_hcd *xhci)
return 0;
}
-static int xhci_dbc_start(struct xhci_hcd *xhci)
+static int xhci_dbc_start(struct xhci_dbc *dbc)
{
int ret;
unsigned long flags;
- struct xhci_dbc *dbc = xhci->dbc;
WARN_ON(!dbc);
- pm_runtime_get_sync(xhci_to_hcd(xhci)->self.controller);
+ pm_runtime_get_sync(dbc->dev); /* note this was self.controller */
spin_lock_irqsave(&dbc->lock, flags);
- ret = xhci_do_dbc_start(xhci);
+ ret = xhci_do_dbc_start(dbc);
spin_unlock_irqrestore(&dbc->lock, flags);
if (ret) {
- pm_runtime_put(xhci_to_hcd(xhci)->self.controller);
+ pm_runtime_put(dbc->dev); /* note this was self.controller */
return ret;
}
return mod_delayed_work(system_wq, &dbc->event_work, 1);
}
-static void xhci_dbc_stop(struct xhci_hcd *xhci)
+static void xhci_dbc_stop(struct xhci_dbc *dbc)
{
int ret;
unsigned long flags;
- struct xhci_dbc *dbc = xhci->dbc;
- struct dbc_port *port = &dbc->port;
WARN_ON(!dbc);
- cancel_delayed_work_sync(&dbc->event_work);
+ switch (dbc->state) {
+ case DS_DISABLED:
+ return;
+ case DS_CONFIGURED:
+ case DS_STALLED:
+ if (dbc->driver->disconnect)
+ dbc->driver->disconnect(dbc);
+ break;
+ default:
+ break;
+ }
- if (port->registered)
- xhci_dbc_tty_unregister_device(xhci);
+ cancel_delayed_work_sync(&dbc->event_work);
spin_lock_irqsave(&dbc->lock, flags);
- ret = xhci_do_dbc_stop(xhci);
+ ret = xhci_do_dbc_stop(dbc);
spin_unlock_irqrestore(&dbc->lock, flags);
if (!ret) {
- xhci_dbc_mem_cleanup(xhci);
- pm_runtime_put_sync(xhci_to_hcd(xhci)->self.controller);
+ xhci_dbc_mem_cleanup(dbc);
+ pm_runtime_put_sync(dbc->dev); /* note, was self.controller */
}
}
static void
-dbc_handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event)
+dbc_handle_port_status(struct xhci_dbc *dbc, union xhci_trb *event)
{
u32 portsc;
- struct xhci_dbc *dbc = xhci->dbc;
portsc = readl(&dbc->regs->portsc);
if (portsc & DBC_PORTSC_CONN_CHANGE)
- xhci_info(xhci, "DbC port connect change\n");
+ dev_info(dbc->dev, "DbC port connect change\n");
if (portsc & DBC_PORTSC_RESET_CHANGE)
- xhci_info(xhci, "DbC port reset change\n");
+ dev_info(dbc->dev, "DbC port reset change\n");
if (portsc & DBC_PORTSC_LINK_CHANGE)
- xhci_info(xhci, "DbC port link status change\n");
+ dev_info(dbc->dev, "DbC port link status change\n");
if (portsc & DBC_PORTSC_CONFIG_CHANGE)
- xhci_info(xhci, "DbC config error change\n");
+ dev_info(dbc->dev, "DbC config error change\n");
/* Port reset change bit will be cleared in other place: */
writel(portsc & ~DBC_PORTSC_RESET_CHANGE, &dbc->regs->portsc);
}
-static void dbc_handle_xfer_event(struct xhci_hcd *xhci, union xhci_trb *event)
+static void dbc_handle_xfer_event(struct xhci_dbc *dbc, union xhci_trb *event)
{
struct dbc_ep *dep;
struct xhci_ring *ring;
@@ -601,7 +693,7 @@ static void dbc_handle_xfer_event(struct xhci_hcd *xhci, union xhci_trb *event)
remain_length = EVENT_TRB_LEN(le32_to_cpu(event->generic.field[2]));
ep_id = TRB_TO_EP_ID(le32_to_cpu(event->generic.field[3]));
dep = (ep_id == EPID_OUT) ?
- get_out_ep(xhci) : get_in_ep(xhci);
+ get_out_ep(dbc) : get_in_ep(dbc);
ring = dep->ring;
switch (comp_code) {
@@ -615,11 +707,11 @@ static void dbc_handle_xfer_event(struct xhci_hcd *xhci, union xhci_trb *event)
case COMP_BABBLE_DETECTED_ERROR:
case COMP_USB_TRANSACTION_ERROR:
case COMP_STALL_ERROR:
- xhci_warn(xhci, "tx error %d detected\n", comp_code);
+ dev_warn(dbc->dev, "tx error %d detected\n", comp_code);
status = -comp_code;
break;
default:
- xhci_err(xhci, "unknown tx error %d\n", comp_code);
+ dev_err(dbc->dev, "unknown tx error %d\n", comp_code);
status = -comp_code;
break;
}
@@ -633,7 +725,7 @@ static void dbc_handle_xfer_event(struct xhci_hcd *xhci, union xhci_trb *event)
}
if (!req) {
- xhci_warn(xhci, "no matched request\n");
+ dev_warn(dbc->dev, "no matched request\n");
return;
}
@@ -644,13 +736,23 @@ static void dbc_handle_xfer_event(struct xhci_hcd *xhci, union xhci_trb *event)
xhci_dbc_giveback(req, status);
}
+static void inc_evt_deq(struct xhci_ring *ring)
+{
+ /* If on the last TRB of the segment go back to the beginning */
+ if (ring->dequeue == &ring->deq_seg->trbs[TRBS_PER_SEGMENT - 1]) {
+ ring->cycle_state ^= 1;
+ ring->dequeue = ring->deq_seg->trbs;
+ return;
+ }
+ ring->dequeue++;
+}
+
static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
{
dma_addr_t deq;
struct dbc_ep *dep;
union xhci_trb *evt;
u32 ctrl, portsc;
- struct xhci_hcd *xhci = dbc->xhci;
bool update_erdp = false;
/* DbC state machine: */
@@ -663,7 +765,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
portsc = readl(&dbc->regs->portsc);
if (portsc & DBC_PORTSC_CONN_STATUS) {
dbc->state = DS_CONNECTED;
- xhci_info(xhci, "DbC connected\n");
+ dev_info(dbc->dev, "DbC connected\n");
}
return EVT_DONE;
@@ -671,7 +773,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
ctrl = readl(&dbc->regs->control);
if (ctrl & DBC_CTRL_DBC_RUN) {
dbc->state = DS_CONFIGURED;
- xhci_info(xhci, "DbC configured\n");
+ dev_info(dbc->dev, "DbC configured\n");
portsc = readl(&dbc->regs->portsc);
writel(portsc, &dbc->regs->portsc);
return EVT_GSER;
@@ -683,7 +785,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
portsc = readl(&dbc->regs->portsc);
if (!(portsc & DBC_PORTSC_PORT_ENABLED) &&
!(portsc & DBC_PORTSC_CONN_STATUS)) {
- xhci_info(xhci, "DbC cable unplugged\n");
+ dev_info(dbc->dev, "DbC cable unplugged\n");
dbc->state = DS_ENABLED;
xhci_dbc_flush_requests(dbc);
@@ -692,7 +794,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
/* Handle debug port reset event: */
if (portsc & DBC_PORTSC_RESET_CHANGE) {
- xhci_info(xhci, "DbC port reset\n");
+ dev_info(dbc->dev, "DbC port reset\n");
writel(portsc, &dbc->regs->portsc);
dbc->state = DS_ENABLED;
xhci_dbc_flush_requests(dbc);
@@ -704,16 +806,16 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
ctrl = readl(&dbc->regs->control);
if ((ctrl & DBC_CTRL_HALT_IN_TR) ||
(ctrl & DBC_CTRL_HALT_OUT_TR)) {
- xhci_info(xhci, "DbC Endpoint stall\n");
+ dev_info(dbc->dev, "DbC Endpoint stall\n");
dbc->state = DS_STALLED;
if (ctrl & DBC_CTRL_HALT_IN_TR) {
- dep = get_in_ep(xhci);
+ dep = get_in_ep(dbc);
xhci_dbc_flush_endpoint_requests(dep);
}
if (ctrl & DBC_CTRL_HALT_OUT_TR) {
- dep = get_out_ep(xhci);
+ dep = get_out_ep(dbc);
xhci_dbc_flush_endpoint_requests(dep);
}
@@ -738,7 +840,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
return EVT_DONE;
default:
- xhci_err(xhci, "Unknown DbC state %d\n", dbc->state);
+ dev_err(dbc->dev, "Unknown DbC state %d\n", dbc->state);
break;
}
@@ -756,16 +858,17 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
switch (le32_to_cpu(evt->event_cmd.flags) & TRB_TYPE_BITMASK) {
case TRB_TYPE(TRB_PORT_STATUS):
- dbc_handle_port_status(xhci, evt);
+ dbc_handle_port_status(dbc, evt);
break;
case TRB_TYPE(TRB_TRANSFER):
- dbc_handle_xfer_event(xhci, evt);
+ dbc_handle_xfer_event(dbc, evt);
break;
default:
break;
}
- inc_deq(xhci, dbc->ring_evt);
+ inc_evt_deq(dbc->ring_evt);
+
evt = dbc->ring_evt->dequeue;
update_erdp = true;
}
@@ -774,7 +877,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
if (update_erdp) {
deq = xhci_trb_virt_to_dma(dbc->ring_evt->deq_seg,
dbc->ring_evt->dequeue);
- xhci_write_64(xhci, deq, &dbc->regs->erdp);
+ lo_hi_writeq(deq, &dbc->regs->erdp);
}
return EVT_DONE;
@@ -782,14 +885,11 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
static void xhci_dbc_handle_events(struct work_struct *work)
{
- int ret;
enum evtreturn evtr;
struct xhci_dbc *dbc;
unsigned long flags;
- struct xhci_hcd *xhci;
dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work);
- xhci = dbc->xhci;
spin_lock_irqsave(&dbc->lock, flags);
evtr = xhci_dbc_do_handle_events(dbc);
@@ -797,21 +897,17 @@ static void xhci_dbc_handle_events(struct work_struct *work)
switch (evtr) {
case EVT_GSER:
- ret = xhci_dbc_tty_register_device(xhci);
- if (ret) {
- xhci_err(xhci, "failed to alloc tty device\n");
- break;
- }
-
- xhci_info(xhci, "DbC now attached to /dev/ttyDBC0\n");
+ if (dbc->driver->configure)
+ dbc->driver->configure(dbc);
break;
case EVT_DISC:
- xhci_dbc_tty_unregister_device(xhci);
+ if (dbc->driver->disconnect)
+ dbc->driver->disconnect(dbc);
break;
case EVT_DONE:
break;
default:
- xhci_info(xhci, "stop handling dbc events\n");
+ dev_info(dbc->dev, "stop handling dbc events\n");
return;
}
@@ -864,6 +960,7 @@ static int xhci_do_dbc_init(struct xhci_hcd *xhci)
spin_unlock_irqrestore(&xhci->lock, flags);
dbc->xhci = xhci;
+ dbc->dev = xhci_to_hcd(xhci)->self.sysdev;
INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events);
spin_lock_init(&dbc->lock);
@@ -912,13 +1009,15 @@ static ssize_t dbc_store(struct device *dev,
const char *buf, size_t count)
{
struct xhci_hcd *xhci;
+ struct xhci_dbc *dbc;
xhci = hcd_to_xhci(dev_get_drvdata(dev));
+ dbc = xhci->dbc;
if (!strncmp(buf, "enable", 6))
- xhci_dbc_start(xhci);
+ xhci_dbc_start(dbc);
else if (!strncmp(buf, "disable", 7))
- xhci_dbc_stop(xhci);
+ xhci_dbc_stop(dbc);
else
return -EINVAL;
@@ -936,7 +1035,7 @@ int xhci_dbc_init(struct xhci_hcd *xhci)
if (ret)
goto init_err3;
- ret = xhci_dbc_tty_register_driver(xhci);
+ ret = xhci_dbc_tty_probe(xhci);
if (ret)
goto init_err2;
@@ -947,7 +1046,7 @@ int xhci_dbc_init(struct xhci_hcd *xhci)
return 0;
init_err1:
- xhci_dbc_tty_unregister_driver();
+ xhci_dbc_tty_remove(xhci->dbc);
init_err2:
xhci_do_dbc_exit(xhci);
init_err3:
@@ -962,8 +1061,8 @@ void xhci_dbc_exit(struct xhci_hcd *xhci)
return;
device_remove_file(dev, &dev_attr_dbc);
- xhci_dbc_tty_unregister_driver();
- xhci_dbc_stop(xhci);
+ xhci_dbc_tty_remove(xhci->dbc);
+ xhci_dbc_stop(xhci->dbc);
xhci_do_dbc_exit(xhci);
}
@@ -978,7 +1077,7 @@ int xhci_dbc_suspend(struct xhci_hcd *xhci)
if (dbc->state == DS_CONFIGURED)
dbc->resume_required = 1;
- xhci_dbc_stop(xhci);
+ xhci_dbc_stop(dbc);
return 0;
}
@@ -993,7 +1092,7 @@ int xhci_dbc_resume(struct xhci_hcd *xhci)
if (dbc->resume_required) {
dbc->resume_required = 0;
- xhci_dbc_start(xhci);
+ xhci_dbc_start(dbc);
}
return ret;
diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h
index ce0c6072bd48..c70b78d504eb 100644
--- a/drivers/usb/host/xhci-dbgcap.h
+++ b/drivers/usb/host/xhci-dbgcap.h
@@ -84,28 +84,11 @@ enum dbc_state {
DS_STALLED,
};
-struct dbc_request {
- void *buf;
- unsigned int length;
- dma_addr_t dma;
- void (*complete)(struct xhci_hcd *xhci,
- struct dbc_request *req);
- struct list_head list_pool;
- int status;
- unsigned int actual;
-
- struct dbc_ep *dep;
- struct list_head list_pending;
- dma_addr_t trb_dma;
- union xhci_trb *trb;
- unsigned direction:1;
-};
-
struct dbc_ep {
struct xhci_dbc *dbc;
struct list_head list_pending;
struct xhci_ring *ring;
- unsigned direction:1;
+ unsigned int direction:1;
};
#define DBC_QUEUE_SIZE 16
@@ -127,12 +110,16 @@ struct dbc_port {
struct kfifo write_fifo;
bool registered;
- struct dbc_ep *in;
- struct dbc_ep *out;
+};
+
+struct dbc_driver {
+ int (*configure)(struct xhci_dbc *dbc);
+ void (*disconnect)(struct xhci_dbc *dbc);
};
struct xhci_dbc {
spinlock_t lock; /* device access */
+ struct device *dev;
struct xhci_hcd *xhci;
struct dbc_regs __iomem *regs;
struct xhci_ring *ring_evt;
@@ -150,7 +137,25 @@ struct xhci_dbc {
unsigned resume_required:1;
struct dbc_ep eps[2];
- struct dbc_port port;
+ const struct dbc_driver *driver;
+ void *priv;
+};
+
+struct dbc_request {
+ void *buf;
+ unsigned int length;
+ dma_addr_t dma;
+ void (*complete)(struct xhci_dbc *dbc,
+ struct dbc_request *req);
+ struct list_head list_pool;
+ int status;
+ unsigned int actual;
+
+ struct xhci_dbc *dbc;
+ struct list_head list_pending;
+ dma_addr_t trb_dma;
+ union xhci_trb *trb;
+ unsigned direction:1;
};
#define dbc_bulkout_ctx(d) \
@@ -178,30 +183,26 @@ enum evtreturn {
EVT_DISC,
};
-static inline struct dbc_ep *get_in_ep(struct xhci_hcd *xhci)
+static inline struct dbc_ep *get_in_ep(struct xhci_dbc *dbc)
{
- struct xhci_dbc *dbc = xhci->dbc;
-
return &dbc->eps[BULK_IN];
}
-static inline struct dbc_ep *get_out_ep(struct xhci_hcd *xhci)
+static inline struct dbc_ep *get_out_ep(struct xhci_dbc *dbc)
{
- struct xhci_dbc *dbc = xhci->dbc;
-
return &dbc->eps[BULK_OUT];
}
#ifdef CONFIG_USB_XHCI_DBGCAP
int xhci_dbc_init(struct xhci_hcd *xhci);
void xhci_dbc_exit(struct xhci_hcd *xhci);
-int xhci_dbc_tty_register_driver(struct xhci_hcd *xhci);
-void xhci_dbc_tty_unregister_driver(void);
-int xhci_dbc_tty_register_device(struct xhci_hcd *xhci);
-void xhci_dbc_tty_unregister_device(struct xhci_hcd *xhci);
-struct dbc_request *dbc_alloc_request(struct dbc_ep *dep, gfp_t gfp_flags);
-void dbc_free_request(struct dbc_ep *dep, struct dbc_request *req);
-int dbc_ep_queue(struct dbc_ep *dep, struct dbc_request *req, gfp_t gfp_flags);
+int xhci_dbc_tty_probe(struct xhci_hcd *xhci);
+void xhci_dbc_tty_remove(struct xhci_dbc *dbc);
+struct dbc_request *dbc_alloc_request(struct xhci_dbc *dbc,
+ unsigned int direction,
+ gfp_t flags);
+void dbc_free_request(struct dbc_request *req);
+int dbc_ep_queue(struct dbc_request *req);
#ifdef CONFIG_PM
int xhci_dbc_suspend(struct xhci_hcd *xhci);
int xhci_dbc_resume(struct xhci_hcd *xhci);
diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c
index be726c791323..b8918f73a432 100644
--- a/drivers/usb/host/xhci-dbgtty.c
+++ b/drivers/usb/host/xhci-dbgtty.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
-/**
+/*
* xhci-dbgtty.c - tty glue for xHCI debug capability
*
* Copyright (C) 2017 Intel Corporation
@@ -14,6 +14,16 @@
#include "xhci.h"
#include "xhci-dbgcap.h"
+static int dbc_tty_init(void);
+static void dbc_tty_exit(void);
+
+static struct tty_driver *dbc_tty_driver;
+
+static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc)
+{
+ return dbc->priv;
+}
+
static unsigned int
dbc_send_packet(struct dbc_port *port, char *packet, unsigned int size)
{
@@ -48,7 +58,7 @@ static int dbc_start_tx(struct dbc_port *port)
list_del(&req->list_pool);
spin_unlock(&port->port_lock);
- status = dbc_ep_queue(port->out, req, GFP_ATOMIC);
+ status = dbc_ep_queue(req);
spin_lock(&port->port_lock);
if (status) {
@@ -80,7 +90,7 @@ static void dbc_start_rx(struct dbc_port *port)
req->length = DBC_MAX_PACKET;
spin_unlock(&port->port_lock);
- status = dbc_ep_queue(port->in, req, GFP_ATOMIC);
+ status = dbc_ep_queue(req);
spin_lock(&port->port_lock);
if (status) {
@@ -91,11 +101,10 @@ static void dbc_start_rx(struct dbc_port *port)
}
static void
-dbc_read_complete(struct xhci_hcd *xhci, struct dbc_request *req)
+dbc_read_complete(struct xhci_dbc *dbc, struct dbc_request *req)
{
unsigned long flags;
- struct xhci_dbc *dbc = xhci->dbc;
- struct dbc_port *port = &dbc->port;
+ struct dbc_port *port = dbc_to_port(dbc);
spin_lock_irqsave(&port->port_lock, flags);
list_add_tail(&req->list_pool, &port->read_queue);
@@ -103,11 +112,10 @@ dbc_read_complete(struct xhci_hcd *xhci, struct dbc_request *req)
spin_unlock_irqrestore(&port->port_lock, flags);
}
-static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req)
+static void dbc_write_complete(struct xhci_dbc *dbc, struct dbc_request *req)
{
unsigned long flags;
- struct xhci_dbc *dbc = xhci->dbc;
- struct dbc_port *port = &dbc->port;
+ struct dbc_port *port = dbc_to_port(dbc);
spin_lock_irqsave(&port->port_lock, flags);
list_add(&req->list_pool, &port->write_pool);
@@ -118,35 +126,36 @@ static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req)
case -ESHUTDOWN:
break;
default:
- xhci_warn(xhci, "unexpected write complete status %d\n",
+ dev_warn(dbc->dev, "unexpected write complete status %d\n",
req->status);
break;
}
spin_unlock_irqrestore(&port->port_lock, flags);
}
-static void xhci_dbc_free_req(struct dbc_ep *dep, struct dbc_request *req)
+static void xhci_dbc_free_req(struct dbc_request *req)
{
kfree(req->buf);
- dbc_free_request(dep, req);
+ dbc_free_request(req);
}
static int
-xhci_dbc_alloc_requests(struct dbc_ep *dep, struct list_head *head,
- void (*fn)(struct xhci_hcd *, struct dbc_request *))
+xhci_dbc_alloc_requests(struct xhci_dbc *dbc, unsigned int direction,
+ struct list_head *head,
+ void (*fn)(struct xhci_dbc *, struct dbc_request *))
{
int i;
struct dbc_request *req;
for (i = 0; i < DBC_QUEUE_SIZE; i++) {
- req = dbc_alloc_request(dep, GFP_KERNEL);
+ req = dbc_alloc_request(dbc, direction, GFP_KERNEL);
if (!req)
break;
req->length = DBC_MAX_PACKET;
req->buf = kmalloc(req->length, GFP_KERNEL);
if (!req->buf) {
- dbc_free_request(dep, req);
+ dbc_free_request(req);
break;
}
@@ -158,14 +167,14 @@ xhci_dbc_alloc_requests(struct dbc_ep *dep, struct list_head *head,
}
static void
-xhci_dbc_free_requests(struct dbc_ep *dep, struct list_head *head)
+xhci_dbc_free_requests(struct list_head *head)
{
struct dbc_request *req;
while (!list_empty(head)) {
req = list_entry(head->next, struct dbc_request, list_pool);
list_del(&req->list_pool);
- xhci_dbc_free_req(dep, req);
+ xhci_dbc_free_req(req);
}
}
@@ -279,55 +288,6 @@ static const struct tty_operations dbc_tty_ops = {
.unthrottle = dbc_tty_unthrottle,
};
-static struct tty_driver *dbc_tty_driver;
-
-int xhci_dbc_tty_register_driver(struct xhci_hcd *xhci)
-{
- int status;
- struct xhci_dbc *dbc = xhci->dbc;
-
- dbc_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV);
- if (IS_ERR(dbc_tty_driver)) {
- status = PTR_ERR(dbc_tty_driver);
- dbc_tty_driver = NULL;
- return status;
- }
-
- dbc_tty_driver->driver_name = "dbc_serial";
- dbc_tty_driver->name = "ttyDBC";
-
- dbc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
- dbc_tty_driver->subtype = SERIAL_TYPE_NORMAL;
- dbc_tty_driver->init_termios = tty_std_termios;
- dbc_tty_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- dbc_tty_driver->init_termios.c_ispeed = 9600;
- dbc_tty_driver->init_termios.c_ospeed = 9600;
- dbc_tty_driver->driver_state = &dbc->port;
-
- tty_set_operations(dbc_tty_driver, &dbc_tty_ops);
-
- status = tty_register_driver(dbc_tty_driver);
- if (status) {
- xhci_err(xhci,
- "can't register dbc tty driver, err %d\n", status);
- put_tty_driver(dbc_tty_driver);
- dbc_tty_driver = NULL;
- }
-
- return status;
-}
-
-void xhci_dbc_tty_unregister_driver(void)
-{
- if (dbc_tty_driver) {
- tty_unregister_driver(dbc_tty_driver);
- put_tty_driver(dbc_tty_driver);
- dbc_tty_driver = NULL;
- }
-}
-
static void dbc_rx_push(unsigned long _port)
{
struct dbc_request *req;
@@ -418,7 +378,7 @@ static const struct tty_port_operations dbc_port_ops = {
};
static void
-xhci_dbc_tty_init_port(struct xhci_hcd *xhci, struct dbc_port *port)
+xhci_dbc_tty_init_port(struct xhci_dbc *dbc, struct dbc_port *port)
{
tty_port_init(&port->port);
spin_lock_init(&port->port_lock);
@@ -427,8 +387,6 @@ xhci_dbc_tty_init_port(struct xhci_hcd *xhci, struct dbc_port *port)
INIT_LIST_HEAD(&port->read_queue);
INIT_LIST_HEAD(&port->write_pool);
- port->in = get_in_ep(xhci);
- port->out = get_out_ep(xhci);
port->port.ops = &dbc_port_ops;
port->n_read = 0;
}
@@ -440,14 +398,16 @@ xhci_dbc_tty_exit_port(struct dbc_port *port)
tty_port_destroy(&port->port);
}
-int xhci_dbc_tty_register_device(struct xhci_hcd *xhci)
+static int xhci_dbc_tty_register_device(struct xhci_dbc *dbc)
{
int ret;
struct device *tty_dev;
- struct xhci_dbc *dbc = xhci->dbc;
- struct dbc_port *port = &dbc->port;
+ struct dbc_port *port = dbc_to_port(dbc);
+
+ if (port->registered)
+ return -EBUSY;
- xhci_dbc_tty_init_port(xhci, port);
+ xhci_dbc_tty_init_port(dbc, port);
tty_dev = tty_port_register_device(&port->port,
dbc_tty_driver, 0, NULL);
if (IS_ERR(tty_dev)) {
@@ -459,12 +419,12 @@ int xhci_dbc_tty_register_device(struct xhci_hcd *xhci)
if (ret)
goto buf_alloc_fail;
- ret = xhci_dbc_alloc_requests(port->in, &port->read_pool,
+ ret = xhci_dbc_alloc_requests(dbc, BULK_IN, &port->read_pool,
dbc_read_complete);
if (ret)
goto request_fail;
- ret = xhci_dbc_alloc_requests(port->out, &port->write_pool,
+ ret = xhci_dbc_alloc_requests(dbc, BULK_OUT, &port->write_pool,
dbc_write_complete);
if (ret)
goto request_fail;
@@ -474,8 +434,8 @@ int xhci_dbc_tty_register_device(struct xhci_hcd *xhci)
return 0;
request_fail:
- xhci_dbc_free_requests(port->in, &port->read_pool);
- xhci_dbc_free_requests(port->out, &port->write_pool);
+ xhci_dbc_free_requests(&port->read_pool);
+ xhci_dbc_free_requests(&port->write_pool);
kfifo_free(&port->write_fifo);
buf_alloc_fail:
@@ -484,22 +444,113 @@ buf_alloc_fail:
register_fail:
xhci_dbc_tty_exit_port(port);
- xhci_err(xhci, "can't register tty port, err %d\n", ret);
+ dev_err(dbc->dev, "can't register tty port, err %d\n", ret);
return ret;
}
-void xhci_dbc_tty_unregister_device(struct xhci_hcd *xhci)
+static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc)
{
- struct xhci_dbc *dbc = xhci->dbc;
- struct dbc_port *port = &dbc->port;
+ struct dbc_port *port = dbc_to_port(dbc);
+ if (!port->registered)
+ return;
tty_unregister_device(dbc_tty_driver, 0);
xhci_dbc_tty_exit_port(port);
port->registered = false;
kfifo_free(&port->write_fifo);
- xhci_dbc_free_requests(get_out_ep(xhci), &port->read_pool);
- xhci_dbc_free_requests(get_out_ep(xhci), &port->read_queue);
- xhci_dbc_free_requests(get_in_ep(xhci), &port->write_pool);
+ xhci_dbc_free_requests(&port->read_pool);
+ xhci_dbc_free_requests(&port->read_queue);
+ xhci_dbc_free_requests(&port->write_pool);
+}
+
+static const struct dbc_driver dbc_driver = {
+ .configure = xhci_dbc_tty_register_device,
+ .disconnect = xhci_dbc_tty_unregister_device,
+};
+
+int xhci_dbc_tty_probe(struct xhci_hcd *xhci)
+{
+ struct xhci_dbc *dbc = xhci->dbc;
+ struct dbc_port *port;
+ int status;
+
+ /* dbc_tty_init will be called by module init() in the future */
+ status = dbc_tty_init();
+ if (status)
+ return status;
+
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
+ if (!port) {
+ status = -ENOMEM;
+ goto out;
+ }
+
+ dbc->driver = &dbc_driver;
+ dbc->priv = port;
+
+
+ dbc_tty_driver->driver_state = port;
+
+ return 0;
+out:
+ /* dbc_tty_exit will be called by module_exit() in the future */
+ dbc_tty_exit();
+ return status;
+}
+
+/*
+ * undo what probe did, assume dbc is stopped already.
+ * we also assume tty_unregister_device() is called before this
+ */
+void xhci_dbc_tty_remove(struct xhci_dbc *dbc)
+{
+ struct dbc_port *port = dbc_to_port(dbc);
+
+ dbc->driver = NULL;
+ dbc->priv = NULL;
+ kfree(port);
+
+ /* dbc_tty_exit will be called by module_exit() in the future */
+ dbc_tty_exit();
+}
+
+static int dbc_tty_init(void)
+{
+ int ret;
+
+ dbc_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_DYNAMIC_DEV);
+ if (IS_ERR(dbc_tty_driver))
+ return PTR_ERR(dbc_tty_driver);
+
+ dbc_tty_driver->driver_name = "dbc_serial";
+ dbc_tty_driver->name = "ttyDBC";
+
+ dbc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ dbc_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+ dbc_tty_driver->init_termios = tty_std_termios;
+ dbc_tty_driver->init_termios.c_cflag =
+ B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ dbc_tty_driver->init_termios.c_ispeed = 9600;
+ dbc_tty_driver->init_termios.c_ospeed = 9600;
+
+ tty_set_operations(dbc_tty_driver, &dbc_tty_ops);
+
+ ret = tty_register_driver(dbc_tty_driver);
+ if (ret) {
+ pr_err("Can't register dbc tty driver\n");
+ put_tty_driver(dbc_tty_driver);
+ }
+ return ret;
+}
+
+static void dbc_tty_exit(void)
+{
+ if (dbc_tty_driver) {
+ tty_unregister_driver(dbc_tty_driver);
+ put_tty_driver(dbc_tty_driver);
+ dbc_tty_driver = NULL;
+ }
}
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 76c3f29562d2..92e25a62fdb5 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -110,6 +110,7 @@ static void xhci_debugfs_free_regset(struct xhci_regset *regset)
kfree(regset);
}
+__printf(6, 7)
static void xhci_debugfs_regset(struct xhci_hcd *xhci, u32 base,
const struct debugfs_reg32 *regs,
size_t nregs, struct dentry *parent,
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index f37316d2c8fa..c3554e37e09f 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -612,7 +612,7 @@ static void xhci_port_set_test_mode(struct xhci_hcd *xhci,
temp |= test_mode << PORT_TEST_MODE_SHIFT;
writel(temp, port->addr + PORTPMSC);
xhci->test_mode = test_mode;
- if (test_mode == TEST_FORCE_EN)
+ if (test_mode == USB_TEST_FORCE_ENABLE)
xhci_start(xhci);
}
@@ -666,7 +666,7 @@ static int xhci_exit_test_mode(struct xhci_hcd *xhci)
xhci_err(xhci, "Not in test mode, do nothing.\n");
return 0;
}
- if (xhci->test_mode == TEST_FORCE_EN &&
+ if (xhci->test_mode == USB_TEST_FORCE_ENABLE &&
!(xhci->xhc_state & XHCI_STATE_HALTED)) {
retval = xhci_halt(xhci);
if (retval)
@@ -1241,7 +1241,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = readl(ports[wIndex]->addr);
/* Disable port */
if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
- xhci_dbg(xhci, "Disable port %d\n", wIndex);
+ xhci_dbg(xhci, "Disable port %d-%d\n",
+ hcd->self.busnum, wIndex + 1);
temp = xhci_port_state_to_neutral(temp);
/*
* Clear all change bits, so that we get a new
@@ -1257,7 +1258,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* Put link in RxDetect (enable port) */
if (link_state == USB_SS_PORT_LS_RX_DETECT) {
- xhci_dbg(xhci, "Enable port %d\n", wIndex);
+ xhci_dbg(xhci, "Enable port %d-%d\n",
+ hcd->self.busnum, wIndex + 1);
xhci_set_link_state(xhci, ports[wIndex],
link_state);
temp = readl(ports[wIndex]->addr);
@@ -1289,8 +1291,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
goto error;
}
- xhci_dbg(xhci, "Enable compliance mode transition for port %d\n",
- wIndex);
+ xhci_dbg(xhci, "Enable compliance mode transition for port %d-%d\n",
+ hcd->self.busnum, wIndex + 1);
xhci_set_link_state(xhci, ports[wIndex],
link_state);
@@ -1304,8 +1306,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
}
/* Can't set port link state above '3' (U3) */
if (link_state > USB_SS_PORT_LS_U3) {
- xhci_warn(xhci, "Cannot set port %d link state %d\n",
- wIndex, link_state);
+ xhci_warn(xhci, "Cannot set port %d-%d link state %d\n",
+ hcd->self.busnum, wIndex + 1,
+ link_state);
goto error;
}
@@ -1340,8 +1343,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
spin_unlock_irqrestore(&xhci->lock, flags);
if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex],
msecs_to_jiffies(100)))
- xhci_dbg(xhci, "missing U0 port change event for port %d\n",
- wIndex);
+ xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n",
+ hcd->self.busnum, wIndex + 1);
spin_lock_irqsave(&xhci->lock, flags);
temp = readl(ports[wIndex]->addr);
break;
@@ -1386,15 +1389,15 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
writel(temp, ports[wIndex]->addr);
temp = readl(ports[wIndex]->addr);
- xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
+ xhci_dbg(xhci, "set port reset, actual port %d-%d status = 0x%x\n",
+ hcd->self.busnum, wIndex + 1, temp);
break;
case USB_PORT_FEAT_REMOTE_WAKE_MASK:
xhci_set_remote_wake_mask(xhci, ports[wIndex],
wake_mask);
temp = readl(ports[wIndex]->addr);
- xhci_dbg(xhci, "set port remote wake mask, "
- "actual port %d status = 0x%x\n",
- wIndex, temp);
+ xhci_dbg(xhci, "set port remote wake mask, actual port %d-%d status = 0x%x\n",
+ hcd->self.busnum, wIndex + 1, temp);
break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
@@ -1421,7 +1424,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
/* 4.19.6 Port Test Modes (USB2 Test Mode) */
if (hcd->speed != HCD_USB2)
goto error;
- if (test_mode > TEST_FORCE_EN || test_mode < TEST_J)
+ if (test_mode > USB_TEST_FORCE_ENABLE ||
+ test_mode < USB_TEST_J)
goto error;
retval = xhci_enter_test_mode(xhci, test_mode, wIndex,
&flags);
@@ -1634,8 +1638,8 @@ retry:
spin_unlock_irqrestore(&xhci->lock, flags);
msleep(XHCI_PORT_POLLING_LFPS_TIME);
spin_lock_irqsave(&xhci->lock, flags);
- xhci_dbg(xhci, "port %d polling in bus suspend, waiting\n",
- port_index);
+ xhci_dbg(xhci, "port %d-%d polling in bus suspend, waiting\n",
+ hcd->self.busnum, port_index + 1);
goto retry;
}
/* bail out if port detected a over-current condition */
@@ -1653,7 +1657,8 @@ retry:
xhci_dbg(xhci, "Bus suspend bailout, port connect change\n");
return -EBUSY;
}
- xhci_dbg(xhci, "port %d not suspended\n", port_index);
+ xhci_dbg(xhci, "port %d-%d not suspended\n",
+ hcd->self.busnum, port_index + 1);
t2 &= ~PORT_PLS_MASK;
t2 |= PORT_LINK_STROBE | XDEV_U3;
set_bit(port_index, &bus_state->bus_suspended);
@@ -1783,7 +1788,8 @@ int xhci_bus_resume(struct usb_hcd *hcd)
if ((xhci->quirks & XHCI_MISSING_CAS) &&
(hcd->speed >= HCD_USB3) &&
xhci_port_missing_cas_quirk(ports[port_index])) {
- xhci_dbg(xhci, "reset stuck port %d\n", port_index);
+ xhci_dbg(xhci, "reset stuck port %d-%d\n",
+ hcd->self.busnum, port_index + 1);
clear_bit(port_index, &bus_state->bus_suspended);
continue;
}
@@ -1830,8 +1836,8 @@ int xhci_bus_resume(struct usb_hcd *hcd)
sret = xhci_handshake(ports[port_index]->addr, PORT_PLC,
PORT_PLC, 10 * 1000);
if (sret) {
- xhci_warn(xhci, "port %d resume PLC timeout\n",
- port_index);
+ xhci_warn(xhci, "port %d-%d resume PLC timeout\n",
+ hcd->self.busnum, port_index + 1);
continue;
}
xhci_test_and_clear_bit(xhci, ports[port_index], PORT_PLC);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 9764122c9cdf..696fad50b478 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -96,8 +96,9 @@ static void xhci_free_segments_for_ring(struct xhci_hcd *xhci,
* DMA address of the next segment. The caller needs to set any Link TRB
* related flags, such as End TRB, Toggle Cycle, and no snoop.
*/
-static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
- struct xhci_segment *next, enum xhci_ring_type type)
+static void xhci_link_segments(struct xhci_segment *prev,
+ struct xhci_segment *next,
+ enum xhci_ring_type type, bool chain_links)
{
u32 val;
@@ -112,11 +113,7 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control);
val &= ~TRB_TYPE_BITMASK;
val |= TRB_TYPE(TRB_LINK);
- /* Always set the chain bit with 0.95 hardware */
- /* Set chain bit for isoc rings on AMD 0.96 host */
- if (xhci_link_trb_quirk(xhci) ||
- (type == TYPE_ISOC &&
- (xhci->quirks & XHCI_AMD_0x96_HOST)))
+ if (chain_links)
val |= TRB_CHAIN;
prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val);
}
@@ -131,13 +128,19 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring,
unsigned int num_segs)
{
struct xhci_segment *next;
+ bool chain_links;
if (!ring || !first || !last)
return;
+ /* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */
+ chain_links = !!(xhci_link_trb_quirk(xhci) ||
+ (ring->type == TYPE_ISOC &&
+ (xhci->quirks & XHCI_AMD_0x96_HOST)));
+
next = ring->enq_seg->next;
- xhci_link_segments(xhci, ring->enq_seg, first, ring->type);
- xhci_link_segments(xhci, last, next, ring->type);
+ xhci_link_segments(ring->enq_seg, first, ring->type, chain_links);
+ xhci_link_segments(last, next, ring->type, chain_links);
ring->num_segs += num_segs;
ring->num_trbs_free += (TRBS_PER_SEGMENT - 1) * num_segs;
@@ -290,8 +293,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)
kfree(ring);
}
-static void xhci_initialize_ring_info(struct xhci_ring *ring,
- unsigned int cycle_state)
+void xhci_initialize_ring_info(struct xhci_ring *ring,
+ unsigned int cycle_state)
{
/* The ring is empty, so the enqueue pointer == dequeue pointer */
ring->enqueue = ring->first_seg->trbs;
@@ -321,6 +324,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
enum xhci_ring_type type, unsigned int max_packet, gfp_t flags)
{
struct xhci_segment *prev;
+ bool chain_links;
+
+ /* Set chain bit for 0.95 hosts, and for isoc rings on AMD 0.96 host */
+ chain_links = !!(xhci_link_trb_quirk(xhci) ||
+ (type == TYPE_ISOC &&
+ (xhci->quirks & XHCI_AMD_0x96_HOST)));
prev = xhci_segment_alloc(xhci, cycle_state, max_packet, flags);
if (!prev)
@@ -341,18 +350,18 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
}
return -ENOMEM;
}
- xhci_link_segments(xhci, prev, next, type);
+ xhci_link_segments(prev, next, type, chain_links);
prev = next;
num_segs--;
}
- xhci_link_segments(xhci, prev, *first, type);
+ xhci_link_segments(prev, *first, type, chain_links);
*last = prev;
return 0;
}
-/**
+/*
* Create a new ring with zero or more segments.
*
* Link each segment together into a ring.
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 9234c82e70e4..3feaafebfe58 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -57,7 +57,10 @@
#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba
#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb
#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc
+#define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042
#define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142
+#define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242
+#define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142
static const char hcd_name[] = "xhci_hcd";
@@ -260,13 +263,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_LPM_SUPPORT;
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
- pdev->device == 0x1042)
+ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
xhci->quirks |= XHCI_BROKEN_STREAMS;
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
- pdev->device == 0x1142)
+ pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI)
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
- pdev->device == 0x2142)
+ (pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI ||
+ pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI))
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index f6b4089bfc4a..3057cfc76d6a 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -2,7 +2,7 @@
/*
* xhci-plat.c - xHCI host controller driver platform Bus Glue.
*
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com
* Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
*
* A lot of code borrowed from the Linux xHCI driver.
@@ -454,12 +454,14 @@ static const struct dev_pm_ops xhci_plat_pm_ops = {
NULL)
};
+#ifdef CONFIG_ACPI
static const struct acpi_device_id usb_xhci_acpi_match[] = {
/* XHCI-compliant USB Controller */
{ "PNP0D10", },
{ }
};
MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
+#endif
static struct platform_driver usb_xhci_driver = {
.probe = xhci_plat_probe,
diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index ee6bf01775bb..014d79334f50 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -1853,11 +1853,7 @@ static const char * const tegra124_supply_names[] = {
"avddio-pex",
"dvddio-pex",
"avdd-usb",
- "avdd-pll-utmip",
- "avdd-pll-erefe",
- "avdd-usb-ss-pll",
"hvdd-usb-ss",
- "hvdd-usb-ss-pll-e",
};
static const struct tegra_xusb_phy_type tegra124_phy_types[] = {
@@ -1931,10 +1927,6 @@ static const char * const tegra210_supply_names[] = {
"dvddio-pex",
"hvddio-pex",
"avdd-usb",
- "avdd-pll-utmip",
- "avdd-pll-uerefe",
- "dvdd-pex-pll",
- "hvdd-pex-pll-e",
};
static const struct tegra_xusb_phy_type tegra210_phy_types[] = {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index ed468eed299c..3c41b14ecce7 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1271,7 +1271,7 @@ static int xhci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
}
-/**
+/*
* xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
* HCDs. Find the index for an endpoint given its descriptor. Use the return
* value to right shift 1 for the bitmask.
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index c295e8a7f5ae..ea1754f185a2 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -2015,6 +2015,8 @@ int xhci_alloc_erst(struct xhci_hcd *xhci,
struct xhci_ring *evt_ring,
struct xhci_erst *erst,
gfp_t flags);
+void xhci_initialize_ring_info(struct xhci_ring *ring,
+ unsigned int cycle_state);
void xhci_free_erst(struct xhci_hcd *xhci, struct xhci_erst *erst);
void xhci_free_endpoint_ring(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,