2 * OHCI HCD (Host Controller Driver) for USB.
4 * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
5 * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
6 * (C) Copyright 2002 Hewlett-Packard Company
10 * Written by Christopher Hoover <ch@hpl.hp.com>
11 * Based on fragments of previous driver by Russell King et al.
13 * Modified for LH7A404 from ohci-sa1111.c
14 * by Durgesh Pattamatta <pattamattad@sharpsec.com>
16 * Modified for pxa27x from ohci-lh7a404.c
17 * by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
19 * This file is licenced under the GPL.
22 #include <linux/device.h>
23 #include <linux/signal.h>
24 #include <linux/platform_device.h>
26 #include <asm/mach-types.h>
27 #include <asm/hardware.h>
28 #include <asm/arch/pxa-regs.h>
29 #include <asm/arch/ohci.h>
31 #define PXA_UHC_MAX_PORTNUM 3
33 #define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 )
36 PMM_NPS_MODE -- PMM Non-power switching mode
37 Ports are powered continuously.
39 PMM_GLOBAL_MODE -- PMM global switching mode
40 All ports are powered at the same time.
42 PMM_PERPORT_MODE -- PMM per port switching mode
43 Ports are powered individually.
45 static int pxa27x_ohci_select_pmm( int mode
)
52 UHCRHDA
&= ~(RH_A_NPS
& RH_A_PSM
);
54 case PMM_PERPORT_MODE
:
55 UHCRHDA
&= ~(RH_A_NPS
);
58 /* Set port power control mask bits, only 3 ports. */
63 "Invalid mode %d, set to non-power switch mode.\n",
72 extern int usb_disabled(void);
74 /*-------------------------------------------------------------------------*/
76 static int pxa27x_start_hc(struct device
*dev
)
79 struct pxaohci_platform_data
*inf
;
81 inf
= dev
->platform_data
;
83 pxa_set_cken(CKEN10_USBHOST
, 1);
90 while (UHCHR
& UHCHR_FSBIR
)
94 retval
= inf
->init(dev
);
101 UHCHIE
= (UHCHIE_UPRIE
| UHCHIE_RWIE
);
103 /* Clear any OTG Pin Hold */
104 if (PSSR
& PSSR_OTGPH
)
110 static void pxa27x_stop_hc(struct device
*dev
)
112 struct pxaohci_platform_data
*inf
;
114 inf
= dev
->platform_data
;
126 pxa_set_cken(CKEN10_USBHOST
, 0);
130 /*-------------------------------------------------------------------------*/
132 /* configure so an HC device and id are always provided */
133 /* always called with process context; sleeping is OK */
137 * usb_hcd_pxa27x_probe - initialize pxa27x-based HCDs
138 * Context: !in_interrupt()
140 * Allocates basic resources for this USB host controller, and
141 * then invokes the start() method for the HCD associated with it
142 * through the hotplug entry's driver_data.
145 int usb_hcd_pxa27x_probe (const struct hc_driver
*driver
, struct platform_device
*pdev
)
149 struct pxaohci_platform_data
*inf
;
151 inf
= pdev
->dev
.platform_data
;
156 if (pdev
->resource
[1].flags
!= IORESOURCE_IRQ
) {
157 pr_debug ("resource[1] is not IORESOURCE_IRQ");
161 hcd
= usb_create_hcd (driver
, &pdev
->dev
, "pxa27x");
164 hcd
->rsrc_start
= pdev
->resource
[0].start
;
165 hcd
->rsrc_len
= pdev
->resource
[0].end
- pdev
->resource
[0].start
+ 1;
167 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
, hcd_name
)) {
168 pr_debug("request_mem_region failed");
173 hcd
->regs
= ioremap(hcd
->rsrc_start
, hcd
->rsrc_len
);
175 pr_debug("ioremap failed");
180 if ((retval
= pxa27x_start_hc(&pdev
->dev
)) < 0) {
181 pr_debug("pxa27x_start_hc failed");
185 /* Select Power Management Mode */
186 pxa27x_ohci_select_pmm(inf
->port_mode
);
188 ohci_hcd_init(hcd_to_ohci(hcd
));
190 retval
= usb_add_hcd(hcd
, pdev
->resource
[1].start
, SA_INTERRUPT
);
194 pxa27x_stop_hc(&pdev
->dev
);
198 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
205 /* may be called without controller electrically present */
206 /* may be called with controller, bus, and devices active */
209 * usb_hcd_pxa27x_remove - shutdown processing for pxa27x-based HCDs
210 * @dev: USB Host Controller being removed
211 * Context: !in_interrupt()
213 * Reverses the effect of usb_hcd_pxa27x_probe(), first invoking
214 * the HCD's stop() method. It is always called from a thread
215 * context, normally "rmmod", "apmd", or something similar.
218 void usb_hcd_pxa27x_remove (struct usb_hcd
*hcd
, struct platform_device
*pdev
)
221 pxa27x_stop_hc(&pdev
->dev
);
223 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
227 /*-------------------------------------------------------------------------*/
230 ohci_pxa27x_start (struct usb_hcd
*hcd
)
232 struct ohci_hcd
*ohci
= hcd_to_ohci (hcd
);
235 ohci_dbg (ohci
, "ohci_pxa27x_start, ohci:%p", ohci
);
237 /* The value of NDP in roothub_a is incorrect on this hardware */
240 if ((ret
= ohci_init(ohci
)) < 0)
243 if ((ret
= ohci_run (ohci
)) < 0) {
244 err ("can't start %s", hcd
->self
.bus_name
);
252 /*-------------------------------------------------------------------------*/
254 static const struct hc_driver ohci_pxa27x_hc_driver
= {
255 .description
= hcd_name
,
256 .product_desc
= "PXA27x OHCI",
257 .hcd_priv_size
= sizeof(struct ohci_hcd
),
260 * generic hardware linkage
263 .flags
= HCD_USB11
| HCD_MEMORY
,
266 * basic lifecycle operations
268 .start
= ohci_pxa27x_start
,
272 * managing i/o requests and associated device resources
274 .urb_enqueue
= ohci_urb_enqueue
,
275 .urb_dequeue
= ohci_urb_dequeue
,
276 .endpoint_disable
= ohci_endpoint_disable
,
281 .get_frame_number
= ohci_get_frame
,
286 .hub_status_data
= ohci_hub_status_data
,
287 .hub_control
= ohci_hub_control
,
289 .bus_suspend
= ohci_bus_suspend
,
290 .bus_resume
= ohci_bus_resume
,
292 .start_port_reset
= ohci_start_port_reset
,
295 /*-------------------------------------------------------------------------*/
297 static int ohci_hcd_pxa27x_drv_probe(struct platform_device
*pdev
)
299 pr_debug ("In ohci_hcd_pxa27x_drv_probe");
304 return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver
, pdev
);
307 static int ohci_hcd_pxa27x_drv_remove(struct platform_device
*pdev
)
309 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
311 usb_hcd_pxa27x_remove(hcd
, pdev
);
312 platform_set_drvdata(pdev
, NULL
);
317 static int ohci_hcd_pxa27x_drv_suspend(struct platform_device
*pdev
, pm_message_t state
)
319 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
320 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
322 if (time_before(jiffies
, ohci
->next_statechange
))
324 ohci
->next_statechange
= jiffies
;
326 pxa27x_stop_hc(&pdev
->dev
);
327 hcd
->state
= HC_STATE_SUSPENDED
;
328 pdev
->dev
.power
.power_state
= PMSG_SUSPEND
;
333 static int ohci_hcd_pxa27x_drv_resume(struct platform_device
*pdev
)
335 struct usb_hcd
*hcd
= platform_get_drvdata(pdev
);
336 struct ohci_hcd
*ohci
= hcd_to_ohci(hcd
);
339 if (time_before(jiffies
, ohci
->next_statechange
))
341 ohci
->next_statechange
= jiffies
;
343 if ((status
= pxa27x_start_hc(&pdev
->dev
)) < 0)
346 pdev
->dev
.power
.power_state
= PMSG_ON
;
347 usb_hcd_resume_root_hub(hcd
);
354 static struct platform_driver ohci_hcd_pxa27x_driver
= {
355 .probe
= ohci_hcd_pxa27x_drv_probe
,
356 .remove
= ohci_hcd_pxa27x_drv_remove
,
358 .suspend
= ohci_hcd_pxa27x_drv_suspend
,
359 .resume
= ohci_hcd_pxa27x_drv_resume
,
362 .name
= "pxa27x-ohci",
366 static int __init
ohci_hcd_pxa27x_init (void)
368 pr_debug (DRIVER_INFO
" (pxa27x)");
369 pr_debug ("block sizes: ed %d td %d\n",
370 sizeof (struct ed
), sizeof (struct td
));
372 return platform_driver_register(&ohci_hcd_pxa27x_driver
);
375 static void __exit
ohci_hcd_pxa27x_cleanup (void)
377 platform_driver_unregister(&ohci_hcd_pxa27x_driver
);
380 module_init (ohci_hcd_pxa27x_init
);
381 module_exit (ohci_hcd_pxa27x_cleanup
);