2 * EHCI HCD (Host Controller Driver) for USB.
6 * 08-03-2007 Victor Yu. Create it.
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
);
27 /* enable host controller */
28 au_writel(USBH_ENABLE_CE
| au_readl(USB_HOST_CONFIG
), USB_HOST_CONFIG
);
29 au_readl(USB_HOST_CONFIG
);
31 au_writel(USBH_ENABLE_INIT
| au_readl(USB_HOST_CONFIG
),
33 au_readl(USB_HOST_CONFIG
);
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");
44 au_writel(~USBH_DISABLE
& au_readl(USB_HOST_CONFIG
), USB_HOST_CONFIG
);
47 au_writel(~USB_MCFG_EHCCLKEN
& au_readl(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 */
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
)
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");
79 hcd
= usb_create_hcd(driver
, &dev
->dev
, "MoxaART");
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");
91 hcd
->regs
= ioremap(hcd
->rsrc_start
, hcd
->rsrc_len
);
93 pr_debug("ioremap failed");
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)); */
107 usb_add_hcd(hcd
, dev
->resource
[1].start
, IRQF_DISABLED
| IRQF_SHARED
);
111 au1xxx_stop_ehc(dev
);
114 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
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
)
137 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
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
153 .flags
= HCD_MEMORY
| HCD_USB2
,
156 * basic lifecycle operations
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
,
173 .get_frame_number
= ehci_get_frame
,
178 .hub_status_data
= ehci_hub_status_data
,
179 .hub_control
= ehci_hub_control
,
181 .hub_suspend
= ehci_hub_suspend
,
182 .hub_resume
= ehci_hub_resume
,
186 /*-------------------------------------------------------------------------*/
188 static int ehci_hcd_moxaart_drv_probe(struct platform_device
*pdev
)
190 struct usb_hcd
*hcd
= NULL
;
193 pr_debug("In ehci_hcd_moxaart_drv_probe\n");
198 ret
= usb_ehci_moxaart_probe(&ehci_moxaart_hc_driver
, &hcd
, pdev
);
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
);
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);
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);
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, */
234 .name
= "moxaart-ehci",
235 .bus
= &platform_bus_type