bcm53xx: update USB 3.0 driver with version submitted upstream

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

SVN-Revision: 47248
owl
Hauke Mehrtens 2015-10-23 22:32:38 +00:00
parent 5682b0d954
commit aaa20ae2c2
6 changed files with 188 additions and 113 deletions

View File

@ -0,0 +1,135 @@
From dd0e5f9a6a4aed849bdb80641c2a2350476cede7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Sun, 21 Jun 2015 11:10:49 +0200
Subject: [PATCH v3 2/6] usb: xhci: add Broadcom specific fake doorbell
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes problem with controller seeing devices only in some small
percentage of cold boots.
This quirk is also added to the platform data so we can activate it
when we register our platform driver.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/xhci-plat.c | 3 +++
drivers/usb/host/xhci.c | 57 +++++++++++++++++++++++++++++++++++++---
drivers/usb/host/xhci.h | 1 +
include/linux/usb/xhci_pdriver.h | 1 +
4 files changed, 59 insertions(+), 3 deletions(-)
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -42,6 +42,9 @@ static void xhci_plat_quirks(struct devi
if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
(pdata && pdata->usb3_lpm_capable))
xhci->quirks |= XHCI_LPM_SUPPORT;
+
+ if (pdata && pdata->usb3_fake_doorbell)
+ xhci->quirks |= XHCI_FAKE_DOORBELL;
}
/* called during probe() after chip reset completes */
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -121,6 +121,39 @@ int xhci_halt(struct xhci_hcd *xhci)
return ret;
}
+static int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
+{
+ u32 temp;
+
+ /* alloc a virt device for slot */
+ if (!xhci_alloc_virt_device(xhci, slot_id, NULL, GFP_NOIO)) {
+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
+ return -ENOMEM;
+ }
+
+ /* ring fake doorbell for slot_id ep 0 */
+ xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
+ usleep_range(1000, 1500);
+
+ /* read the status register to check if HSE is set or not? */
+ temp = readl(&xhci->op_regs->status);
+
+ /* clear HSE if set */
+ if (temp & STS_FATAL) {
+ xhci_dbg(xhci, "HSE problem detected, status: 0x%x\n", temp);
+ temp &= ~(0x1fff);
+ temp |= STS_FATAL;
+ writel(temp, &xhci->op_regs->status);
+ usleep_range(1000, 1500);
+ readl(&xhci->op_regs->status);
+ }
+
+ /* Free virt device */
+ xhci_free_virt_device(xhci, slot_id);
+
+ return 0;
+}
+
/*
* Set the run bit and wait for the host to be running.
*/
@@ -556,10 +589,25 @@ int xhci_init(struct usb_hcd *hcd)
static int xhci_run_finished(struct xhci_hcd *xhci)
{
- if (xhci_start(xhci)) {
- xhci_halt(xhci);
- return -ENODEV;
+ int err;
+
+ err = xhci_start(xhci);
+ if (err) {
+ err = -ENODEV;
+ goto out_err;
+ }
+ if (xhci->quirks & XHCI_FAKE_DOORBELL) {
+ err = xhci_fake_doorbell(xhci, 1);
+ if (err)
+ goto out_err;
+
+ err = xhci_start(xhci);
+ if (err) {
+ err = -ENODEV;
+ goto out_err;
+ }
}
+
xhci->shared_hcd->state = HC_STATE_RUNNING;
xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
@@ -569,6 +617,9 @@ static int xhci_run_finished(struct xhci
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB3 roothub");
return 0;
+out_err:
+ xhci_halt(xhci);
+ return err;
}
/*
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1568,6 +1568,7 @@ struct xhci_hcd {
/* For controllers with a broken beyond repair streams implementation */
#define XHCI_BROKEN_STREAMS (1 << 19)
#define XHCI_PME_STUCK_QUIRK (1 << 20)
+#define XHCI_FAKE_DOORBELL (1 << 21)
unsigned int num_active_eps;
unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
--- a/include/linux/usb/xhci_pdriver.h
+++ b/include/linux/usb/xhci_pdriver.h
@@ -22,6 +22,7 @@
*/
struct usb_xhci_pdata {
unsigned usb3_lpm_capable:1;
+ unsigned usb3_fake_doorbell:1;
};
#endif /* __USB_CORE_XHCI_PDRIVER_H */

View File

@ -1,7 +1,8 @@
From 5b4fed9fc917cc2bfc5297eeab03aeba5d340618 Mon Sep 17 00:00:00 2001
From c7c7bf7fcbacadac7781783de25fe1e13e2a2c35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Tue, 16 Jun 2015 12:33:46 +0200
Subject: [PATCH] USB: bcma: make helper creating platform dev more generic
Subject: [PATCH v3 3/6] usb: bcma: make helper creating platform dev more
generic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -10,6 +11,7 @@ Having "bool ohci" argument bounded us to two cases only and didn't
allow re-using this code for XHCI.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/bcma-hcd.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)

View File

@ -1,7 +1,8 @@
From 4aed231f49954114d5ae23e97789e9aa540a0b70 Mon Sep 17 00:00:00 2001
From fa5622c2fadae573dd6b0f5bffe436b230b411f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Tue, 16 Jun 2015 12:52:07 +0200
Subject: [PATCH] USB: bcma: use separated function for USB 2.0 initialization
Subject: [PATCH v3 4/6] usb: bcma: use separated function for USB 2.0
initialization
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -9,6 +10,7 @@ Content-Transfer-Encoding: 8bit
This will allow adding USB 3.0 (XHCI) support cleanly.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/bcma-hcd.c | 51 +++++++++++++++++++++++++++++++--------------
1 file changed, 35 insertions(+), 16 deletions(-)

View File

@ -1,19 +1,28 @@
From 12c6932caa6b1fce44d0f0c68ec77d4c00ac0be7 Mon Sep 17 00:00:00 2001
From 121ec6539abedbc0e975cf35f48ee044b323e4c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Tue, 16 Jun 2015 17:14:26 +0200
Subject: [PATCH] USB: bcma: add USB 3.0 support
Subject: [PATCH v3 5/6] usb: bcma: add USB 3.0 support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/bcma-hcd.c | 219 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 219 insertions(+)
drivers/usb/host/bcma-hcd.c | 225 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 225 insertions(+)
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -37,6 +37,7 @@ struct bcma_hcd_device {
@@ -28,6 +28,7 @@
#include <linux/of_gpio.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
+#include <linux/usb/xhci_pdriver.h>
MODULE_AUTHOR("Hauke Mehrtens");
MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
@@ -37,6 +38,7 @@ struct bcma_hcd_device {
struct bcma_device *core;
struct platform_device *ehci_dev;
struct platform_device *ohci_dev;
@ -21,7 +30,18 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
};
/* Wait for bitmask in a register to get set or cleared.
@@ -343,6 +344,215 @@ err_unregister_ohci_dev:
@@ -250,6 +252,10 @@ static const struct usb_ehci_pdata ehci_
static const struct usb_ohci_pdata ohci_pdata = {
};
+static const struct usb_xhci_pdata xhci_pdata = {
+ .usb3_fake_doorbell = 1
+};
+
static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev,
const char *name, u32 addr,
const void *data,
@@ -343,6 +349,216 @@ err_unregister_ohci_dev:
return err;
}
@ -227,7 +247,8 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+ bcma_hcd_usb30_phy_init(bcma_hcd);
+
+ bcma_hcd->xhci_dev = bcma_hcd_create_pdev(core, "xhci-hcd", core->addr,
+ NULL, 0);
+ &xhci_pdata,
+ sizeof(xhci_pdata));
+ if (IS_ERR(bcma_hcd->ohci_dev))
+ return PTR_ERR(bcma_hcd->ohci_dev);
+
@ -237,7 +258,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
static int bcma_hcd_probe(struct bcma_device *dev)
{
int err;
@@ -365,6 +575,11 @@ static int bcma_hcd_probe(struct bcma_de
@@ -365,6 +581,11 @@ static int bcma_hcd_probe(struct bcma_de
if (err)
return err;
break;
@ -249,7 +270,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
default:
return -ENODEV;
}
@@ -378,11 +593,14 @@ static void bcma_hcd_remove(struct bcma_
@@ -378,11 +599,14 @@ static void bcma_hcd_remove(struct bcma_
struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
struct platform_device *ohci_dev = usb_dev->ohci_dev;
struct platform_device *ehci_dev = usb_dev->ehci_dev;
@ -264,7 +285,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
bcma_core_disable(dev, 0);
}
@@ -419,6 +637,7 @@ static int bcma_hcd_resume(struct bcma_d
@@ -419,6 +643,7 @@ static int bcma_hcd_resume(struct bcma_d
static const struct bcma_device_id bcma_hcd_table[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_USB20, BCMA_ANY_REV, BCMA_ANY_CLASS),

View File

@ -1,7 +1,7 @@
From bdc3b01d94b22f8b5f9621a1c37336e78f4f1bce Mon Sep 17 00:00:00 2001
From 7572673e06393b117f87b20b82be0518634d7042 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Sun, 21 Jun 2015 12:09:57 +0200
Subject: [PATCH] USB: bcma: fix setting VCC GPIO value
Subject: [PATCH v3 6/6] usb: bcma: fix setting VCC GPIO value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -10,13 +10,22 @@ It wasn't working (on most of devices?) without setting GPIO direction
and wasn't respecting ACTIVE_LOW flag.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/bcma-hcd.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
drivers/usb/host/bcma-hcd.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/usb/host/bcma-hcd.c
+++ b/drivers/usb/host/bcma-hcd.c
@@ -230,17 +230,22 @@ static void bcma_hcd_init_chip_arm(struc
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/usb/ehci_pdriver.h>
#include <linux/usb/ohci_pdriver.h>
#include <linux/usb/xhci_pdriver.h>
@@ -231,17 +232,22 @@ static void bcma_hcd_init_chip_arm(struc
static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
{

View File

@ -1,94 +0,0 @@
From 9cc14ca0aae53c16d10ffea49848ac61a5015562 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Sun, 21 Jun 2015 11:10:49 +0200
Subject: [PATCH] xhci: add Broadcom specific fake doorbell
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes problem with controller seeing devices only in some small
percentage of cold boots.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/usb/host/xhci.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -121,6 +121,64 @@ int xhci_halt(struct xhci_hcd *xhci)
return ret;
}
+#ifdef CONFIG_ARCH_BCM_5301X
+int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
+{
+ unsigned int temp1, ret;
+
+ /* alloc a virt device for slot */
+ if (!xhci_alloc_virt_device(xhci, slot_id, 0, GFP_NOIO)) {
+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
+ return 1;
+ }
+
+ /* ring fake doorbell for slot_id ep 0 */
+ xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
+ mdelay(1);
+
+ /* read the status register to check if HSE is set or not? */
+ temp1 = readl(&xhci->op_regs->status);
+ xhci_dbg(xhci, "op reg status = %x\n",temp1);
+
+ /* clear HSE if set */
+ if(temp1 & STS_FATAL) {
+ xhci_dbg(xhci, "HSE problem detected\n");
+ temp1 &= ~(0x1fff);
+ temp1 |= STS_FATAL;
+ xhci_dbg(xhci, "temp1=%x\n",temp1);
+ writel(temp1, &xhci->op_regs->status);
+ mdelay(1);
+ temp1 = readl(&xhci->op_regs->status);
+ xhci_dbg(xhci, "After clear op reg status=%x\n", temp1);
+ }
+
+ /* Free virt device */
+ xhci_free_virt_device(xhci, slot_id);
+
+ /* Run the controller if needed */
+ temp1 = readl(&xhci->op_regs->command);
+ if (temp1 & CMD_RUN)
+ return 0;
+ temp1 |= (CMD_RUN);
+
+ writel(temp1, &xhci->op_regs->command);
+ /*
+ * Wait for the HCHalted Status bit to be 0 to indicate the host is running.
+ */
+ ret = xhci_handshake(&xhci->op_regs->status,
+ STS_HALT, 0, XHCI_MAX_HALT_USEC);
+
+ if (ret == -ETIMEDOUT) {
+ xhci_err(xhci, "Host took too long to start, "
+ "waited %u microseconds.\n",
+ XHCI_MAX_HALT_USEC);
+ return 1;
+ }
+
+ return 0;
+}
+#endif /* CONFIG_ARCH_BCM_5301X */
+
/*
* Set the run bit and wait for the host to be running.
*/
@@ -145,6 +203,10 @@ static int xhci_start(struct xhci_hcd *x
xhci_err(xhci, "Host took too long to start, "
"waited %u microseconds.\n",
XHCI_MAX_HALT_USEC);
+#ifdef CONFIG_ARCH_BCM_5301X
+ xhci_fake_doorbell(xhci, 1);
+#endif /* CONFIG_ARCH_BCM_5301X */
+
if (!ret)
xhci->xhc_state &= ~XHCI_STATE_HALTED;
return ret;