#endif
 
        void            (*restart)(char *cmd);
-       void            (*power_off)(void);
        void            (*halt)(void);
        void            (*panic)(char *str);
        void            (*cpu_die)(void);
 
 void machine_power_off(void)
 {
        machine_shutdown();
-       if (ppc_md.power_off)
-               ppc_md.power_off();
+       if (pm_power_off)
+               pm_power_off();
 #ifdef CONFIG_SMP
        smp_send_stop();
 #endif
 /* Used by the G5 thermal driver */
 EXPORT_SYMBOL_GPL(machine_power_off);
 
-void (*pm_power_off)(void) = machine_power_off;
+void (*pm_power_off)(void);
 EXPORT_SYMBOL_GPL(pm_power_off);
 
 void machine_halt(void)
 
 {
        avr_i2c_client = client;
        ppc_md.restart = avr_reset_system;
-       ppc_md.power_off = avr_power_off_system;
+       pm_power_off = avr_power_off_system;
        return 0;
 }
 
 
        DMA_MODE_READ = 0x44;
        DMA_MODE_WRITE = 0x48;
 
+       pm_power_off = rtas_power_off;
+
        return 1;
 }
 
        .init_IRQ               = mpc52xx_init_irq,
        .get_irq                = mpc52xx_get_irq,
        .restart                = rtas_restart,
-       .power_off              = rtas_power_off,
        .halt                   = rtas_halt,
        .set_rtc_time           = rtas_set_rtc_time,
        .get_rtc_time           = rtas_get_rtc_time,
 
        if (ret)
                goto err;
 
-       /* XXX: this is potentially racy, but there is no lock for ppc_md */
-       if (!ppc_md.power_off) {
+       /* XXX: this is potentially racy, but there is no lock for pm_power_off */
+       if (!pm_power_off) {
                glob_mcu = mcu;
-               ppc_md.power_off = mcu_power_off;
+               pm_power_off = mcu_power_off;
                dev_info(&client->dev, "will provide power-off service\n");
        }
 
        device_remove_file(&client->dev, &dev_attr_status);
 
        if (glob_mcu == mcu) {
-               ppc_md.power_off = NULL;
+               pm_power_off = NULL;
                glob_mcu = NULL;
        }
 
 
 
                        ppc_md.get_irq = ehv_pic_get_irq;
                        ppc_md.restart = fsl_hv_restart;
-                       ppc_md.power_off = fsl_hv_halt;
+                       pm_power_off = fsl_hv_halt;
                        ppc_md.halt = fsl_hv_halt;
 #ifdef CONFIG_SMP
                        /*
 
 
        /* Register our halt function */
        ppc_md.halt = gpio_halt_cb;
-       ppc_md.power_off = gpio_halt_cb;
+       pm_power_off = gpio_halt_cb;
 
        printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
               " irq).\n", gpio, trigger, irq);
                free_irq(irq, halt_node);
 
                ppc_md.halt = NULL;
-               ppc_md.power_off = NULL;
+               pm_power_off = NULL;
 
                gpio_free(gpio);
 
 
        powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS
                | FW_FEATURE_BEAT | FW_FEATURE_LPAR;
        hpte_init_beat_v3();
+       pm_power_off = beat_power_off;
 
        return 1;
 }
 
        powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS;
        hpte_init_native();
+       pm_power_off = rtas_power_off;
 
        return 1;
 }
        .setup_arch             = celleb_setup_arch_beat,
        .show_cpuinfo           = celleb_show_cpuinfo,
        .restart                = beat_restart,
-       .power_off              = beat_power_off,
        .halt                   = beat_halt,
        .get_rtc_time           = beat_get_rtc_time,
        .set_rtc_time           = beat_set_rtc_time,
        .setup_arch             = celleb_setup_arch_native,
        .show_cpuinfo           = celleb_show_cpuinfo,
        .restart                = rtas_restart,
-       .power_off              = rtas_power_off,
        .halt                   = rtas_halt,
        .get_boot_time          = rtas_get_boot_time,
        .get_rtc_time           = rtas_get_rtc_time,
 
                return 0;
 
        hpte_init_native();
+       pm_power_off = rtas_power_off;
 
        return 1;
 }
        .setup_arch             = qpace_setup_arch,
        .show_cpuinfo           = qpace_show_cpuinfo,
        .restart                = rtas_restart,
-       .power_off              = rtas_power_off,
        .halt                   = rtas_halt,
        .get_boot_time          = rtas_get_boot_time,
        .get_rtc_time           = rtas_get_rtc_time,
 
                return 0;
 
        hpte_init_native();
+       pm_power_off = rtas_power_off;
 
        return 1;
 }
        .setup_arch             = cell_setup_arch,
        .show_cpuinfo           = cell_show_cpuinfo,
        .restart                = rtas_restart,
-       .power_off              = rtas_power_off,
        .halt                   = rtas_halt,
        .get_boot_time          = rtas_get_boot_time,
        .get_rtc_time           = rtas_get_rtc_time,
 
        DMA_MODE_READ = 0x44;
        DMA_MODE_WRITE = 0x48;
 
+       pm_power_off = rtas_power_off;
+
        return 1;
 }
 
        .show_cpuinfo           = chrp_show_cpuinfo,
        .init_IRQ               = chrp_init_IRQ,
        .restart                = rtas_restart,
-       .power_off              = rtas_power_off,
        .halt                   = rtas_halt,
        .time_init              = chrp_time_init,
        .set_rtc_time           = chrp_set_rtc_time,
 
        if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube"))
                return 0;
 
+       pm_power_off = gamecube_power_off;
+
        return 1;
 }
 
        .probe                  = gamecube_probe,
        .init_early             = gamecube_init_early,
        .restart                = gamecube_restart,
-       .power_off              = gamecube_power_off,
        .halt                   = gamecube_halt,
        .init_IRQ               = flipper_pic_probe,
        .get_irq                = flipper_pic_get_irq,
 
 
        if (!of_flat_dt_is_compatible(root, "linkstation"))
                return 0;
+
+       pm_power_off = linkstation_power_off;
+
        return 1;
 }
 
        .show_cpuinfo           = linkstation_show_cpuinfo,
        .get_irq                = mpic_get_irq,
        .restart                = linkstation_restart,
-       .power_off              = linkstation_power_off,
        .halt                   = linkstation_halt,
        .calibrate_decr         = generic_calibrate_decr,
 };
 
        if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii"))
                return 0;
 
+       pm_power_off = wii_power_off;
+
        return 1;
 }
 
        .init_early             = wii_init_early,
        .setup_arch             = wii_setup_arch,
        .restart                = wii_restart,
-       .power_off              = wii_power_off,
        .halt                   = wii_halt,
        .init_IRQ               = wii_pic_probe,
        .get_irq                = flipper_pic_get_irq,
 
        if (rtas_service_present("system-reboot") &&
            rtas_service_present("power-off")) {
                ppc_md.restart = rtas_restart;
-               ppc_md.power_off = rtas_power_off;
+               pm_power_off = rtas_power_off;
                ppc_md.halt = rtas_halt;
        }
 }
        alloc_dart_table();
 
        hpte_init_native();
+       pm_power_off = maple_power_off;
 
        return 1;
 }
        .pci_irq_fixup          = maple_pci_irq_fixup,
        .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
        .restart                = maple_restart,
-       .power_off              = maple_power_off,
        .halt                   = maple_halt,
                .get_boot_time          = maple_get_boot_time,
                .set_rtc_time           = maple_set_rtc_time,
 
        smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL);
 #endif /* CONFIG_PMAC_SMU */
 
+       pm_power_off = pmac_power_off;
+
        return 1;
 }
 
        .get_irq                = NULL, /* changed later */
        .pci_irq_fixup          = pmac_pci_irq_fixup,
        .restart                = pmac_restart,
-       .power_off              = pmac_power_off,
        .halt                   = pmac_halt,
        .time_init              = pmac_time_init,
        .get_boot_time          = pmac_get_boot_time,
 
        ppc_md.get_rtc_time = opal_get_rtc_time;
        ppc_md.set_rtc_time = opal_set_rtc_time;
        ppc_md.restart = pnv_restart;
-       ppc_md.power_off = pnv_power_off;
+       pm_power_off = pnv_power_off;
        ppc_md.halt = pnv_halt;
        ppc_md.machine_check_exception = opal_machine_check;
        ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
                ppc_md.set_rtc_time = rtas_set_rtc_time;
        }
        ppc_md.restart = rtas_restart;
-       ppc_md.power_off = rtas_power_off;
+       pm_power_off = rtas_power_off;
        ppc_md.halt = rtas_halt;
 }
 #endif /* CONFIG_PPC_POWERNV_RTAS */
 
        ps3_mm_init();
        ps3_mm_vas_create(&htab_size);
        ps3_hpte_init(htab_size);
+       pm_power_off = ps3_power_off;
 
        DBG(" <- %s:%d\n", __func__, __LINE__);
        return 1;
        .calibrate_decr                 = ps3_calibrate_decr,
        .progress                       = ps3_progress,
        .restart                        = ps3_restart,
-       .power_off                      = ps3_power_off,
        .halt                           = ps3_halt,
 #if defined(CONFIG_KEXEC)
        .kexec_cpu_down                 = ps3_kexec_cpu_down,
 
        pr_debug(" <- pSeries_init_early()\n");
 }
 
+/**
+ * pseries_power_off - tell firmware about how to power off the system.
+ *
+ * This function calls either the power-off rtas token in normal cases
+ * or the ibm,power-off-ups token (if present & requested) in case of
+ * a power failure. If power-off token is used, power on will only be
+ * possible with power button press. If ibm,power-off-ups token is used
+ * it will allow auto poweron after power is restored.
+ */
+static void pseries_power_off(void)
+{
+       int rc;
+       int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
+
+       if (rtas_flash_term_hook)
+               rtas_flash_term_hook(SYS_POWER_OFF);
+
+       if (rtas_poweron_auto == 0 ||
+               rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
+               rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
+               printk(KERN_INFO "RTAS power-off returned %d\n", rc);
+       } else {
+               rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
+               printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
+       }
+       for (;;);
+}
+
 /*
  * Called very early, MMU is off, device-tree isn't unflattened
  */
        else
                hpte_init_native();
 
+       pm_power_off = pseries_power_off;
+
        pr_debug("Machine is%s LPAR !\n",
                 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
 
        return PCI_PROBE_NORMAL;
 }
 
-/**
- * pSeries_power_off - tell firmware about how to power off the system.
- *
- * This function calls either the power-off rtas token in normal cases
- * or the ibm,power-off-ups token (if present & requested) in case of
- * a power failure. If power-off token is used, power on will only be
- * possible with power button press. If ibm,power-off-ups token is used
- * it will allow auto poweron after power is restored.
- */
-static void pSeries_power_off(void)
-{
-       int rc;
-       int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
-
-       if (rtas_flash_term_hook)
-               rtas_flash_term_hook(SYS_POWER_OFF);
-
-       if (rtas_poweron_auto == 0 ||
-               rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
-               rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
-               printk(KERN_INFO "RTAS power-off returned %d\n", rc);
-       } else {
-               rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
-               printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
-       }
-       for (;;);
-}
-
 #ifndef CONFIG_PCI
 void pSeries_final_fixup(void) { }
 #endif
        .pcibios_fixup          = pSeries_final_fixup,
        .pci_probe_mode         = pSeries_pci_probe_mode,
        .restart                = rtas_restart,
-       .power_off              = pSeries_power_off,
        .halt                   = rtas_halt,
        .panic                  = rtas_os_term,
        .get_boot_time          = rtas_get_boot_time,
 
 /*
  * Halt the current partition
  *
- * This function should be assigned to the ppc_md.power_off and ppc_md.halt
+ * This function should be assigned to the pm_power_off and ppc_md.halt
  * function pointers, to shut down the partition when we're running under
  * the Freescale hypervisor.
  */
 
        else if (cmd == 'h')
                ppc_md.halt();
        else if (cmd == 'p')
-               ppc_md.power_off();
+               if (pm_power_off)
+                       pm_power_off();
 }
 
 static int cpu_cmd(void)