Merge branch 'misc' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc...
[pandora-kernel.git] / arch / powerpc / platforms / iseries / setup.c
index c6bbe5c..a6fd9be 100644 (file)
 #include <asm/iseries/hv_call_xm.h>
 #include <asm/iseries/it_lp_queue.h>
 #include <asm/iseries/mf.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/udbg.h>
+#include <asm/irq.h>
 
 #include "naca.h"
 #include "setup.h"
@@ -89,8 +91,6 @@ extern unsigned long embedded_sysmap_end;
 extern unsigned long iSeries_recal_tb;
 extern unsigned long iSeries_recal_titan;
 
-static int mf_initialized;
-
 static unsigned long cmd_mem_limit;
 
 struct MemoryBlock {
@@ -303,8 +303,6 @@ static void __init iSeries_init_early(void)
 {
        DBG(" -> iSeries_init_early()\n");
 
-       ppc64_firmware_features = FW_FEATURE_ISERIES;
-
        ppc64_interrupt_controller = IC_ISERIES;
 
 #if defined(CONFIG_BLK_DEV_INITRD)
@@ -349,8 +347,6 @@ static void __init iSeries_init_early(void)
        HvCallEvent_setLpEventQueueInterruptProc(0, 0);
 
        mf_init();
-       mf_initialized = 1;
-       mb();
 
        /* If we were passed an initrd, set the ROOT_DEV properly if the values
         * look sensible. If not, clear initrd reference.
@@ -538,7 +534,7 @@ static unsigned long __init build_iSeries_Memory_Map(void)
  */
 static void __init iSeries_setup_arch(void)
 {
-       if (get_paca()->lppaca.shared_proc) {
+       if (get_lppaca()->shared_proc) {
                ppc_md.idle_loop = iseries_shared_idle;
                printk(KERN_INFO "Using shared processor idle loop\n");
        } else {
@@ -560,39 +556,10 @@ static void iSeries_show_cpuinfo(struct seq_file *m)
        seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
 }
 
-/*
- * Document me.
- */
-static void iSeries_restart(char *cmd)
-{
-       mf_reboot();
-}
-
-/*
- * Document me.
- */
-static void iSeries_power_off(void)
-{
-       mf_power_off();
-}
-
-/*
- * Document me.
- */
-static void iSeries_halt(void)
-{
-       mf_power_off();
-}
-
 static void __init iSeries_progress(char * st, unsigned short code)
 {
        printk("Progress: [%04x] - %s\n", (unsigned)code, st);
-       if (!piranha_simulator && mf_initialized) {
-               if (code != 0xffff)
-                       mf_display_progress(code);
-               else
-                       mf_clear_src();
-       }
+       mf_display_progress(code);
 }
 
 static void __init iSeries_fixup_klimit(void)
@@ -647,7 +614,8 @@ static void yield_shared_processor(void)
         * The decrementer stops during the yield.  Force a fake decrementer
         * here and let the timer_interrupt code sort out the actual time.
         */
-       get_paca()->lppaca.int_dword.fields.decr_int = 1;
+       get_lppaca()->int_dword.fields.decr_int = 1;
+       ppc64_runlatch_on();
        process_iSeries_events();
 }
 
@@ -708,21 +676,35 @@ static void iseries_dedicated_idle(void)
 void __init iSeries_init_IRQ(void) { }
 #endif
 
-static int __init iseries_probe(int platform)
+static int __init iseries_probe(void)
 {
-       return PLATFORM_ISERIES_LPAR == platform;
+       unsigned long root = of_get_flat_dt_root();
+       if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
+               return 0;
+
+       powerpc_firmware_features |= FW_FEATURE_ISERIES;
+       powerpc_firmware_features |= FW_FEATURE_LPAR;
+
+       /*
+        * The Hypervisor only allows us up to 256 interrupt
+        * sources (the irq number is passed in a u8).
+        */
+       virt_irq_max = 255;
+
+       return 1;
 }
 
-struct machdep_calls __initdata iseries_md = {
+define_machine(iseries) {
+       .name           = "iSeries",
        .setup_arch     = iSeries_setup_arch,
        .show_cpuinfo   = iSeries_show_cpuinfo,
        .init_IRQ       = iSeries_init_IRQ,
        .get_irq        = iSeries_get_irq,
        .init_early     = iSeries_init_early,
        .pcibios_fixup  = iSeries_pci_final_fixup,
-       .restart        = iSeries_restart,
-       .power_off      = iSeries_power_off,
-       .halt           = iSeries_halt,
+       .restart        = mf_reboot,
+       .power_off      = mf_power_off,
+       .halt           = mf_power_off,
        .get_boot_time  = iSeries_get_boot_time,
        .set_rtc_time   = iSeries_set_rtc_time,
        .get_rtc_time   = iSeries_get_rtc_time,
@@ -883,7 +865,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
        pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
 
        for (i = 0; i < NR_CPUS; i++) {
-               if (paca[i].lppaca.dyn_proc_status >= 2)
+               if (lppaca[i].dyn_proc_status >= 2)
                        continue;
 
                snprintf(p, 32 - (p - buf), "@%d", i);
@@ -891,7 +873,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
 
                dt_prop_str(dt, "device_type", "cpu");
 
-               index = paca[i].lppaca.dyn_hv_phys_proc_index;
+               index = lppaca[i].dyn_hv_phys_proc_index;
                d = &xIoHriProcessorVpd[index];
 
                dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
@@ -916,6 +898,24 @@ void dt_cpus(struct iseries_flat_dt *dt)
        dt_end_node(dt);
 }
 
+void dt_model(struct iseries_flat_dt *dt)
+{
+       char buf[16] = "IBM,";
+
+       /* "IBM," + mfgId[2:3] + systemSerial[1:5] */
+       strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2);
+       strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5);
+       buf[11] = '\0';
+       dt_prop_str(dt, "system-id", buf);
+
+       /* "IBM," + machineType[0:4] */
+       strne2a(buf + 4, xItExtVpdPanel.machineType, 4);
+       buf[8] = '\0';
+       dt_prop_str(dt, "model", buf);
+
+       dt_prop_str(dt, "compatible", "IBM,iSeries");
+}
+
 void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
 {
        u64 tmp[2];
@@ -926,6 +926,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
 
        dt_prop_u32(dt, "#address-cells", 2);
        dt_prop_u32(dt, "#size-cells", 2);
+       dt_model(dt);
 
        /* /memory */
        dt_start_node(dt, "memory@0");
@@ -938,7 +939,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
 
        /* /chosen */
        dt_start_node(dt, "chosen");
-       dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
+       dt_prop_str(dt, "bootargs", cmd_line);
        if (cmd_mem_limit)
                dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
        dt_end_node(dt);