From 7c6f25141b88b5e926f9d43932ce668602d611ae Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Sun, 27 Aug 2006 12:42:08 +0100 Subject: [ARM] 3748/3: Correct error check in vfp_raise_exceptions Patch from Daniel Jacobowitz The recent fix to hide VFP_NAN_FLAG broke the check in vfp_raise_exceptions; it would attempt to deliver an exception mask of 0xfffffeff instead of reporting a serious error condition using printk. Define a safe constant to use for an invalid exception maskm, and use it at both ends. Signed-off-by: Daniel Jacobowitz Signed-off-by: Russell King --- arch/arm/vfp/vfp.h | 8 ++++++++ arch/arm/vfp/vfpmodule.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) 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 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); * 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/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 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ 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 void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ */ 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); -- cgit v1.1 From c29ecac18cb740ae845db14963ac586c53962453 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Sun, 27 Aug 2006 12:42:10 +0100 Subject: [ARM] 3749/3: Correct VFP single/double conversion emulation Patch from Daniel Jacobowitz The fcvtsd/fcvtds emulation was left behind when the numbering of double precision registers was changed from 0-30 to 0-15. Both conversion instructions were writing their results to the wrong register. Also, the conversion instructions should stop after the first element even if a vector length is specified. Signed-off-by: Daniel Jacobowitz Signed-off-by: Russell King --- arch/arm/vfp/vfpdouble.c | 28 +++++++++++++++++++++------- arch/arm/vfp/vfpsingle.c | 33 ++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 009038c..0215816 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -1127,7 +1127,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) { 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 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) 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 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) 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 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) * 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/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index dae2c2f..5bbd5d1 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -514,10 +514,6 @@ static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr) 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 vfp_single_cpdo(u32 inst, u32 fpscr) { 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 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) 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 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) 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 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) * 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); -- cgit v1.1 From b53a2b41f156a9c9b62c14502037cbc15bc08b54 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Sun, 27 Aug 2006 12:42:14 +0100 Subject: [ARM] 3758/1: Preserve signalling NaNs in conversion Patch from Daniel Jacobowitz The fcvtds and fcvtsd instructions were generating a qnan bit pattern for both quiet and signalling NaNs. Signed-off-by: Daniel Jacobowitz Signed-off-by: Russell King --- arch/arm/vfp/vfpdouble.c | 2 +- arch/arm/vfp/vfpsingle.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 0215816..04bd342 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) */ 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) diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 5bbd5d1..78d7cac 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) */ 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) -- cgit v1.1 From 8f1bf8743c459399685f5df43021acd156548c22 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 27 Aug 2006 12:54:56 +0100 Subject: [ARM] 3760/1: This patch adds timeouts while working with SSP registers. Such timeouts were en Patch from Paul Sokolovsky This patch adds timeouts while working with SSP registers. Such timeouts were envisioned by docstrings in ssp.c, but were not implemented. There were actual lockups while accessing touchscreen for iPaqs h1910, h4000 due to lack of the timeouts. This is updated version of previously submitted patch: 3738/1. Signed-off-by: Paul Sokolovsky Signed-off-by: Russell King --- arch/arm/mach-pxa/corgi_ssp.c | 20 ++++++++++-------- arch/arm/mach-pxa/ssp.c | 35 +++++++++++++++++++++++++------- arch/arm/mach-sa1100/ssp.c | 46 ++++++++++++++++++++++++++++++++++-------- include/asm-arm/arch-pxa/ssp.h | 4 ++-- include/asm-arm/hardware/ssp.h | 4 ++-- 5 files changed, 82 insertions(+), 27 deletions(-) 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 @@ static struct corgissp_machinfo *ssp_machinfo; */ 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 @@ void corgi_ssp_ads7846_put(ulong data) 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 @@ EXPORT_SYMBOL(corgi_ssp_ads7846_get); 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 @@ unsigned long corgi_ssp_dac_put(ulong data) 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 @@ EXPORT_SYMBOL(corgi_ssp_blduty_set); 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 @@ int corgi_ssp_max1111_get(ulong data) /* 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 93096be..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 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) * 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 @@ int ssp_write_word(struct ssp_dev *dev, u32 data) * 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)) + int timeout = TIMEOUT; + + while (!(SSSR_P(dev->port) & SSSR_RNE)) { + if (!--timeout) + return -ETIMEDOUT; cpu_relax(); + } - return SSDR_P(dev->port); + *data = SSDR_P(dev->port); + return 0; } /** @@ -136,13 +149,21 @@ int ssp_read_word(struct ssp_dev *dev) * * 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 #include +#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 @@ static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs) * 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 @@ int ssp_write_word(u16 data) * 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)) + int timeout = TIMEOUT; + + while (!(Ser4SSSR & SSSR_RNE)) { + if (!--timeout) + return -ETIMEDOUT; cpu_relax(); + } + + *data = (u16)Ser4SSDR; - return Ser4SSDR; + return 0; } /** @@ -93,14 +111,26 @@ int ssp_read_word(void) * 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/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 @@ struct ssp_dev { }; 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 @@ struct ssp_state { }; 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); -- cgit v1.1 From 416112f818afcc08aeaba79ebba899aee5ddf571 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 27 Aug 2006 13:09:14 +0100 Subject: [ARM] 3741/1: remove sa1111.c build warning on non-sa1100 systems Patch from David Brownell Remove buld warning when building sa1111 on non-sa1100 platforms (e.g. PXA). Signed-off-by: David Brownell Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) { 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_probe(struct device *me, struct resource *mem, int irq) 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 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) * Enable the SA1110 memory bus request and grant signals. */ sa1110_mb_enable(); + } #endif /* -- cgit v1.1 From 7034b0e60a2ccfab4ee2d3a468cb8cad6de3740d Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 28 Aug 2006 12:44:03 +0100 Subject: [ARM] Arrange for isa.c to use named initialisers Convert isa.c (the glibc interface for emulating ISA IO) to use named initialisers. Signed-off-by: Russell King --- arch/arm/kernel/isa.c | 63 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 21 deletions(-) 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 #include #include @@ -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) -- cgit v1.1 From 1645f20bc4440d6f67f73f570f3cf873b4e37f3c Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 28 Aug 2006 12:45:16 +0100 Subject: [ARM] Move prototype for register_isa_ports to asm/io.h Signed-off-by: Russell King --- arch/arm/mach-footbridge/dc21285.c | 1 - include/asm-arm/io.h | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) 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/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 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); */ #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 */ -- cgit v1.1 From 863dab453b869136453944bda63e20b6ed39c5ef Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 28 Aug 2006 12:47:05 +0100 Subject: [ARM] Add Integrator support for glibc outb() and friends Add the necessary call to register_isa_ports() so that glibc knows where these are found on Integrator platforms. Signed-off-by: Russell King --- arch/arm/kernel/Makefile | 3 +-- arch/arm/mach-integrator/pci_v3.c | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) 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-y := compat.o entry-armv.o entry-common.o irq.o \ 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/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 @@ void __init pci_v3_postinit(void) 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); } -- cgit v1.1 From 260e98edc8ae8ea862c9c222eeffb1a2eeafa7fc Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 28 Aug 2006 12:51:20 +0100 Subject: [ARM] 3761/1: fix armv4t breakage after adding thumb interworking to userspace helpers Patch from Lennert Buytenhek On armv4t systems, we have always compiled the kernel with -march=armv4 instead of -march=armv4t, which means that any use of bx will bomb out. Commit ba9b5d76372dc290b6ca04dad93927a22c2ac49a introduced the use of bx in the kernel, which means we need to compile with -march=armv4t on armv4t systems now. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/Makefile | 3 ++- arch/arm/mm/Kconfig | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) 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 @@ comma = , # 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/mm/Kconfig b/arch/arm/mm/Kconfig index 5f80f18..b4f220d 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -46,7 +46,7 @@ config CPU_ARM710 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 @@ config CPU_ARM920T 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 @@ config CPU_ARM922T 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 @@ config CPU_ARM925T 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 @@ config CPU_32v4 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 -- cgit v1.1