diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /arch/arm/kernel | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'arch/arm/kernel')
27 files changed, 218 insertions, 472 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a30fc9b..5140df5f 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -17,8 +17,7 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := elf.o entry-common.o irq.o opcodes.o \ process.o ptrace.o return_address.o \ - setup.o signal.o sigreturn_codes.o \ - stacktrace.o sys_arm.o time.o traps.o + setup.o signal.o stacktrace.o sys_arm.o time.o traps.o obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o @@ -79,7 +78,6 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o -obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index 1791f12..221f07b 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -11,6 +11,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/errno.h> +#include <linux/sched_clock.h> #include <asm/delay.h> @@ -21,6 +22,13 @@ static unsigned long arch_timer_read_counter_long(void) return arch_timer_read_counter(); } +static u32 sched_clock_mult __read_mostly; + +static unsigned long long notrace arch_timer_sched_clock(void) +{ + return arch_timer_read_counter() * sched_clock_mult; +} + static struct delay_timer arch_delay_timer; static void __init arch_timer_delay_timer_register(void) @@ -40,5 +48,11 @@ int __init arch_timer_arch_init(void) arch_timer_delay_timer_register(); + /* Cache the sched_clock multiplier to save a divide in the hot path. */ + sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; + sched_clock_func = arch_timer_sched_clock; + pr_info("sched_clock: ARM arch timer >56 bits at %ukHz, resolution %uns\n", + arch_timer_rate / 1000, sched_clock_mult); + return 0; } diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 1f031dd..60d3b73 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -155,5 +155,4 @@ EXPORT_SYMBOL(__gnu_mcount_nc); #ifdef CONFIG_ARM_PATCH_PHYS_VIRT EXPORT_SYMBOL(__pv_phys_offset); -EXPORT_SYMBOL(__pv_offset); #endif diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 739c3df..f35906b 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -174,19 +174,6 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu); } -static const void * __init arch_get_next_mach(const char *const **match) -{ - static const struct machine_desc *mdesc = __arch_info_begin; - const struct machine_desc *m = mdesc; - - if (m >= __arch_info_end) - return NULL; - - mdesc++; - *match = m->dt_compat; - return m; -} - /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel * @dt_phys: physical address of dt blob @@ -196,7 +183,11 @@ static const void * __init arch_get_next_mach(const char *const **match) */ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) { + struct boot_param_header *devtree; const struct machine_desc *mdesc, *mdesc_best = NULL; + unsigned int score, mdesc_score = ~1; + unsigned long dt_root; + const char *model; #ifdef CONFIG_ARCH_MULTIPLATFORM DT_MACHINE_START(GENERIC_DT, "Generic DT based system") @@ -205,20 +196,32 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) mdesc_best = &__mach_desc_GENERIC_DT; #endif - if (!dt_phys || !early_init_dt_scan(phys_to_virt(dt_phys))) + if (!dt_phys) return NULL; - mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach); + devtree = phys_to_virt(dt_phys); - if (!mdesc) { + /* check device tree validity */ + if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) + return NULL; + + /* Search the mdescs for the 'best' compatible value match */ + initial_boot_params = devtree; + dt_root = of_get_flat_dt_root(); + for_each_machine_desc(mdesc) { + score = of_flat_dt_match(dt_root, mdesc->dt_compat); + if (score > 0 && score < mdesc_score) { + mdesc_best = mdesc; + mdesc_score = score; + } + } + if (!mdesc_best) { const char *prop; long size; - unsigned long dt_root; early_print("\nError: unrecognized/unsupported " "device tree compatible list:\n[ "); - dt_root = of_get_flat_dt_root(); prop = of_get_flat_dt_prop(dt_root, "compatible", &size); while (size > 0) { early_print("'%s' ", prop); @@ -230,8 +233,22 @@ const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) dump_machine_table(); /* does not return */ } + model = of_get_flat_dt_prop(dt_root, "model", NULL); + if (!model) + model = of_get_flat_dt_prop(dt_root, "compatible", NULL); + if (!model) + model = "<unknown>"; + pr_info("Machine: %s, model: %s\n", mdesc_best->name, model); + + /* Retrieve various information from the /chosen node */ + of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); + /* Initialize {size,address}-cells info */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + /* Setup memory, calling early_init_dt_add_memory_arch */ + of_scan_flat_dt(early_init_dt_scan_memory, NULL); + /* Change machine number to match the mdesc we're using */ - __machine_arch_type = mdesc->nr; + __machine_arch_type = mdesc_best->nr; - return mdesc; + return mdesc_best; } diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index b3fb8c9..9cbe70c 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -192,7 +192,6 @@ __dabt_svc: svc_entry mov r2, sp dabt_helper - THUMB( ldr r5, [sp, #S_PSR] ) @ potentially updated CPSR svc_exit r5 @ return from exception UNWIND(.fnend ) ENDPROC(__dabt_svc) @@ -417,8 +416,9 @@ __und_usr: bne __und_usr_thumb sub r4, r2, #4 @ ARM instr at LR - 4 1: ldrt r0, [r4] - ARM_BE8(rev r0, r0) @ little endian instruction - +#ifdef CONFIG_CPU_ENDIAN_BE8 + rev r0, r0 @ little endian instruction +#endif @ r0 = 32-bit ARM instruction which caused the exception @ r2 = PC value for the following instruction (:= regs->ARM_pc) @ r4 = PC value for the faulting instruction diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index a2dcafd..bc6bd96 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -393,7 +393,9 @@ ENTRY(vector_swi) #else USER( ldr r10, [lr, #-4] ) @ get SWI instruction #endif - ARM_BE8(rev r10, r10) @ little endian instruction +#ifdef CONFIG_CPU_ENDIAN_BE8 + rev r10, r10 @ little endian instruction +#endif #elif defined(CONFIG_AEABI) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 11d59b3..476de57 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -77,7 +77,6 @@ __HEAD ENTRY(stext) - ARM_BE8(setend be ) @ ensure we are in BE8 mode THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel, @@ -353,9 +352,6 @@ ENTRY(secondary_startup) * the processor type - there is no need to check the machine type * as it has already been validated by the primary processor. */ - - ARM_BE8(setend be) @ ensure we are in BE8 mode - #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install_secondary #endif @@ -508,7 +504,6 @@ __fixup_smp: teq r0, #0x0 @ '0' on actual UP A9 hardware beq __fixup_smp_on_up @ So its an A9 UP ldr r0, [r0, #4] @ read SCU Config -ARM_BE8(rev r0, r0) @ byteswap if big endian and r0, r0, #0x3 @ number of CPUs teq r0, #0x0 @ is 1? movne pc, lr @@ -560,14 +555,6 @@ ENTRY(fixup_smp) ldmfd sp!, {r4 - r6, pc} ENDPROC(fixup_smp) -#ifdef __ARMEB__ -#define LOW_OFFSET 0x4 -#define HIGH_OFFSET 0x0 -#else -#define LOW_OFFSET 0x0 -#define HIGH_OFFSET 0x4 -#endif - #ifdef CONFIG_ARM_PATCH_PHYS_VIRT /* __fixup_pv_table - patch the stub instructions with the delta between @@ -578,20 +565,17 @@ ENDPROC(fixup_smp) __HEAD __fixup_pv_table: adr r0, 1f - ldmia r0, {r3-r7} - mvn ip, #0 - subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET + ldmia r0, {r3-r5, r7} + sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET add r4, r4, r3 @ adjust table start address add r5, r5, r3 @ adjust table end address - add r6, r6, r3 @ adjust __pv_phys_offset address - add r7, r7, r3 @ adjust __pv_offset address - str r8, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_offset - strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits + add r7, r7, r3 @ adjust __pv_phys_offset address + str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset mov r6, r3, lsr #24 @ constant for add/sub instructions teq r3, r6, lsl #24 @ must be 16MiB aligned THUMB( it ne @ cross section branch ) bne __error - str r3, [r7, #LOW_OFFSET] @ save to __pv_offset low bits + str r6, [r7, #4] @ save to __pv_offset b __fixup_a_pv_table ENDPROC(__fixup_pv_table) @@ -600,19 +584,10 @@ ENDPROC(__fixup_pv_table) .long __pv_table_begin .long __pv_table_end 2: .long __pv_phys_offset - .long __pv_offset .text __fixup_a_pv_table: - adr r0, 3f - ldr r6, [r0] - add r6, r6, r3 - ldr r0, [r6, #HIGH_OFFSET] @ pv_offset high word - ldr r6, [r6, #LOW_OFFSET] @ pv_offset low word - mov r6, r6, lsr #24 - cmn r0, #1 #ifdef CONFIG_THUMB2_KERNEL - moveq r0, #0x200000 @ set bit 21, mov to mvn instruction lsls r6, #24 beq 2f clz r7, r6 @@ -626,46 +601,18 @@ __fixup_a_pv_table: b 2f 1: add r7, r3 ldrh ip, [r7, #2] -ARM_BE8(rev16 ip, ip) - tst ip, #0x4000 - and ip, #0x8f00 - orrne ip, r6 @ mask in offset bits 31-24 - orreq ip, r0 @ mask in offset bits 7-0 -ARM_BE8(rev16 ip, ip) + and ip, 0x8f00 + orr ip, r6 @ mask in offset bits 31-24 strh ip, [r7, #2] - bne 2f - ldrh ip, [r7] -ARM_BE8(rev16 ip, ip) - bic ip, #0x20 - orr ip, ip, r0, lsr #16 -ARM_BE8(rev16 ip, ip) - strh ip, [r7] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot bcc 1b bx lr #else -#ifdef CONFIG_CPU_ENDIAN_BE8 - moveq r0, #0x00004000 @ set bit 22, mov to mvn instruction -#else - moveq r0, #0x400000 @ set bit 22, mov to mvn instruction -#endif b 2f 1: ldr ip, [r7, r3] -#ifdef CONFIG_CPU_ENDIAN_BE8 - @ in BE8, we load data in BE, but instructions still in LE - bic ip, ip, #0xff000000 - tst ip, #0x000f0000 @ check the rotation field - orrne ip, ip, r6, lsl #24 @ mask in offset bits 31-24 - biceq ip, ip, #0x00004000 @ clear bit 22 - orreq ip, ip, r0 @ mask in offset bits 7-0 -#else bic ip, ip, #0x000000ff - tst ip, #0xf00 @ check the rotation field - orrne ip, ip, r6 @ mask in offset bits 31-24 - biceq ip, ip, #0x400000 @ clear bit 22 - orreq ip, ip, r0 @ mask in offset bits 7-0 -#endif + orr ip, ip, r6 @ mask in offset bits 31-24 str ip, [r7, r3] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot @@ -674,30 +621,28 @@ ARM_BE8(rev16 ip, ip) #endif ENDPROC(__fixup_a_pv_table) - .align -3: .long __pv_offset - ENTRY(fixup_pv_table) stmfd sp!, {r4 - r7, lr} + ldr r2, 2f @ get address of __pv_phys_offset mov r3, #0 @ no offset mov r4, r0 @ r0 = table start add r5, r0, r1 @ r1 = table size + ldr r6, [r2, #4] @ get __pv_offset bl __fixup_a_pv_table ldmfd sp!, {r4 - r7, pc} ENDPROC(fixup_pv_table) + .align +2: .long __pv_phys_offset + .data .globl __pv_phys_offset .type __pv_phys_offset, %object __pv_phys_offset: - .quad 0 - .size __pv_phys_offset, . -__pv_phys_offset - - .globl __pv_offset - .type __pv_offset, %object + .long 0 + .size __pv_phys_offset, . - __pv_phys_offset __pv_offset: - .quad 0 - .size __pv_offset, . -__pv_offset + .long 0 #endif #include "head-common.S" diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 3d44660..7b95de6 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -344,13 +344,13 @@ int arch_install_hw_breakpoint(struct perf_event *bp) /* Breakpoint */ ctrl_base = ARM_BASE_BCR; val_base = ARM_BASE_BVR; - slots = this_cpu_ptr(bp_on_reg); + slots = (struct perf_event **)__get_cpu_var(bp_on_reg); max_slots = core_num_brps; } else { /* Watchpoint */ ctrl_base = ARM_BASE_WCR; val_base = ARM_BASE_WVR; - slots = this_cpu_ptr(wp_on_reg); + slots = (struct perf_event **)__get_cpu_var(wp_on_reg); max_slots = core_num_wrps; } @@ -396,12 +396,12 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { /* Breakpoint */ base = ARM_BASE_BCR; - slots = this_cpu_ptr(bp_on_reg); + slots = (struct perf_event **)__get_cpu_var(bp_on_reg); max_slots = core_num_brps; } else { /* Watchpoint */ base = ARM_BASE_WCR; - slots = this_cpu_ptr(wp_on_reg); + slots = (struct perf_event **)__get_cpu_var(wp_on_reg); max_slots = core_num_wrps; } @@ -697,7 +697,7 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; - slots = this_cpu_ptr(wp_on_reg); + slots = (struct perf_event **)__get_cpu_var(wp_on_reg); for (i = 0; i < core_num_wrps; ++i) { rcu_read_lock(); @@ -768,7 +768,7 @@ static void watchpoint_single_step_handler(unsigned long pc) struct perf_event *wp, **slots; struct arch_hw_breakpoint *info; - slots = this_cpu_ptr(wp_on_reg); + slots = (struct perf_event **)__get_cpu_var(wp_on_reg); for (i = 0; i < core_num_wrps; ++i) { rcu_read_lock(); @@ -802,7 +802,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; - slots = this_cpu_ptr(bp_on_reg); + slots = (struct perf_event **)__get_cpu_var(bp_on_reg); /* The exception entry code places the amended lr in the PC. */ addr = regs->ARM_pc; diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index a7b621e..170e9f3 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -171,13 +171,13 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) { - __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); + __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; kcb->kprobe_status = kcb->prev_kprobe.status; } static void __kprobes set_current_kprobe(struct kprobe *p) { - __this_cpu_write(current_kprobe, p); + __get_cpu_var(current_kprobe) = p; } static void __kprobes @@ -421,10 +421,10 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs) continue; if (ri->rp && ri->rp->handler) { - __this_cpu_write(current_kprobe, &ri->rp->kp); + __get_cpu_var(current_kprobe) = &ri->rp->kp; get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, NULL); + __get_cpu_var(current_kprobe) = NULL; } orig_ret_address = (unsigned long)ri->ret_addr; diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index f0d180d..57221e3 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -14,12 +14,11 @@ #include <asm/pgalloc.h> #include <asm/mmu_context.h> #include <asm/cacheflush.h> -#include <asm/fncpy.h> #include <asm/mach-types.h> #include <asm/smp_plat.h> #include <asm/system_misc.h> -extern void relocate_new_kernel(void); +extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; extern unsigned long kexec_start_address; @@ -143,8 +142,6 @@ void machine_kexec(struct kimage *image) { unsigned long page_list; unsigned long reboot_code_buffer_phys; - unsigned long reboot_entry = (unsigned long)relocate_new_kernel; - unsigned long reboot_entry_phys; void *reboot_code_buffer; /* @@ -171,16 +168,16 @@ void machine_kexec(struct kimage *image) /* copy our kernel relocation code to the control code page */ - reboot_entry = fncpy(reboot_code_buffer, - reboot_entry, - relocate_new_kernel_size); - reboot_entry_phys = (unsigned long)reboot_entry + - (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); + memcpy(reboot_code_buffer, + relocate_new_kernel, relocate_new_kernel_size); + + flush_icache_range((unsigned long) reboot_code_buffer, + (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); printk(KERN_INFO "Bye!\n"); if (kexec_reinit) kexec_reinit(); - soft_restart(reboot_entry_phys); + soft_restart(reboot_code_buffer_phys); } diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 45e4781..084dc88 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -24,7 +24,6 @@ #include <asm/sections.h> #include <asm/smp_plat.h> #include <asm/unwind.h> -#include <asm/opcodes.h> #ifdef CONFIG_XIP_KERNEL /* @@ -41,7 +40,7 @@ void *module_alloc(unsigned long size) { return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, - GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, + GFP_KERNEL, PAGE_KERNEL_EXEC, -1, __builtin_return_address(0)); } #endif @@ -61,7 +60,6 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, Elf32_Sym *sym; const char *symname; s32 offset; - u32 tmp; #ifdef CONFIG_THUMB2_KERNEL u32 upper, lower, sign, j1, j2; #endif @@ -97,8 +95,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_PC24: case R_ARM_CALL: case R_ARM_JUMP24: - offset = __mem_to_opcode_arm(*(u32 *)loc); - offset = (offset & 0x00ffffff) << 2; + offset = (*(u32 *)loc & 0x00ffffff) << 2; if (offset & 0x02000000) offset -= 0x04000000; @@ -114,10 +111,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, } offset >>= 2; - offset &= 0x00ffffff; - *(u32 *)loc &= __opcode_to_mem_arm(0xff000000); - *(u32 *)loc |= __opcode_to_mem_arm(offset); + *(u32 *)loc &= 0xff000000; + *(u32 *)loc |= offset & 0x00ffffff; break; case R_ARM_V4BX: @@ -125,8 +121,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, * other bits to re-code instruction as * MOV PC,Rm. */ - *(u32 *)loc &= __opcode_to_mem_arm(0xf000000f); - *(u32 *)loc |= __opcode_to_mem_arm(0x01a0f000); + *(u32 *)loc &= 0xf000000f; + *(u32 *)loc |= 0x01a0f000; break; case R_ARM_PREL31: @@ -136,7 +132,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: - offset = tmp = __mem_to_opcode_arm(*(u32 *)loc); + offset = *(u32 *)loc; offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); offset = (offset ^ 0x8000) - 0x8000; @@ -144,18 +140,16 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS) offset >>= 16; - tmp &= 0xfff0f000; - tmp |= ((offset & 0xf000) << 4) | - (offset & 0x0fff); - - *(u32 *)loc = __opcode_to_mem_arm(tmp); + *(u32 *)loc &= 0xfff0f000; + *(u32 *)loc |= ((offset & 0xf000) << 4) | + (offset & 0x0fff); break; #ifdef CONFIG_THUMB2_KERNEL case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: - upper = __mem_to_opcode_thumb16(*(u16 *)loc); - lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); + upper = *(u16 *)loc; + lower = *(u16 *)(loc + 2); /* * 25 bit signed address range (Thumb-2 BL and B.W @@ -204,20 +198,17 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, sign = (offset >> 24) & 1; j1 = sign ^ (~(offset >> 23) & 1); j2 = sign ^ (~(offset >> 22) & 1); - upper = (u16)((upper & 0xf800) | (sign << 10) | + *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) | ((offset >> 12) & 0x03ff)); - lower = (u16)((lower & 0xd000) | - (j1 << 13) | (j2 << 11) | - ((offset >> 1) & 0x07ff)); - - *(u16 *)loc = __opcode_to_mem_thumb16(upper); - *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); + *(u16 *)(loc + 2) = (u16)((lower & 0xd000) | + (j1 << 13) | (j2 << 11) | + ((offset >> 1) & 0x07ff)); break; case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: - upper = __mem_to_opcode_thumb16(*(u16 *)loc); - lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); + upper = *(u16 *)loc; + lower = *(u16 *)(loc + 2); /* * MOVT/MOVW instructions encoding in Thumb-2: @@ -238,14 +229,12 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS) offset >>= 16; - upper = (u16)((upper & 0xfbf0) | - ((offset & 0xf000) >> 12) | - ((offset & 0x0800) >> 1)); - lower = (u16)((lower & 0x8f00) | - ((offset & 0x0700) << 4) | - (offset & 0x00ff)); - *(u16 *)loc = __opcode_to_mem_thumb16(upper); - *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); + *(u16 *)loc = (u16)((upper & 0xfbf0) | + ((offset & 0xf000) >> 12) | + ((offset & 0x0800) >> 1)); + *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) | + ((offset & 0x0700) << 4) | + (offset & 0x00ff)); break; #endif diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index bc3f2ef..e186ee1 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -256,11 +256,12 @@ validate_event(struct pmu_hw_events *hw_events, struct perf_event *event) { struct arm_pmu *armpmu = to_arm_pmu(event->pmu); + struct pmu *leader_pmu = event->group_leader->pmu; if (is_software_event(event)) return 1; - if (event->state < PERF_EVENT_STATE_OFF) + if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) return 1; if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index d85055c..8d6147b 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c @@ -68,7 +68,7 @@ EXPORT_SYMBOL_GPL(perf_num_counters); static struct pmu_hw_events *cpu_pmu_get_cpu_events(void) { - return this_cpu_ptr(&cpu_hw_events); + return &__get_cpu_var(cpu_hw_events); } static void cpu_pmu_free_irq(struct arm_pmu *cpu_pmu) diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c deleted file mode 100644 index 6e4379c..0000000 --- a/arch/arm/kernel/perf_regs.c +++ /dev/null @@ -1,30 +0,0 @@ - -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/perf_event.h> -#include <linux/bug.h> -#include <asm/perf_regs.h> -#include <asm/ptrace.h> - -u64 perf_reg_value(struct pt_regs *regs, int idx) -{ - if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX)) - return 0; - - return regs->uregs[idx]; -} - -#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1)) - -int perf_reg_validate(u64 mask) -{ - if (!mask || mask & REG_RESERVED) - return -EINVAL; - - return 0; -} - -u64 perf_reg_abi(struct task_struct *task) -{ - return PERF_SAMPLE_REGS_ABI_32; -} diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c index 570a48c..70ded3f 100644 --- a/arch/arm/kernel/psci_smp.c +++ b/arch/arm/kernel/psci_smp.c @@ -14,6 +14,7 @@ */ #include <linux/init.h> +#include <linux/irqchip/arm-gic.h> #include <linux/smp.h> #include <linux/of.h> diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 9585896..d0cdedf 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -2,12 +2,10 @@ * relocate_kernel.S - put the kernel image in place to boot */ -#include <linux/linkage.h> #include <asm/kexec.h> - .align 3 /* not needed for this code, but keeps fncpy() happy */ - -ENTRY(relocate_new_kernel) + .globl relocate_new_kernel +relocate_new_kernel: ldr r0,kexec_indirection_page ldr r1,kexec_start_address @@ -81,8 +79,6 @@ kexec_mach_type: kexec_boot_atags: .long 0x0 -ENDPROC(relocate_new_kernel) - relocate_new_kernel_end: .globl relocate_new_kernel_size diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 6a1b8a8..0e1e2b3 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -73,8 +73,6 @@ __setup("fpe=", fpe_setup); #endif extern void paging_init(const struct machine_desc *desc); -extern void early_paging_init(const struct machine_desc *, - struct proc_info_list *); extern void sanity_check_meminfo(void); extern enum reboot_mode reboot_mode; extern void setup_dma_zone(const struct machine_desc *desc); @@ -601,8 +599,6 @@ static void __init setup_processor(void) elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); #endif - erratum_a15_798181_init(); - feat_v6_fixup(); cacheid_init(); @@ -623,10 +619,9 @@ void __init dump_machine_table(void) /* can't use cpu_relax() here as it may require MMU setup */; } -int __init arm_add_memory(u64 start, u64 size) +int __init arm_add_memory(phys_addr_t start, phys_addr_t size) { struct membank *bank = &meminfo.bank[meminfo.nr_banks]; - u64 aligned_start; if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_CRIT "NR_BANKS too low, " @@ -639,16 +634,10 @@ int __init arm_add_memory(u64 start, u64 size) * Size is appropriately rounded down, start is rounded up. */ size -= start & ~PAGE_MASK; - aligned_start = PAGE_ALIGN(start); + bank->start = PAGE_ALIGN(start); -#ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT - if (aligned_start > ULONG_MAX) { - printk(KERN_CRIT "Ignoring memory at 0x%08llx outside " - "32-bit physical address space\n", (long long)start); - return -EINVAL; - } - - if (aligned_start + size > ULONG_MAX) { +#ifndef CONFIG_ARM_LPAE + if (bank->start + size < bank->start) { printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " "32-bit physical address space\n", (long long)start); /* @@ -656,11 +645,10 @@ int __init arm_add_memory(u64 start, u64 size) * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. * This means we lose a page after masking. */ - size = ULONG_MAX - aligned_start; + size = ULONG_MAX - bank->start; } #endif - bank->start = aligned_start; bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); /* @@ -681,8 +669,8 @@ int __init arm_add_memory(u64 start, u64 size) static int __init early_mem(char *p) { static int usermem __initdata = 0; - u64 size; - u64 start; + phys_addr_t size; + phys_addr_t start; char *endp; /* @@ -890,8 +878,6 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); - - early_paging_init(mdesc, lookup_processor_type(read_cpuid_id())); sanity_check_meminfo(); arm_memblock_init(&meminfo, mdesc); @@ -989,7 +975,6 @@ static const char *hwcap_str[] = { "idivt", "vfpd32", "lpae", - "evtstrm", NULL }; diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 04d6388..ab33042 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -21,7 +21,29 @@ #include <asm/unistd.h> #include <asm/vfp.h> -extern const unsigned long sigreturn_codes[7]; +/* + * For ARM syscalls, we encode the syscall number into the instruction. + */ +#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) +#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) + +/* + * With EABI, the syscall number has to be loaded into r7. + */ +#define MOV_R7_NR_SIGRETURN (0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE)) +#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) + +/* + * For Thumb syscalls, we pass the syscall number via r7. We therefore + * need two 16-bit instructions. + */ +#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) +#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE)) + +static const unsigned long sigreturn_codes[7] = { + MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN, + MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN, +}; static unsigned long signal_return_offset; @@ -353,18 +375,12 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig, */ thumb = handler & 1; -#if __LINUX_ARM_ARCH__ >= 7 - /* - * Clear the If-Then Thumb-2 execution state - * ARM spec requires this to be all 000s in ARM mode - * Snapdragon S4/Krait misbehaves on a Thumb=>ARM - * signal transition without this. - */ - cpsr &= ~PSR_IT_MASK; -#endif - if (thumb) { cpsr |= PSR_T_BIT; +#if __LINUX_ARM_ARCH__ >= 7 + /* clear the If-Then Thumb-2 execution state */ + cpsr &= ~PSR_IT_MASK; +#endif } else cpsr &= ~PSR_T_BIT; } diff --git a/arch/arm/kernel/sigreturn_codes.S b/arch/arm/kernel/sigreturn_codes.S deleted file mode 100644 index b84d0cb..0000000 --- a/arch/arm/kernel/sigreturn_codes.S +++ /dev/null @@ -1,102 +0,0 @@ -/* - * sigreturn_codes.S - code sinpets for sigreturn syscalls - * - * Created by: Victor Kamensky, 2013-08-13 - * Copyright: (C) 2013 Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <asm/unistd.h> - -/* - * For ARM syscalls, we encode the syscall number into the instruction. - * With EABI, the syscall number has to be loaded into r7. As result - * ARM syscall sequence snippet will have move and svc in .arm encoding - * - * For Thumb syscalls, we pass the syscall number via r7. We therefore - * need two 16-bit instructions in .thumb encoding - * - * Please note sigreturn_codes code are not executed in place. Instead - * they just copied by kernel into appropriate places. Code inside of - * arch/arm/kernel/signal.c is very sensitive to layout of these code - * snippets. - */ - -/* - * In CPU_THUMBONLY case kernel arm opcodes are not allowed. - * Note in this case codes skips those instructions but it uses .org - * directive to keep correct layout of sigreturn_codes array. - */ -#ifndef CONFIG_CPU_THUMBONLY -#define ARM_OK(code...) code -#else -#define ARM_OK(code...) -#endif - - .macro arm_slot n - .org sigreturn_codes + 12 * (\n) -ARM_OK( .arm ) - .endm - - .macro thumb_slot n - .org sigreturn_codes + 12 * (\n) + 8 - .thumb - .endm - -#if __LINUX_ARM_ARCH__ <= 4 - /* - * Note we manually set minimally required arch that supports - * required thumb opcodes for early arch versions. It is OK - * for this file to be used in combination with other - * lower arch variants, since these code snippets are only - * used as input data. - */ - .arch armv4t -#endif - - .section .rodata - .global sigreturn_codes - .type sigreturn_codes, #object - - .align - -sigreturn_codes: - - /* ARM sigreturn syscall code snippet */ - arm_slot 0 -ARM_OK( mov r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) ) -ARM_OK( swi #(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) - - /* Thumb sigreturn syscall code snippet */ - thumb_slot 0 - movs r7, #(__NR_sigreturn - __NR_SYSCALL_BASE) - swi #0 - - /* ARM sigreturn_rt syscall code snippet */ - arm_slot 1 -ARM_OK( mov r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) ) -ARM_OK( swi #(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE) ) - - /* Thumb sigreturn_rt syscall code snippet */ - thumb_slot 1 - movs r7, #(__NR_rt_sigreturn - __NR_SYSCALL_BASE) - swi #0 - - /* - * Note on addtional space: setup_return in signal.c - * algorithm uses two words copy regardless whether - * it is thumb case or not, so we need additional - * word after real last entry. - */ - arm_slot 2 - .space 4 - - .size sigreturn_codes, . - sigreturn_codes diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index b907d9b..db1536b 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -55,7 +55,6 @@ * specific registers and some other data for resume. * r0 = suspend function arg0 * r1 = suspend function - * r2 = MPIDR value the resuming CPU will use */ ENTRY(__cpu_suspend) stmfd sp!, {r4 - r11, lr} @@ -68,18 +67,23 @@ ENTRY(__cpu_suspend) mov r5, sp @ current virtual SP add r4, r4, #12 @ Space for pgd, virt sp, phys resume fn sub sp, sp, r4 @ allocate CPU state on stack - ldr r3, =sleep_save_sp stmfd sp!, {r0, r1} @ save suspend func arg and pointer - ldr r3, [r3, #SLEEP_SAVE_SP_VIRT] - ALT_SMP(ldr r0, =mpidr_hash) - ALT_UP_B(1f) - /* This ldmia relies on the memory layout of the mpidr_hash struct */ - ldmia r0, {r1, r6-r8} @ r1 = mpidr mask (r6,r7,r8) = l[0,1,2] shifts - compute_mpidr_hash r0, r6, r7, r8, r2, r1 - add r3, r3, r0, lsl #2 -1: mov r2, r5 @ virtual SP + add r0, sp, #8 @ save pointer to save block mov r1, r4 @ size of save block - add r0, sp, #8 @ pointer to save block + mov r2, r5 @ virtual SP + ldr r3, =sleep_save_sp + ldr r3, [r3, #SLEEP_SAVE_SP_VIRT] + ALT_SMP(mrc p15, 0, r9, c0, c0, 5) + ALT_UP_B(1f) + ldr r8, =mpidr_hash + /* + * This ldmia relies on the memory layout of the mpidr_hash + * struct mpidr_hash. + */ + ldmia r8, {r4-r7} @ r4 = mpidr mask (r5,r6,r7) = l[0,1,2] shifts + compute_mpidr_hash lr, r5, r6, r7, r9, r4 + add r3, r3, lr, lsl #2 +1: bl __cpu_suspend_save adr lr, BSYM(cpu_suspend_abort) ldmfd sp!, {r0, pc} @ call suspend fn @@ -126,7 +130,6 @@ ENDPROC(cpu_resume_after_mmu) .data .align ENTRY(cpu_resume) -ARM_BE8(setend be) @ ensure we are in BE mode mov r1, #0 ALT_SMP(mrc p15, 0, r0, c0, c0, 5) ALT_UP_B(1f) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index dc894ab..72024ea 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -25,7 +25,6 @@ #include <linux/clockchips.h> #include <linux/completion.h> #include <linux/cpufreq.h> -#include <linux/irq_work.h> #include <linux/atomic.h> #include <asm/smp.h> @@ -67,8 +66,6 @@ enum ipi_msg_type { IPI_CALL_FUNC, IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, - IPI_IRQ_WORK, - IPI_COMPLETION, }; static DECLARE_COMPLETION(cpu_running); @@ -83,7 +80,7 @@ void __init smp_set_ops(struct smp_operations *ops) static unsigned long get_arch_pgd(pgd_t *pgd) { - phys_addr_t pgdir = virt_to_idmap(pgd); + phys_addr_t pgdir = virt_to_phys(pgd); BUG_ON(pgdir & ARCH_PGD_MASK); return pgdir >> ARCH_PGD_SHIFT; } @@ -451,14 +448,6 @@ void arch_send_call_function_single_ipi(int cpu) smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); } -#ifdef CONFIG_IRQ_WORK -void arch_irq_work_raise(void) -{ - if (is_smp()) - smp_cross_call(cpumask_of(smp_processor_id()), IPI_IRQ_WORK); -} -#endif - static const char *ipi_types[NR_IPI] = { #define S(x,s) [x] = s S(IPI_WAKEUP, "CPU wakeup interrupts"), @@ -467,8 +456,6 @@ static const char *ipi_types[NR_IPI] = { S(IPI_CALL_FUNC, "Function call interrupts"), S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"), S(IPI_CPU_STOP, "CPU stop interrupts"), - S(IPI_IRQ_WORK, "IRQ work interrupts"), - S(IPI_COMPLETION, "completion interrupts"), }; void show_ipi_list(struct seq_file *p, int prec) @@ -528,19 +515,6 @@ static void ipi_cpu_stop(unsigned int cpu) cpu_relax(); } -static DEFINE_PER_CPU(struct completion *, cpu_completion); - -int register_ipi_completion(struct completion *completion, int cpu) -{ - per_cpu(cpu_completion, cpu) = completion; - return IPI_COMPLETION; -} - -static void ipi_complete(unsigned int cpu) -{ - complete(per_cpu(cpu_completion, cpu)); -} - /* * Main handler for inter-processor interrupts */ @@ -591,20 +565,6 @@ void handle_IPI(int ipinr, struct pt_regs *regs) irq_exit(); break; -#ifdef CONFIG_IRQ_WORK - case IPI_IRQ_WORK: - irq_enter(); - irq_work_run(); - irq_exit(); - break; -#endif - - case IPI_COMPLETION: - irq_enter(); - ipi_complete(cpu); - irq_exit(); - break; - default: printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index 1aafa0d..5bc1a63 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c @@ -28,7 +28,7 @@ */ unsigned int __init scu_get_core_count(void __iomem *scu_base) { - unsigned int ncores = readl_relaxed(scu_base + SCU_CONFIG); + unsigned int ncores = __raw_readl(scu_base + SCU_CONFIG); return (ncores & 0x03) + 1; } @@ -42,19 +42,19 @@ void scu_enable(void __iomem *scu_base) #ifdef CONFIG_ARM_ERRATA_764369 /* Cortex-A9 only */ if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090) { - scu_ctrl = readl_relaxed(scu_base + 0x30); + scu_ctrl = __raw_readl(scu_base + 0x30); if (!(scu_ctrl & 1)) - writel_relaxed(scu_ctrl | 0x1, scu_base + 0x30); + __raw_writel(scu_ctrl | 0x1, scu_base + 0x30); } #endif - scu_ctrl = readl_relaxed(scu_base + SCU_CTRL); + scu_ctrl = __raw_readl(scu_base + SCU_CTRL); /* already enabled? */ if (scu_ctrl & 1) return; scu_ctrl |= 1; - writel_relaxed(scu_ctrl, scu_base + SCU_CTRL); + __raw_writel(scu_ctrl, scu_base + SCU_CTRL); /* * Ensure that the data accessed by CPU0 before the SCU was @@ -80,9 +80,9 @@ int scu_power_mode(void __iomem *scu_base, unsigned int mode) if (mode > 3 || mode == 1 || cpu > 3) return -EINVAL; - val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu) & ~0x03; + val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03; val |= mode; - writeb_relaxed(val, scu_base + SCU_CPU_STATUS + cpu); + __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu); return 0; } diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index 95d0636..83ccca3 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c @@ -70,40 +70,6 @@ static inline void ipi_flush_bp_all(void *ignored) local_flush_bp_all(); } -#ifdef CONFIG_ARM_ERRATA_798181 -bool (*erratum_a15_798181_handler)(void); - -static bool erratum_a15_798181_partial(void) -{ - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); - dsb(ish); - return false; -} - -static bool erratum_a15_798181_broadcast(void) -{ - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); - dsb(ish); - return true; -} - -void erratum_a15_798181_init(void) -{ - unsigned int midr = read_cpuid_id(); - unsigned int revidr = read_cpuid(CPUID_REVIDR); - - /* Cortex-A15 r0p0..r3p2 w/o ECO fix affected */ - if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2 || - (revidr & 0x210) == 0x210) { - return; - } - if (revidr & 0x10) - erratum_a15_798181_handler = erratum_a15_798181_partial; - else - erratum_a15_798181_handler = erratum_a15_798181_broadcast; -} -#endif - static void ipi_flush_tlb_a15_erratum(void *arg) { dmb(); @@ -114,6 +80,7 @@ static void broadcast_tlb_a15_erratum(void) if (!erratum_a15_798181()) return; + dummy_flush_tlb_a15_erratum(); smp_call_function(ipi_flush_tlb_a15_erratum, NULL, 1); } @@ -125,6 +92,7 @@ static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) if (!erratum_a15_798181()) return; + dummy_flush_tlb_a15_erratum(); this_cpu = get_cpu(); a15_erratum_get_cpumask(this_cpu, mm, &mask); smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 6591e26..2985c9f 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -45,7 +45,7 @@ static void twd_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_PERIODIC: ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_PERIODIC; - writel_relaxed(DIV_ROUND_CLOSEST(twd_timer_rate, HZ), + __raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ), twd_base + TWD_TIMER_LOAD); break; case CLOCK_EVT_MODE_ONESHOT: @@ -58,18 +58,18 @@ static void twd_set_mode(enum clock_event_mode mode, ctrl = 0; } - writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL); + __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); } static int twd_set_next_event(unsigned long evt, struct clock_event_device *unused) { - unsigned long ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL); + unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); ctrl |= TWD_TIMER_CONTROL_ENABLE; - writel_relaxed(evt, twd_base + TWD_TIMER_COUNTER); - writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL); + __raw_writel(evt, twd_base + TWD_TIMER_COUNTER); + __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL); return 0; } @@ -82,8 +82,8 @@ static int twd_set_next_event(unsigned long evt, */ static int twd_timer_ack(void) { - if (readl_relaxed(twd_base + TWD_TIMER_INTSTAT)) { - writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT); + if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) { + __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); return 1; } @@ -211,15 +211,15 @@ static void twd_calibrate_rate(void) waitjiffies += 5; /* enable, no interrupt or reload */ - writel_relaxed(0x1, twd_base + TWD_TIMER_CONTROL); + __raw_writel(0x1, twd_base + TWD_TIMER_CONTROL); /* maximum value */ - writel_relaxed(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER); + __raw_writel(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER); while (get_jiffies_64() < waitjiffies) udelay(10); - count = readl_relaxed(twd_base + TWD_TIMER_COUNTER); + count = __raw_readl(twd_base + TWD_TIMER_COUNTER); twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); @@ -277,7 +277,7 @@ static void twd_timer_setup(void) * bother with the below. */ if (per_cpu(percpu_setup_called, cpu)) { - writel_relaxed(0, twd_base + TWD_TIMER_CONTROL); + __raw_writel(0, twd_base + TWD_TIMER_CONTROL); clockevents_register_device(clk); enable_percpu_irq(clk->irq, 0); return; @@ -290,7 +290,7 @@ static void twd_timer_setup(void) * The following is done once per CPU the first time .setup() is * called. */ - writel_relaxed(0, twd_base + TWD_TIMER_CONTROL); + __raw_writel(0, twd_base + TWD_TIMER_CONTROL); clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c index 2835d35..41cf3cb 100644 --- a/arch/arm/kernel/suspend.c +++ b/arch/arm/kernel/suspend.c @@ -10,7 +10,7 @@ #include <asm/suspend.h> #include <asm/tlbflush.h> -extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid); +extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); extern void cpu_resume_mmu(void); #ifdef CONFIG_MMU @@ -21,7 +21,6 @@ extern void cpu_resume_mmu(void); int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) { struct mm_struct *mm = current->active_mm; - u32 __mpidr = cpu_logical_map(smp_processor_id()); int ret; if (!idmap_pgd) @@ -33,7 +32,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) * resume (indicated by a zero return code), we need to switch * back to the correct page tables. */ - ret = __cpu_suspend(arg, fn, __mpidr); + ret = __cpu_suspend(arg, fn); if (ret == 0) { cpu_switch_mm(mm->pgd, mm); local_flush_bp_all(); @@ -45,8 +44,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) #else int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) { - u32 __mpidr = cpu_logical_map(smp_processor_id()); - return __cpu_suspend(arg, fn, __mpidr); + return __cpu_suspend(arg, fn); } #define idmap_pgd NULL #endif diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 829a96d..98aee32 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -11,26 +11,25 @@ * This file contains the ARM-specific time handling details: * reading the RTC at bootup, etc... */ -#include <linux/clk-provider.h> -#include <linux/clocksource.h> -#include <linux/errno.h> #include <linux/export.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/kernel.h> -#include <linux/profile.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/init.h> #include <linux/sched.h> -#include <linux/sched_clock.h> #include <linux/smp.h> -#include <linux/time.h> #include <linux/timex.h> +#include <linux/errno.h> +#include <linux/profile.h> #include <linux/timer.h> +#include <linux/clocksource.h> +#include <linux/irq.h> +#include <linux/sched_clock.h> +#include <asm/thread_info.h> +#include <asm/stacktrace.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> -#include <asm/stacktrace.h> -#include <asm/thread_info.h> #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \ defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) @@ -117,12 +116,8 @@ int __init register_persistent_clock(clock_access_fn read_boot, void __init time_init(void) { - if (machine_desc->init_time) { + if (machine_desc->init_time) machine_desc->init_time(); - } else { -#ifdef CONFIG_COMMON_CLK - of_clk_init(NULL); -#endif + else clocksource_of_init(); - } } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index dbf0923..8fcda14 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -34,7 +34,6 @@ #include <asm/unwind.h> #include <asm/tls.h> #include <asm/system_misc.h> -#include <asm/opcodes.h> static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; @@ -342,17 +341,15 @@ void arm_notify_die(const char *str, struct pt_regs *regs, int is_valid_bugaddr(unsigned long pc) { #ifdef CONFIG_THUMB2_KERNEL - u16 bkpt; - u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE); + unsigned short bkpt; #else - u32 bkpt; - u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE); + unsigned long bkpt; #endif if (probe_kernel_address((unsigned *)pc, bkpt)) return 0; - return bkpt == insn; + return bkpt == BUG_INSTR_VALUE; } #endif @@ -405,28 +402,25 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) if (processor_mode(regs) == SVC_MODE) { #ifdef CONFIG_THUMB2_KERNEL if (thumb_mode(regs)) { - instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]); + instr = ((u16 *)pc)[0]; if (is_wide_instruction(instr)) { - u16 inst2; - inst2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]); - instr = __opcode_thumb32_compose(instr, inst2); + instr <<= 16; + instr |= ((u16 *)pc)[1]; } } else #endif - instr = __mem_to_opcode_arm(*(u32 *) pc); + instr = *(u32 *) pc; } else if (thumb_mode(regs)) { if (get_user(instr, (u16 __user *)pc)) goto die_sig; - instr = __mem_to_opcode_thumb16(instr); if (is_wide_instruction(instr)) { unsigned int instr2; if (get_user(instr2, (u16 __user *)pc+1)) goto die_sig; - instr2 = __mem_to_opcode_thumb16(instr2); - instr = __opcode_thumb32_compose(instr, instr2); + instr <<= 16; + instr |= instr2; } } else if (get_user(instr, (u32 __user *)pc)) { - instr = __mem_to_opcode_arm(instr); goto die_sig; } @@ -856,7 +850,7 @@ static void __init kuser_init(void *vectors) memcpy(vectors + 0xfe0, vectors + 0xfe8, 4); } #else -static inline void __init kuser_init(void *vectors) +static void __init kuser_init(void *vectors) { } #endif |