Merge bk://kernel.bkbits.net/davem/sparc-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 57f7f0f..6dff06a 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -1214,10 +1214,24 @@
 	for (size = 1UL; size < goal; size <<= 1UL)
 		__per_cpu_shift++;
 
-	ptr = alloc_bootmem_pages(size * NR_CPUS);
+	/* Make sure the resulting __per_cpu_base value
+	 * will fit in the 43-bit sign extended IMMU
+	 * TSB register.
+	 */
+	ptr = __alloc_bootmem(size * NR_CPUS, PAGE_SIZE,
+			      (unsigned long) __per_cpu_start);
 
 	__per_cpu_base = ptr - __per_cpu_start;
 
+	if ((__per_cpu_shift < PAGE_SHIFT) ||
+	    (__per_cpu_base & ~PAGE_MASK) ||
+	    (__per_cpu_base != (((long) __per_cpu_base << 20) >> 20))) {
+		prom_printf("PER_CPU: Invalid layout, "
+			    "ptr[%p] shift[%lx] base[%lx]\n",
+			    ptr, __per_cpu_shift, __per_cpu_base);
+		prom_halt();
+	}
+
 	for (i = 0; i < NR_CPUS; i++, ptr += size)
 		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
 
@@ -1226,7 +1240,5 @@
 	 * entry and exit loading of %g5.  That is why it
 	 * has to be page aligned.
 	 */
-	BUG_ON((__per_cpu_shift < PAGE_SHIFT) ||
-	       (__per_cpu_base & ~PAGE_MASK));
 	cpu_setup_percpu_base(hard_smp_processor_id());
 }
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c
index e7be415..247b463 100644
--- a/drivers/fc4/soc.c
+++ b/drivers/fc4/soc.c
@@ -106,8 +106,8 @@
 static inline void soc_solicited (struct soc *s)
 {
 	fc_hdr fchdr;
-	soc_rsp *hwrsp;
-	soc_cq *sw_cq;
+	soc_rsp __iomem *hwrsp;
+	soc_cq_rsp *sw_cq;
 	int token;
 	int status;
 	fc_channel *fc;
@@ -115,12 +115,12 @@
 	sw_cq = &s->rsp[SOC_SOLICITED_RSP_Q];
 
 	if (sw_cq->pool == NULL)
-		sw_cq->pool = (soc_req *)
+		sw_cq->pool = (soc_req __iomem *)
 			(s->xram + xram_get_32low ((xram_p)&sw_cq->hw_cq->address));
 	sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in);
 	SOD (("soc_solicited, %d pkts arrived\n", (sw_cq->in-sw_cq->out) & sw_cq->last))
 	for (;;) {
-		hwrsp = (soc_rsp *)sw_cq->pool + sw_cq->out;
+		hwrsp = (soc_rsp __iomem *)sw_cq->pool + sw_cq->out;
 		token = xram_get_32low ((xram_p)&hwrsp->shdr.token);
 		status = xram_get_32low ((xram_p)&hwrsp->status);
 		fc = (fc_channel *)(&s->port[(token >> 11) & 1]);
@@ -185,8 +185,8 @@
 
 static inline void soc_unsolicited (struct soc *s)
 {
-	soc_rsp *hwrsp, *hwrspc;
-	soc_cq *sw_cq;
+	soc_rsp __iomem *hwrsp, *hwrspc;
+	soc_cq_rsp *sw_cq;
 	int count;
 	int status;
 	int flags;
@@ -194,14 +194,14 @@
 
 	sw_cq = &s->rsp[SOC_UNSOLICITED_RSP_Q];
 	if (sw_cq->pool == NULL)
-		sw_cq->pool = (soc_req *)
+		sw_cq->pool = (soc_req __iomem *)
 			(s->xram + (xram_get_32low ((xram_p)&sw_cq->hw_cq->address)));
 
 	sw_cq->in = xram_get_8 ((xram_p)&sw_cq->hw_cq->in);
 	SOD (("soc_unsolicited, %d packets arrived\n", (sw_cq->in - sw_cq->out) & sw_cq->last))
 	while (sw_cq->in != sw_cq->out) {
 		/* ...real work per entry here... */
-		hwrsp = (soc_rsp *)sw_cq->pool + sw_cq->out;
+		hwrsp = (soc_rsp __iomem *)sw_cq->pool + sw_cq->out;
 
 		hwrspc = NULL;
 		flags = xram_get_16 ((xram_p)&hwrsp->shdr.flags);
@@ -239,7 +239,7 @@
 					return;
 			}
 			if (sw_cq->out == sw_cq->last)
-				hwrspc = (soc_rsp *)sw_cq->pool;
+				hwrspc = (soc_rsp __iomem *)sw_cq->pool;
 			else
 				hwrspc = hwrsp + 1;
 		}
@@ -359,7 +359,7 @@
 	soc_port *port = (soc_port *)fc;
 	struct soc *s = port->s;
 	int qno;
-	soc_cq *sw_cq;
+	soc_cq_req *sw_cq;
 	int cq_next_in;
 	soc_req *request;
 	fc_hdr *fch;
diff --git a/drivers/fc4/soc.h b/drivers/fc4/soc.h
index c4edefd..d38cf5b 100644
--- a/drivers/fc4/soc.h
+++ b/drivers/fc4/soc.h
@@ -261,18 +261,27 @@
 
 typedef struct {
 	soc_hw_cq		__iomem *hw_cq;	/* Related XRAM cq */
+	soc_req			__iomem *pool;
+	u8			in;
+	u8			out;
+	u8			last;
+	u8			seqno;
+} soc_cq_rsp;
+
+typedef struct {
+	soc_hw_cq		__iomem *hw_cq;	/* Related XRAM cq */
 	soc_req			*pool;
 	u8			in;
 	u8			out;
 	u8			last;
 	u8			seqno;
-} soc_cq;
+} soc_cq_req;
 
 struct soc {
 	spinlock_t		lock;
 	soc_port		port[2]; /* Every SOC has one or two FC ports */
-	soc_cq			req[2]; /* Request CQs */
-	soc_cq			rsp[2]; /* Response CQs */
+	soc_cq_req		req[2]; /* Request CQs */
+	soc_cq_rsp		rsp[2]; /* Response CQs */
 	int			soc_no;
 	void __iomem		*regs;
 	xram_p			xram;