diff options
Diffstat (limited to 'arch/arm/kernel')
| -rw-r--r-- | arch/arm/kernel/arch_timer.c | 29 | ||||
| -rw-r--r-- | arch/arm/kernel/asm-offsets.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/devtree.c | 7 | ||||
| -rw-r--r-- | arch/arm/kernel/sched_clock.c | 15 | ||||
| -rw-r--r-- | arch/arm/kernel/setup.c | 13 | ||||
| -rw-r--r-- | arch/arm/kernel/swp_emulate.c | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/time.c | 7 | ||||
| -rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 7 |
8 files changed, 59 insertions, 23 deletions
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index d957a51435d8..59dcdced6e30 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c @@ -22,9 +22,11 @@ static unsigned long arch_timer_read_counter_long(void) return arch_timer_read_counter(); } -static u32 arch_timer_read_counter_u32(void) +static u32 sched_clock_mult __read_mostly; + +static unsigned long long notrace arch_timer_sched_clock(void) { - return arch_timer_read_counter(); + return arch_timer_read_counter() * sched_clock_mult; } static struct delay_timer arch_delay_timer; @@ -37,25 +39,20 @@ static void __init arch_timer_delay_timer_register(void) register_current_timer_delay(&arch_delay_timer); } -int __init arch_timer_of_register(void) +int __init arch_timer_arch_init(void) { - int ret; + u32 arch_timer_rate = arch_timer_get_rate(); - ret = arch_timer_init(); - if (ret) - return ret; + if (arch_timer_rate == 0) + return -ENXIO; arch_timer_delay_timer_register(); - return 0; -} - -int __init arch_timer_sched_clock_init(void) -{ - if (arch_timer_get_rate() == 0) - return -ENXIO; + /* 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); - setup_sched_clock(arch_timer_read_counter_u32, - 32, arch_timer_get_rate()); return 0; } diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index a53efa993690..ee68cce6b48e 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -158,7 +158,7 @@ int main(void) DEFINE(VCPU_MIDR, offsetof(struct kvm_vcpu, arch.midr)); DEFINE(VCPU_CP15, offsetof(struct kvm_vcpu, arch.cp15)); DEFINE(VCPU_VFP_GUEST, offsetof(struct kvm_vcpu, arch.vfp_guest)); - DEFINE(VCPU_VFP_HOST, offsetof(struct kvm_vcpu, arch.vfp_host)); + DEFINE(VCPU_VFP_HOST, offsetof(struct kvm_vcpu, arch.host_cpu_context)); DEFINE(VCPU_REGS, offsetof(struct kvm_vcpu, arch.regs)); DEFINE(VCPU_USR_REGS, offsetof(struct kvm_vcpu, arch.regs.usr_regs)); DEFINE(VCPU_SVC_REGS, offsetof(struct kvm_vcpu, arch.regs.svc_regs)); diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 70f1bdeb241b..5af04f6daa33 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -180,6 +180,13 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) unsigned long dt_root; const char *model; +#ifdef CONFIG_ARCH_MULTIPLATFORM + DT_MACHINE_START(GENERIC_DT, "Generic DT based system") + MACHINE_END + + mdesc_best = (struct machine_desc *)&__mach_desc_GENERIC_DT; +#endif + if (!dt_phys) return NULL; diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 59d2adb764a9..e8edcaa0e432 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -20,6 +20,7 @@ struct clock_data { u64 epoch_ns; u32 epoch_cyc; u32 epoch_cyc_copy; + unsigned long rate; u32 mult; u32 shift; bool suspended; @@ -113,11 +114,14 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) u64 res, wrap; char r_unit; + if (cd.rate > rate) + return; + BUG_ON(bits > 32); WARN_ON(!irqs_disabled()); - WARN_ON(read_sched_clock != jiffy_sched_clock_read); read_sched_clock = read; sched_clock_mask = (1 << bits) - 1; + cd.rate = rate; /* calculate the mult/shift to convert counter ticks to ns. */ clocks_calc_mult_shift(&cd.mult, &cd.shift, rate, NSEC_PER_SEC, 0); @@ -161,12 +165,19 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) pr_debug("Registered %pF as sched_clock source\n", read); } -unsigned long long notrace sched_clock(void) +static unsigned long long notrace sched_clock_32(void) { u32 cyc = read_sched_clock(); return cyc_to_sched_clock(cyc, sched_clock_mask); } +unsigned long long __read_mostly (*sched_clock_func)(void) = sched_clock_32; + +unsigned long long notrace sched_clock(void) +{ + return sched_clock_func(); +} + void __init sched_clock_postinit(void) { /* diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 728007c4a2b7..1522c7ae31b0 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -18,6 +18,7 @@ #include <linux/bootmem.h> #include <linux/seq_file.h> #include <linux/screen_info.h> +#include <linux/of_platform.h> #include <linux/init.h> #include <linux/kexec.h> #include <linux/of_fdt.h> @@ -659,9 +660,19 @@ struct screen_info screen_info = { static int __init customize_machine(void) { - /* customizes platform devices, or adds new ones */ + /* + * customizes platform devices, or adds new ones + * On DT based machines, we fall back to populating the + * machine from the device tree, if no callback is provided, + * otherwise we would always need an init_machine callback. + */ if (machine_desc->init_machine) machine_desc->init_machine(); +#ifdef CONFIG_OF + else + of_platform_populate(NULL, of_default_bus_match_table, + NULL, NULL); +#endif return 0; } arch_initcall(customize_machine); diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 087fc321e9e5..b1b89882b113 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c @@ -99,7 +99,7 @@ static const struct file_operations proc_status_fops = { .open = proc_status_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; #endif diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 955d92d265e5..abff4e9aaee0 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -22,6 +22,7 @@ #include <linux/errno.h> #include <linux/profile.h> #include <linux/timer.h> +#include <linux/clocksource.h> #include <linux/irq.h> #include <asm/thread_info.h> @@ -115,6 +116,10 @@ int __init register_persistent_clock(clock_access_fn read_boot, void __init time_init(void) { - machine_desc->init_time(); + if (machine_desc->init_time) + machine_desc->init_time(); + else + clocksource_of_init(); + sched_clock_postinit(); } diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index b571484e9f03..a871b8e00fca 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -20,7 +20,7 @@ VMLINUX_SYMBOL(__idmap_text_start) = .; \ *(.idmap.text) \ VMLINUX_SYMBOL(__idmap_text_end) = .; \ - ALIGN_FUNCTION(); \ + . = ALIGN(32); \ VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ *(.hyp.idmap.text) \ VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; @@ -315,3 +315,8 @@ SECTIONS */ ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") +/* + * The HYP init code can't be more than a page long. + * The above comment applies as well. + */ +ASSERT(((__hyp_idmap_text_end - __hyp_idmap_text_start) <= PAGE_SIZE), "HYP init code too big") |
