diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-09 08:29:31 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-09 08:29:31 -0800 |
commit | 437f2f91d6597c67662f847d9ed4c99cb3c440cd (patch) | |
tree | 9051f1a9cccd9951f1c7eb89f064d27c1b592497 /arch/arm | |
parent | 4d9c6a21befe6c73c35f2799c7e25a9eda82a95d (diff) | |
parent | baa745a3378046ca1c5477495df6ccbec7690428 (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm:
[ARM] Fix alignment fault handling for ARMv6 and later CPUs
[ARM] 5340/1: fix stack placement after noexecstack changes
[ARM] 5339/1: fix __fls() on ARM
[ARM] Orion: fix bug in pcie configuration cycle function field mask
[ARM] omap: fix a pile of issues
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/bitops.h | 16 | ||||
-rw-r--r-- | arch/arm/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap1/io.c | 2 | ||||
-rw-r--r-- | arch/arm/mm/alignment.c | 26 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/omapfb.h | 4 | ||||
-rw-r--r-- | arch/arm/plat-omap/sram.c | 8 | ||||
-rw-r--r-- | arch/arm/plat-orion/pcie.c | 2 |
7 files changed, 42 insertions, 18 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index 9a1db20e032..63a481fbbed 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -237,6 +237,7 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); #if __LINUX_ARM_ARCH__ < 5 #include <asm-generic/bitops/ffz.h> +#include <asm-generic/bitops/__fls.h> #include <asm-generic/bitops/__ffs.h> #include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/ffs.h> @@ -277,16 +278,19 @@ static inline int constant_fls(int x) * the clz instruction for much better code efficiency. */ -#define __fls(x) \ - ( __builtin_constant_p(x) ? constant_fls(x) : \ - ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) - -/* Implement fls() in C so that 64-bit args are suitably truncated */ static inline int fls(int x) { - return __fls(x); + int ret; + + if (__builtin_constant_p(x)) + return constant_fls(x); + + asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc"); + ret = 32 - ret; + return ret; } +#define __fls(x) (fls(x) - 1) #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) #define __ffs(x) (ffs(x) - 1) #define ffz(x) __ffs( ~(x) ) diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 517a4d6ffc7..6ff33790f47 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -23,7 +23,7 @@ #include <asm/types.h> #ifdef __KERNEL__ -#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \ +#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ TASK_SIZE : TASK_SIZE_26) #define STACK_TOP_MAX TASK_SIZE #endif diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index b3bd8ca8511..4c3e582f3d3 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -128,7 +128,7 @@ void __init omap1_map_common_io(void) * Common low-level hardware init for omap1. This should only get called from * board specific init. */ -void __init omap1_init_common_hw() +void __init omap1_init_common_hw(void) { /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort * on a Posted Write in the TIPB Bridge". diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 133e65d166b..2d5884ce043 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -70,6 +70,10 @@ static unsigned long ai_dword; static unsigned long ai_multi; static int ai_usermode; +#define UM_WARN (1 << 0) +#define UM_FIXUP (1 << 1) +#define UM_SIGNAL (1 << 2) + #ifdef CONFIG_PROC_FS static const char *usermode_action[] = { "ignored", @@ -754,7 +758,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) user: ai_user += 1; - if (ai_usermode & 1) + if (ai_usermode & UM_WARN) printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx " "Address=0x%08lx FSR 0x%03x\n", current->comm, task_pid_nr(current), instrptr, @@ -762,10 +766,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) thumb_mode(regs) ? tinstr : instr, addr, fsr); - if (ai_usermode & 2) + if (ai_usermode & UM_FIXUP) goto fixup; - if (ai_usermode & 4) + if (ai_usermode & UM_SIGNAL) force_sig(SIGBUS, current); else set_cr(cr_no_alignment); @@ -796,6 +800,22 @@ static int __init alignment_init(void) res->write_proc = proc_alignment_write; #endif + /* + * ARMv6 and later CPUs can perform unaligned accesses for + * most single load and store instructions up to word size. + * LDM, STM, LDRD and STRD still need to be handled. + * + * Ignoring the alignment fault is not an option on these + * CPUs since we spin re-faulting the instruction without + * making any progress. + */ + if (cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U)) { + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + ai_usermode = UM_FIXUP; + } + hook_fault_code(1, do_alignment, SIGILL, "alignment exception"); hook_fault_code(3, do_alignment, SIGILL, "alignment exception"); diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h index ec67fb42860..7b74d1255e0 100644 --- a/arch/arm/plat-omap/include/mach/omapfb.h +++ b/arch/arm/plat-omap/include/mach/omapfb.h @@ -353,8 +353,8 @@ struct omapfb_device { u32 pseudo_palette[17]; struct lcd_panel *panel; /* LCD panel */ - struct lcd_ctrl *ctrl; /* LCD controller */ - struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */ + const struct lcd_ctrl *ctrl; /* LCD controller */ + const struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */ struct lcd_ctrl_extif *ext_if; /* LCD ctrl external interface */ struct device *dev; diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 9f9a921829c..dcd9d16da2e 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -255,7 +255,7 @@ void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) if (!_omap_sram_reprogram_clock) omap_sram_error(); - return _omap_sram_reprogram_clock(dpllctl, ckctl); + _omap_sram_reprogram_clock(dpllctl, ckctl); } int __init omap1_sram_init(void) @@ -282,8 +282,8 @@ void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, if (!_omap2_sram_ddr_init) omap_sram_error(); - return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, - base_cs, force_unlock); + _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, + base_cs, force_unlock); } static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val, @@ -294,7 +294,7 @@ void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) if (!_omap2_sram_reprogram_sdrc) omap_sram_error(); - return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); + _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); } static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index 883902fead8..d41d41d78ad 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c @@ -35,7 +35,7 @@ #define PCIE_CONF_REG(r) ((((r) & 0xf00) << 16) | ((r) & 0xfc)) #define PCIE_CONF_BUS(b) (((b) & 0xff) << 16) #define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11) -#define PCIE_CONF_FUNC(f) (((f) & 0x3) << 8) +#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8) #define PCIE_CONF_DATA_OFF 0x18fc #define PCIE_MASK_OFF 0x1910 #define PCIE_CTRL_OFF 0x1a00 |