Skip to content

Commit

Permalink
USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
Browse files Browse the repository at this point in the history
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: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Gabor Juhos authored and Greg Kroah-Hartman committed Apr 13, 2011
1 parent 2f7ac6c commit 90e6ca5
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 0 deletions.
2 changes: 2 additions & 0 deletions arch/mips/ath79/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions drivers/usb/host/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,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)
Expand Down
151 changes: 151 additions & 0 deletions drivers/usb/host/ohci-ath79.c
Original file line number Diff line number Diff line change
@@ -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");
5 changes: 5 additions & 0 deletions drivers/usb/host/ohci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) && \
Expand Down

0 comments on commit 90e6ca5

Please sign in to comment.