2 * OHCI HCD (Host Controller Driver) for USB.
4 * Copyright (C) 2007 Atheros Communications, Inc.
5 * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
8 * Bus Glue for Atheros AR71xx built-in OHCI controller
12 #include <linux/platform_device.h>
13 #include <linux/delay.h>
15 extern int usb_disabled(void);
17 static void ar71xx_start_ohci(struct platform_device
*pdev
)
21 static void ar71xx_stop_ohci(struct platform_device
*pdev
)
28 int usb_hcd_ar71xx_probe(const struct hc_driver
*driver
,
29 struct platform_device
*pdev
)
36 res
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
38 dev_dbg(&pdev
->dev
, "no IRQ specified for %s\n",
44 hcd
= usb_create_hcd(driver
, &pdev
->dev
, pdev
->dev
.bus_id
);
48 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
50 dev_dbg(&pdev
->dev
, "no base address specified for %s\n",
55 hcd
->rsrc_start
= res
->start
;
56 hcd
->rsrc_len
= res
->end
- res
->start
+ 1;
58 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
, hcd_name
)) {
59 dev_dbg(&pdev
->dev
, "controller already in use\n");
64 hcd
->regs
= ioremap(hcd
->rsrc_start
, hcd
->rsrc_len
);
66 dev_dbg(&pdev
->dev
, "error mapping memory\n");
68 goto err_release_region
;
71 ar71xx_start_ohci(pdev
);
72 ohci_hcd_init(hcd_to_ohci(hcd
));
74 ret
= usb_add_hcd(hcd
, irq
, IRQF_DISABLED
);
81 ar71xx_stop_ohci(pdev
);
84 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
91 /* may be called without controller electrically present */
92 /* may be called with controller, bus, and devices active */
95 * usb_hcd_ar71xx_remove - shutdown processing for AR71xx HCDs
96 * @dev: USB Host Controller being removed
97 * Context: !in_interrupt()
99 * Reverses the effect of usb_hcd_ar71xx_probe(), first invoking
100 * the HCD's stop() method. It is always called from a thread
101 * context, normally "rmmod", "apmd", or something similar.
104 void usb_hcd_ar71xx_remove(struct usb_hcd
*hcd
, struct platform_device
*pdev
)
107 ar71xx_stop_ohci(pdev
);
109 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
113 static int __devinit
ohci_ar71xx_start(struct usb_hcd
*hcd
)
115 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
118 ret
= ohci_init(ohci
);
122 ret
= ohci_run(ohci
);
133 static const struct hc_driver ohci_ar71xx_hc_driver
= {
134 .description
= hcd_name
,
135 .product_desc
= "Atheros AR71xx built-in OHCI controller",
136 .hcd_priv_size
= sizeof(struct ohci_hcd
),
139 * generic hardware linkage
142 .flags
= HCD_USB11
| HCD_MEMORY
,
145 * basic lifecycle operations
147 .start
= ohci_ar71xx_start
,
149 .shutdown
= ohci_shutdown
,
152 * managing i/o requests and associated device resources
154 .urb_enqueue
= ohci_urb_enqueue
,
155 .urb_dequeue
= ohci_urb_dequeue
,
156 .endpoint_disable
= ohci_endpoint_disable
,
161 .get_frame_number
= ohci_get_frame
,
166 .hub_status_data
= ohci_hub_status_data
,
167 .hub_control
= ohci_hub_control
,
168 .start_port_reset
= ohci_start_port_reset
,
171 static int ohci_hcd_ar71xx_drv_probe(struct platform_device
*pdev
)
177 ret
= usb_hcd_ar71xx_probe(&ohci_ar71xx_hc_driver
, pdev
);
182 static int ohci_hcd_ar71xx_drv_remove(struct platform_device
*pdev
)
184 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
186 usb_hcd_ar71xx_remove(hcd
, pdev
);
190 static struct platform_driver ohci_hcd_ar71xx_driver
= {
191 .probe
= ohci_hcd_ar71xx_drv_probe
,
192 .remove
= ohci_hcd_ar71xx_drv_remove
,
193 .shutdown
= usb_hcd_platform_shutdown
,
195 .name
= "ar71xx-ohci",
196 .owner
= THIS_MODULE
,
200 MODULE_ALIAS("ar71xx-ohci");