aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-pxa27x.c
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2005-11-12 09:22:11 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-04 16:48:28 -0500
commit81f280e22f14d6d976620acaa1b346a90f4e1adc (patch)
tree298db1ef614489451fecdd35439c630c8086a368 /drivers/usb/host/ohci-pxa27x.c
parent88026842b0a760145aa71d69e74fbc9ec118ca44 (diff)
[PATCH] USB: pxa27x OHCI - Separate platform code from main driver
To allow multiple platforms to use the PXA27x OHCI driver, the platform code needs to be moved into the board specific files in arch/arm/mach-pxa. This patch does this for mainstone and adds preliminary hooks to allow other boards to use the driver. This has been compile tested for mainstone and successfully run on Spitz (Sharp Zaurus SL-C3000) with the addition of an appropriate board support file. Signed-off-by: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Nicolas Pitre <nico@cam.org> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-pxa27x.c')
-rw-r--r--drivers/usb/host/ohci-pxa27x.c85
1 files changed, 43 insertions, 42 deletions
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 9d65ec30799..c165d1ebed5 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -26,18 +26,12 @@
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <asm/hardware.h> 27#include <asm/hardware.h>
28#include <asm/arch/pxa-regs.h> 28#include <asm/arch/pxa-regs.h>
29 29#include <asm/arch/ohci.h>
30
31#define PMM_NPS_MODE 1
32#define PMM_GLOBAL_MODE 2
33#define PMM_PERPORT_MODE 3
34 30
35#define PXA_UHC_MAX_PORTNUM 3 31#define PXA_UHC_MAX_PORTNUM 3
36 32
37#define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 ) 33#define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 )
38 34
39static int pxa27x_ohci_pmm_state;
40
41/* 35/*
42 PMM_NPS_MODE -- PMM Non-power switching mode 36 PMM_NPS_MODE -- PMM Non-power switching mode
43 Ports are powered continuously. 37 Ports are powered continuously.
@@ -50,8 +44,6 @@ static int pxa27x_ohci_pmm_state;
50 */ 44 */
51static int pxa27x_ohci_select_pmm( int mode ) 45static int pxa27x_ohci_select_pmm( int mode )
52{ 46{
53 pxa27x_ohci_pmm_state = mode;
54
55 switch ( mode ) { 47 switch ( mode ) {
56 case PMM_NPS_MODE: 48 case PMM_NPS_MODE:
57 UHCRHDA |= RH_A_NPS; 49 UHCRHDA |= RH_A_NPS;
@@ -71,7 +63,6 @@ static int pxa27x_ohci_select_pmm( int mode )
71 "Invalid mode %d, set to non-power switch mode.\n", 63 "Invalid mode %d, set to non-power switch mode.\n",
72 mode ); 64 mode );
73 65
74 pxa27x_ohci_pmm_state = PMM_NPS_MODE;
75 UHCRHDA |= RH_A_NPS; 66 UHCRHDA |= RH_A_NPS;
76 } 67 }
77 68
@@ -82,8 +73,13 @@ extern int usb_disabled(void);
82 73
83/*-------------------------------------------------------------------------*/ 74/*-------------------------------------------------------------------------*/
84 75
85static void pxa27x_start_hc(struct platform_device *dev) 76static int pxa27x_start_hc(struct device *dev)
86{ 77{
78 int retval = 0;
79 struct pxaohci_platform_data *inf;
80
81 inf = dev->platform_data;
82
87 pxa_set_cken(CKEN10_USBHOST, 1); 83 pxa_set_cken(CKEN10_USBHOST, 1);
88 84
89 UHCHR |= UHCHR_FHR; 85 UHCHR |= UHCHR_FHR;
@@ -94,21 +90,11 @@ static void pxa27x_start_hc(struct platform_device *dev)
94 while (UHCHR & UHCHR_FSBIR) 90 while (UHCHR & UHCHR_FSBIR)
95 cpu_relax(); 91 cpu_relax();
96 92
97 /* This could be properly abstracted away through the 93 if (inf->init)
98 device data the day more machines are supported and 94 retval = inf->init(dev);
99 their differences can be figured out correctly. */
100 if (machine_is_mainstone()) {
101 /* setup Port1 GPIO pin. */
102 pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
103 pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
104
105 /* Set the Power Control Polarity Low and Power Sense
106 Polarity Low to active low. Supply power to USB ports. */
107 UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
108 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
109 95
110 pxa27x_ohci_pmm_state = PMM_PERPORT_MODE; 96 if (retval < 0)
111 } 97 return retval;
112 98
113 UHCHR &= ~UHCHR_SSE; 99 UHCHR &= ~UHCHR_SSE;
114 100
@@ -117,10 +103,19 @@ static void pxa27x_start_hc(struct platform_device *dev)
117 /* Clear any OTG Pin Hold */ 103 /* Clear any OTG Pin Hold */
118 if (PSSR & PSSR_OTGPH) 104 if (PSSR & PSSR_OTGPH)
119 PSSR |= PSSR_OTGPH; 105 PSSR |= PSSR_OTGPH;
106
107 return 0;
120} 108}
121 109
122static void pxa27x_stop_hc(struct platform_device *dev) 110static void pxa27x_stop_hc(struct device *dev)
123{ 111{
112 struct pxaohci_platform_data *inf;
113
114 inf = dev->platform_data;
115
116 if (inf->exit)
117 inf->exit(dev);
118
124 UHCHR |= UHCHR_FHR; 119 UHCHR |= UHCHR_FHR;
125 udelay(11); 120 udelay(11);
126 UHCHR &= ~UHCHR_FHR; 121 UHCHR &= ~UHCHR_FHR;
@@ -147,22 +142,27 @@ static void pxa27x_stop_hc(struct platform_device *dev)
147 * through the hotplug entry's driver_data. 142 * through the hotplug entry's driver_data.
148 * 143 *
149 */ 144 */
150int usb_hcd_pxa27x_probe (const struct hc_driver *driver, 145int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
151 struct platform_device *dev)
152{ 146{
153 int retval; 147 int retval;
154 struct usb_hcd *hcd; 148 struct usb_hcd *hcd;
149 struct pxaohci_platform_data *inf;
150
151 inf = pdev->dev.platform_data;
155 152
156 if (dev->resource[1].flags != IORESOURCE_IRQ) { 153 if (!inf)
154 return -ENODEV;
155
156 if (pdev->resource[1].flags != IORESOURCE_IRQ) {
157 pr_debug ("resource[1] is not IORESOURCE_IRQ"); 157 pr_debug ("resource[1] is not IORESOURCE_IRQ");
158 return -ENOMEM; 158 return -ENOMEM;
159 } 159 }
160 160
161 hcd = usb_create_hcd (driver, &dev->dev, "pxa27x"); 161 hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
162 if (!hcd) 162 if (!hcd)
163 return -ENOMEM; 163 return -ENOMEM;
164 hcd->rsrc_start = dev->resource[0].start; 164 hcd->rsrc_start = pdev->resource[0].start;
165 hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; 165 hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
166 166
167 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { 167 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
168 pr_debug("request_mem_region failed"); 168 pr_debug("request_mem_region failed");
@@ -177,18 +177,22 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
177 goto err2; 177 goto err2;
178 } 178 }
179 179
180 pxa27x_start_hc(dev); 180 if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
181 pr_debug("pxa27x_start_hc failed");
182 goto err3;
183 }
181 184
182 /* Select Power Management Mode */ 185 /* Select Power Management Mode */
183 pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state); 186 pxa27x_ohci_select_pmm(inf->port_mode);
184 187
185 ohci_hcd_init(hcd_to_ohci(hcd)); 188 ohci_hcd_init(hcd_to_ohci(hcd));
186 189
187 retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); 190 retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
188 if (retval == 0) 191 if (retval == 0)
189 return retval; 192 return retval;
190 193
191 pxa27x_stop_hc(dev); 194 pxa27x_stop_hc(&pdev->dev);
195 err3:
192 iounmap(hcd->regs); 196 iounmap(hcd->regs);
193 err2: 197 err2:
194 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 198 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -211,10 +215,10 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
211 * context, normally "rmmod", "apmd", or something similar. 215 * context, normally "rmmod", "apmd", or something similar.
212 * 216 *
213 */ 217 */
214void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev) 218void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
215{ 219{
216 usb_remove_hcd(hcd); 220 usb_remove_hcd(hcd);
217 pxa27x_stop_hc(dev); 221 pxa27x_stop_hc(&pdev->dev);
218 iounmap(hcd->regs); 222 iounmap(hcd->regs);
219 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 223 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
220 usb_put_hcd(hcd); 224 usb_put_hcd(hcd);
@@ -292,15 +296,12 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
292 296
293static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) 297static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
294{ 298{
295 int ret;
296
297 pr_debug ("In ohci_hcd_pxa27x_drv_probe"); 299 pr_debug ("In ohci_hcd_pxa27x_drv_probe");
298 300
299 if (usb_disabled()) 301 if (usb_disabled())
300 return -ENODEV; 302 return -ENODEV;
301 303
302 ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev); 304 return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
303 return ret;
304} 305}
305 306
306static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) 307static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)