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>

diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index bfe5f30..df00fcb 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -47,7 +47,7 @@
 		ehci_quiesce (ehci);
 		hcd->state = HC_STATE_QUIESCING;
 	}
-	ehci->command = readl (&ehci->regs->command);
+	ehci->command = ehci_readl(ehci, &ehci->regs->command);
 	if (ehci->reclaim)
 		ehci->reclaim_ready = 1;
 	ehci_work(ehci);
@@ -60,7 +60,7 @@
 	ehci->bus_suspended = 0;
 	while (port--) {
 		u32 __iomem	*reg = &ehci->regs->port_status [port];
-		u32		t1 = readl (reg) & ~PORT_RWC_BITS;
+		u32		t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
 		u32		t2 = t1;
 
 		/* keep track of which ports we suspend */
@@ -79,7 +79,7 @@
 		if (t1 != t2) {
 			ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
 				port + 1, t1, t2);
-			writel (t2, reg);
+			ehci_writel(ehci, t2, reg);
 		}
 	}
 
@@ -92,8 +92,8 @@
 	mask = INTR_MASK;
 	if (!device_may_wakeup(&hcd->self.root_hub->dev))
 		mask &= ~STS_PCD;
-	writel(mask, &ehci->regs->intr_enable);
-	readl(&ehci->regs->intr_enable);
+	ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+	ehci_readl(ehci, &ehci->regs->intr_enable);
 
 	ehci->next_statechange = jiffies + msecs_to_jiffies(10);
 	spin_unlock_irq (&ehci->lock);
@@ -118,26 +118,26 @@
 	 * the last user of the controller, not reset/pm hardware keeping
 	 * state we gave to it.
 	 */
-	temp = readl(&ehci->regs->intr_enable);
+	temp = ehci_readl(ehci, &ehci->regs->intr_enable);
 	ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
 
 	/* at least some APM implementations will try to deliver
 	 * IRQs right away, so delay them until we're ready.
 	 */
-	writel(0, &ehci->regs->intr_enable);
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
 
 	/* re-init operational registers */
-	writel(0, &ehci->regs->segment);
-	writel(ehci->periodic_dma, &ehci->regs->frame_list);
-	writel((u32) ehci->async->qh_dma, &ehci->regs->async_next);
+	ehci_writel(ehci, 0, &ehci->regs->segment);
+	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
+	ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
 
 	/* restore CMD_RUN, framelist size, and irq threshold */
-	writel (ehci->command, &ehci->regs->command);
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 
 	/* manually resume the ports we suspended during bus_suspend() */
 	i = HCS_N_PORTS (ehci->hcs_params);
 	while (i--) {
-		temp = readl (&ehci->regs->port_status [i]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		temp &= ~(PORT_RWC_BITS
 			| PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
 		if (test_bit(i, &ehci->bus_suspended) &&
@@ -145,20 +145,20 @@
 			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
 			temp |= PORT_RESUME;
 		}
-		writel (temp, &ehci->regs->port_status [i]);
+		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 	}
 	i = HCS_N_PORTS (ehci->hcs_params);
 	mdelay (20);
 	while (i--) {
-		temp = readl (&ehci->regs->port_status [i]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		if (test_bit(i, &ehci->bus_suspended) &&
 				(temp & PORT_SUSPEND)) {
 			temp &= ~(PORT_RWC_BITS | PORT_RESUME);
-			writel (temp, &ehci->regs->port_status [i]);
+			ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 			ehci_vdbg (ehci, "resumed port %d\n", i + 1);
 		}
 	}
-	(void) readl (&ehci->regs->command);
+	(void) ehci_readl(ehci, &ehci->regs->command);
 
 	/* maybe re-activate the schedule(s) */
 	temp = 0;
@@ -168,14 +168,14 @@
 		temp |= CMD_PSE;
 	if (temp) {
 		ehci->command |= temp;
-		writel (ehci->command, &ehci->regs->command);
+		ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	}
 
 	ehci->next_statechange = jiffies + msecs_to_jiffies(5);
 	hcd->state = HC_STATE_RUNNING;
 
 	/* Now we can safely re-enable irqs */
-	writel(INTR_MASK, &ehci->regs->intr_enable);
+	ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
 
 	spin_unlock_irq (&ehci->lock);
 	return 0;
@@ -217,7 +217,8 @@
 		// what happens if HCS_N_CC(params) == 0 ?
 		port_status |= PORT_OWNER;
 		port_status &= ~PORT_RWC_BITS;
-		writel (port_status, &ehci->regs->port_status [index]);
+		ehci_writel(ehci, port_status,
+			    &ehci->regs->port_status [index]);
 
 	} else
 		ehci_dbg (ehci, "port %d high speed\n", index + 1);
@@ -268,13 +269,14 @@
 	/* port N changes (bit N)? */
 	spin_lock_irqsave (&ehci->lock, flags);
 	for (i = 0; i < ports; i++) {
-		temp = readl (&ehci->regs->port_status [i]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		if (temp & PORT_OWNER) {
 			/* don't report this in GetPortStatus */
 			if (temp & PORT_CSC) {
 				temp &= ~PORT_RWC_BITS;
 				temp |= PORT_CSC;
-				writel (temp, &ehci->regs->port_status [i]);
+				ehci_writel(ehci, temp,
+					    &ehci->regs->port_status [i]);
 			}
 			continue;
 		}
@@ -373,18 +375,18 @@
 		if (!wIndex || wIndex > ports)
 			goto error;
 		wIndex--;
-		temp = readl (&ehci->regs->port_status [wIndex]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
 		if (temp & PORT_OWNER)
 			break;
 
 		switch (wValue) {
 		case USB_PORT_FEAT_ENABLE:
-			writel (temp & ~PORT_PE,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp & ~PORT_PE,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_ENABLE:
-			writel((temp & ~PORT_RWC_BITS) | PORT_PEC,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_SUSPEND:
 			if (temp & PORT_RESET)
@@ -396,8 +398,8 @@
 					goto error;
 				/* resume signaling for 20 msec */
 				temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
-				writel (temp | PORT_RESUME,
-					&ehci->regs->port_status [wIndex]);
+				ehci_writel(ehci, temp | PORT_RESUME,
+					    &ehci->regs->port_status [wIndex]);
 				ehci->reset_done [wIndex] = jiffies
 						+ msecs_to_jiffies (20);
 			}
@@ -407,16 +409,17 @@
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
-				writel (temp & ~(PORT_RWC_BITS | PORT_POWER),
-					&ehci->regs->port_status [wIndex]);
+				ehci_writel(ehci,
+					  temp & ~(PORT_RWC_BITS | PORT_POWER),
+					  &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_CONNECTION:
-			writel((temp & ~PORT_RWC_BITS) | PORT_CSC,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
-			writel((temp & ~PORT_RWC_BITS) | PORT_OCC,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
@@ -424,7 +427,7 @@
 		default:
 			goto error;
 		}
-		readl (&ehci->regs->command);	/* unblock posted write */
+		ehci_readl(ehci, &ehci->regs->command);	/* unblock posted write */
 		break;
 	case GetHubDescriptor:
 		ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
@@ -440,7 +443,7 @@
 			goto error;
 		wIndex--;
 		status = 0;
-		temp = readl (&ehci->regs->port_status [wIndex]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
 
 		// wPortChange bits
 		if (temp & PORT_CSC)
@@ -458,12 +461,14 @@
 			ehci->reset_done [wIndex] = 0;
 
 			/* stop resume signaling */
-			temp = readl (&ehci->regs->port_status [wIndex]);
-			writel (temp & ~(PORT_RWC_BITS | PORT_RESUME),
-				&ehci->regs->port_status [wIndex]);
-			retval = handshake (
-					&ehci->regs->port_status [wIndex],
-					PORT_RESUME, 0, 2000 /* 2msec */);
+			temp = ehci_readl(ehci,
+					  &ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci,
+				    temp & ~(PORT_RWC_BITS | PORT_RESUME),
+				    &ehci->regs->port_status [wIndex]);
+			retval = handshake(ehci,
+					   &ehci->regs->port_status [wIndex],
+					   PORT_RESUME, 0, 2000 /* 2msec */);
 			if (retval != 0) {
 				ehci_err (ehci, "port %d resume error %d\n",
 					wIndex + 1, retval);
@@ -480,13 +485,13 @@
 			ehci->reset_done [wIndex] = 0;
 
 			/* force reset to complete */
-			writel (temp & ~(PORT_RWC_BITS | PORT_RESET),
-					&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
+				    &ehci->regs->port_status [wIndex]);
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			 * this bit; seems too long to spin routinely...
 			 */
-			retval = handshake (
-					&ehci->regs->port_status [wIndex],
+			retval = handshake(ehci,
+					   &ehci->regs->port_status [wIndex],
 					PORT_RESET, 0, 750);
 			if (retval != 0) {
 				ehci_err (ehci, "port %d reset error %d\n",
@@ -496,7 +501,8 @@
 
 			/* see what we found out */
 			temp = check_reset_complete (ehci, wIndex,
-				readl (&ehci->regs->port_status [wIndex]));
+				ehci_readl(ehci,
+					   &ehci->regs->port_status [wIndex]));
 		}
 
 		// don't show wPortStatus if it's owned by a companion hc
@@ -541,7 +547,7 @@
 		if (!wIndex || wIndex > ports)
 			goto error;
 		wIndex--;
-		temp = readl (&ehci->regs->port_status [wIndex]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
 		if (temp & PORT_OWNER)
 			break;
 
@@ -555,13 +561,13 @@
 				goto error;
 			if (device_may_wakeup(&hcd->self.root_hub->dev))
 				temp |= PORT_WAKE_BITS;
-			writel (temp | PORT_SUSPEND,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp | PORT_SUSPEND,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
-				writel (temp | PORT_POWER,
-					&ehci->regs->port_status [wIndex]);
+				ehci_writel(ehci, temp | PORT_POWER,
+					    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_RESET:
 			if (temp & PORT_RESUME)
@@ -589,7 +595,8 @@
 				ehci->reset_done [wIndex] = jiffies
 						+ msecs_to_jiffies (50);
 			}
-			writel (temp, &ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 
 		/* For downstream facing ports (these):  one hub port is put
@@ -604,13 +611,14 @@
 			ehci_quiesce(ehci);
 			ehci_halt(ehci);
 			temp |= selector << 16;
-			writel (temp, &ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 
 		default:
 			goto error;
 		}
-		readl (&ehci->regs->command);	/* unblock posted writes */
+		ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 		break;
 
 	default: