summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/irq.c19
-rw-r--r--arch/arm/kernel/module.c13
-rw-r--r--arch/arm/kernel/perf_event.c6
-rw-r--r--arch/arm/kernel/setup.c2
-rw-r--r--arch/arm/kernel/smp.c6
-rw-r--r--arch/arm/kernel/smp_twd.c2
6 files changed, 37 insertions, 11 deletions
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 83bbad03fcc6..dbc1f41575b2 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -67,12 +67,12 @@ int arch_show_interrupts(struct seq_file *p, int prec)
}
/*
- * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
- * come via this function. Instead, they should provide their
- * own 'handler'
+ * handle_IRQ handles all hardware IRQ's. Decoded IRQs should
+ * not come via this function. Instead, they should provide their
+ * own 'handler'. Used by platform code implementing C-based 1st
+ * level decoding.
*/
-asmlinkage void __exception_irq_entry
-asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+void handle_IRQ(unsigned int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
@@ -97,6 +97,15 @@ asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
set_irq_regs(old_regs);
}
+/*
+ * asm_do_IRQ is the interface to be used from assembly code.
+ */
+asmlinkage void __exception_irq_entry
+asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+ handle_IRQ(irq, regs);
+}
+
void set_irq_flags(unsigned int irq, unsigned int iflags)
{
unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index fee7c36349eb..016d6a0830a3 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -193,8 +193,17 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
offset -= 0x02000000;
offset += sym->st_value - loc;
- /* only Thumb addresses allowed (no interworking) */
- if (!(offset & 1) ||
+ /*
+ * For function symbols, only Thumb addresses are
+ * allowed (no interworking).
+ *
+ * For non-function symbols, the destination
+ * has no specific ARM/Thumb disposition, so
+ * the branch is resolved under the assumption
+ * that interworking is not required.
+ */
+ if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+ !(offset & 1)) ||
offset <= (s32)0xff000000 ||
offset >= (s32)0x01000000) {
pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d53c0abc4dd3..2b5b1421596c 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -583,7 +583,7 @@ static int armpmu_event_init(struct perf_event *event)
static void armpmu_enable(struct pmu *pmu)
{
/* Enable all of the perf events on hardware. */
- int idx;
+ int idx, enabled = 0;
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
if (!armpmu)
@@ -596,9 +596,11 @@ static void armpmu_enable(struct pmu *pmu)
continue;
armpmu->enable(&event->hw, idx);
+ enabled = 1;
}
- armpmu->start();
+ if (enabled)
+ armpmu->start();
}
static void armpmu_disable(struct pmu *pmu)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ed11fb08b05a..acbb447ac6b5 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -73,6 +73,7 @@ __setup("fpe=", fpe_setup);
#endif
extern void paging_init(struct machine_desc *desc);
+extern void sanity_check_meminfo(void);
extern void reboot_setup(char *str);
unsigned int processor_id;
@@ -900,6 +901,7 @@ void __init setup_arch(char **cmdline_p)
parse_early_param();
+ sanity_check_meminfo();
arm_memblock_init(&meminfo, mdesc);
paging_init(mdesc);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 344e52b16c8c..e7f92a4321f3 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -318,9 +318,13 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
smp_store_cpu_info(cpu);
/*
- * OK, now it's safe to let the boot CPU continue
+ * OK, now it's safe to let the boot CPU continue. Wait for
+ * the CPU migration code to notice that the CPU is online
+ * before we continue.
*/
set_cpu_online(cpu, true);
+ while (!cpu_active(cpu))
+ cpu_relax();
/*
* OK, it's off to the idle thread for us
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 60636f499cb3..2c277d40cee6 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -115,7 +115,7 @@ static void __cpuinit twd_calibrate_rate(void)
twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
- (twd_timer_rate / 1000000) % 100);
+ (twd_timer_rate / 10000) % 100);
}
}