aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-08-28 23:19:16 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-08-28 23:19:16 -0400
commit1b8b22f44bc68b066c571ca2b5ab4fda123c15bd (patch)
treebb7e9bf87204a60fea86389d5f79fc4fa79b7ec7 /arch
parent60d4684068ff1eec78f55b5888d0bd2d4cca1520 (diff)
parent260e98edc8ae8ea862c9c222eeffb1a2eeafa7fc (diff)
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
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/common/sa1111.c6
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/isa.c63
-rw-r--r--arch/arm/mach-footbridge/dc21285.c1
-rw-r--r--arch/arm/mach-integrator/pci_v3.c2
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c20
-rw-r--r--arch/arm/mach-pxa/ssp.c35
-rw-r--r--arch/arm/mach-sa1100/ssp.c46
-rw-r--r--arch/arm/mm/Kconfig13
-rw-r--r--arch/arm/vfp/vfp.h8
-rw-r--r--arch/arm/vfp/vfpdouble.c30
-rw-r--r--arch/arm/vfp/vfpmodule.c4
-rw-r--r--arch/arm/vfp/vfpsingle.c35
14 files changed, 194 insertions, 75 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 3345c6d0fd1e..92873cdee31f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -47,7 +47,8 @@ comma = ,
47# testing for a specific architecture or later rather impossible. 47# testing for a specific architecture or later rather impossible.
48arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) 48arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
49arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) 49arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
50arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4) 50arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
51arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
51arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 52arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
52arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 53arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
53 54
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index a331c12cead9..29818bd3248f 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -618,7 +618,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
618{ 618{
619 struct sa1111 *sachip; 619 struct sa1111 *sachip;
620 unsigned long id; 620 unsigned long id;
621 unsigned int has_devs, val; 621 unsigned int has_devs;
622 int i, ret = -ENODEV; 622 int i, ret = -ENODEV;
623 623
624 sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); 624 sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
@@ -669,6 +669,9 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
669 sa1111_wake(sachip); 669 sa1111_wake(sachip);
670 670
671#ifdef CONFIG_ARCH_SA1100 671#ifdef CONFIG_ARCH_SA1100
672 {
673 unsigned int val;
674
672 /* 675 /*
673 * The SDRAM configuration of the SA1110 and the SA1111 must 676 * The SDRAM configuration of the SA1110 and the SA1111 must
674 * match. This is very important to ensure that SA1111 accesses 677 * match. This is very important to ensure that SA1111 accesses
@@ -692,6 +695,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
692 * Enable the SA1110 memory bus request and grant signals. 695 * Enable the SA1110 memory bus request and grant signals.
693 */ 696 */
694 sa1110_mb_enable(); 697 sa1110_mb_enable();
698 }
695#endif 699#endif
696 700
697 /* 701 /*
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index f0c0cdb1c183..1320a0efca73 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -13,12 +13,11 @@ obj-y := compat.o entry-armv.o entry-common.o irq.o \
13obj-$(CONFIG_APM) += apm.o 13obj-$(CONFIG_APM) += apm.o
14obj-$(CONFIG_ISA_DMA_API) += dma.o 14obj-$(CONFIG_ISA_DMA_API) += dma.o
15obj-$(CONFIG_ARCH_ACORN) += ecard.o 15obj-$(CONFIG_ARCH_ACORN) += ecard.o
16obj-$(CONFIG_FOOTBRIDGE) += isa.o
17obj-$(CONFIG_FIQ) += fiq.o 16obj-$(CONFIG_FIQ) += fiq.o
18obj-$(CONFIG_MODULES) += armksyms.o module.o 17obj-$(CONFIG_MODULES) += armksyms.o module.o
19obj-$(CONFIG_ARTHUR) += arthur.o 18obj-$(CONFIG_ARTHUR) += arthur.o
20obj-$(CONFIG_ISA_DMA) += dma-isa.o 19obj-$(CONFIG_ISA_DMA) += dma-isa.o
21obj-$(CONFIG_PCI) += bios32.o 20obj-$(CONFIG_PCI) += bios32.o isa.o
22obj-$(CONFIG_SMP) += smp.o 21obj-$(CONFIG_SMP) += smp.o
23obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 22obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
24 23
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 685c3e591a7e..54bbd9fe255c 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -3,21 +3,14 @@
3 * 3 *
4 * Copyright (C) 1999 Phil Blundell 4 * Copyright (C) 1999 Phil Blundell
5 * 5 *
6 * ISA shared memory and I/O port support
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 *
11 * ISA shared memory and I/O port support, and is required to support
12 * iopl, inb, outb and friends in userspace via glibc emulation.
14 */ 13 */
15
16/*
17 * Nothing about this is actually ARM specific. One day we could move
18 * it into kernel/resource.c or some place like that.
19 */
20
21#include <linux/stddef.h> 14#include <linux/stddef.h>
22#include <linux/types.h> 15#include <linux/types.h>
23#include <linux/fs.h> 16#include <linux/fs.h>
@@ -27,21 +20,49 @@
27static unsigned int isa_membase, isa_portbase, isa_portshift; 20static unsigned int isa_membase, isa_portbase, isa_portshift;
28 21
29static ctl_table ctl_isa_vars[4] = { 22static ctl_table ctl_isa_vars[4] = {
30 {BUS_ISA_MEM_BASE, "membase", &isa_membase, 23 {
31 sizeof(isa_membase), 0444, NULL, &proc_dointvec}, 24 .ctl_name = BUS_ISA_MEM_BASE,
32 {BUS_ISA_PORT_BASE, "portbase", &isa_portbase, 25 .procname = "membase",
33 sizeof(isa_portbase), 0444, NULL, &proc_dointvec}, 26 .data = &isa_membase,
34 {BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift, 27 .maxlen = sizeof(isa_membase),
35 sizeof(isa_portshift), 0444, NULL, &proc_dointvec}, 28 .mode = 0444,
36 {0} 29 .proc_handler = &proc_dointvec,
30 }, {
31 .ctl_name = BUS_ISA_PORT_BASE,
32 .procname = "portbase",
33 .data = &isa_portbase,
34 .maxlen = sizeof(isa_portbase),
35 .mode = 0444,
36 .proc_handler = &proc_dointvec,
37 }, {
38 .ctl_name = BUS_ISA_PORT_SHIFT,
39 .procname = "portshift",
40 .data = &isa_portshift,
41 .maxlen = sizeof(isa_portshift),
42 .mode = 0444,
43 .proc_handler = &proc_dointvec,
44 }, {0}
37}; 45};
38 46
39static struct ctl_table_header *isa_sysctl_header; 47static struct ctl_table_header *isa_sysctl_header;
40 48
41static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars}, 49static ctl_table ctl_isa[2] = {
42 {0}}; 50 {
43static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa}, 51 .ctl_name = CTL_BUS_ISA,
44 {0}}; 52 .procname = "isa",
53 .mode = 0555,
54 .child = ctl_isa_vars,
55 }, {0}
56};
57
58static ctl_table ctl_bus[2] = {
59 {
60 .ctl_name = CTL_BUS,
61 .procname = "bus",
62 .mode = 0555,
63 .child = ctl_isa,
64 }, {0}
65};
45 66
46void __init 67void __init
47register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift) 68register_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 607ed1f5b3f8..823e25d4547e 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -35,7 +35,6 @@
35 35
36extern int setup_arm_irq(int, struct irqaction *); 36extern int setup_arm_irq(int, struct irqaction *);
37extern void pcibios_report_status(u_int status_mask, int warn); 37extern void pcibios_report_status(u_int status_mask, int warn);
38extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
39 38
40static unsigned long 39static unsigned long
41dc21285_base_address(struct pci_bus *bus, unsigned int devfn) 40dc21285_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 f9043592e299..4418f6d7572d 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -600,4 +600,6 @@ void __init pci_v3_postinit(void)
600 printk(KERN_ERR "PCI: unable to grab local bus timeout " 600 printk(KERN_ERR "PCI: unable to grab local bus timeout "
601 "interrupt: %d\n", ret); 601 "interrupt: %d\n", ret);
602#endif 602#endif
603
604 register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
603} 605}
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index f9421318cb7a..ff6b4ee037f5 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -47,14 +47,15 @@ static struct corgissp_machinfo *ssp_machinfo;
47 */ 47 */
48unsigned long corgi_ssp_ads7846_putget(ulong data) 48unsigned long corgi_ssp_ads7846_putget(ulong data)
49{ 49{
50 unsigned long ret,flag; 50 unsigned long flag;
51 u32 ret = 0;
51 52
52 spin_lock_irqsave(&corgi_ssp_lock, flag); 53 spin_lock_irqsave(&corgi_ssp_lock, flag);
53 if (ssp_machinfo->cs_ads7846 >= 0) 54 if (ssp_machinfo->cs_ads7846 >= 0)
54 GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); 55 GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
55 56
56 ssp_write_word(&corgi_ssp_dev,data); 57 ssp_write_word(&corgi_ssp_dev,data);
57 ret = ssp_read_word(&corgi_ssp_dev); 58 ssp_read_word(&corgi_ssp_dev, &ret);
58 59
59 if (ssp_machinfo->cs_ads7846 >= 0) 60 if (ssp_machinfo->cs_ads7846 >= 0)
60 GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); 61 GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
@@ -88,7 +89,9 @@ void corgi_ssp_ads7846_put(ulong data)
88 89
89unsigned long corgi_ssp_ads7846_get(void) 90unsigned long corgi_ssp_ads7846_get(void)
90{ 91{
91 return ssp_read_word(&corgi_ssp_dev); 92 u32 ret = 0;
93 ssp_read_word(&corgi_ssp_dev, &ret);
94 return ret;
92} 95}
93 96
94EXPORT_SYMBOL(corgi_ssp_ads7846_putget); 97EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
@@ -104,6 +107,7 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get);
104unsigned long corgi_ssp_dac_put(ulong data) 107unsigned long corgi_ssp_dac_put(ulong data)
105{ 108{
106 unsigned long flag, sscr1 = SSCR1_SPH; 109 unsigned long flag, sscr1 = SSCR1_SPH;
110 u32 tmp;
107 111
108 spin_lock_irqsave(&corgi_ssp_lock, flag); 112 spin_lock_irqsave(&corgi_ssp_lock, flag);
109 113
@@ -118,7 +122,7 @@ unsigned long corgi_ssp_dac_put(ulong data)
118 GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); 122 GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
119 ssp_write_word(&corgi_ssp_dev,data); 123 ssp_write_word(&corgi_ssp_dev,data);
120 /* Read null data back from device to prevent SSP overflow */ 124 /* Read null data back from device to prevent SSP overflow */
121 ssp_read_word(&corgi_ssp_dev); 125 ssp_read_word(&corgi_ssp_dev, &tmp);
122 if (ssp_machinfo->cs_lcdcon >= 0) 126 if (ssp_machinfo->cs_lcdcon >= 0)
123 GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); 127 GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
124 128
@@ -150,7 +154,7 @@ EXPORT_SYMBOL(corgi_ssp_blduty_set);
150int corgi_ssp_max1111_get(ulong data) 154int corgi_ssp_max1111_get(ulong data)
151{ 155{
152 unsigned long flag; 156 unsigned long flag;
153 int voltage,voltage1,voltage2; 157 long voltage = 0, voltage1 = 0, voltage2 = 0;
154 158
155 spin_lock_irqsave(&corgi_ssp_lock, flag); 159 spin_lock_irqsave(&corgi_ssp_lock, flag);
156 if (ssp_machinfo->cs_max1111 >= 0) 160 if (ssp_machinfo->cs_max1111 >= 0)
@@ -163,15 +167,15 @@ int corgi_ssp_max1111_get(ulong data)
163 167
164 /* TB1/RB1 */ 168 /* TB1/RB1 */
165 ssp_write_word(&corgi_ssp_dev,data); 169 ssp_write_word(&corgi_ssp_dev,data);
166 ssp_read_word(&corgi_ssp_dev); /* null read */ 170 ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
167 171
168 /* TB12/RB2 */ 172 /* TB12/RB2 */
169 ssp_write_word(&corgi_ssp_dev,0); 173 ssp_write_word(&corgi_ssp_dev,0);
170 voltage1=ssp_read_word(&corgi_ssp_dev); 174 ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
171 175
172 /* TB13/RB3*/ 176 /* TB13/RB3*/
173 ssp_write_word(&corgi_ssp_dev,0); 177 ssp_write_word(&corgi_ssp_dev,0);
174 voltage2=ssp_read_word(&corgi_ssp_dev); 178 ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
175 179
176 ssp_disable(&corgi_ssp_dev); 180 ssp_disable(&corgi_ssp_dev);
177 ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846)); 181 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 93096befd017..1fddfeaa630d 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -40,6 +40,8 @@
40 40
41#define PXA_SSP_PORTS 3 41#define PXA_SSP_PORTS 3
42 42
43#define TIMEOUT 100000
44
43struct ssp_info_ { 45struct ssp_info_ {
44 int irq; 46 int irq;
45 u32 clock; 47 u32 clock;
@@ -92,13 +94,18 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
92 * The caller is expected to perform the necessary locking. 94 * The caller is expected to perform the necessary locking.
93 * 95 *
94 * Returns: 96 * Returns:
95 * %-ETIMEDOUT timeout occurred (for future) 97 * %-ETIMEDOUT timeout occurred
96 * 0 success 98 * 0 success
97 */ 99 */
98int ssp_write_word(struct ssp_dev *dev, u32 data) 100int ssp_write_word(struct ssp_dev *dev, u32 data)
99{ 101{
100 while (!(SSSR_P(dev->port) & SSSR_TNF)) 102 int timeout = TIMEOUT;
103
104 while (!(SSSR_P(dev->port) & SSSR_TNF)) {
105 if (!--timeout)
106 return -ETIMEDOUT;
101 cpu_relax(); 107 cpu_relax();
108 }
102 109
103 SSDR_P(dev->port) = data; 110 SSDR_P(dev->port) = data;
104 111
@@ -117,15 +124,21 @@ int ssp_write_word(struct ssp_dev *dev, u32 data)
117 * The caller is expected to perform the necessary locking. 124 * The caller is expected to perform the necessary locking.
118 * 125 *
119 * Returns: 126 * Returns:
120 * %-ETIMEDOUT timeout occurred (for future) 127 * %-ETIMEDOUT timeout occurred
121 * 32-bit data success 128 * 32-bit data success
122 */ 129 */
123int ssp_read_word(struct ssp_dev *dev) 130int ssp_read_word(struct ssp_dev *dev, u32 *data)
124{ 131{
125 while (!(SSSR_P(dev->port) & SSSR_RNE)) 132 int timeout = TIMEOUT;
133
134 while (!(SSSR_P(dev->port) & SSSR_RNE)) {
135 if (!--timeout)
136 return -ETIMEDOUT;
126 cpu_relax(); 137 cpu_relax();
138 }
127 139
128 return SSDR_P(dev->port); 140 *data = SSDR_P(dev->port);
141 return 0;
129} 142}
130 143
131/** 144/**
@@ -136,13 +149,21 @@ int ssp_read_word(struct ssp_dev *dev)
136 * 149 *
137 * The caller is expected to perform the necessary locking. 150 * The caller is expected to perform the necessary locking.
138 */ 151 */
139void ssp_flush(struct ssp_dev *dev) 152int ssp_flush(struct ssp_dev *dev)
140{ 153{
154 int timeout = TIMEOUT * 2;
155
141 do { 156 do {
142 while (SSSR_P(dev->port) & SSSR_RNE) { 157 while (SSSR_P(dev->port) & SSSR_RNE) {
158 if (!--timeout)
159 return -ETIMEDOUT;
143 (void) SSDR_P(dev->port); 160 (void) SSDR_P(dev->port);
144 } 161 }
162 if (!--timeout)
163 return -ETIMEDOUT;
145 } while (SSSR_P(dev->port) & SSSR_BSY); 164 } while (SSSR_P(dev->port) & SSSR_BSY);
165
166 return 0;
146} 167}
147 168
148/** 169/**
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
index 1604dadf27fc..5eba5fbbb561 100644
--- a/arch/arm/mach-sa1100/ssp.c
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -23,6 +23,8 @@
23#include <asm/hardware.h> 23#include <asm/hardware.h>
24#include <asm/hardware/ssp.h> 24#include <asm/hardware/ssp.h>
25 25
26#define TIMEOUT 100000
27
26static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) 28static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
27{ 29{
28 unsigned int status = Ser4SSSR; 30 unsigned int status = Ser4SSSR;
@@ -47,18 +49,27 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
47 * The caller is expected to perform the necessary locking. 49 * The caller is expected to perform the necessary locking.
48 * 50 *
49 * Returns: 51 * Returns:
50 * %-ETIMEDOUT timeout occurred (for future) 52 * %-ETIMEDOUT timeout occurred
51 * 0 success 53 * 0 success
52 */ 54 */
53int ssp_write_word(u16 data) 55int ssp_write_word(u16 data)
54{ 56{
55 while (!(Ser4SSSR & SSSR_TNF)) 57 int timeout = TIMEOUT;
58
59 while (!(Ser4SSSR & SSSR_TNF)) {
60 if (!--timeout)
61 return -ETIMEDOUT;
56 cpu_relax(); 62 cpu_relax();
63 }
57 64
58 Ser4SSDR = data; 65 Ser4SSDR = data;
59 66
60 while (!(Ser4SSSR & SSSR_BSY)) 67 timeout = TIMEOUT;
68 while (!(Ser4SSSR & SSSR_BSY)) {
69 if (!--timeout)
70 return -ETIMEDOUT;
61 cpu_relax(); 71 cpu_relax();
72 }
62 73
63 return 0; 74 return 0;
64} 75}
@@ -75,15 +86,22 @@ int ssp_write_word(u16 data)
75 * The caller is expected to perform the necessary locking. 86 * The caller is expected to perform the necessary locking.
76 * 87 *
77 * Returns: 88 * Returns:
78 * %-ETIMEDOUT timeout occurred (for future) 89 * %-ETIMEDOUT timeout occurred
79 * 16-bit data success 90 * 16-bit data success
80 */ 91 */
81int ssp_read_word(void) 92int ssp_read_word(u16 *data)
82{ 93{
83 while (!(Ser4SSSR & SSSR_RNE)) 94 int timeout = TIMEOUT;
95
96 while (!(Ser4SSSR & SSSR_RNE)) {
97 if (!--timeout)
98 return -ETIMEDOUT;
84 cpu_relax(); 99 cpu_relax();
100 }
101
102 *data = (u16)Ser4SSDR;
85 103
86 return Ser4SSDR; 104 return 0;
87} 105}
88 106
89/** 107/**
@@ -93,14 +111,26 @@ int ssp_read_word(void)
93 * is empty. 111 * is empty.
94 * 112 *
95 * The caller is expected to perform the necessary locking. 113 * The caller is expected to perform the necessary locking.
114 *
115 * Returns:
116 * %-ETIMEDOUT timeout occurred
117 * 0 success
96 */ 118 */
97void ssp_flush(void) 119int ssp_flush(void)
98{ 120{
121 int timeout = TIMEOUT * 2;
122
99 do { 123 do {
100 while (Ser4SSSR & SSSR_RNE) { 124 while (Ser4SSSR & SSSR_RNE) {
125 if (!--timeout)
126 return -ETIMEDOUT;
101 (void) Ser4SSDR; 127 (void) Ser4SSDR;
102 } 128 }
129 if (!--timeout)
130 return -ETIMEDOUT;
103 } while (Ser4SSSR & SSSR_BSY); 131 } while (Ser4SSSR & SSSR_BSY);
132
133 return 0;
104} 134}
105 135
106/** 136/**
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5f80f184cd32..b4f220dd5eb8 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -46,7 +46,7 @@ config CPU_ARM710
46config CPU_ARM720T 46config CPU_ARM720T
47 bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR 47 bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
48 default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X 48 default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
49 select CPU_32v4 49 select CPU_32v4T
50 select CPU_ABRT_LV4T 50 select CPU_ABRT_LV4T
51 select CPU_CACHE_V4 51 select CPU_CACHE_V4
52 select CPU_CACHE_VIVT 52 select CPU_CACHE_VIVT
@@ -64,7 +64,7 @@ config CPU_ARM920T
64 bool "Support ARM920T processor" 64 bool "Support ARM920T processor"
65 depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 65 depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
66 default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200 66 default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
67 select CPU_32v4 67 select CPU_32v4T
68 select CPU_ABRT_EV4T 68 select CPU_ABRT_EV4T
69 select CPU_CACHE_V4WT 69 select CPU_CACHE_V4WT
70 select CPU_CACHE_VIVT 70 select CPU_CACHE_VIVT
@@ -85,7 +85,7 @@ config CPU_ARM922T
85 bool "Support ARM922T processor" if ARCH_INTEGRATOR 85 bool "Support ARM922T processor" if ARCH_INTEGRATOR
86 depends on ARCH_LH7A40X || ARCH_INTEGRATOR 86 depends on ARCH_LH7A40X || ARCH_INTEGRATOR
87 default y if ARCH_LH7A40X 87 default y if ARCH_LH7A40X
88 select CPU_32v4 88 select CPU_32v4T
89 select CPU_ABRT_EV4T 89 select CPU_ABRT_EV4T
90 select CPU_CACHE_V4WT 90 select CPU_CACHE_V4WT
91 select CPU_CACHE_VIVT 91 select CPU_CACHE_VIVT
@@ -104,7 +104,7 @@ config CPU_ARM925T
104 bool "Support ARM925T processor" if ARCH_OMAP1 104 bool "Support ARM925T processor" if ARCH_OMAP1
105 depends on ARCH_OMAP15XX 105 depends on ARCH_OMAP15XX
106 default y if ARCH_OMAP15XX 106 default y if ARCH_OMAP15XX
107 select CPU_32v4 107 select CPU_32v4T
108 select CPU_ABRT_EV4T 108 select CPU_ABRT_EV4T
109 select CPU_CACHE_V4WT 109 select CPU_CACHE_V4WT
110 select CPU_CACHE_VIVT 110 select CPU_CACHE_VIVT
@@ -285,6 +285,11 @@ config CPU_32v4
285 select TLS_REG_EMUL if SMP || !MMU 285 select TLS_REG_EMUL if SMP || !MMU
286 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP 286 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
287 287
288config CPU_32v4T
289 bool
290 select TLS_REG_EMUL if SMP || !MMU
291 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
292
288config CPU_32v5 293config CPU_32v5
289 bool 294 bool
290 select TLS_REG_EMUL if SMP || !MMU 295 select TLS_REG_EMUL if SMP || !MMU
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 4b97950984e9..5fbdf81a8aaf 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -353,3 +353,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand);
353 * A special flag to tell the normalisation code not to normalise. 353 * A special flag to tell the normalisation code not to normalise.
354 */ 354 */
355#define VFP_NAN_FLAG 0x100 355#define VFP_NAN_FLAG 0x100
356
357/*
358 * A bit pattern used to indicate the initial (unset) value of the
359 * exception mask, in case nothing handles an instruction. This
360 * doesn't include the NAN flag, which get masked out before
361 * we check for an error.
362 */
363#define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG)
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 009038c8113e..04bd3425b29b 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -465,7 +465,7 @@ static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr)
465 */ 465 */
466 if (tm & (VFP_INFINITY|VFP_NAN)) { 466 if (tm & (VFP_INFINITY|VFP_NAN)) {
467 vsd.exponent = 255; 467 vsd.exponent = 255;
468 if (tm & VFP_NAN) 468 if (tm == VFP_QNAN)
469 vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; 469 vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
470 goto pack_nan; 470 goto pack_nan;
471 } else if (tm & VFP_ZERO) 471 } else if (tm & VFP_ZERO)
@@ -1127,7 +1127,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1127{ 1127{
1128 u32 op = inst & FOP_MASK; 1128 u32 op = inst & FOP_MASK;
1129 u32 exceptions = 0; 1129 u32 exceptions = 0;
1130 unsigned int dd = vfp_get_dd(inst); 1130 unsigned int dest;
1131 unsigned int dn = vfp_get_dn(inst); 1131 unsigned int dn = vfp_get_dn(inst);
1132 unsigned int dm = vfp_get_dm(inst); 1132 unsigned int dm = vfp_get_dm(inst);
1133 unsigned int vecitr, veclen, vecstride; 1133 unsigned int vecitr, veclen, vecstride;
@@ -1137,10 +1137,20 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1137 vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; 1137 vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2;
1138 1138
1139 /* 1139 /*
1140 * fcvtds takes an sN register number as destination, not dN.
1141 * It also always operates on scalars.
1142 */
1143 if ((inst & FEXT_MASK) == FEXT_FCVT) {
1144 veclen = 0;
1145 dest = vfp_get_sd(inst);
1146 } else
1147 dest = vfp_get_dd(inst);
1148
1149 /*
1140 * If destination bank is zero, vector length is always '1'. 1150 * If destination bank is zero, vector length is always '1'.
1141 * ARM DDI0100F C5.1.3, C5.3.2. 1151 * ARM DDI0100F C5.1.3, C5.3.2.
1142 */ 1152 */
1143 if (FREG_BANK(dd) == 0) 1153 if (FREG_BANK(dest) == 0)
1144 veclen = 0; 1154 veclen = 0;
1145 1155
1146 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1156 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
@@ -1153,16 +1163,20 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1153 for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { 1163 for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
1154 u32 except; 1164 u32 except;
1155 1165
1156 if (op == FOP_EXT) 1166 if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
1167 pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n",
1168 vecitr >> FPSCR_LENGTH_BIT,
1169 dest, dn, dm);
1170 else if (op == FOP_EXT)
1157 pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", 1171 pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
1158 vecitr >> FPSCR_LENGTH_BIT, 1172 vecitr >> FPSCR_LENGTH_BIT,
1159 dd, dn, dm); 1173 dest, dn, dm);
1160 else 1174 else
1161 pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", 1175 pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
1162 vecitr >> FPSCR_LENGTH_BIT, 1176 vecitr >> FPSCR_LENGTH_BIT,
1163 dd, dn, FOP_TO_IDX(op), dm); 1177 dest, dn, FOP_TO_IDX(op), dm);
1164 1178
1165 except = fop(dd, dn, dm, fpscr); 1179 except = fop(dest, dn, dm, fpscr);
1166 pr_debug("VFP: itr%d: exceptions=%08x\n", 1180 pr_debug("VFP: itr%d: exceptions=%08x\n",
1167 vecitr >> FPSCR_LENGTH_BIT, except); 1181 vecitr >> FPSCR_LENGTH_BIT, except);
1168 1182
@@ -1180,7 +1194,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1180 * we encounter an exception. We continue. 1194 * we encounter an exception. We continue.
1181 */ 1195 */
1182 1196
1183 dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6); 1197 dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6);
1184 dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); 1198 dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6);
1185 if (FREG_BANK(dm) != 0) 1199 if (FREG_BANK(dm) != 0)
1186 dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6); 1200 dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6);
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 9d265d5e748c..4178f6cc3d37 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -131,7 +131,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
131 131
132 pr_debug("VFP: raising exceptions %08x\n", exceptions); 132 pr_debug("VFP: raising exceptions %08x\n", exceptions);
133 133
134 if (exceptions == (u32)-1) { 134 if (exceptions == VFP_EXCEPTION_ERROR) {
135 vfp_panic("unhandled bounce"); 135 vfp_panic("unhandled bounce");
136 vfp_raise_sigfpe(0, regs); 136 vfp_raise_sigfpe(0, regs);
137 return; 137 return;
@@ -170,7 +170,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
170 */ 170 */
171static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) 171static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
172{ 172{
173 u32 exceptions = (u32)-1; 173 u32 exceptions = VFP_EXCEPTION_ERROR;
174 174
175 pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr); 175 pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr);
176 176
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index dae2c2f46052..78d7cac5f36b 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -506,7 +506,7 @@ static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr)
506 */ 506 */
507 if (tm & (VFP_INFINITY|VFP_NAN)) { 507 if (tm & (VFP_INFINITY|VFP_NAN)) {
508 vdd.exponent = 2047; 508 vdd.exponent = 2047;
509 if (tm & VFP_NAN) 509 if (tm == VFP_QNAN)
510 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; 510 vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
511 goto pack_nan; 511 goto pack_nan;
512 } else if (tm & VFP_ZERO) 512 } else if (tm & VFP_ZERO)
@@ -514,10 +514,6 @@ static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr)
514 else 514 else
515 vdd.exponent = vsm.exponent + (1023 - 127); 515 vdd.exponent = vsm.exponent + (1023 - 127);
516 516
517 /*
518 * Technically, if bit 0 of dd is set, this is an invalid
519 * instruction. However, we ignore this for efficiency.
520 */
521 return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd"); 517 return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd");
522 518
523 pack_nan: 519 pack_nan:
@@ -1174,7 +1170,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
1174{ 1170{
1175 u32 op = inst & FOP_MASK; 1171 u32 op = inst & FOP_MASK;
1176 u32 exceptions = 0; 1172 u32 exceptions = 0;
1177 unsigned int sd = vfp_get_sd(inst); 1173 unsigned int dest;
1178 unsigned int sn = vfp_get_sn(inst); 1174 unsigned int sn = vfp_get_sn(inst);
1179 unsigned int sm = vfp_get_sm(inst); 1175 unsigned int sm = vfp_get_sm(inst);
1180 unsigned int vecitr, veclen, vecstride; 1176 unsigned int vecitr, veclen, vecstride;
@@ -1184,10 +1180,22 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
1184 vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); 1180 vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
1185 1181
1186 /* 1182 /*
1183 * fcvtsd takes a dN register number as destination, not sN.
1184 * Technically, if bit 0 of dd is set, this is an invalid
1185 * instruction. However, we ignore this for efficiency.
1186 * It also only operates on scalars.
1187 */
1188 if ((inst & FEXT_MASK) == FEXT_FCVT) {
1189 veclen = 0;
1190 dest = vfp_get_dd(inst);
1191 } else
1192 dest = vfp_get_sd(inst);
1193
1194 /*
1187 * If destination bank is zero, vector length is always '1'. 1195 * If destination bank is zero, vector length is always '1'.
1188 * ARM DDI0100F C5.1.3, C5.3.2. 1196 * ARM DDI0100F C5.1.3, C5.3.2.
1189 */ 1197 */
1190 if (FREG_BANK(sd) == 0) 1198 if (FREG_BANK(dest) == 0)
1191 veclen = 0; 1199 veclen = 0;
1192 1200
1193 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1201 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
@@ -1201,15 +1209,18 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
1201 s32 m = vfp_get_float(sm); 1209 s32 m = vfp_get_float(sm);
1202 u32 except; 1210 u32 except;
1203 1211
1204 if (op == FOP_EXT) 1212 if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
1213 pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n",
1214 vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
1215 else if (op == FOP_EXT)
1205 pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n", 1216 pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n",
1206 vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m); 1217 vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
1207 else 1218 else
1208 pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", 1219 pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n",
1209 vecitr >> FPSCR_LENGTH_BIT, sd, sn, 1220 vecitr >> FPSCR_LENGTH_BIT, dest, sn,
1210 FOP_TO_IDX(op), sm, m); 1221 FOP_TO_IDX(op), sm, m);
1211 1222
1212 except = fop(sd, sn, m, fpscr); 1223 except = fop(dest, sn, m, fpscr);
1213 pr_debug("VFP: itr%d: exceptions=%08x\n", 1224 pr_debug("VFP: itr%d: exceptions=%08x\n",
1214 vecitr >> FPSCR_LENGTH_BIT, except); 1225 vecitr >> FPSCR_LENGTH_BIT, except);
1215 1226
@@ -1227,7 +1238,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
1227 * we encounter an exception. We continue. 1238 * we encounter an exception. We continue.
1228 */ 1239 */
1229 1240
1230 sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7); 1241 dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
1231 sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); 1242 sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
1232 if (FREG_BANK(sm) != 0) 1243 if (FREG_BANK(sm) != 0)
1233 sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7); 1244 sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);