aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2008-09-27 03:49:57 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-07 14:12:57 -0400
commit097b53348f34a461d2b07081eae12d823cf3d729 (patch)
tree62f59bdfc0252346666158b6c236fc250850cb36
parent52358ba3a89012c54712c24074ceb4b1c669af52 (diff)
[ARM] ohci-pxa27x: introduce flags to avoid direct access to OHCI registers
Direct access to USB host controller registers is considered to be not portable, and is usually a bad sign for poorly abstracted interface. Introduce .flags and .power_on_delay to "struct pxaohci_platform_data" so that most platforms don't bother to write their own .init/.exit() sequences. Signed-off-by: Eric Miao <eric.miao@marvell.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-pxa/cm-x270.c11
-rw-r--r--arch/arm/mach-pxa/cm-x300.c12
-rw-r--r--arch/arm/mach-pxa/em-x270.c5
-rw-r--r--arch/arm/mach-pxa/include/mach/ohci.h16
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa-regs.h3
-rw-r--r--arch/arm/mach-pxa/lpd270.c12
-rw-r--r--arch/arm/mach-pxa/magician.c14
-rw-r--r--arch/arm/mach-pxa/mainstone.c12
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c30
-rw-r--r--arch/arm/mach-pxa/spitz.c10
-rw-r--r--arch/arm/mach-pxa/trizeps4.c12
-rw-r--r--drivers/usb/host/ohci-pxa27x.c37
12 files changed, 70 insertions, 104 deletions
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 102a43186618..a82dad1a8cc8 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -257,18 +257,9 @@ static inline void cmx270_init_2700G(void) {}
257 257
258/* PXA27x OHCI controller setup */ 258/* PXA27x OHCI controller setup */
259#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 259#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
260static int cmx270_ohci_init(struct device *dev)
261{
262 /* Set the Power Control Polarity Low */
263 UHCHR = (UHCHR | UHCHR_PCPL) &
264 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
265
266 return 0;
267}
268
269static struct pxaohci_platform_data cmx270_ohci_platform_data = { 260static struct pxaohci_platform_data cmx270_ohci_platform_data = {
270 .port_mode = PMM_PERPORT_MODE, 261 .port_mode = PMM_PERPORT_MODE,
271 .init = cmx270_ohci_init, 262 .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
272}; 263};
273 264
274static void __init cmx270_init_ohci(void) 265static void __init cmx270_init_ohci(void)
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 7bc5679b41ba..deb46cd144bf 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -365,19 +365,11 @@ static inline void cm_x300_init_mmc(void) {}
365#endif 365#endif
366 366
367#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 367#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
368static int cm_x300_ohci_init(struct device *dev)
369{
370 /* Set the Power Control Polarity Low */
371 UHCHR = (UHCHR | UHCHR_PCPL) &
372 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
373
374 return 0;
375}
376
377static struct pxaohci_platform_data cm_x300_ohci_platform_data = { 368static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
378 .port_mode = PMM_PERPORT_MODE, 369 .port_mode = PMM_PERPORT_MODE,
379 .init = cm_x300_ohci_init, 370 .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
380}; 371};
372
381static void __init cm_x300_init_ohci(void) 373static void __init cm_x300_init_ohci(void)
382{ 374{
383 pxa_set_ohci_info(&cm_x300_ohci_platform_data); 375 pxa_set_ohci_info(&cm_x300_ohci_platform_data);
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 7a0a681a5847..f5ed8038ede5 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -373,10 +373,6 @@ static inline void em_x270_init_nand(void) {}
373#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 373#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
374static int em_x270_ohci_init(struct device *dev) 374static int em_x270_ohci_init(struct device *dev)
375{ 375{
376 /* Set the Power Control Polarity Low */
377 UHCHR = (UHCHR | UHCHR_PCPL) &
378 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
379
380 /* enable port 2 transiever */ 376 /* enable port 2 transiever */
381 UP2OCR = UP2OCR_HXS | UP2OCR_HXOE; 377 UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
382 378
@@ -385,6 +381,7 @@ static int em_x270_ohci_init(struct device *dev)
385 381
386static struct pxaohci_platform_data em_x270_ohci_platform_data = { 382static struct pxaohci_platform_data em_x270_ohci_platform_data = {
387 .port_mode = PMM_PERPORT_MODE, 383 .port_mode = PMM_PERPORT_MODE,
384 .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
388 .init = em_x270_ohci_init, 385 .init = em_x270_ohci_init,
389}; 386};
390 387
diff --git a/arch/arm/mach-pxa/include/mach/ohci.h b/arch/arm/mach-pxa/include/mach/ohci.h
index e848a47128cd..95b6e2a6e514 100644
--- a/arch/arm/mach-pxa/include/mach/ohci.h
+++ b/arch/arm/mach-pxa/include/mach/ohci.h
@@ -7,6 +7,22 @@ struct pxaohci_platform_data {
7 int (*init)(struct device *); 7 int (*init)(struct device *);
8 void (*exit)(struct device *); 8 void (*exit)(struct device *);
9 9
10 unsigned long flags;
11#define ENABLE_PORT1 (1 << 0)
12#define ENABLE_PORT2 (1 << 1)
13#define ENABLE_PORT3 (1 << 2)
14#define ENABLE_PORT_ALL (ENABLE_PORT1 | ENABLE_PORT2 | ENABLE_PORT3)
15
16#define POWER_SENSE_LOW (1 << 3)
17#define POWER_CONTROL_LOW (1 << 4)
18#define NO_OC_PROTECTION (1 << 5)
19#define OC_MODE_GLOBAL (0 << 6)
20#define OC_MODE_PERPORT (1 << 6)
21
22 int power_on_delay; /* Power On to Power Good time - in ms
23 * HCD must wait for this duration before
24 * accessing a powered on port
25 */
10 int port_mode; 26 int port_mode;
11#define PMM_NPS_MODE 1 27#define PMM_NPS_MODE 1
12#define PMM_GLOBAL_MODE 2 28#define PMM_GLOBAL_MODE 2
diff --git a/arch/arm/mach-pxa/include/mach/pxa-regs.h b/arch/arm/mach-pxa/include/mach/pxa-regs.h
index 98ded450d0fe..b34e8a735391 100644
--- a/arch/arm/mach-pxa/include/mach/pxa-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa-regs.h
@@ -784,6 +784,9 @@
784 784
785#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */ 785#define UHCRHDA __REG(0x4C000048) /* UHC Root Hub Descriptor A */
786#define UHCRHDA_NOCP (1 << 12) /* No over current protection */ 786#define UHCRHDA_NOCP (1 << 12) /* No over current protection */
787#define UHCRHDA_OCPM (1 << 11) /* Over Current Protection Mode */
788#define UHCRHDA_POTPGT(x) \
789 (((x) & 0xff) << 24) /* Power On To Power Good Time */
787 790
788#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */ 791#define UHCRHDB __REG(0x4C00004C) /* UHC Root Hub Descriptor B */
789#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */ 792#define UHCRHS __REG(0x4C000050) /* UHC Root Hub Status */
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 7b158e5248ad..92728a37298a 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -448,19 +448,9 @@ static struct platform_device *platform_devices[] __initdata = {
448 &lpd270_flash_device[1], 448 &lpd270_flash_device[1],
449}; 449};
450 450
451static int lpd270_ohci_init(struct device *dev)
452{
453 /* Set the Power Control Polarity Low and Power Sense
454 Polarity Low to active low. */
455 UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
456 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
457
458 return 0;
459}
460
461static struct pxaohci_platform_data lpd270_ohci_platform_data = { 451static struct pxaohci_platform_data lpd270_ohci_platform_data = {
462 .port_mode = PMM_PERPORT_MODE, 452 .port_mode = PMM_PERPORT_MODE,
463 .init = lpd270_ohci_init, 453 .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
464}; 454};
465 455
466static void __init lpd270_init(void) 456static void __init lpd270_init(void)
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 8ebdac7e9a13..519138bc5f85 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -669,18 +669,10 @@ static struct pxamci_platform_data magician_mci_info = {
669 * USB OHCI 669 * USB OHCI
670 */ 670 */
671 671
672static int magician_ohci_init(struct device *dev)
673{
674 UHCHR = (UHCHR | UHCHR_SSEP2 | UHCHR_PCPL | UHCHR_CGR) &
675 ~(UHCHR_SSEP1 | UHCHR_SSEP3 | UHCHR_SSE);
676
677 return 0;
678}
679
680static struct pxaohci_platform_data magician_ohci_info = { 672static struct pxaohci_platform_data magician_ohci_info = {
681 .port_mode = PMM_PERPORT_MODE, 673 .port_mode = PMM_PERPORT_MODE,
682 .init = magician_ohci_init, 674 .flags = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
683 .power_budget = 0, 675 .power_budget = 0,
684}; 676};
685 677
686 678
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index d44af761564d..a02edfd4fc0a 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -508,19 +508,9 @@ static struct platform_device *platform_devices[] __initdata = {
508 &mst_gpio_keys_device, 508 &mst_gpio_keys_device,
509}; 509};
510 510
511static int mainstone_ohci_init(struct device *dev)
512{
513 /* Set the Power Control Polarity Low and Power Sense
514 Polarity Low to active low. */
515 UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
516 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
517
518 return 0;
519}
520
521static struct pxaohci_platform_data mainstone_ohci_platform_data = { 511static struct pxaohci_platform_data mainstone_ohci_platform_data = {
522 .port_mode = PMM_PERPORT_MODE, 512 .port_mode = PMM_PERPORT_MODE,
523 .init = mainstone_ohci_init, 513 .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
524}; 514};
525 515
526#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE) 516#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 420c9b3813f6..e9efb80bb339 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -328,36 +328,10 @@ static struct pxamci_platform_data pcm990_mci_platform_data = {
328 .exit = pcm990_mci_exit, 328 .exit = pcm990_mci_exit,
329}; 329};
330 330
331/*
332 * init OHCI hardware to work with
333 *
334 * Note: Only USB port 1 (host only) is connected
335 *
336 * GPIO88 (USBHPWR#1): overcurrent in, overcurrent when low
337 * GPIO89 (USBHPEN#1): power-on out, on when low
338 */
339static int pcm990_ohci_init(struct device *dev)
340{
341 /*
342 * disable USB port 2 and 3
343 * power sense is active low
344 */
345 UHCHR = ((UHCHR) | UHCHR_PCPL | UHCHR_PSPL | UHCHR_SSEP2 |
346 UHCHR_SSEP3) & ~(UHCHR_SSEP1 | UHCHR_SSE);
347 /*
348 * wait 10ms after Power on
349 * overcurrent per port
350 * power switch per port
351 */
352 UHCRHDA = (5<<24) | (1<<11) | (1<<8); /* FIXME: Required? */
353
354 return 0;
355}
356
357static struct pxaohci_platform_data pcm990_ohci_platform_data = { 331static struct pxaohci_platform_data pcm990_ohci_platform_data = {
358 .port_mode = PMM_PERPORT_MODE, 332 .port_mode = PMM_PERPORT_MODE,
359 .init = pcm990_ohci_init, 333 .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
360 .exit = NULL, 334 .power_on_delay = 10,
361}; 335};
362 336
363/* 337/*
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 245890d2b6b5..7ef346182371 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -495,19 +495,13 @@ static int spitz_ohci_init(struct device *dev)
495 */ 495 */
496 UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; 496 UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
497 497
498 gpio_direction_output(SPITZ_GPIO_USB_HOST, 1); 498 return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
499
500 UHCHR = (UHCHR) &
501 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
502
503 UHCRHDA |= UHCRHDA_NOCP;
504
505 return 0;
506} 499}
507 500
508static struct pxaohci_platform_data spitz_ohci_platform_data = { 501static struct pxaohci_platform_data spitz_ohci_platform_data = {
509 .port_mode = PMM_NPS_MODE, 502 .port_mode = PMM_NPS_MODE,
510 .init = spitz_ohci_init, 503 .init = spitz_ohci_init,
504 .flags = ENABLE_PORT_ALL | NO_OC_PROTECTION,
511 .power_budget = 150, 505 .power_budget = 150,
512}; 506};
513 507
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 75ff8f4243f1..a13dbf3c2c05 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -425,19 +425,9 @@ static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
425/**************************************************************************** 425/****************************************************************************
426 * OHCI USB port 426 * OHCI USB port
427 ****************************************************************************/ 427 ****************************************************************************/
428static int trizeps4_ohci_init(struct device *dev)
429{
430 /* Set the Power Control Polarity Low and Power Sense
431 Polarity Low to active low. */
432 UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
433 ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
434
435 return 0;
436}
437
438static struct pxaohci_platform_data trizeps4_ohci_platform_data = { 428static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
439 .port_mode = PMM_PERPORT_MODE, 429 .port_mode = PMM_PERPORT_MODE,
440 .init = trizeps4_ohci_init, 430 .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
441}; 431};
442 432
443static struct map_desc trizeps4_io_desc[] __initdata = { 433static struct map_desc trizeps4_io_desc[] __initdata = {
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 7f0f35c78185..2a7d5e0965d7 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -76,6 +76,41 @@ extern int usb_disabled(void);
76 76
77/*-------------------------------------------------------------------------*/ 77/*-------------------------------------------------------------------------*/
78 78
79static inline void pxa27x_setup_hc(struct pxaohci_platform_data *inf)
80{
81 uint32_t uhchr = UHCHR;
82 uint32_t uhcrhda = UHCRHDA;
83
84 if (inf->flags & ENABLE_PORT1)
85 uhchr &= ~UHCHR_SSEP1;
86
87 if (inf->flags & ENABLE_PORT2)
88 uhchr &= ~UHCHR_SSEP2;
89
90 if (inf->flags & ENABLE_PORT3)
91 uhchr &= ~UHCHR_SSEP3;
92
93 if (inf->flags & POWER_CONTROL_LOW)
94 uhchr |= UHCHR_PCPL;
95
96 if (inf->flags & POWER_SENSE_LOW)
97 uhchr |= UHCHR_PSPL;
98
99 if (inf->flags & NO_OC_PROTECTION)
100 uhcrhda |= UHCRHDA_NOCP;
101
102 if (inf->flags & OC_MODE_PERPORT)
103 uhcrhda |= UHCRHDA_OCPM;
104
105 if (inf->power_on_delay) {
106 uhcrhda &= ~UHCRHDA_POTPGT(0xff);
107 uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
108 }
109
110 UHCHR = uhchr;
111 UHCRHDA = uhcrhda;
112}
113
79static int pxa27x_start_hc(struct device *dev) 114static int pxa27x_start_hc(struct device *dev)
80{ 115{
81 int retval = 0; 116 int retval = 0;
@@ -93,6 +128,8 @@ static int pxa27x_start_hc(struct device *dev)
93 while (UHCHR & UHCHR_FSBIR) 128 while (UHCHR & UHCHR_FSBIR)
94 cpu_relax(); 129 cpu_relax();
95 130
131 pxa27x_setup_hc(inf);
132
96 if (inf->init) 133 if (inf->init)
97 retval = inf->init(dev); 134 retval = inf->init(dev);
98 135