X-Git-Url: http://git.agner.ch/gitweb/?a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fsmp.c;h=1fac215252e403bc25af1fbc3a58fe88e22e3994;hb=5f757f91e70a97eda8f0cc13bddc853209b2d173;hp=f03d52d0b88dd73803cee49b98d9b0aeb90e5d92;hpb=2edc322d420a4cec8dbc184a1220ecd7fa9f8ae6;p=linux-drm-fsl-dcu.git diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index f03d52d0b88d..1fac215252e4 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -39,11 +40,12 @@ #include #include #include +#include extern void calibrate_delay(void); /* Please don't make this stuff initdata!!! --DaveM */ -static unsigned char boot_cpu_id; +unsigned char boot_cpu_id; cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; @@ -76,41 +78,40 @@ void smp_bogo(struct seq_file *m) void __init smp_store_cpu_info(int id) { - int cpu_node, def; + struct device_node *dp; + int def; - /* multiplier and counter set by - smp_setup_percpu_timer() */ cpu_data(id).udelay_val = loops_per_jiffy; - cpu_find_by_mid(id, &cpu_node); - cpu_data(id).clock_tick = prom_getintdefault(cpu_node, - "clock-frequency", 0); + cpu_find_by_mid(id, &dp); + cpu_data(id).clock_tick = + of_getintprop_default(dp, "clock-frequency", 0); def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024)); - cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size", - def); + cpu_data(id).dcache_size = + of_getintprop_default(dp, "dcache-size", def); def = 32; cpu_data(id).dcache_line_size = - prom_getintdefault(cpu_node, "dcache-line-size", def); + of_getintprop_default(dp, "dcache-line-size", def); def = 16 * 1024; - cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size", - def); + cpu_data(id).icache_size = + of_getintprop_default(dp, "icache-size", def); def = 32; cpu_data(id).icache_line_size = - prom_getintdefault(cpu_node, "icache-line-size", def); + of_getintprop_default(dp, "icache-line-size", def); def = ((tlb_type == hypervisor) ? (3 * 1024 * 1024) : (4 * 1024 * 1024)); - cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size", - def); + cpu_data(id).ecache_size = + of_getintprop_default(dp, "ecache-size", def); def = 64; cpu_data(id).ecache_line_size = - prom_getintdefault(cpu_node, "ecache-line-size", def); + of_getintprop_default(dp, "ecache-line-size", def); printk("CPU[%d]: Caches " "D[sz(%d):line_sz(%d)] " @@ -122,7 +123,7 @@ void __init smp_store_cpu_info(int id) cpu_data(id).ecache_size, cpu_data(id).ecache_line_size); } -static void smp_setup_percpu_timer(void); +extern void setup_sparc64_timer(void); static volatile unsigned long callin_flag = 0; @@ -137,7 +138,7 @@ void __init smp_callin(void) __flush_tlb_all(); - smp_setup_percpu_timer(); + setup_sparc64_timer(); if (cheetah_pcache_forced_on) cheetah_enable_pcache(); @@ -174,8 +175,6 @@ void cpu_panic(void) panic("SMP bolixed\n"); } -static unsigned long current_tick_offset __read_mostly; - /* This tick register synchronization scheme is taken entirely from * the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit. * @@ -258,7 +257,7 @@ void smp_synchronize_tick_client(void) } else adj = -delta; - tick_ops->add_tick(adj, current_tick_offset); + tick_ops->add_tick(adj); } #if DEBUG_TICK_SYNC t[i].rt = rt; @@ -342,10 +341,10 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) prom_startcpu_cpuid(cpu, entry, cookie); } else { - int cpu_node; + struct device_node *dp; - cpu_find_by_mid(cpu, &cpu_node); - prom_startcpu(cpu_node, entry, cookie); + cpu_find_by_mid(cpu, &dp); + prom_startcpu(dp->node, entry, cookie); } for (timeout = 0; timeout < 5000000; timeout++) { @@ -1177,119 +1176,21 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) preempt_enable(); } -#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier -#define prof_counter(__cpu) cpu_data(__cpu).counter - -void smp_percpu_timer_interrupt(struct pt_regs *regs) -{ - unsigned long compare, tick, pstate; - int cpu = smp_processor_id(); - int user = user_mode(regs); - - /* - * Check for level 14 softint. - */ - { - unsigned long tick_mask = tick_ops->softint_mask; - - if (!(get_softint() & tick_mask)) { - extern void handler_irq(int, struct pt_regs *); - - handler_irq(14, regs); - return; - } - clear_softint(tick_mask); - } - - do { - profile_tick(CPU_PROFILING, regs); - if (!--prof_counter(cpu)) { - irq_enter(); - - if (cpu == boot_cpu_id) { - kstat_this_cpu.irqs[0]++; - timer_tick_interrupt(regs); - } - - update_process_times(user); - - irq_exit(); - - prof_counter(cpu) = prof_multiplier(cpu); - } - - /* Guarantee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - compare = tick_ops->add_compare(current_tick_offset); - tick = tick_ops->get_tick(); - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); - } while (time_after_eq(tick, compare)); -} - -static void __init smp_setup_percpu_timer(void) -{ - int cpu = smp_processor_id(); - unsigned long pstate; - - prof_counter(cpu) = prof_multiplier(cpu) = 1; - - /* Guarantee that the following sequences execute - * uninterrupted. - */ - __asm__ __volatile__("rdpr %%pstate, %0\n\t" - "wrpr %0, %1, %%pstate" - : "=r" (pstate) - : "i" (PSTATE_IE)); - - tick_ops->init_tick(current_tick_offset); - - /* Restore PSTATE_IE. */ - __asm__ __volatile__("wrpr %0, 0x0, %%pstate" - : /* no outputs */ - : "r" (pstate)); -} - void __init smp_tick_init(void) { boot_cpu_id = hard_smp_processor_id(); - current_tick_offset = timer_tick_offset; - - prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1; } /* /proc/profile writes can call this, don't __init it please. */ -static DEFINE_SPINLOCK(prof_setup_lock); - int setup_profiling_timer(unsigned int multiplier) { - unsigned long flags; - int i; - - if ((!multiplier) || (timer_tick_offset / multiplier) < 1000) - return -EINVAL; - - spin_lock_irqsave(&prof_setup_lock, flags); - for_each_possible_cpu(i) - prof_multiplier(i) = multiplier; - current_tick_offset = (timer_tick_offset / multiplier); - spin_unlock_irqrestore(&prof_setup_lock, flags); - - return 0; + return -EINVAL; } static void __init smp_tune_scheduling(void) { - int instance, node; + struct device_node *dp; + int instance; unsigned int def, smallest = ~0U; def = ((tlb_type == hypervisor) ? @@ -1297,10 +1198,10 @@ static void __init smp_tune_scheduling(void) (4 * 1024 * 1024)); instance = 0; - while (!cpu_find_by_instance(instance, &node, NULL)) { + while (!cpu_find_by_instance(instance, &dp, NULL)) { unsigned int val; - val = prom_getintdefault(node, "ecache-size", def); + val = of_getintprop_default(dp, "ecache-size", def); if (val < smallest) smallest = val; @@ -1381,7 +1282,7 @@ void __devinit smp_prepare_boot_cpu(void) { } -int __devinit __cpu_up(unsigned int cpu) +int __cpuinit __cpu_up(unsigned int cpu) { int ret = smp_boot_one_cpu(cpu); @@ -1440,16 +1341,13 @@ void __init setup_per_cpu_areas(void) char *ptr; /* Copy section for each CPU (we discard the original) */ - goal = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); -#ifdef CONFIG_MODULES - if (goal < PERCPU_ENOUGH_ROOM) - goal = PERCPU_ENOUGH_ROOM; -#endif - __per_cpu_shift = 0; - for (size = 1UL; size < goal; size <<= 1UL) + goal = PERCPU_ENOUGH_ROOM; + + __per_cpu_shift = PAGE_SHIFT; + for (size = PAGE_SIZE; size < goal; size <<= 1UL) __per_cpu_shift++; - ptr = alloc_bootmem(size * NR_CPUS); + ptr = alloc_bootmem_pages(size * NR_CPUS); __per_cpu_base = ptr - __per_cpu_start;