brcm47xx: update usb driver for brcm47xx.

SVN-Revision: 30480
This commit is contained in:
Hauke Mehrtens 2012-02-12 16:38:10 +00:00
parent c2e411fa8d
commit 838c363886
8 changed files with 283 additions and 393 deletions

View file

@ -1,115 +0,0 @@
From 6e8ae6e2cee0e7e5939dc7042584c808366e61e0 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sun, 27 Nov 2011 14:01:01 +0100
Subject: [PATCH 16/21] =?UTF-8?q?bcma:=20add=20function=20to=20check=20every?=
=?UTF-8?q?=2010=20=C2=B5s=20if=20a=20reg=20is=20set?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This function checks if a reg get set or cleared every 10 microseconds.
It is used in bcma_core_set_clockmode() and bcma_core_pll_ctl() to
reduce code duplication. In addition it is needed in the USB host
driver.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/core.c | 48 ++++++++++++++++++++++++++++----------------
include/linux/bcma/bcma.h | 2 +
2 files changed, 32 insertions(+), 18 deletions(-)
--- a/drivers/bcma/core.c
+++ b/drivers/bcma/core.c
@@ -52,11 +52,36 @@ int bcma_core_enable(struct bcma_device
}
EXPORT_SYMBOL_GPL(bcma_core_enable);
+/* Wait for bitmask in a register to get set or cleared.
+ * timeout is in units of ten-microseconds.
+ */
+int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask, int timeout,
+ int set)
+{
+ int i;
+ u32 val;
+
+ for (i = 0; i < timeout; i++) {
+ val = bcma_read32(dev, reg);
+ if (set) {
+ if ((val & bitmask) == bitmask)
+ return 0;
+ } else {
+ if (!(val & bitmask))
+ return 0;
+ }
+ udelay(10);
+ }
+ pr_err("Timeout waiting for bitmask %08X on register %04X to %s.\n",
+ bitmask, reg, (set ? "set" : "clear"));
+
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_GPL(bcma_wait_bits);
+
void bcma_core_set_clockmode(struct bcma_device *core,
enum bcma_clkmode clkmode)
{
- u16 i;
-
WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
core->id.id != BCMA_CORE_PCIE &&
core->id.id != BCMA_CORE_80211);
@@ -65,15 +90,8 @@ void bcma_core_set_clockmode(struct bcma
case BCMA_CLKMODE_FAST:
bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
udelay(64);
- for (i = 0; i < 1500; i++) {
- if (bcma_read32(core, BCMA_CLKCTLST) &
- BCMA_CLKCTLST_HAVEHT) {
- i = 0;
- break;
- }
- udelay(10);
- }
- if (i)
+ if (bcma_wait_bits(core, BCMA_CLKCTLST, BCMA_CLKCTLST_HAVEHT,
+ 1500, 1))
pr_err("HT force timeout\n");
break;
case BCMA_CLKMODE_DYNAMIC:
@@ -85,22 +103,12 @@ EXPORT_SYMBOL_GPL(bcma_core_set_clockmod
void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
{
- u16 i;
-
WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
if (on) {
bcma_set32(core, BCMA_CLKCTLST, req);
- for (i = 0; i < 10000; i++) {
- if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
- status) {
- i = 0;
- break;
- }
- udelay(10);
- }
- if (i)
+ if (bcma_wait_bits(core, BCMA_CLKCTLST, status, 10000, 1))
pr_err("PLL enable timeout\n");
} else {
pr_warn("Disabling PLL not supported yet!\n");
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -283,6 +283,9 @@ static inline void bcma_maskset16(struct
bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
}
+extern int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
+ int timeout, int set);
+
extern bool bcma_core_is_enabled(struct bcma_device *core);
extern void bcma_core_disable(struct bcma_device *core, u32 flags);
extern int bcma_core_enable(struct bcma_device *core, u32 flags);

View file

@ -0,0 +1,48 @@
From d85bba4eb399a8273aabaef5c21c89820d7a0514 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Thu, 9 Feb 2012 23:14:57 +0100
Subject: [PATCH 180/186] USB: HCI: add struct for ehci and ohci platform
driver
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
include/linux/usb/hci_driver.h | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
create mode 100644 include/linux/usb/hci_driver.h
--- /dev/null
+++ b/include/linux/usb/hci_driver.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __USB_CORE_HCI_PDRIVER_H
+#define __USB_CORE_HCI_PDRIVER_H
+
+#define USB_HCI_PDATA_PORT_POWER_SET (1 << 0)
+#define USB_HCI_PDATA_HAS_TT_SET (1 << 1)
+
+struct usb_hci_pdata {
+ int flags;
+ int caps_offset;
+ unsigned has_tt:1;
+ unsigned power_set_is_on:1;
+};
+
+#endif /* __USB_CORE_HCI_PDRIVER_H */

View file

@ -1,7 +1,7 @@
From 14297ee700e1c2e04a35466304f9a3c5e1387146 Mon Sep 17 00:00:00 2001
From 2232a2ab6015496fecdfad68a9d6794312a9b2f2 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 26 Nov 2011 21:20:54 +0100
Subject: [PATCH 17/30] USB: OHCI: Add a generic platform device driver
Subject: [PATCH 181/186] USB: OHCI: Add a generic platform device driver
This adds a generic driver for platform devices. It works like the PCI
driver and is based on it. This is for devices which do not have an own
@ -11,9 +11,9 @@ used for the Broadcom bcma and ssb USB OHCI controller.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/Kconfig | 10 ++
drivers/usb/host/ohci-hcd.c | 21 ++++-
drivers/usb/host/ohci-platform.c | 197 ++++++++++++++++++++++++++++++++++++++
3 files changed, 227 insertions(+), 1 deletions(-)
drivers/usb/host/ohci-hcd.c | 5 +
drivers/usb/host/ohci-platform.c | 183 ++++++++++++++++++++++++++++++++++++++
3 files changed, 198 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ohci-platform.c
--- a/drivers/usb/host/Kconfig
@ -43,61 +43,22 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+#ifdef CONFIG_USB_OHCI_HCD_PLATFORM
+#include "ohci-platform.c"
+#define PLATFORM_OHCI_DRIVER ohci_platform_driver
+#define PLATFORM_DRIVER ohci_platform_driver
+#endif
+
#if !defined(PCI_DRIVER) && \
!defined(PLATFORM_DRIVER) && \
!defined(OMAP1_PLATFORM_DRIVER) && \
@@ -1125,7 +1130,8 @@ MODULE_LICENSE ("GPL");
!defined(PS3_SYSTEM_BUS_DRIVER) && \
!defined(SM501_OHCI_DRIVER) && \
!defined(TMIO_OHCI_DRIVER) && \
- !defined(SSB_OHCI_DRIVER)
+ !defined(SSB_OHCI_DRIVER) && \
+ !defined(PLATFORM_OHCI_DRIVER)
#error "missing bus glue for ohci-hcd"
#endif
@@ -1209,9 +1215,19 @@ static int __init ohci_hcd_mod_init(void
goto error_tmio;
#endif
+#ifdef PLATFORM_OHCI_DRIVER
+ retval = platform_driver_register(&PLATFORM_OHCI_DRIVER);
+ if (retval)
+ goto error_platform;
+#endif
+
return retval;
/* Error path */
+#ifdef PLATFORM_OHCI_DRIVER
+ platform_driver_unregister(&PLATFORM_OHCI_DRIVER);
+ error_platform:
+#endif
#ifdef TMIO_OHCI_DRIVER
platform_driver_unregister(&TMIO_OHCI_DRIVER);
error_tmio:
@@ -1265,6 +1281,9 @@ module_init(ohci_hcd_mod_init);
static void __exit ohci_hcd_mod_exit(void)
{
+#ifdef PLATFORM_OHCI_DRIVER
+ platform_driver_unregister(&PLATFORM_OHCI_DRIVER);
+#endif
#ifdef TMIO_OHCI_DRIVER
platform_driver_unregister(&TMIO_OHCI_DRIVER);
#endif
--- /dev/null
+++ b/drivers/usb/host/ohci-platform.c
@@ -0,0 +1,197 @@
@@ -0,0 +1,183 @@
+/*
+ * Generic platform ohci driver
+ *
+ * Copyright 2007 Michael Buesch <m@bues.ch>
+ * Copyright 2011 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Derived from the OCHI-SSB driver
+ * Derived from the OHCI-PCI driver
+ * Copyright 1999 Roman Weissgaerber
+ * Copyright 2000-2002 David Brownell
@ -107,6 +68,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/platform_device.h>
+#include <linux/usb/hci_driver.h>
+
+static int ohci_platform_reset(struct usb_hcd *hcd)
+{
@ -134,7 +96,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+}
+
+static const struct hc_driver ohci_platform_hc_driver = {
+ .description = "platform-usb-ohci",
+ .description = hcd_name,
+ .product_desc = "Generic Platform OHCI Controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
@ -162,34 +124,46 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int ohci_platform_attach(struct platform_device *dev)
+static int __devinit ohci_platform_probe(struct platform_device *dev)
+{
+ struct usb_hcd *hcd;
+ struct resource *res_irq, *res_mem;
+ struct resource *res_mem;
+ int irq;
+ int err = -ENOMEM;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0) {
+ pr_err("no irq provieded");
+ return irq;
+ }
+
+ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ pr_err("no memory recourse provieded");
+ return -ENXIO;
+ }
+
+ hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
+ dev_name(&dev->dev));
+ if (!hcd)
+ goto err_return;
+ return -ENOMEM;
+
+ res_irq = platform_get_resource(dev, IORESOURCE_IRQ, 0);
+ if (!res_irq) {
+ err = -ENXIO;
+ goto err_return;
+ }
+ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ err = -ENXIO;
+ goto err_return;
+ }
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+ hcd->rsrc_len = resource_size(res_mem);
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_err("controller already in use");
+ err = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs)
+ goto err_put_hcd;
+ err = usb_add_hcd(hcd, res_irq->start, IRQF_SHARED);
+ goto err_release_region;
+ err = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (err)
+ goto err_iounmap;
+
@ -199,69 +173,36 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+err_iounmap:
+ iounmap(hcd->regs);
+err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+ usb_put_hcd(hcd);
+err_return:
+ return err;
+}
+
+static int ohci_platform_probe(struct platform_device *dev)
+static int __devexit ohci_platform_remove(struct platform_device *dev)
+{
+ int err;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ /* We currently always attach BCMA_DEV_USB11_HOSTDEV
+ * as HOST OHCI. If we want to attach it as Client device,
+ * we must branch here and call into the (yet to
+ * be written) Client mode driver. Same for remove(). */
+
+ err = ohci_platform_attach(dev);
+
+ return err;
+}
+
+static int ohci_platform_remove(struct platform_device *dev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(dev);
+ if (!hcd)
+ return -ENODEV;
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+static void ohci_platform_shutdown(struct platform_device *dev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(dev);
+ if (!hcd)
+ return;
+
+ if (hcd->driver->shutdown)
+ hcd->driver->shutdown(hcd);
+}
+
+#ifdef CONFIG_PM
+
+static int ohci_platform_suspend(struct platform_device *dev,
+ pm_message_t state)
+static int ohci_platform_suspend(struct device *dev)
+{
+
+ return 0;
+}
+
+static int ohci_platform_resume(struct platform_device *dev)
+static int ohci_platform_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+ ohci_finish_controller_resume(hcd);
+ return 0;
@ -278,14 +219,19 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+};
+MODULE_DEVICE_TABLE(platform, ohci_platform_table);
+
+static const struct dev_pm_ops ohci_platform_pm_ops = {
+ .suspend = ohci_platform_suspend,
+ .resume = ohci_platform_resume,
+};
+
+static struct platform_driver ohci_platform_driver = {
+ .id_table = ohci_platform_table,
+ .probe = ohci_platform_probe,
+ .remove = ohci_platform_remove,
+ .shutdown = ohci_platform_shutdown,
+ .suspend = ohci_platform_suspend,
+ .resume = ohci_platform_resume,
+ .remove = __devexit_p(ohci_platform_remove),
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ohci-platform",
+ .pm = &ohci_platform_pm_ops,
+ }
+};

View file

@ -1,7 +1,7 @@
From 2ade1c32109d2f17fdfc0b414411d4ee7f828706 Mon Sep 17 00:00:00 2001
From 1be00523336ac484c52681f838dfb8a76e8531cd Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 26 Nov 2011 21:28:56 +0100
Subject: [PATCH 18/30] USB: EHCI: Add a generic platform device driver
Subject: [PATCH 182/186] USB: EHCI: Add a generic platform device driver
This adds a generic driver for platform devices. It works like the PCI
driver and is based on it. This is for devices which do not have an own
@ -12,8 +12,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/Kconfig | 10 ++
drivers/usb/host/ehci-hcd.c | 5 +
drivers/usb/host/ehci-platform.c | 211 ++++++++++++++++++++++++++++++++++++++
3 files changed, 226 insertions(+), 0 deletions(-)
drivers/usb/host/ehci-platform.c | 199 ++++++++++++++++++++++++++++++++++++++
3 files changed, 214 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ehci-platform.c
--- a/drivers/usb/host/Kconfig
@ -51,15 +51,15 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
!defined(XILINX_OF_PLATFORM_DRIVER)
--- /dev/null
+++ b/drivers/usb/host/ehci-platform.c
@@ -0,0 +1,211 @@
@@ -0,0 +1,199 @@
+/*
+ * Generic platform ehci driver
+ *
+ * Copyright 2007 Steven Brown <sbrown@cortland.com>
+ * Copyright 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
+ * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Derived from the ohci-ssb driver
+ * Copyright 2007 Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007 Michael Buesch <m@bues.ch>
+ *
+ * Derived from the EHCI-PCI driver
+ * Copyright (c) 2000-2004 by David Brownell
@ -73,40 +73,38 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+#include <linux/platform_device.h>
+#include <linux/usb/hci_driver.h>
+
+static int ehci_platform_reset(struct usb_hcd *hcd)
+{
+ struct platform_device *pdev = to_platform_device(hcd->self.controller);
+ struct usb_hci_pdata *pdata = pdev->dev.platform_data;
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int caps_offset = 0;
+ int flags = 0;
+ int retval;
+
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
+ if (pdata) {
+ caps_offset = pdata->caps_offset;
+ flags = pdata->flags;
+ }
+
+ dbg_hcs_params(ehci, "reset");
+ dbg_hcc_params(ehci, "reset");
+ if (flags & USB_HCI_PDATA_HAS_TT_SET)
+ hcd->has_tt = pdata->has_tt;
+
+ /* cache this readonly data; minimize chip reads */
+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+ retval = ehci_halt(ehci);
+ ehci->caps = hcd->regs + caps_offset;
+ retval = ehci_setup(hcd);
+ if (retval)
+ return retval;
+
+ /* data structure init */
+ retval = ehci_init(hcd);
+ if (retval)
+ return retval;
+ if (flags & USB_HCI_PDATA_PORT_POWER_SET)
+ ehci_port_power(ehci, pdata->power_set_is_on);
+
+ ehci_reset(ehci);
+
+ ehci_port_power(ehci, 1);
+
+ return retval;
+ return 0;
+}
+
+static const struct hc_driver ehci_platform_hc_driver = {
+ .description = "platform-usb-ehci",
+ .description = hcd_name,
+ .product_desc = "Generic Platform EHCI Controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+
@ -139,37 +137,45 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_platform_attach(struct platform_device *dev)
+static int __devinit ehci_platform_probe(struct platform_device *dev)
+{
+ struct usb_hcd *hcd;
+ struct resource *res_irq, *res_mem;
+ struct resource *res_mem;
+ int irq;
+ int err = -ENOMEM;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0) {
+ pr_err("no irq provieded");
+ return irq;
+ }
+ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ pr_err("no memory recourse provieded");
+ return -ENXIO;
+ }
+
+ hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
+ dev_name(&dev->dev));
+ if (!hcd)
+ goto err_return;
+ return -ENOMEM;
+
+ res_irq = platform_get_resource(dev, IORESOURCE_IRQ, 0);
+ if (!res_irq) {
+ err = -ENXIO;
+ goto err_return;
+ }
+ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ err = -ENXIO;
+ goto err_return;
+ }
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+ hcd->rsrc_len = resource_size(res_mem);
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_err("controller already in use");
+ err = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ /*
+ * start & size modified per sbutils.c
+ */
+ hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs)
+ goto err_put_hcd;
+ err = usb_add_hcd(hcd, res_irq->start, IRQF_SHARED);
+ goto err_release_region;
+ err = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (err)
+ goto err_iounmap;
+
@ -179,65 +185,42 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+err_iounmap:
+ iounmap(hcd->regs);
+err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+ usb_put_hcd(hcd);
+err_return:
+ return err;
+}
+
+static int ehci_platform_probe(struct platform_device *dev)
+static int __devexit ehci_platform_remove(struct platform_device *dev)
+{
+ int err;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ err = ehci_platform_attach(dev);
+
+ return err;
+}
+
+static int ehci_platform_remove(struct platform_device *dev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(dev);
+ if (!hcd)
+ return -ENODEV;
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+static void ehci_platform_shutdown(struct platform_device *dev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(dev);
+ if (!hcd)
+ return;
+
+ if (hcd->driver->shutdown)
+ hcd->driver->shutdown(hcd);
+}
+
+#ifdef CONFIG_PM
+
+static int ehci_platform_suspend(struct platform_device *dev,
+ pm_message_t state)
+static int ehci_platform_suspend(struct device *dev)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ bool wakeup = device_may_wakeup(dev);
+
+ ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), wakeup);
+ return 0;
+}
+
+static int ehci_platform_resume(struct platform_device *dev)
+static int ehci_platform_resume(struct device *dev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+ ehci_finish_controller_resume(hcd);
+ ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd));
+ return 0;
+}
+
@ -252,14 +235,19 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+};
+MODULE_DEVICE_TABLE(platform, ehci_platform_table);
+
+static const struct dev_pm_ops ehci_platform_pm_ops = {
+ .suspend = ehci_platform_suspend,
+ .resume = ehci_platform_resume,
+};
+
+static struct platform_driver ehci_platform_driver = {
+ .id_table = ehci_platform_table,
+ .probe = ehci_platform_probe,
+ .remove = ehci_platform_remove,
+ .shutdown = ehci_platform_shutdown,
+ .suspend = ehci_platform_suspend,
+ .resume = ehci_platform_resume,
+ .remove = __devexit_p(ehci_platform_remove),
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ehci-platform",
+ .pm = &ehci_platform_pm_ops,
+ }
+};

View file

@ -1,7 +1,7 @@
From 1735daf1db79d338dccfc55444b52ed52af79e86 Mon Sep 17 00:00:00 2001
From adebff2358c2b631fc04e31ba87eee48e546c655 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sun, 20 Nov 2011 18:22:35 +0100
Subject: [PATCH 15/21] bcma: scan for extra address space
Subject: [PATCH 183/186] bcma: scan for extra address space
Some cores like the USB core have two address spaces. In the USB host
controller one address space is used for the OHCI and the other for the
@ -11,13 +11,13 @@ ai_scan() in shared/aiutils.c i the Broadcom SDK.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/bcma/scan.c | 17 ++++++++++++++++-
drivers/bcma/scan.c | 18 +++++++++++++++++-
include/linux/bcma/bcma.h | 1 +
2 files changed, 17 insertions(+), 1 deletions(-)
2 files changed, 18 insertions(+), 1 deletions(-)
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -286,6 +286,21 @@ static int bcma_get_next_core(struct bcm
@@ -297,6 +297,22 @@ static int bcma_get_next_core(struct bcm
return -EILSEQ;
}
@ -26,20 +26,21 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ * the main register space for the core
+ */
+ tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
+ if (tmp < 0) {
+ if (tmp <= 0) {
+ /* Try again to see if it is a bridge */
+ tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_BRIDGE, 0);
+ if (tmp) {
+ printk("found bridge\n");
+ tmp = bcma_erom_get_addr_desc(bus, eromptr,
+ SCAN_ADDR_TYPE_BRIDGE, 0);
+ if (tmp > 0) {
+ pr_info("found bridge");
+ return -ENXIO;
+ }
+
+ }
+ core->addr = tmp;
+
/* get & parse slave ports */
for (i = 0; i < ports[1]; i++) {
for (j = 0; ; j++) {
@@ -298,7 +313,7 @@ static int bcma_get_next_core(struct bcm
@@ -309,7 +325,7 @@ static int bcma_get_next_core(struct bcm
break;
} else {
if (i == 0 && j == 0)
@ -50,8 +51,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
}
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -138,6 +138,7 @@ struct bcma_device {
u8 core_index;
@@ -139,6 +139,7 @@ struct bcma_device {
u8 core_unit;
u32 addr;
+ u32 addr1;

View file

@ -1,7 +1,7 @@
From 0da055d81f77272ebc41d4c2cd5f533aa9025cc7 Mon Sep 17 00:00:00 2001
From 70fc4b2a6200ef7a1b99a6aa28234b919f23b43c Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 26 Nov 2011 21:33:41 +0100
Subject: [PATCH 19/30] USB: Add driver for the bcma bus
Subject: [PATCH 184/186] USB: Add driver for the bcma bus
This adds a USB driver using the generic platform device driver for the
USB controller found on the Broadcom bcma bus. The bcma bus just
@ -15,8 +15,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/Kconfig | 12 ++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/bcma-hcd.c | 309 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 322 insertions(+), 0 deletions(-)
drivers/usb/host/bcma-hcd.c | 328 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 341 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/bcma-hcd.c
--- a/drivers/usb/host/Kconfig
@ -46,7 +46,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
--- /dev/null
+++ b/drivers/usb/host/bcma-hcd.c
@@ -0,0 +1,309 @@
@@ -0,0 +1,328 @@
+/*
+ * Broadcom specific Advanced Microcontroller Bus
+ * Broadcom USB-core driver (BCMA bus glue)
@ -71,6 +71,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/usb/hci_driver.h>
+
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
@ -81,6 +82,25 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ struct platform_device *ohci_dev;
+};
+
+/* Wait for bitmask in a register to get set or cleared.
+ * timeout is in units of ten-microseconds.
+ */
+static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
+ int timeout)
+{
+ int i;
+ u32 val;
+
+ for (i = 0; i < timeout; i++) {
+ val = bcma_read32(dev, reg);
+ if ((val & bitmask) == bitmask)
+ return 0;
+ udelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
+{
+#ifdef CONFIG_BCMA_DRIVER_MIPS
@ -137,7 +157,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ tmp = bcma_read32(dev, 0x1e0);
+ tmp |= 0x100;
+ bcma_write32(dev, 0x1e0, tmp);
+ if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100, 1))
+ if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100))
+ printk(KERN_EMERG "Failed to enable misc PPL!\n");
+
+ /* Take out of resets */
@ -163,7 +183,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ udelay(50);
+ tmp = bcma_read32(dev, 0x524);
+
+ if (bcma_wait_bits(dev, 0x528, 0xc000, 10000, 1)) {
+ if (bcma_wait_bits(dev, 0x528, 0xc000, 10000)) {
+ tmp = bcma_read32(dev, 0x528);
+ printk(KERN_EMERG
+ "USB20H mdio_rddata 0x%08x\n", tmp);
@ -186,6 +206,11 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ }
+}
+
+static const struct usb_hci_pdata p_data = {
+ .flags = USB_HCI_PDATA_PORT_POWER_SET,
+ .power_set_is_on = 1,
+};
+
+static struct platform_device * __devinit
+bcma_hcd_create_pdev(struct bcma_device *dev, char *name, u32 addr)
+{
@ -204,7 +229,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+ hci_dev = platform_device_alloc(name, 0);
+ if (!hci_dev)
+ goto err_alloc;
+ return NULL;
+
+ hci_dev->dev.parent = &dev->dev;
+ hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
@ -213,17 +238,20 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ ARRAY_SIZE(hci_res));
+ if (ret)
+ goto err_alloc;
+
+ ret = platform_device_add_data(hci_dev, &p_data, sizeof(p_data));
+ if (ret)
+ goto err_alloc;
+ ret = platform_device_add(hci_dev);
+ if (ret) {
+ if (ret)
+ goto err_alloc;
+
+ return hci_dev;
+
+err_alloc:
+ platform_device_put(hci_dev);
+ return ERR_PTR(ret);
+}
+
+ return hci_dev;
+}
+
+static int __devinit bcma_hcd_probe(struct bcma_device *dev)
+{
+ int err;
@ -282,23 +310,14 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+static void __devexit bcma_hcd_remove(struct bcma_device *dev)
+{
+ struct bcma_hcd_device *usb_dev;
+ struct platform_device *ohci_dev;
+ struct platform_device *ehci_dev;
+ 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;
+
+ usb_dev = bcma_get_drvdata(dev);
+ if (!usb_dev)
+ return;
+
+ ohci_dev = usb_dev->ohci_dev;
+ ehci_dev = usb_dev->ehci_dev;
+
+ if (ohci_dev) {
+ if (ohci_dev)
+ platform_device_unregister(ohci_dev);
+ }
+ if (ehci_dev) {
+ if (ehci_dev)
+ platform_device_unregister(ehci_dev);
+ }
+
+ bcma_core_disable(dev, 0);
+}

View file

@ -1,7 +1,7 @@
From ca1db834336ac19edc7a5d342f8acece1ae1feb9 Mon Sep 17 00:00:00 2001
From 1840ddf07a452e640549fbd82e2f570da28e377f Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 26 Nov 2011 21:35:17 +0100
Subject: [PATCH 20/30] USB: Add driver for the ssb bus
Subject: [PATCH 185/186] USB: Add driver for the ssb bus
This adds a USB driver using the generic platform device driver for the
USB controller found on the Broadcom ssb bus. The ssb bus just
@ -19,8 +19,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/Kconfig | 12 ++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/ssb-hcd.c | 272 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 285 insertions(+), 0 deletions(-)
drivers/usb/host/ssb-hcd.c | 273 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 286 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ssb-hcd.c
--- a/drivers/usb/host/Kconfig
@ -50,7 +50,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
--- /dev/null
+++ b/drivers/usb/host/ssb-hcd.c
@@ -0,0 +1,272 @@
@@ -0,0 +1,273 @@
+/*
+ * Sonics Silicon Backplane
+ * Broadcom USB-core driver (SSB bus glue)
@ -75,6 +75,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/usb/hci_driver.h>
+
+MODULE_AUTHOR("Hauke Mehrtens");
+MODULE_DESCRIPTION("Common USB driver for SSB Bus");
@ -145,6 +146,11 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ return flags;
+}
+
+static const struct usb_hci_pdata p_data = {
+ .flags = USB_HCI_PDATA_PORT_POWER_SET,
+ .power_set_is_on = 1,
+};
+
+static struct platform_device * __devinit
+ssb_hcd_create_pdev(struct ssb_device *dev, char *name, u32 addr, u32 len)
+{
@ -163,31 +169,36 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+ hci_dev = platform_device_alloc(name, 0);
+ if (!hci_dev)
+ goto err_alloc;
+ return NULL;
+
+ hci_dev->dev.parent = dev->dev;
+ hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
+
+ ret = platform_device_add_resources(hci_dev, hci_res, 2);
+ ret = platform_device_add_resources(hci_dev, hci_res,
+ ARRAY_SIZE(hci_res));
+ if (ret)
+ goto err_alloc;
+ ret = platform_device_add_data(hci_dev, &p_data, sizeof(p_data));
+ if (ret)
+ goto err_alloc;
+ ret = platform_device_add(hci_dev);
+ if (ret)
+ goto err_alloc;
+
+ ret = platform_device_add(hci_dev);
+ if (ret) {
+ return hci_dev;
+
+err_alloc:
+ platform_device_put(hci_dev);
+ return ERR_PTR(ret);
+}
+
+ return hci_dev;
+}
+
+static int __devinit ssb_hcd_probe(struct ssb_device *dev,
+ const struct ssb_device_id *id)
+{
+ int err, tmp;
+ int start, len;
+ u16 chipid_top;
+ u16 coreid = dev->id.coreid;
+ struct ssb_hcd_device *usb_dev;
+
+ /* USBcores are only connected on embedded devices. */
@ -214,7 +225,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ tmp = ssb_read32(dev, SSB_ADMATCH0);
+
+ start = ssb_admatch_base(tmp);
+ len = ssb_admatch_size(tmp);
+ len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp);
+ usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, "ohci-platform", start,
+ len);
+ if (IS_ERR(usb_dev->ohci_dev)) {
@ -222,9 +233,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ goto err_free_usb_dev;
+ }
+
+ if (dev->id.coreid == SSB_DEV_USB20_HOST) {
+ if (coreid == SSB_DEV_USB20_HOST) {
+ start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */
+ len = 0x100; /* ehci reg block size */
+ usb_dev->ehci_dev = ssb_hcd_create_pdev(dev, "ehci-platform",
+ start, len);
+ if (IS_ERR(usb_dev->ehci_dev)) {
@ -245,23 +255,14 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+
+static void __devexit ssb_hcd_remove(struct ssb_device *dev)
+{
+ struct ssb_hcd_device *usb_dev;
+ struct platform_device *ohci_dev;
+ struct platform_device *ehci_dev;
+ struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
+ struct platform_device *ohci_dev = usb_dev->ohci_dev;
+ struct platform_device *ehci_dev = usb_dev->ehci_dev;
+
+ usb_dev = ssb_get_drvdata(dev);
+ if (!usb_dev)
+ return;
+
+ ohci_dev = usb_dev->ohci_dev;
+ ehci_dev = usb_dev->ehci_dev;
+
+ if (ohci_dev) {
+ if (ohci_dev)
+ platform_device_unregister(ohci_dev);
+ }
+ if (ehci_dev) {
+ if (ehci_dev)
+ platform_device_unregister(ehci_dev);
+ }
+
+ ssb_device_disable(dev, 0);
+}

View file

@ -1,7 +1,7 @@
From 77190e21ed262397eb924e6d48e12ecf3e9f6316 Mon Sep 17 00:00:00 2001
From 57857d7df6c22eaf11e3c67042d55a9546415059 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 26 Nov 2011 21:36:50 +0100
Subject: [PATCH 21/30] USB: OHCI: remove old SSB OHCI driver
Subject: [PATCH 186/186] USB: OHCI: remove old SSB OHCI driver
This is now replaced by the new ssb USB driver, which also supports
devices with an EHCI controller.
@ -9,9 +9,9 @@ devices with an EHCI controller.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/usb/host/Kconfig | 13 --
drivers/usb/host/ohci-hcd.c | 19 ---
drivers/usb/host/ohci-hcd.c | 21 +----
drivers/usb/host/ohci-ssb.c | 260 -------------------------------------------
3 files changed, 0 insertions(+), 292 deletions(-)
3 files changed, 1 insertions(+), 293 deletions(-)
delete mode 100644 drivers/usb/host/ohci-ssb.c
--- a/drivers/usb/host/Kconfig
@ -50,15 +50,17 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
#ifdef CONFIG_MFD_SM501
#include "ohci-sm501.c"
#define SM501_OHCI_DRIVER ohci_hcd_sm501_driver
@@ -1130,7 +1125,6 @@ MODULE_LICENSE ("GPL");
@@ -1129,8 +1124,7 @@ MODULE_LICENSE ("GPL");
!defined(SA1111_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && \
!defined(SM501_OHCI_DRIVER) && \
!defined(TMIO_OHCI_DRIVER) && \
- !defined(SSB_OHCI_DRIVER) && \
!defined(PLATFORM_OHCI_DRIVER)
- !defined(TMIO_OHCI_DRIVER) && \
- !defined(SSB_OHCI_DRIVER)
+ !defined(TMIO_OHCI_DRIVER)
#error "missing bus glue for ohci-hcd"
#endif
@@ -1197,12 +1191,6 @@ static int __init ohci_hcd_mod_init(void
@@ -1196,12 +1190,6 @@ static int __init ohci_hcd_mod_init(void
goto error_pci;
#endif
@ -71,7 +73,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
#ifdef SM501_OHCI_DRIVER
retval = platform_driver_register(&SM501_OHCI_DRIVER);
if (retval < 0)
@@ -1236,10 +1224,6 @@ static int __init ohci_hcd_mod_init(void
@@ -1225,10 +1213,6 @@ static int __init ohci_hcd_mod_init(void
platform_driver_unregister(&SM501_OHCI_DRIVER);
error_sm501:
#endif
@ -82,7 +84,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
#ifdef PCI_DRIVER
pci_unregister_driver(&PCI_DRIVER);
error_pci:
@@ -1290,9 +1274,6 @@ static void __exit ohci_hcd_mod_exit(voi
@@ -1276,9 +1260,6 @@ static void __exit ohci_hcd_mod_exit(voi
#ifdef SM501_OHCI_DRIVER
platform_driver_unregister(&SM501_OHCI_DRIVER);
#endif