Merge branch 'e1000-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / arch / sparc64 / kernel / smp.c
index f03d52d..d4f0a70 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/cpudata.h>
 
 #include <asm/irq.h>
+#include <asm/irq_regs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/oplib.h>
 #include <asm/starfire.h>
 #include <asm/tlb.h>
 #include <asm/sections.h>
+#include <asm/prom.h>
 
 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,11 +1341,8 @@ 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
+       goal = PERCPU_ENOUGH_ROOM;
+
        __per_cpu_shift = 0;
        for (size = 1UL; size < goal; size <<= 1UL)
                __per_cpu_shift++;