powerpc: Merge remaining RTAS code
authorPaul Mackerras <paulus@samba.org>
Thu, 3 Nov 2005 03:41:19 +0000 (14:41 +1100)
committerPaul Mackerras <paulus@samba.org>
Thu, 3 Nov 2005 03:41:19 +0000 (14:41 +1100)
This moves rtas-proc.c and rtas_flash.c into arch/powerpc/kernel, since
cell wants them as well as pseries (and chrp can use rtas-proc.c too,
at least in principle).  rtas_fw.c is gone, with its bits moved into
rtas_flash.c and rtas.c.

Signed-off-by: Paul Mackerras <paulus@samba.org>
12 files changed:
arch/powerpc/Kconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/rtas-proc.c [moved from arch/ppc64/kernel/rtas-proc.c with 100% similarity]
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_flash.c [moved from arch/ppc64/kernel/rtas_flash.c with 83% similarity]
arch/powerpc/kernel/rtas_fw.c [deleted file]
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/rtasd.c [moved from arch/ppc64/kernel/rtasd.c with 100% similarity]
arch/powerpc/platforms/pseries/setup.c
arch/ppc64/kernel/Makefile
include/asm-powerpc/rtas.h

index 1c44a1d..3cf03ab 100644 (file)
@@ -278,7 +278,6 @@ config PPC_PSERIES
        select PPC_I8259
        select PPC_RTAS
        select RTAS_ERROR_LOGGING
-       select RTAS_FW
        default y
 
 config PPC_CHRP
@@ -324,7 +323,6 @@ config PPC_CELL
        bool "  Cell Broadband Processor Architecture"
        depends on PPC_MULTIPLATFORM && PPC64
        select PPC_RTAS
-       select RTAS_FW
        select MMIO_NVRAM
 
 config PPC_OF
@@ -356,10 +354,14 @@ config RTAS_ERROR_LOGGING
        depends on PPC_RTAS
        default n
 
-config RTAS_FW
-       bool
+config RTAS_PROC
+       bool "Proc interface to RTAS"
        depends on PPC_RTAS
-       default n
+       default y
+
+config RTAS_FLASH
+       tristate "Firmware flash interface"
+       depends on PPC64 && RTAS_PROC
 
 config MMIO_NVRAM
        bool
index abad305..601ddbf 100644 (file)
@@ -18,7 +18,8 @@ obj-$(CONFIG_ALTIVEC)         += vecemu.o vector.o
 obj-$(CONFIG_POWER4)           += idle_power4.o
 obj-$(CONFIG_PPC_OF)           += of_device.o
 obj-$(CONFIG_PPC_RTAS)         += rtas.o
-obj-$(CONFIG_RTAS_FW)          += rtas_fw.o
+obj-$(CONFIG_RTAS_FLASH)       += rtas_flash.o
+obj-$(CONFIG_RTAS_PROC)                += rtas-proc.o
 obj-$(CONFIG_IBMVIO)           += vio.o
 
 ifeq ($(CONFIG_PPC_MERGE),y)
index 4d22eee..b7fc2d8 100644 (file)
@@ -43,6 +43,13 @@ char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
 unsigned long rtas_rmo_buf;
 
 /*
+ * If non-NULL, this gets called when the kernel terminates.
+ * This is done like this so rtas_flash can be a module.
+ */
+void (*rtas_flash_term_hook)(int);
+EXPORT_SYMBOL(rtas_flash_term_hook);
+
+/*
  * call_rtas_display_status and call_rtas_display_status_delay
  * are designed only for very early low-level debugging, which
  * is why the token is hard-coded to 10.
@@ -206,6 +213,7 @@ void rtas_progress(char *s, unsigned short hex)
  
        spin_unlock(&progress_lock);
 }
+EXPORT_SYMBOL(rtas_progress);          /* needed by rtas_flash module */
 
 int rtas_token(const char *service)
 {
@@ -492,6 +500,8 @@ int rtas_set_indicator(int indicator, int index, int new_value)
 
 void rtas_restart(char *cmd)
 {
+       if (rtas_flash_term_hook)
+               rtas_flash_term_hook(SYS_RESTART);
        printk("RTAS system-reboot returned %d\n",
               rtas_call(rtas_token("system-reboot"), 0, 1, NULL));
        for (;;);
@@ -499,6 +509,8 @@ void rtas_restart(char *cmd)
 
 void rtas_power_off(void)
 {
+       if (rtas_flash_term_hook)
+               rtas_flash_term_hook(SYS_POWER_OFF);
        /* allow power on only with power button press */
        printk("RTAS power-off returned %d\n",
               rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
@@ -507,7 +519,12 @@ void rtas_power_off(void)
 
 void rtas_halt(void)
 {
-       rtas_power_off();
+       if (rtas_flash_term_hook)
+               rtas_flash_term_hook(SYS_HALT);
+       /* allow power on only with power button press */
+       printk("RTAS power-off returned %d\n",
+              rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1));
+       for (;;);
 }
 
 /* Must be in the RMO region, so we place it here */
similarity index 83%
rename from arch/ppc64/kernel/rtas_flash.c
rename to arch/powerpc/kernel/rtas_flash.c
index 923e2e2..5050009 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/delay.h>
 #include <asm/uaccess.h>
 #include <asm/rtas.h>
+#include <asm/abs_addr.h>
 
 #define MODULE_VERS "1.0"
 #define MODULE_NAME "rtas_flash"
 #define VALIDATE_BUF_SIZE 4096    
 #define RTAS_MSG_MAXLEN   64
 
+struct flash_block {
+       char *data;
+       unsigned long length;
+};
+
+/* This struct is very similar but not identical to
+ * that needed by the rtas flash update.
+ * All we need to do for rtas is rewrite num_blocks
+ * into a version/length and translate the pointers
+ * to absolute.
+ */
+#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
+struct flash_block_list {
+       unsigned long num_blocks;
+       struct flash_block_list *next;
+       struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
+};
+struct flash_block_list_header { /* just the header of flash_block_list */
+       unsigned long num_blocks;
+       struct flash_block_list *next;
+};
+
+static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
+
+#define FLASH_BLOCK_LIST_VERSION (1UL)
+
 /* Local copy of the flash block list.
  * We only allow one open of the flash proc file and create this
- * list as we go.  This list will be put in the kernel's
- * rtas_firmware_flash_list global var once it is fully read.
+ * list as we go.  This list will be put in the
+ * rtas_firmware_flash_list var once it is fully read.
  *
  * For convenience as we build the list we use virtual addrs,
  * we do not fill in the version number, and the length field
@@ -562,6 +589,86 @@ static int validate_flash_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+static void rtas_flash_firmware(int reboot_type)
+{
+       unsigned long image_size;
+       struct flash_block_list *f, *next, *flist;
+       unsigned long rtas_block_list;
+       int i, status, update_token;
+
+       if (rtas_firmware_flash_list.next == NULL)
+               return;         /* nothing to do */
+
+       if (reboot_type != SYS_RESTART) {
+               printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
+               printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
+               return;
+       }
+
+       update_token = rtas_token("ibm,update-flash-64-and-reboot");
+       if (update_token == RTAS_UNKNOWN_SERVICE) {
+               printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot "
+                      "is not available -- not a service partition?\n");
+               printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
+               return;
+       }
+
+       /* NOTE: the "first" block list is a global var with no data
+        * blocks in the kernel data segment.  We do this because
+        * we want to ensure this block_list addr is under 4GB.
+        */
+       rtas_firmware_flash_list.num_blocks = 0;
+       flist = (struct flash_block_list *)&rtas_firmware_flash_list;
+       rtas_block_list = virt_to_abs(flist);
+       if (rtas_block_list >= 4UL*1024*1024*1024) {
+               printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
+               return;
+       }
+
+       printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
+       /* Update the block_list in place. */
+       image_size = 0;
+       for (f = flist; f; f = next) {
+               /* Translate data addrs to absolute */
+               for (i = 0; i < f->num_blocks; i++) {
+                       f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
+                       image_size += f->blocks[i].length;
+               }
+               next = f->next;
+               /* Don't translate NULL pointer for last entry */
+               if (f->next)
+                       f->next = (struct flash_block_list *)virt_to_abs(f->next);
+               else
+                       f->next = NULL;
+               /* make num_blocks into the version/length field */
+               f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
+       }
+
+       printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
+       printk(KERN_ALERT "FLASH: performing flash and reboot\n");
+       rtas_progress("Flashing        \n", 0x0);
+       rtas_progress("Please Wait...  ", 0x0);
+       printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
+       status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
+       switch (status) {       /* should only get "bad" status */
+           case 0:
+               printk(KERN_ALERT "FLASH: success\n");
+               break;
+           case -1:
+               printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
+               break;
+           case -3:
+               printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
+               break;
+           case -4:
+               printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
+               break;
+           default:
+               printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
+               break;
+       }
+}
+
 static void remove_flash_pde(struct proc_dir_entry *dp)
 {
        if (dp) {
@@ -701,6 +808,7 @@ int __init rtas_flash_init(void)
        if (rc != 0)
                goto cleanup;
 
+       rtas_flash_term_hook = rtas_flash_firmware;
        return 0;
 
 cleanup:
@@ -714,6 +822,7 @@ cleanup:
 
 void __exit rtas_flash_cleanup(void)
 {
+       rtas_flash_term_hook = NULL;
        remove_flash_pde(firmware_flash_pde);
        remove_flash_pde(firmware_update_pde);
        remove_flash_pde(validate_pde);
diff --git a/arch/powerpc/kernel/rtas_fw.c b/arch/powerpc/kernel/rtas_fw.c
deleted file mode 100644 (file)
index 448922e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *
- * Procedures for firmware flash updates.
- *
- * Peter Bergner, IBM  March 2001.
- * Copyright (C) 2001 IBM.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-
-#include <stdarg.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <asm/prom.h>
-#include <asm/rtas.h>
-#include <asm/semaphore.h>
-#include <asm/machdep.h>
-#include <asm/page.h>
-#include <asm/param.h>
-#include <asm/system.h>
-#include <asm/abs_addr.h>
-#include <asm/udbg.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include <asm/systemcfg.h>
-
-struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
-
-#define FLASH_BLOCK_LIST_VERSION (1UL)
-
-static void rtas_flash_firmware(void)
-{
-       unsigned long image_size;
-       struct flash_block_list *f, *next, *flist;
-       unsigned long rtas_block_list;
-       int i, status, update_token;
-
-       update_token = rtas_token("ibm,update-flash-64-and-reboot");
-       if (update_token == RTAS_UNKNOWN_SERVICE) {
-               printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
-               printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
-               return;
-       }
-
-       /* NOTE: the "first" block list is a global var with no data
-        * blocks in the kernel data segment.  We do this because
-        * we want to ensure this block_list addr is under 4GB.
-        */
-       rtas_firmware_flash_list.num_blocks = 0;
-       flist = (struct flash_block_list *)&rtas_firmware_flash_list;
-       rtas_block_list = virt_to_abs(flist);
-       if (rtas_block_list >= 4UL*1024*1024*1024) {
-               printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
-               return;
-       }
-
-       printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
-       /* Update the block_list in place. */
-       image_size = 0;
-       for (f = flist; f; f = next) {
-               /* Translate data addrs to absolute */
-               for (i = 0; i < f->num_blocks; i++) {
-                       f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
-                       image_size += f->blocks[i].length;
-               }
-               next = f->next;
-               /* Don't translate NULL pointer for last entry */
-               if (f->next)
-                       f->next = (struct flash_block_list *)virt_to_abs(f->next);
-               else
-                       f->next = NULL;
-               /* make num_blocks into the version/length field */
-               f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
-       }
-
-       printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
-       printk(KERN_ALERT "FLASH: performing flash and reboot\n");
-       rtas_progress("Flashing        \n", 0x0);
-       rtas_progress("Please Wait...  ", 0x0);
-       printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
-       status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
-       switch (status) {       /* should only get "bad" status */
-           case 0:
-               printk(KERN_ALERT "FLASH: success\n");
-               break;
-           case -1:
-               printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
-               break;
-           case -3:
-               printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
-               break;
-           case -4:
-               printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
-               break;
-           default:
-               printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
-               break;
-       }
-}
-
-void rtas_flash_bypass_warning(void)
-{
-       printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
-       printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
-}
-
-
-void rtas_fw_restart(char *cmd)
-{
-       if (rtas_firmware_flash_list.next)
-               rtas_flash_firmware();
-       rtas_restart(cmd);
-}
-
-void rtas_fw_power_off(void)
-{
-       if (rtas_firmware_flash_list.next)
-               rtas_flash_bypass_warning();
-       rtas_power_off();
-}
-
-void rtas_fw_halt(void)
-{
-       if (rtas_firmware_flash_list.next)
-               rtas_flash_bypass_warning();
-       rtas_halt();
-}
-
-EXPORT_SYMBOL(rtas_firmware_flash_list);
index 2d57f58..e3fc340 100644 (file)
@@ -21,15 +21,6 @@ config EEH
        depends on PPC_PSERIES
        default y if !EMBEDDED
 
-config RTAS_PROC
-       bool "Proc interface to RTAS"
-       depends on PPC_RTAS
-       default y
-
-config RTAS_FLASH
-       tristate "Firmware flash interface"
-       depends on PPC64 && RTAS_PROC
-
 config SCANLOG
        tristate "Scanlog dump interface"
        depends on RTAS_PROC && PPC_PSERIES
index 91909a8..b9938fe 100644 (file)
@@ -1,5 +1,5 @@
 obj-y                  := pci.o lpar.o hvCall.o nvram.o reconfig.o \
-                          setup.o iommu.o ras.o
+                          setup.o iommu.o ras.o rtasd.o
 obj-$(CONFIG_SMP)      += smp.o
 obj-$(CONFIG_IBMVIO)   += vio.o
 obj-$(CONFIG_XICS)     += xics.o
index c0a3d91..f73d691 100644 (file)
@@ -589,9 +589,9 @@ struct machdep_calls __initdata pSeries_md = {
        .pcibios_fixup          = pSeries_final_fixup,
        .pci_probe_mode         = pSeries_pci_probe_mode,
        .irq_bus_setup          = pSeries_irq_bus_setup,
-       .restart                = rtas_fw_restart,
-       .power_off              = rtas_fw_power_off,
-       .halt                   = rtas_fw_halt,
+       .restart                = rtas_restart,
+       .power_off              = rtas_power_off,
+       .halt                   = rtas_halt,
        .panic                  = rtas_os_term,
        .cpu_die                = pSeries_mach_cpu_die,
        .get_boot_time          = rtas_get_boot_time,
index 990df09..74892ad 100644 (file)
@@ -29,19 +29,17 @@ ifneq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
 endif
 
-obj-$(CONFIG_PPC_PSERIES) += rtasd.o udbg_16550.o
+obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
 
 obj-$(CONFIG_KEXEC)            += machine_kexec.o
 obj-$(CONFIG_EEH)              += eeh.o
 obj-$(CONFIG_PROC_FS)          += proc_ppc64.o
-obj-$(CONFIG_RTAS_FLASH)       += rtas_flash.o
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_MODULES)          += module.o
 ifneq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_MODULES)          += ppc_ksyms.o
 endif
 obj-$(CONFIG_PPC_RTAS)         += rtas_pci.o
-obj-$(CONFIG_RTAS_PROC)                += rtas-proc.o
 obj-$(CONFIG_SCANLOG)          += scanlog.o
 obj-$(CONFIG_LPARCFG)          += lparcfg.o
 obj-$(CONFIG_HVC_CONSOLE)      += hvconsole.o
index d9fd786..d1bb611 100644 (file)
@@ -149,31 +149,11 @@ struct rtas_error_log {
        unsigned char buffer[1];
 };
 
-struct flash_block {
-       char *data;
-       unsigned long length;
-};
-
-/* This struct is very similar but not identical to
- * that needed by the rtas flash update.
- * All we need to do for rtas is rewrite num_blocks
- * into a version/length and translate the pointers
- * to absolute.
+/*
+ * This can be set by the rtas_flash module so that it can get called
+ * as the absolutely last thing before the kernel terminates.
  */
-#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block))
-struct flash_block_list {
-       unsigned long num_blocks;
-       struct flash_block_list *next;
-       struct flash_block blocks[FLASH_BLOCKS_PER_NODE];
-};
-struct flash_block_list_header { /* just the header of flash_block_list */
-       unsigned long num_blocks;
-       struct flash_block_list *next;
-};
-extern struct flash_block_list_header rtas_firmware_flash_list;
-void rtas_fw_restart(char *cmd);
-void rtas_fw_power_off(void);
-void rtas_fw_halt(void);
+extern void (*rtas_flash_term_hook)(int);
 
 extern struct rtas_t rtas;