Merge master.kernel.org:/home/rmk/linux-2.6-arm

* master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] 3761/1: fix armv4t breakage after adding thumb interworking to userspace helpers
  [ARM] Add Integrator support for glibc outb() and friends
  [ARM] Move prototype for register_isa_ports to asm/io.h
  [ARM] Arrange for isa.c to use named initialisers
  [ARM] 3741/1: remove sa1111.c build warning on non-sa1100 systems
  [ARM] 3760/1: This patch adds timeouts while working with SSP registers. Such timeouts were en
  [ARM] 3758/1: Preserve signalling NaNs in conversion
  [ARM] 3749/3: Correct VFP single/double conversion emulation
  [ARM] 3748/3: Correct error check in vfp_raise_exceptions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 3345c6d..92873cd 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -47,7 +47,8 @@
 # testing for a specific architecture or later rather impossible.
 arch-$(CONFIG_CPU_32v6)		:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
 arch-$(CONFIG_CPU_32v6K)	:=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
-arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4)
+arch-$(CONFIG_CPU_32v5)		:=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
+arch-$(CONFIG_CPU_32v4T)	:=-D__LINUX_ARM_ARCH__=4 -march=armv4t
 arch-$(CONFIG_CPU_32v4)		:=-D__LINUX_ARM_ARCH__=4 -march=armv4
 arch-$(CONFIG_CPU_32v3)		:=-D__LINUX_ARM_ARCH__=3 -march=armv3
 
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a331c12..29818bd 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -618,7 +618,7 @@
 {
 	struct sa1111 *sachip;
 	unsigned long id;
-	unsigned int has_devs, val;
+	unsigned int has_devs;
 	int i, ret = -ENODEV;
 
 	sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
@@ -669,6 +669,9 @@
 	sa1111_wake(sachip);
 
 #ifdef CONFIG_ARCH_SA1100
+	{
+	unsigned int val;
+
 	/*
 	 * The SDRAM configuration of the SA1110 and the SA1111 must
 	 * match.  This is very important to ensure that SA1111 accesses
@@ -692,6 +695,7 @@
 	 * Enable the SA1110 memory bus request and grant signals.
 	 */
 	sa1110_mb_enable();
+	}
 #endif
 
 	/*
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index f0c0cdb..1320a0e 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -13,12 +13,11 @@
 obj-$(CONFIG_APM)		+= apm.o
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
-obj-$(CONFIG_FOOTBRIDGE)	+= isa.o
 obj-$(CONFIG_FIQ)		+= fiq.o
 obj-$(CONFIG_MODULES)		+= armksyms.o module.o
 obj-$(CONFIG_ARTHUR)		+= arthur.o
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
-obj-$(CONFIG_PCI)		+= bios32.o
+obj-$(CONFIG_PCI)		+= bios32.o isa.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o
 
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 685c3e5..54bbd9f 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -3,21 +3,14 @@
  *
  *  Copyright (C) 1999 Phil Blundell
  *
- *  ISA shared memory and I/O port support
- */
-
-/*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
+ *
+ *  ISA shared memory and I/O port support, and is required to support
+ *  iopl, inb, outb and friends in userspace via glibc emulation.
  */
-
-/* 
- * Nothing about this is actually ARM specific.  One day we could move
- * it into kernel/resource.c or some place like that.  
- */
-
 #include <linux/stddef.h>
 #include <linux/types.h>
 #include <linux/fs.h>
@@ -27,21 +20,49 @@
 static unsigned int isa_membase, isa_portbase, isa_portshift;
 
 static ctl_table ctl_isa_vars[4] = {
-	{BUS_ISA_MEM_BASE, "membase", &isa_membase, 
-	 sizeof(isa_membase), 0444, NULL, &proc_dointvec},
-	{BUS_ISA_PORT_BASE, "portbase", &isa_portbase, 
-	 sizeof(isa_portbase), 0444, NULL, &proc_dointvec},
-	{BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift, 
-	 sizeof(isa_portshift), 0444, NULL, &proc_dointvec},
-	{0}
+	{
+		.ctl_name	= BUS_ISA_MEM_BASE,
+		.procname	= "membase",
+		.data		= &isa_membase, 
+		.maxlen		= sizeof(isa_membase),
+		.mode		= 0444,
+		.proc_handler	= &proc_dointvec,
+	}, {
+		.ctl_name	= BUS_ISA_PORT_BASE,
+		.procname	= "portbase",
+		.data		= &isa_portbase, 
+		.maxlen		= sizeof(isa_portbase),
+		.mode		= 0444,
+		.proc_handler	= &proc_dointvec,
+	}, {
+		.ctl_name	= BUS_ISA_PORT_SHIFT,
+		.procname	= "portshift",
+		.data		= &isa_portshift, 
+		.maxlen		= sizeof(isa_portshift),
+		.mode		= 0444,
+		.proc_handler	= &proc_dointvec,
+	}, {0}
 };
 
 static struct ctl_table_header *isa_sysctl_header;
 
-static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
-			       {0}};
-static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa},
-			       {0}};
+static ctl_table ctl_isa[2] = {
+	{
+		.ctl_name	= CTL_BUS_ISA,
+		.procname	= "isa",
+		.mode		= 0555,
+		.child		= ctl_isa_vars,
+	}, {0}
+};
+
+static ctl_table ctl_bus[2] = {
+	{
+		.ctl_name	= CTL_BUS,
+		.procname	= "bus",
+		.mode		= 0555,
+		.child		= ctl_isa,
+	}, {0}
+};
 
 void __init
 register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift)
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index 607ed1f..823e25d 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -35,7 +35,6 @@
 
 extern int setup_arm_irq(int, struct irqaction *);
 extern void pcibios_report_status(u_int status_mask, int warn);
-extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
 
 static unsigned long
 dc21285_base_address(struct pci_bus *bus, unsigned int devfn)
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index f904359..4418f6d 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -600,4 +600,6 @@
 		printk(KERN_ERR "PCI: unable to grab local bus timeout "
 		       "interrupt: %d\n", ret);
 #endif
+
+	register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
 }
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index f942131..ff6b4ee 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -47,14 +47,15 @@
  */
 unsigned long corgi_ssp_ads7846_putget(ulong data)
 {
-	unsigned long ret,flag;
+	unsigned long flag;
+	u32 ret = 0;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
 	if (ssp_machinfo->cs_ads7846 >= 0)
 		GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 
 	ssp_write_word(&corgi_ssp_dev,data);
-	ret = ssp_read_word(&corgi_ssp_dev);
+ 	ssp_read_word(&corgi_ssp_dev, &ret);
 
 	if (ssp_machinfo->cs_ads7846 >= 0)
 		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
@@ -88,7 +89,9 @@
 
 unsigned long corgi_ssp_ads7846_get(void)
 {
-	return ssp_read_word(&corgi_ssp_dev);
+	u32 ret = 0;
+	ssp_read_word(&corgi_ssp_dev, &ret);
+	return ret;
 }
 
 EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
@@ -104,6 +107,7 @@
 unsigned long corgi_ssp_dac_put(ulong data)
 {
 	unsigned long flag, sscr1 = SSCR1_SPH;
+	u32 tmp;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
 
@@ -118,7 +122,7 @@
 		GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 	ssp_write_word(&corgi_ssp_dev,data);
 	/* Read null data back from device to prevent SSP overflow */
-	ssp_read_word(&corgi_ssp_dev);
+	ssp_read_word(&corgi_ssp_dev, &tmp);
 	if (ssp_machinfo->cs_lcdcon >= 0)
 		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 
@@ -150,7 +154,7 @@
 int corgi_ssp_max1111_get(ulong data)
 {
 	unsigned long flag;
-	int voltage,voltage1,voltage2;
+	long voltage = 0, voltage1 = 0, voltage2 = 0;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
 	if (ssp_machinfo->cs_max1111 >= 0)
@@ -163,15 +167,15 @@
 
 	/* TB1/RB1 */
 	ssp_write_word(&corgi_ssp_dev,data);
-	ssp_read_word(&corgi_ssp_dev); /* null read */
+	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
 
 	/* TB12/RB2 */
 	ssp_write_word(&corgi_ssp_dev,0);
-	voltage1=ssp_read_word(&corgi_ssp_dev);
+	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
 
 	/* TB13/RB3*/
 	ssp_write_word(&corgi_ssp_dev,0);
-	voltage2=ssp_read_word(&corgi_ssp_dev);
+	ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
 
 	ssp_disable(&corgi_ssp_dev);
 	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 93096bef..1fddfea 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -40,6 +40,8 @@
 
 #define PXA_SSP_PORTS 	3
 
+#define TIMEOUT 100000
+
 struct ssp_info_ {
 	int irq;
 	u32 clock;
@@ -92,13 +94,18 @@
  * The caller is expected to perform the necessary locking.
  *
  * Returns:
- *   %-ETIMEDOUT	timeout occurred (for future)
+ *   %-ETIMEDOUT	timeout occurred
  *   0			success
  */
 int ssp_write_word(struct ssp_dev *dev, u32 data)
 {
-	while (!(SSSR_P(dev->port) & SSSR_TNF))
+	int timeout = TIMEOUT;
+
+	while (!(SSSR_P(dev->port) & SSSR_TNF)) {
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
 		cpu_relax();
+	}
 
 	SSDR_P(dev->port) = data;
 
@@ -117,15 +124,21 @@
  * The caller is expected to perform the necessary locking.
  *
  * Returns:
- *   %-ETIMEDOUT	timeout occurred (for future)
+ *   %-ETIMEDOUT	timeout occurred
  *   32-bit data	success
  */
-int ssp_read_word(struct ssp_dev *dev)
+int ssp_read_word(struct ssp_dev *dev, u32 *data)
 {
-	while (!(SSSR_P(dev->port) & SSSR_RNE))
-		cpu_relax();
+	int timeout = TIMEOUT;
 
-	return SSDR_P(dev->port);
+	while (!(SSSR_P(dev->port) & SSSR_RNE)) {
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
+		cpu_relax();
+	}
+
+	*data = SSDR_P(dev->port);
+	return 0;
 }
 
 /**
@@ -136,13 +149,21 @@
  *
  * The caller is expected to perform the necessary locking.
  */
-void ssp_flush(struct ssp_dev *dev)
+int ssp_flush(struct ssp_dev *dev)
 {
+	int timeout = TIMEOUT * 2;
+
 	do {
 		while (SSSR_P(dev->port) & SSSR_RNE) {
+		        if (!--timeout)
+		        	return -ETIMEDOUT;
 			(void) SSDR_P(dev->port);
 		}
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
 	} while (SSSR_P(dev->port) & SSSR_BSY);
+
+	return 0;
 }
 
 /**
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
index 1604dad..5eba5fb 100644
--- a/arch/arm/mach-sa1100/ssp.c
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -23,6 +23,8 @@
 #include <asm/hardware.h>
 #include <asm/hardware/ssp.h>
 
+#define TIMEOUT 100000
+
 static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned int status = Ser4SSSR;
@@ -47,18 +49,27 @@
  * The caller is expected to perform the necessary locking.
  *
  * Returns:
- *   %-ETIMEDOUT	timeout occurred (for future)
+ *   %-ETIMEDOUT	timeout occurred
  *   0			success
  */
 int ssp_write_word(u16 data)
 {
-	while (!(Ser4SSSR & SSSR_TNF))
+	int timeout = TIMEOUT;
+
+	while (!(Ser4SSSR & SSSR_TNF)) {
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
 		cpu_relax();
+	}
 
 	Ser4SSDR = data;
 
-	while (!(Ser4SSSR & SSSR_BSY))
+	timeout = TIMEOUT;
+	while (!(Ser4SSSR & SSSR_BSY)) {
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
 		cpu_relax();
+	}
 
 	return 0;
 }
@@ -75,15 +86,22 @@
  * The caller is expected to perform the necessary locking.
  *
  * Returns:
- *   %-ETIMEDOUT	timeout occurred (for future)
+ *   %-ETIMEDOUT	timeout occurred
  *   16-bit data	success
  */
-int ssp_read_word(void)
+int ssp_read_word(u16 *data)
 {
-	while (!(Ser4SSSR & SSSR_RNE))
-		cpu_relax();
+	int timeout = TIMEOUT;
 
-	return Ser4SSDR;
+	while (!(Ser4SSSR & SSSR_RNE)) {
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
+		cpu_relax();
+	}
+
+	*data = (u16)Ser4SSDR;
+
+	return 0;
 }
 
 /**
@@ -93,14 +111,26 @@
  * is empty.
  *
  * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ *   %-ETIMEDOUT	timeout occurred
+ *   0			success
  */
-void ssp_flush(void)
+int ssp_flush(void)
 {
+	int timeout = TIMEOUT * 2;
+
 	do {
 		while (Ser4SSSR & SSSR_RNE) {
+		        if (!--timeout)
+		        	return -ETIMEDOUT;
 			(void) Ser4SSDR;
 		}
+	        if (!--timeout)
+	        	return -ETIMEDOUT;
 	} while (Ser4SSSR & SSSR_BSY);
+
+	return 0;
 }
 
 /**
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5f80f18..b4f220dd 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -46,7 +46,7 @@
 config CPU_ARM720T
 	bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
 	default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
-	select CPU_32v4
+	select CPU_32v4T
 	select CPU_ABRT_LV4T
 	select CPU_CACHE_V4
 	select CPU_CACHE_VIVT
@@ -64,7 +64,7 @@
 	bool "Support ARM920T processor"
 	depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
 	default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
-	select CPU_32v4
+	select CPU_32v4T
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
@@ -85,7 +85,7 @@
 	bool "Support ARM922T processor" if ARCH_INTEGRATOR
 	depends on ARCH_LH7A40X || ARCH_INTEGRATOR
 	default y if ARCH_LH7A40X
-	select CPU_32v4
+	select CPU_32v4T
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
@@ -104,7 +104,7 @@
  	bool "Support ARM925T processor" if ARCH_OMAP1
  	depends on ARCH_OMAP15XX
  	default y if ARCH_OMAP15XX
-	select CPU_32v4
+	select CPU_32v4T
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
@@ -285,6 +285,11 @@
 	select TLS_REG_EMUL if SMP || !MMU
 	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
 
+config CPU_32v4T
+	bool
+	select TLS_REG_EMUL if SMP || !MMU
+	select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+
 config CPU_32v5
 	bool
 	select TLS_REG_EMUL if SMP || !MMU
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 4b97950..5fbdf81a 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -353,3 +353,11 @@
  * A special flag to tell the normalisation code not to normalise.
  */
 #define VFP_NAN_FLAG	0x100
+
+/*
+ * A bit pattern used to indicate the initial (unset) value of the
+ * exception mask, in case nothing handles an instruction.  This
+ * doesn't include the NAN flag, which get masked out before
+ * we check for an error.
+ */
+#define VFP_EXCEPTION_ERROR	((u32)-1 & ~VFP_NAN_FLAG)
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 009038c..04bd342 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -465,7 +465,7 @@
 	 */
 	if (tm & (VFP_INFINITY|VFP_NAN)) {
 		vsd.exponent = 255;
-		if (tm & VFP_NAN)
+		if (tm == VFP_QNAN)
 			vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
 		goto pack_nan;
 	} else if (tm & VFP_ZERO)
@@ -1127,7 +1127,7 @@
 {
 	u32 op = inst & FOP_MASK;
 	u32 exceptions = 0;
-	unsigned int dd = vfp_get_dd(inst);
+	unsigned int dest;
 	unsigned int dn = vfp_get_dn(inst);
 	unsigned int dm = vfp_get_dm(inst);
 	unsigned int vecitr, veclen, vecstride;
@@ -1137,10 +1137,20 @@
 	vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2;
 
 	/*
+	 * fcvtds takes an sN register number as destination, not dN.
+	 * It also always operates on scalars.
+	 */
+	if ((inst & FEXT_MASK) == FEXT_FCVT) {
+		veclen = 0;
+		dest = vfp_get_sd(inst);
+	} else
+		dest = vfp_get_dd(inst);
+
+	/*
 	 * If destination bank is zero, vector length is always '1'.
 	 * ARM DDI0100F C5.1.3, C5.3.2.
 	 */
-	if (FREG_BANK(dd) == 0)
+	if (FREG_BANK(dest) == 0)
 		veclen = 0;
 
 	pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
@@ -1153,16 +1163,20 @@
 	for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
 		u32 except;
 
-		if (op == FOP_EXT)
+		if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
+			pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n",
+				 vecitr >> FPSCR_LENGTH_BIT,
+				 dest, dn, dm);
+		else if (op == FOP_EXT)
 			pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
 				 vecitr >> FPSCR_LENGTH_BIT,
-				 dd, dn, dm);
+				 dest, dn, dm);
 		else
 			pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
 				 vecitr >> FPSCR_LENGTH_BIT,
-				 dd, dn, FOP_TO_IDX(op), dm);
+				 dest, dn, FOP_TO_IDX(op), dm);
 
-		except = fop(dd, dn, dm, fpscr);
+		except = fop(dest, dn, dm, fpscr);
 		pr_debug("VFP: itr%d: exceptions=%08x\n",
 			 vecitr >> FPSCR_LENGTH_BIT, except);
 
@@ -1180,7 +1194,7 @@
 		 * we encounter an exception.  We continue.
 		 */
 
-		dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6);
+		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6);
 		dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6);
 		if (FREG_BANK(dm) != 0)
 			dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6);
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 9d265d5..4178f6c 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -131,7 +131,7 @@
 
 	pr_debug("VFP: raising exceptions %08x\n", exceptions);
 
-	if (exceptions == (u32)-1) {
+	if (exceptions == VFP_EXCEPTION_ERROR) {
 		vfp_panic("unhandled bounce");
 		vfp_raise_sigfpe(0, regs);
 		return;
@@ -170,7 +170,7 @@
  */
 static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
 {
-	u32 exceptions = (u32)-1;
+	u32 exceptions = VFP_EXCEPTION_ERROR;
 
 	pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr);
 
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index dae2c2f..78d7cac 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -506,7 +506,7 @@
 	 */
 	if (tm & (VFP_INFINITY|VFP_NAN)) {
 		vdd.exponent = 2047;
-		if (tm & VFP_NAN)
+		if (tm == VFP_QNAN)
 			vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
 		goto pack_nan;
 	} else if (tm & VFP_ZERO)
@@ -514,10 +514,6 @@
 	else
 		vdd.exponent = vsm.exponent + (1023 - 127);
 
-	/*
-	 * Technically, if bit 0 of dd is set, this is an invalid
-	 * instruction.  However, we ignore this for efficiency.
-	 */
 	return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd");
 
  pack_nan:
@@ -1174,7 +1170,7 @@
 {
 	u32 op = inst & FOP_MASK;
 	u32 exceptions = 0;
-	unsigned int sd = vfp_get_sd(inst);
+	unsigned int dest;
 	unsigned int sn = vfp_get_sn(inst);
 	unsigned int sm = vfp_get_sm(inst);
 	unsigned int vecitr, veclen, vecstride;
@@ -1184,10 +1180,22 @@
 	vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
 
 	/*
+	 * fcvtsd takes a dN register number as destination, not sN.
+	 * Technically, if bit 0 of dd is set, this is an invalid
+	 * instruction.  However, we ignore this for efficiency.
+	 * It also only operates on scalars.
+	 */
+	if ((inst & FEXT_MASK) == FEXT_FCVT) {
+		veclen = 0;
+		dest = vfp_get_dd(inst);
+	} else
+		dest = vfp_get_sd(inst);
+
+	/*
 	 * If destination bank is zero, vector length is always '1'.
 	 * ARM DDI0100F C5.1.3, C5.3.2.
 	 */
-	if (FREG_BANK(sd) == 0)
+	if (FREG_BANK(dest) == 0)
 		veclen = 0;
 
 	pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
@@ -1201,15 +1209,18 @@
 		s32 m = vfp_get_float(sm);
 		u32 except;
 
-		if (op == FOP_EXT)
+		if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
+			pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n",
+				 vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
+		else if (op == FOP_EXT)
 			pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n",
-				 vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m);
+				 vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
 		else
 			pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n",
-				 vecitr >> FPSCR_LENGTH_BIT, sd, sn,
+				 vecitr >> FPSCR_LENGTH_BIT, dest, sn,
 				 FOP_TO_IDX(op), sm, m);
 
-		except = fop(sd, sn, m, fpscr);
+		except = fop(dest, sn, m, fpscr);
 		pr_debug("VFP: itr%d: exceptions=%08x\n",
 			 vecitr >> FPSCR_LENGTH_BIT, except);
 
@@ -1227,7 +1238,7 @@
 		 * we encounter an exception.  We continue.
 		 */
 
-		sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7);
+		dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
 		sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
 		if (FREG_BANK(sm) != 0)
 			sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);
diff --git a/include/asm-arm/arch-pxa/ssp.h b/include/asm-arm/arch-pxa/ssp.h
index 949878c..ea20055 100644
--- a/include/asm-arm/arch-pxa/ssp.h
+++ b/include/asm-arm/arch-pxa/ssp.h
@@ -40,8 +40,8 @@
 };
 
 int ssp_write_word(struct ssp_dev *dev, u32 data);
-int ssp_read_word(struct ssp_dev *dev);
-void ssp_flush(struct ssp_dev *dev);
+int ssp_read_word(struct ssp_dev *dev, u32 *data);
+int ssp_flush(struct ssp_dev *dev);
 void ssp_enable(struct ssp_dev *dev);
 void ssp_disable(struct ssp_dev *dev);
 void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
diff --git a/include/asm-arm/hardware/ssp.h b/include/asm-arm/hardware/ssp.h
index 28aa11b..3b42e18 100644
--- a/include/asm-arm/hardware/ssp.h
+++ b/include/asm-arm/hardware/ssp.h
@@ -16,8 +16,8 @@
 };
 
 int ssp_write_word(u16 data);
-int ssp_read_word(void);
-void ssp_flush(void);
+int ssp_read_word(u16 *data);
+int ssp_flush(void);
 void ssp_enable(void);
 void ssp_disable(void);
 void ssp_save_state(struct ssp_state *ssp);
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index b3479fc..bf7b9de 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -291,5 +291,12 @@
  */
 #define xlate_dev_kmem_ptr(p)	p
 
+/*
+ * Register ISA memory and port locations for glibc iopl/inb/outb
+ * emulation.
+ */
+extern void register_isa_ports(unsigned int mmio, unsigned int io,
+			       unsigned int io_shift);
+
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_ARM_IO_H */