MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / drivers / usb / host / ehci-moxaart.c
blob710f3731ab9e36cffce28fcc788f404d7201a602
1 /*
2 * EHCI HCD (Host Controller Driver) for USB.
4 * History :
5 * Date Author Comment
6 * 08-03-2007 Victor Yu. Create it.
7 */
9 #include <linux/platform_device.h>
10 #include <asm/arch/moxa.h>
11 #include <asm/arch/cpe_int.h>
13 extern int usb_disabled(void);
15 /*-------------------------------------------------------------------------*/
17 static void moxaart_start_ehc(struct platform_device *dev)
19 pr_debug(__FILE__ ": starting Au1xxx EHCI USB Controller\n");
21 /* write HW defaults again in case Yamon cleared them */
22 if (au_readl(USB_HOST_CONFIG) == 0) {
23 au_writel(0x00d02000, USB_HOST_CONFIG);
24 au_readl(USB_HOST_CONFIG);
25 udelay(1000);
27 /* enable host controller */
28 au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
29 au_readl(USB_HOST_CONFIG);
30 udelay(1000);
31 au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG),
32 USB_HOST_CONFIG);
33 au_readl(USB_HOST_CONFIG);
34 udelay(1000);
36 pr_debug(__FILE__ ": Clock to USB host has been enabled\n");
39 static void moxaart_stop_ehc(struct platform_device *dev)
41 pr_debug(__FILE__ ": stopping Au1xxx EHCI USB Controller\n");
43 /* Disable mem */
44 au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
45 udelay(1000);
46 /* Disable clock */
47 au_writel(~USB_MCFG_EHCCLKEN & au_readl(USB_HOST_CONFIG),
48 USB_HOST_CONFIG);
49 au_readl(USB_HOST_CONFIG);
52 /*-------------------------------------------------------------------------*/
54 /* configure so an HC device and id are always provided */
55 /* always called with process context; sleeping is OK */
57 /**
58 * usb_ehci_moxaart_probe - initialize Au1xxx-based HCDs
59 * Context: !in_interrupt()
61 * Allocates basic resources for this USB host controller, and
62 * then invokes the start() method for the HCD associated with it
63 * through the hotplug entry's driver_data.
66 int usb_ehci_moxaart_probe(const struct hc_driver *driver,
67 struct usb_hcd **hcd_out, struct platform_device *dev)
69 int retval;
70 struct usb_hcd *hcd;
71 struct ehci_hcd *ehci;
73 moxaart_start_ehc(dev);
75 if (dev->resource[1].flags != IORESOURCE_IRQ) {
76 pr_debug("resource[1] is not IORESOURCE_IRQ");
77 retval = -ENOMEM;
79 hcd = usb_create_hcd(driver, &dev->dev, "MoxaART");
80 if (!hcd)
81 return -ENOMEM;
82 hcd->rsrc_start = dev->resource[0].start;
83 hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
85 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
86 pr_debug("request_mem_region failed");
87 retval = -EBUSY;
88 goto err1;
91 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
92 if (!hcd->regs) {
93 pr_debug("ioremap failed");
94 retval = -ENOMEM;
95 goto err2;
98 ehci = hcd_to_ehci(hcd);
99 ehci->caps = hcd->regs;
100 ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
101 /* cache this readonly data; minimize chip reads */
102 ehci->hcs_params = readl(&ehci->caps->hcs_params);
104 /* ehci_hcd_init(hcd_to_ehci(hcd)); */
106 retval =
107 usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED | IRQF_SHARED);
108 if (retval == 0)
109 return retval;
111 au1xxx_stop_ehc(dev);
112 iounmap(hcd->regs);
113 err2:
114 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
115 err1:
116 usb_put_hcd(hcd);
117 return retval;
120 /* may be called without controller electrically present */
121 /* may be called with controller, bus, and devices active */
124 * usb_ehci_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
125 * @dev: USB Host Controller being removed
126 * Context: !in_interrupt()
128 * Reverses the effect of usb_ehci_hcd_au1xxx_probe(), first invoking
129 * the HCD's stop() method. It is always called from a thread
130 * context, normally "rmmod", "apmd", or something similar.
133 void usb_ehci_moxaart_remove(struct usb_hcd *hcd, struct platform_device *dev)
135 usb_remove_hcd(hcd);
136 iounmap(hcd->regs);
137 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
138 usb_put_hcd(hcd);
139 moxaart_stop_ehc(dev);
142 /*-------------------------------------------------------------------------*/
144 static const struct hc_driver ehci_moxaart_hc_driver = {
145 .description = hcd_name,
146 .product_desc = "MoxaART EHCI",
147 .hcd_priv_size = sizeof(struct ehci_hcd),
150 * generic hardware linkage
152 .irq = ehci_irq,
153 .flags = HCD_MEMORY | HCD_USB2,
156 * basic lifecycle operations
158 .reset = ehci_init,
159 .start = ehci_run,
160 .stop = ehci_stop,
161 .shutdown = ehci_shutdown,
164 * managing i/o requests and associated device resources
166 .urb_enqueue = ehci_urb_enqueue,
167 .urb_dequeue = ehci_urb_dequeue,
168 .endpoint_disable = ehci_endpoint_disable,
171 * scheduling support
173 .get_frame_number = ehci_get_frame,
176 * root hub support
178 .hub_status_data = ehci_hub_status_data,
179 .hub_control = ehci_hub_control,
180 #ifdef CONFIG_PM
181 .hub_suspend = ehci_hub_suspend,
182 .hub_resume = ehci_hub_resume,
183 #endif
186 /*-------------------------------------------------------------------------*/
188 static int ehci_hcd_moxaart_drv_probe(struct platform_device *pdev)
190 struct usb_hcd *hcd = NULL;
191 int ret;
193 pr_debug("In ehci_hcd_moxaart_drv_probe\n");
195 if (usb_disabled())
196 return -ENODEV;
198 ret = usb_ehci_moxaart_probe(&ehci_moxaart_hc_driver, &hcd, pdev);
199 return ret;
202 static int ehci_hcd_moxaart_drv_remove(struct platform_device *pdev)
204 struct usb_hcd *hcd = platform_get_drvdata(pdev);
206 usb_ehci_moxaart_remove(hcd, pdev);
207 return 0;
210 /*TBD*/
211 /*static int ehci_hcd_moxaart_drv_suspend(struct device *dev)
213 struct platform_device *pdev = to_platform_device(dev);
214 struct usb_hcd *hcd = dev_get_drvdata(dev);
216 return 0;
218 static int ehci_hcd_moxaart_drv_resume(struct device *dev)
220 struct platform_device *pdev = to_platform_device(dev);
221 struct usb_hcd *hcd = dev_get_drvdata(dev);
223 return 0;
226 MODULE_ALIAS("moxaart-ehci");
227 static struct platform_driver ehci_hcd_moxaart_driver = {
228 .probe = ehci_hcd_moxaart_drv_probe,
229 .remove = ehci_hcd_moxaart_drv_remove,
230 .shutdown = usb_hcd_platform_shutdown,
231 /*.suspend = ehci_hcd_moxaart_drv_suspend, */
232 /*.resume = ehci_hcd_moxaart_drv_resume, */
233 .driver = {
234 .name = "moxaart-ehci",
235 .bus = &platform_bus_type