* [PATCH 1/3] USB: ehci: add bus glue for the Atheros AR7XXX/AR9XXX SoCs
@ 2011-04-10 20:04 Gabor Juhos
2011-04-10 20:04 ` [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
2011-04-10 20:05 ` [PATCH 3/3] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs Gabor Juhos
0 siblings, 2 replies; 6+ messages in thread
From: Gabor Juhos @ 2011-04-10 20:04 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Gabor Juhos, Imre Kaloz, Greg Kroah-Hartman,
Alan Stern, linux-usb
The Atheros AR71XX/AR9XXX SoCs have a built-in EHCI controller.
This patch adds the necessary glue code to make the generic EHCI
driver usable for them.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org
---
arch/mips/ath79/Kconfig | 3 +
drivers/usb/host/Kconfig | 8 ++
drivers/usb/host/ehci-ath79.c | 200 +++++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ehci-hcd.c | 5 +
4 files changed, 216 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ehci-ath79.c
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index b058282..649a2a3 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -26,12 +26,15 @@ config ATH79_MACH_PB44
endmenu
config SOC_AR71XX
+ select USB_ARCH_HAS_EHCI
def_bool n
config SOC_AR724X
+ select USB_ARCH_HAS_EHCI
def_bool n
config SOC_AR913X
+ select USB_ARCH_HAS_EHCI
def_bool n
config ATH79_DEV_AR913X_WMAC
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 9483acd..9970c86 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -202,6 +202,14 @@ config USB_CNS3XXX_EHCI
It is needed for high-speed (480Mbit/sec) USB 2.0 device
support.
+config USB_EHCI_ATH79
+ bool "EHCI support for AR7XX/AR9XXX SoCs"
+ depends on USB_EHCI_HCD && ATH79
+ select USB_EHCI_ROOT_HUB_TT
+ ---help---
+ Enables support for the built-in EHCI controller present
+ on the Atheros AR7XXX/AR9XXX SoCs.
+
config USB_OXU210HP_HCD
tristate "OXU210HP HCD support"
depends on USB
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
new file mode 100644
index 0000000..74325b8
--- /dev/null
+++ b/drivers/usb/host/ehci-ath79.c
@@ -0,0 +1,200 @@
+/*
+ * Bus Glue for Atheros AR7XXX/AR9XXX built-in EHCI controller.
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ * Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+enum {
+ EHCI_ATH79_IP_V1 = 0,
+ EHCI_ATH79_IP_V2,
+};
+
+static const struct platform_device_id ehci_ath79_id_table[] = {
+ {
+ .name = "ar71xx-ehci",
+ .driver_data = EHCI_ATH79_IP_V1,
+ },
+ {
+ .name = "ar724x-ehci",
+ .driver_data = EHCI_ATH79_IP_V2,
+ },
+ {
+ .name = "ar913x-ehci",
+ .driver_data = EHCI_ATH79_IP_V2,
+ },
+ {
+ /* terminating entry */
+ },
+};
+
+MODULE_DEVICE_TABLE(platform, ehci_ath79_id_table);
+
+static int ehci_ath79_init(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct platform_device *pdev = to_platform_device(hcd->self.controller);
+ const struct platform_device_id *id;
+ int ret;
+
+ id = platform_get_device_id(pdev);
+ if (!id) {
+ dev_err(hcd->self.controller, "missing device id\n");
+ return -EINVAL;
+ }
+
+ switch (id->driver_data) {
+ case EHCI_ATH79_IP_V1:
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+ break;
+
+ case EHCI_ATH79_IP_V2:
+ hcd->has_tt = 1;
+
+ ehci->caps = hcd->regs + 0x100;
+ ehci->regs = hcd->regs + 0x100 +
+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+ break;
+
+ default:
+ BUG();
+ }
+
+ dbg_hcs_params(ehci, "reset");
+ dbg_hcc_params(ehci, "reset");
+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+ ehci->sbrn = 0x20;
+
+ ehci_reset(ehci);
+
+ ret = ehci_init(hcd);
+ if (ret)
+ return ret;
+
+ ehci_port_power(ehci, 0);
+
+ return 0;
+}
+
+static const struct hc_driver ehci_ath79_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "Atheros built-in EHCI controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ .reset = ehci_ath79_init,
+ .start = ehci_run,
+ .stop = ehci_stop,
+ .shutdown = ehci_shutdown,
+
+ .urb_enqueue = ehci_urb_enqueue,
+ .urb_dequeue = ehci_urb_dequeue,
+ .endpoint_disable = ehci_endpoint_disable,
+ .endpoint_reset = ehci_endpoint_reset,
+
+ .get_frame_number = ehci_get_frame,
+
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_ath79_probe(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+ struct resource *res;
+ int irq;
+ int ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no IRQ specified\n");
+ return -ENODEV;
+ }
+ irq = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no base address specified\n");
+ return -ENODEV;
+ }
+
+ hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev,
+ dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = res->end - res->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ dev_dbg(&pdev->dev, "controller already in use\n");
+ ret = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_dbg(&pdev->dev, "error mapping memory\n");
+ ret = -EFAULT;
+ goto err_release_region;
+ }
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+ if (ret)
+ goto err_iounmap;
+
+ return 0;
+
+err_iounmap:
+ iounmap(hcd->regs);
+
+err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int ehci_ath79_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+static struct platform_driver ehci_ath79_driver = {
+ .probe = ehci_ath79_probe,
+ .remove = ehci_ath79_remove,
+ .id_table = ehci_ath79_id_table,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ath79-ehci",
+ }
+};
+
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ehci");
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 78561d1..a29527d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1265,6 +1265,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER tegra_ehci_driver
#endif
+#ifdef CONFIG_USB_EHCI_ATH79
+#include "ehci-ath79.c"
+#define PLATFORM_DRIVER ehci_ath79_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
!defined(XILINX_OF_PLATFORM_DRIVER)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug
2011-04-10 20:04 [PATCH 1/3] USB: ehci: add bus glue for the Atheros AR7XXX/AR9XXX SoCs Gabor Juhos
@ 2011-04-10 20:04 ` Gabor Juhos
2011-04-11 18:53 ` Alan Stern
2011-04-10 20:05 ` [PATCH 3/3] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs Gabor Juhos
1 sibling, 1 reply; 6+ messages in thread
From: Gabor Juhos @ 2011-04-10 20:04 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Gabor Juhos, Greg Kroah-Hartman, Alan Stern,
linux-usb
A Synopsys USB core used in various SoCs has a bug which might cause
that the host controller not issuing ping.
When software uses the Doorbell mechanism to remove queue heads, the
host controller still has references to the removed queue head even
after indicating an Interrupt on Async Advance. This happens if the last
executed queue head's Next Link queue head is removed.
Consequences of the defect:
The Host controller fetches the removed queue head, using memory that
would otherwise be deallocated.This results in incorrect transactions on
both the USB and system memory. This may result in undefined behavior.
Workarounds:
1) If no queue head is active (no Status field's Active bit is set)
after removing the queue heads, the software can write one of the valid
queue head addresses to the ASYNCLISTADDR register and deallocate the
removed queue head's memory after 2 microframes.
If one or more of the queue heads is active (the Active bit is set in
the Status field) after removing the queue heads, the software can delay
memory deallocation after time X, where X is the time required for the
Host Controller to go through all the queue heads once. X varies with
the number of queue heads and the time required to process periodic
transactions: if more periodic transactions must be performed, the Host
Controller has less time to process asynchronous transaction processing.
2) Do not use the Doorbell mechanism to remove the queue heads. Disable
the Asynchronous Schedule Enable bit instead.
The bug has been discussed on the linux-usb-devel mailing-list
four years ago, the original thread can be found here:
http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg45345.html
This patch implements the first workaround as suggested by David Brownell.
The built-in USB host controller of the Atheros AR7130/AR7141/AR7161 SoCs
requires this to work properly.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org
---
drivers/usb/host/ehci-ath79.c | 2 ++
drivers/usb/host/ehci-q.c | 3 +++
drivers/usb/host/ehci.h | 1 +
3 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
index 74325b8..7ea23b5 100644
--- a/drivers/usb/host/ehci-ath79.c
+++ b/drivers/usb/host/ehci-ath79.c
@@ -54,6 +54,8 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
switch (id->driver_data) {
case EHCI_ATH79_IP_V1:
+ ehci->has_synopsys_hc_bug = 1;
+
ehci->caps = hcd->regs;
ehci->regs = hcd->regs +
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 98ded66..38c1206 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1183,6 +1183,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
ehci->reclaim = NULL;
start_unlink_async (ehci, next);
}
+
+ if (ehci->has_synopsys_hc_bug)
+ writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
}
/* makes sure the async qh will become idle */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index f86d3fa..28ef8ca 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -134,6 +134,7 @@ struct ehci_hcd { /* one per controller */
unsigned amd_pll_fix:1;
unsigned fs_i_thresh:1; /* Intel iso scheduling */
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
+ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug
2011-04-10 20:04 ` [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
@ 2011-04-11 18:53 ` Alan Stern
2011-04-11 18:53 ` Alan Stern
2011-04-11 19:42 ` Gabor Juhos
0 siblings, 2 replies; 6+ messages in thread
From: Alan Stern @ 2011-04-11 18:53 UTC (permalink / raw)
To: Gabor Juhos; +Cc: Ralf Baechle, linux-mips, Greg Kroah-Hartman, linux-usb
On Sun, 10 Apr 2011, Gabor Juhos wrote:
> A Synopsys USB core used in various SoCs has a bug which might cause
> that the host controller not issuing ping.
>
> When software uses the Doorbell mechanism to remove queue heads, the
> host controller still has references to the removed queue head even
> after indicating an Interrupt on Async Advance. This happens if the last
> executed queue head's Next Link queue head is removed.
>
> Consequences of the defect:
> The Host controller fetches the removed queue head, using memory that
> would otherwise be deallocated.This results in incorrect transactions on
> both the USB and system memory. This may result in undefined behavior.
> --- a/drivers/usb/host/ehci-q.c
> +++ b/drivers/usb/host/ehci-q.c
> @@ -1183,6 +1183,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
> ehci->reclaim = NULL;
> start_unlink_async (ehci, next);
> }
> +
> + if (ehci->has_synopsys_hc_bug)
> + writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
> }
This should be ehci_writel(ehci, ...).
Alan Stern
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug
2011-04-11 18:53 ` Alan Stern
@ 2011-04-11 18:53 ` Alan Stern
2011-04-11 19:42 ` Gabor Juhos
1 sibling, 0 replies; 6+ messages in thread
From: Alan Stern @ 2011-04-11 18:53 UTC (permalink / raw)
To: Gabor Juhos; +Cc: Ralf Baechle, linux-mips, Greg Kroah-Hartman, linux-usb
On Sun, 10 Apr 2011, Gabor Juhos wrote:
> A Synopsys USB core used in various SoCs has a bug which might cause
> that the host controller not issuing ping.
>
> When software uses the Doorbell mechanism to remove queue heads, the
> host controller still has references to the removed queue head even
> after indicating an Interrupt on Async Advance. This happens if the last
> executed queue head's Next Link queue head is removed.
>
> Consequences of the defect:
> The Host controller fetches the removed queue head, using memory that
> would otherwise be deallocated.This results in incorrect transactions on
> both the USB and system memory. This may result in undefined behavior.
> --- a/drivers/usb/host/ehci-q.c
> +++ b/drivers/usb/host/ehci-q.c
> @@ -1183,6 +1183,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
> ehci->reclaim = NULL;
> start_unlink_async (ehci, next);
> }
> +
> + if (ehci->has_synopsys_hc_bug)
> + writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
> }
This should be ehci_writel(ehci, ...).
Alan Stern
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug
2011-04-11 18:53 ` Alan Stern
2011-04-11 18:53 ` Alan Stern
@ 2011-04-11 19:42 ` Gabor Juhos
1 sibling, 0 replies; 6+ messages in thread
From: Gabor Juhos @ 2011-04-11 19:42 UTC (permalink / raw)
To: Alan Stern; +Cc: Ralf Baechle, linux-mips, Greg Kroah-Hartman, linux-usb
2011.04.11. 20:53 keltezéssel, Alan Stern írta:
> On Sun, 10 Apr 2011, Gabor Juhos wrote:
>
>> A Synopsys USB core used in various SoCs has a bug which might cause
>> that the host controller not issuing ping.
>>
>> When software uses the Doorbell mechanism to remove queue heads, the
>> host controller still has references to the removed queue head even
>> after indicating an Interrupt on Async Advance. This happens if the last
>> executed queue head's Next Link queue head is removed.
>>
>> Consequences of the defect:
>> The Host controller fetches the removed queue head, using memory that
>> would otherwise be deallocated.This results in incorrect transactions on
>> both the USB and system memory. This may result in undefined behavior.
>
>> --- a/drivers/usb/host/ehci-q.c
>> +++ b/drivers/usb/host/ehci-q.c
>> @@ -1183,6 +1183,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
>> ehci->reclaim = NULL;
>> start_unlink_async (ehci, next);
>> }
>> +
>> + if (ehci->has_synopsys_hc_bug)
>> + writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
>> }
>
> This should be ehci_writel(ehci, ...).
You are right, I will change that.
Thanks,
Gabor
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
2011-04-10 20:04 [PATCH 1/3] USB: ehci: add bus glue for the Atheros AR7XXX/AR9XXX SoCs Gabor Juhos
2011-04-10 20:04 ` [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
@ 2011-04-10 20:05 ` Gabor Juhos
1 sibling, 0 replies; 6+ messages in thread
From: Gabor Juhos @ 2011-04-10 20:05 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Gabor Juhos, Imre Kaloz, Greg Kroah-Hartman,
Alan Stern, linux-usb
The Atheros AR71XX/AR7240 SoCs have a built-in OHCI controller.
This patch adds the necessary glue code to make the generic OHCI
driver usable for them.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org
---
arch/mips/ath79/Kconfig | 2 +
drivers/usb/host/Kconfig | 8 ++
drivers/usb/host/ohci-ath79.c | 151 +++++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ohci-hcd.c | 5 ++
4 files changed, 166 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ohci-ath79.c
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 649a2a3..4770741 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -27,10 +27,12 @@ endmenu
config SOC_AR71XX
select USB_ARCH_HAS_EHCI
+ select USB_ARCH_HAS_OHCI
def_bool n
config SOC_AR724X
select USB_ARCH_HAS_EHCI
+ select USB_ARCH_HAS_OHCI
def_bool n
config SOC_AR913X
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 9970c86..9a6751e 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -295,6 +295,14 @@ config USB_OHCI_HCD_OMAP3
Enables support for the on-chip OHCI controller on
OMAP3 and later chips.
+config USB_OHCI_ATH79
+ bool "USB OHCI support for the Atheros AR71XX/AR7240 SoCs"
+ depends on USB_OHCI_HCD && (SOC_AR71XX || SOC_AR724X)
+ default y
+ help
+ Enables support for the built-in OHCI controller present on the
+ Atheros AR71XX/AR7240 SoCs.
+
config USB_OHCI_HCD_PPC_SOC
bool "OHCI support for on-chip PPC USB controller"
depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c
new file mode 100644
index 0000000..ffea3e7
--- /dev/null
+++ b/drivers/usb/host/ohci-ath79.c
@@ -0,0 +1,151 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller.
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ * Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+static int __devinit ohci_ath79_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int ret;
+
+ ret = ohci_init(ohci);
+ if (ret < 0)
+ return ret;
+
+ ret = ohci_run(ohci);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+
+err:
+ ohci_stop(hcd);
+ return ret;
+}
+
+static const struct hc_driver ohci_ath79_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "Atheros built-in OHCI controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ .start = ohci_ath79_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int ohci_ath79_probe(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+ struct resource *res;
+ int irq;
+ int ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no IRQ specified\n");
+ return -ENODEV;
+ }
+ irq = res->start;
+
+ hcd = usb_create_hcd(&ohci_ath79_hc_driver, &pdev->dev,
+ dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no base address specified\n");
+ ret = -ENODEV;
+ goto err_put_hcd;
+ }
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = res->end - res->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ dev_dbg(&pdev->dev, "controller already in use\n");
+ ret = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_dbg(&pdev->dev, "error mapping memory\n");
+ ret = -EFAULT;
+ goto err_release_region;
+ }
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (ret)
+ goto err_stop_hcd;
+
+ return 0;
+
+err_stop_hcd:
+ iounmap(hcd->regs);
+err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int ohci_ath79_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+static struct platform_driver ohci_hcd_ath79_driver = {
+ .probe = ohci_ath79_probe,
+ .remove = ohci_ath79_remove,
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "ath79-ohci",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index e728863..8aec65f 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1105,6 +1105,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver
#endif
+#ifdef CONFIG_USB_OHCI_ATH79
+#include "ohci-ath79.c"
+#define PLATFORM_DRIVER ohci_hcd_ath79_driver
+#endif
+
#if !defined(PCI_DRIVER) && \
!defined(PLATFORM_DRIVER) && \
!defined(OMAP1_PLATFORM_DRIVER) && \
--
1.7.2.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-04-11 19:42 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-10 20:04 [PATCH 1/3] USB: ehci: add bus glue for the Atheros AR7XXX/AR9XXX SoCs Gabor Juhos
2011-04-10 20:04 ` [PATCH 2/3] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
2011-04-11 18:53 ` Alan Stern
2011-04-11 18:53 ` Alan Stern
2011-04-11 19:42 ` Gabor Juhos
2011-04-10 20:05 ` [PATCH 3/3] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs Gabor Juhos
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox