aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hub.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-12-14 14:54:08 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:32 -0500
commit083522d76662cda71328df1f3d75e5a9057c7c9f (patch)
treeeafbb962ec90431d0c1b490b4caea7cf9b54672c /drivers/usb/host/ehci-hub.c
parent11d1a4aa8d657478cb2e5d33f203ba8f01b9ac24 (diff)
USB: Implement support for EHCI with big endian MMIO
This patch implements supports for EHCI controllers whose MMIO registers are big endian and enables that functionality for the Toshiba SCC chip. It does _not_ add support for big endian in-memory data structures as this is not needed for that chip and I hope it will never be. The guts of the patch are to convert readl(...) to ehci_readl(ehci, ...) and similarly for register writes. Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Geoff Levand <geoffrey.levand@am.sony.com> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r--drivers/usb/host/ehci-hub.c118
1 files changed, 63 insertions, 55 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index bfe5f307cba6..df00fcbadfbc 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -47,7 +47,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
47 ehci_quiesce (ehci); 47 ehci_quiesce (ehci);
48 hcd->state = HC_STATE_QUIESCING; 48 hcd->state = HC_STATE_QUIESCING;
49 } 49 }
50 ehci->command = readl (&ehci->regs->command); 50 ehci->command = ehci_readl(ehci, &ehci->regs->command);
51 if (ehci->reclaim) 51 if (ehci->reclaim)
52 ehci->reclaim_ready = 1; 52 ehci->reclaim_ready = 1;
53 ehci_work(ehci); 53 ehci_work(ehci);
@@ -60,7 +60,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
60 ehci->bus_suspended = 0; 60 ehci->bus_suspended = 0;
61 while (port--) { 61 while (port--) {
62 u32 __iomem *reg = &ehci->regs->port_status [port]; 62 u32 __iomem *reg = &ehci->regs->port_status [port];
63 u32 t1 = readl (reg) & ~PORT_RWC_BITS; 63 u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
64 u32 t2 = t1; 64 u32 t2 = t1;
65 65
66 /* keep track of which ports we suspend */ 66 /* keep track of which ports we suspend */
@@ -79,7 +79,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
79 if (t1 != t2) { 79 if (t1 != t2) {
80 ehci_vdbg (ehci, "port %d, %08x -> %08x\n", 80 ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
81 port + 1, t1, t2); 81 port + 1, t1, t2);
82 writel (t2, reg); 82 ehci_writel(ehci, t2, reg);
83 } 83 }
84 } 84 }
85 85
@@ -92,8 +92,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
92 mask = INTR_MASK; 92 mask = INTR_MASK;
93 if (!device_may_wakeup(&hcd->self.root_hub->dev)) 93 if (!device_may_wakeup(&hcd->self.root_hub->dev))
94 mask &= ~STS_PCD; 94 mask &= ~STS_PCD;
95 writel(mask, &ehci->regs->intr_enable); 95 ehci_writel(ehci, mask, &ehci->regs->intr_enable);
96 readl(&ehci->regs->intr_enable); 96 ehci_readl(ehci, &ehci->regs->intr_enable);
97 97
98 ehci->next_statechange = jiffies + msecs_to_jiffies(10); 98 ehci->next_statechange = jiffies + msecs_to_jiffies(10);
99 spin_unlock_irq (&ehci->lock); 99 spin_unlock_irq (&ehci->lock);
@@ -118,26 +118,26 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
118 * the last user of the controller, not reset/pm hardware keeping 118 * the last user of the controller, not reset/pm hardware keeping
119 * state we gave to it. 119 * state we gave to it.
120 */ 120 */
121 temp = readl(&ehci->regs->intr_enable); 121 temp = ehci_readl(ehci, &ehci->regs->intr_enable);
122 ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); 122 ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
123 123
124 /* at least some APM implementations will try to deliver 124 /* at least some APM implementations will try to deliver
125 * IRQs right away, so delay them until we're ready. 125 * IRQs right away, so delay them until we're ready.
126 */ 126 */
127 writel(0, &ehci->regs->intr_enable); 127 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
128 128
129 /* re-init operational registers */ 129 /* re-init operational registers */
130 writel(0, &ehci->regs->segment); 130 ehci_writel(ehci, 0, &ehci->regs->segment);
131 writel(ehci->periodic_dma, &ehci->regs->frame_list); 131 ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
132 writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); 132 ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
133 133
134 /* restore CMD_RUN, framelist size, and irq threshold */ 134 /* restore CMD_RUN, framelist size, and irq threshold */
135 writel (ehci->command, &ehci->regs->command); 135 ehci_writel(ehci, ehci->command, &ehci->regs->command);
136 136
137 /* manually resume the ports we suspended during bus_suspend() */ 137 /* manually resume the ports we suspended during bus_suspend() */
138 i = HCS_N_PORTS (ehci->hcs_params); 138 i = HCS_N_PORTS (ehci->hcs_params);
139 while (i--) { 139 while (i--) {
140 temp = readl (&ehci->regs->port_status [i]); 140 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
141 temp &= ~(PORT_RWC_BITS 141 temp &= ~(PORT_RWC_BITS
142 | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); 142 | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
143 if (test_bit(i, &ehci->bus_suspended) && 143 if (test_bit(i, &ehci->bus_suspended) &&
@@ -145,20 +145,20 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
145 ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); 145 ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
146 temp |= PORT_RESUME; 146 temp |= PORT_RESUME;
147 } 147 }
148 writel (temp, &ehci->regs->port_status [i]); 148 ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
149 } 149 }
150 i = HCS_N_PORTS (ehci->hcs_params); 150 i = HCS_N_PORTS (ehci->hcs_params);
151 mdelay (20); 151 mdelay (20);
152 while (i--) { 152 while (i--) {
153 temp = readl (&ehci->regs->port_status [i]); 153 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
154 if (test_bit(i, &ehci->bus_suspended) && 154 if (test_bit(i, &ehci->bus_suspended) &&
155 (temp & PORT_SUSPEND)) { 155 (temp & PORT_SUSPEND)) {
156 temp &= ~(PORT_RWC_BITS | PORT_RESUME); 156 temp &= ~(PORT_RWC_BITS | PORT_RESUME);
157 writel (temp, &ehci->regs->port_status [i]); 157 ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
158 ehci_vdbg (ehci, "resumed port %d\n", i + 1); 158 ehci_vdbg (ehci, "resumed port %d\n", i + 1);
159 } 159 }
160 } 160 }
161 (void) readl (&ehci->regs->command); 161 (void) ehci_readl(ehci, &ehci->regs->command);
162 162
163 /* maybe re-activate the schedule(s) */ 163 /* maybe re-activate the schedule(s) */
164 temp = 0; 164 temp = 0;
@@ -168,14 +168,14 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
168 temp |= CMD_PSE; 168 temp |= CMD_PSE;
169 if (temp) { 169 if (temp) {
170 ehci->command |= temp; 170 ehci->command |= temp;
171 writel (ehci->command, &ehci->regs->command); 171 ehci_writel(ehci, ehci->command, &ehci->regs->command);
172 } 172 }
173 173
174 ehci->next_statechange = jiffies + msecs_to_jiffies(5); 174 ehci->next_statechange = jiffies + msecs_to_jiffies(5);
175 hcd->state = HC_STATE_RUNNING; 175 hcd->state = HC_STATE_RUNNING;
176 176
177 /* Now we can safely re-enable irqs */ 177 /* Now we can safely re-enable irqs */
178 writel(INTR_MASK, &ehci->regs->intr_enable); 178 ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
179 179
180 spin_unlock_irq (&ehci->lock); 180 spin_unlock_irq (&ehci->lock);
181 return 0; 181 return 0;
@@ -217,7 +217,8 @@ static int check_reset_complete (
217 // what happens if HCS_N_CC(params) == 0 ? 217 // what happens if HCS_N_CC(params) == 0 ?
218 port_status |= PORT_OWNER; 218 port_status |= PORT_OWNER;
219 port_status &= ~PORT_RWC_BITS; 219 port_status &= ~PORT_RWC_BITS;
220 writel (port_status, &ehci->regs->port_status [index]); 220 ehci_writel(ehci, port_status,
221 &ehci->regs->port_status [index]);
221 222
222 } else 223 } else
223 ehci_dbg (ehci, "port %d high speed\n", index + 1); 224 ehci_dbg (ehci, "port %d high speed\n", index + 1);
@@ -268,13 +269,14 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
268 /* port N changes (bit N)? */ 269 /* port N changes (bit N)? */
269 spin_lock_irqsave (&ehci->lock, flags); 270 spin_lock_irqsave (&ehci->lock, flags);
270 for (i = 0; i < ports; i++) { 271 for (i = 0; i < ports; i++) {
271 temp = readl (&ehci->regs->port_status [i]); 272 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
272 if (temp & PORT_OWNER) { 273 if (temp & PORT_OWNER) {
273 /* don't report this in GetPortStatus */ 274 /* don't report this in GetPortStatus */
274 if (temp & PORT_CSC) { 275 if (temp & PORT_CSC) {
275 temp &= ~PORT_RWC_BITS; 276 temp &= ~PORT_RWC_BITS;
276 temp |= PORT_CSC; 277 temp |= PORT_CSC;
277 writel (temp, &ehci->regs->port_status [i]); 278 ehci_writel(ehci, temp,
279 &ehci->regs->port_status [i]);
278 } 280 }
279 continue; 281 continue;
280 } 282 }
@@ -373,18 +375,18 @@ static int ehci_hub_control (
373 if (!wIndex || wIndex > ports) 375 if (!wIndex || wIndex > ports)
374 goto error; 376 goto error;
375 wIndex--; 377 wIndex--;
376 temp = readl (&ehci->regs->port_status [wIndex]); 378 temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
377 if (temp & PORT_OWNER) 379 if (temp & PORT_OWNER)
378 break; 380 break;
379 381
380 switch (wValue) { 382 switch (wValue) {
381 case USB_PORT_FEAT_ENABLE: 383 case USB_PORT_FEAT_ENABLE:
382 writel (temp & ~PORT_PE, 384 ehci_writel(ehci, temp & ~PORT_PE,
383 &ehci->regs->port_status [wIndex]); 385 &ehci->regs->port_status [wIndex]);
384 break; 386 break;
385 case USB_PORT_FEAT_C_ENABLE: 387 case USB_PORT_FEAT_C_ENABLE:
386 writel((temp & ~PORT_RWC_BITS) | PORT_PEC, 388 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
387 &ehci->regs->port_status [wIndex]); 389 &ehci->regs->port_status [wIndex]);
388 break; 390 break;
389 case USB_PORT_FEAT_SUSPEND: 391 case USB_PORT_FEAT_SUSPEND:
390 if (temp & PORT_RESET) 392 if (temp & PORT_RESET)
@@ -396,8 +398,8 @@ static int ehci_hub_control (
396 goto error; 398 goto error;
397 /* resume signaling for 20 msec */ 399 /* resume signaling for 20 msec */
398 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); 400 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
399 writel (temp | PORT_RESUME, 401 ehci_writel(ehci, temp | PORT_RESUME,
400 &ehci->regs->port_status [wIndex]); 402 &ehci->regs->port_status [wIndex]);
401 ehci->reset_done [wIndex] = jiffies 403 ehci->reset_done [wIndex] = jiffies
402 + msecs_to_jiffies (20); 404 + msecs_to_jiffies (20);
403 } 405 }
@@ -407,16 +409,17 @@ static int ehci_hub_control (
407 break; 409 break;
408 case USB_PORT_FEAT_POWER: 410 case USB_PORT_FEAT_POWER:
409 if (HCS_PPC (ehci->hcs_params)) 411 if (HCS_PPC (ehci->hcs_params))
410 writel (temp & ~(PORT_RWC_BITS | PORT_POWER), 412 ehci_writel(ehci,
411 &ehci->regs->port_status [wIndex]); 413 temp & ~(PORT_RWC_BITS | PORT_POWER),
414 &ehci->regs->port_status [wIndex]);
412 break; 415 break;
413 case USB_PORT_FEAT_C_CONNECTION: 416 case USB_PORT_FEAT_C_CONNECTION:
414 writel((temp & ~PORT_RWC_BITS) | PORT_CSC, 417 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
415 &ehci->regs->port_status [wIndex]); 418 &ehci->regs->port_status [wIndex]);
416 break; 419 break;
417 case USB_PORT_FEAT_C_OVER_CURRENT: 420 case USB_PORT_FEAT_C_OVER_CURRENT:
418 writel((temp & ~PORT_RWC_BITS) | PORT_OCC, 421 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
419 &ehci->regs->port_status [wIndex]); 422 &ehci->regs->port_status [wIndex]);
420 break; 423 break;
421 case USB_PORT_FEAT_C_RESET: 424 case USB_PORT_FEAT_C_RESET:
422 /* GetPortStatus clears reset */ 425 /* GetPortStatus clears reset */
@@ -424,7 +427,7 @@ static int ehci_hub_control (
424 default: 427 default:
425 goto error; 428 goto error;
426 } 429 }
427 readl (&ehci->regs->command); /* unblock posted write */ 430 ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */
428 break; 431 break;
429 case GetHubDescriptor: 432 case GetHubDescriptor:
430 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) 433 ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
@@ -440,7 +443,7 @@ static int ehci_hub_control (
440 goto error; 443 goto error;
441 wIndex--; 444 wIndex--;
442 status = 0; 445 status = 0;
443 temp = readl (&ehci->regs->port_status [wIndex]); 446 temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
444 447
445 // wPortChange bits 448 // wPortChange bits
446 if (temp & PORT_CSC) 449 if (temp & PORT_CSC)
@@ -458,12 +461,14 @@ static int ehci_hub_control (
458 ehci->reset_done [wIndex] = 0; 461 ehci->reset_done [wIndex] = 0;
459 462
460 /* stop resume signaling */ 463 /* stop resume signaling */
461 temp = readl (&ehci->regs->port_status [wIndex]); 464 temp = ehci_readl(ehci,
462 writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), 465 &ehci->regs->port_status [wIndex]);
463 &ehci->regs->port_status [wIndex]); 466 ehci_writel(ehci,
464 retval = handshake ( 467 temp & ~(PORT_RWC_BITS | PORT_RESUME),
465 &ehci->regs->port_status [wIndex], 468 &ehci->regs->port_status [wIndex]);
466 PORT_RESUME, 0, 2000 /* 2msec */); 469 retval = handshake(ehci,
470 &ehci->regs->port_status [wIndex],
471 PORT_RESUME, 0, 2000 /* 2msec */);
467 if (retval != 0) { 472 if (retval != 0) {
468 ehci_err (ehci, "port %d resume error %d\n", 473 ehci_err (ehci, "port %d resume error %d\n",
469 wIndex + 1, retval); 474 wIndex + 1, retval);
@@ -480,13 +485,13 @@ static int ehci_hub_control (
480 ehci->reset_done [wIndex] = 0; 485 ehci->reset_done [wIndex] = 0;
481 486
482 /* force reset to complete */ 487 /* force reset to complete */
483 writel (temp & ~(PORT_RWC_BITS | PORT_RESET), 488 ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
484 &ehci->regs->port_status [wIndex]); 489 &ehci->regs->port_status [wIndex]);
485 /* REVISIT: some hardware needs 550+ usec to clear 490 /* REVISIT: some hardware needs 550+ usec to clear
486 * this bit; seems too long to spin routinely... 491 * this bit; seems too long to spin routinely...
487 */ 492 */
488 retval = handshake ( 493 retval = handshake(ehci,
489 &ehci->regs->port_status [wIndex], 494 &ehci->regs->port_status [wIndex],
490 PORT_RESET, 0, 750); 495 PORT_RESET, 0, 750);
491 if (retval != 0) { 496 if (retval != 0) {
492 ehci_err (ehci, "port %d reset error %d\n", 497 ehci_err (ehci, "port %d reset error %d\n",
@@ -496,7 +501,8 @@ static int ehci_hub_control (
496 501
497 /* see what we found out */ 502 /* see what we found out */
498 temp = check_reset_complete (ehci, wIndex, 503 temp = check_reset_complete (ehci, wIndex,
499 readl (&ehci->regs->port_status [wIndex])); 504 ehci_readl(ehci,
505 &ehci->regs->port_status [wIndex]));
500 } 506 }
501 507
502 // don't show wPortStatus if it's owned by a companion hc 508 // don't show wPortStatus if it's owned by a companion hc
@@ -541,7 +547,7 @@ static int ehci_hub_control (
541 if (!wIndex || wIndex > ports) 547 if (!wIndex || wIndex > ports)
542 goto error; 548 goto error;
543 wIndex--; 549 wIndex--;
544 temp = readl (&ehci->regs->port_status [wIndex]); 550 temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
545 if (temp & PORT_OWNER) 551 if (temp & PORT_OWNER)
546 break; 552 break;
547 553
@@ -555,13 +561,13 @@ static int ehci_hub_control (
555 goto error; 561 goto error;
556 if (device_may_wakeup(&hcd->self.root_hub->dev)) 562 if (device_may_wakeup(&hcd->self.root_hub->dev))
557 temp |= PORT_WAKE_BITS; 563 temp |= PORT_WAKE_BITS;
558 writel (temp | PORT_SUSPEND, 564 ehci_writel(ehci, temp | PORT_SUSPEND,
559 &ehci->regs->port_status [wIndex]); 565 &ehci->regs->port_status [wIndex]);
560 break; 566 break;
561 case USB_PORT_FEAT_POWER: 567 case USB_PORT_FEAT_POWER:
562 if (HCS_PPC (ehci->hcs_params)) 568 if (HCS_PPC (ehci->hcs_params))
563 writel (temp | PORT_POWER, 569 ehci_writel(ehci, temp | PORT_POWER,
564 &ehci->regs->port_status [wIndex]); 570 &ehci->regs->port_status [wIndex]);
565 break; 571 break;
566 case USB_PORT_FEAT_RESET: 572 case USB_PORT_FEAT_RESET:
567 if (temp & PORT_RESUME) 573 if (temp & PORT_RESUME)
@@ -589,7 +595,8 @@ static int ehci_hub_control (
589 ehci->reset_done [wIndex] = jiffies 595 ehci->reset_done [wIndex] = jiffies
590 + msecs_to_jiffies (50); 596 + msecs_to_jiffies (50);
591 } 597 }
592 writel (temp, &ehci->regs->port_status [wIndex]); 598 ehci_writel(ehci, temp,
599 &ehci->regs->port_status [wIndex]);
593 break; 600 break;
594 601
595 /* For downstream facing ports (these): one hub port is put 602 /* For downstream facing ports (these): one hub port is put
@@ -604,13 +611,14 @@ static int ehci_hub_control (
604 ehci_quiesce(ehci); 611 ehci_quiesce(ehci);
605 ehci_halt(ehci); 612 ehci_halt(ehci);
606 temp |= selector << 16; 613 temp |= selector << 16;
607 writel (temp, &ehci->regs->port_status [wIndex]); 614 ehci_writel(ehci, temp,
615 &ehci->regs->port_status [wIndex]);
608 break; 616 break;
609 617
610 default: 618 default:
611 goto error; 619 goto error;
612 } 620 }
613 readl (&ehci->regs->command); /* unblock posted writes */ 621 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
614 break; 622 break;
615 623
616 default: 624 default: