Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Merge remaining RTAS code

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>

+147 -185
+7 -5
arch/powerpc/Kconfig
··· 278 278 select PPC_I8259 279 279 select PPC_RTAS 280 280 select RTAS_ERROR_LOGGING 281 - select RTAS_FW 282 281 default y 283 282 284 283 config PPC_CHRP ··· 323 324 bool " Cell Broadband Processor Architecture" 324 325 depends on PPC_MULTIPLATFORM && PPC64 325 326 select PPC_RTAS 326 - select RTAS_FW 327 327 select MMIO_NVRAM 328 328 329 329 config PPC_OF ··· 354 356 depends on PPC_RTAS 355 357 default n 356 358 357 - config RTAS_FW 358 - bool 359 + config RTAS_PROC 360 + bool "Proc interface to RTAS" 359 361 depends on PPC_RTAS 360 - default n 362 + default y 363 + 364 + config RTAS_FLASH 365 + tristate "Firmware flash interface" 366 + depends on PPC64 && RTAS_PROC 361 367 362 368 config MMIO_NVRAM 363 369 bool
+2 -1
arch/powerpc/kernel/Makefile
··· 18 18 obj-$(CONFIG_POWER4) += idle_power4.o 19 19 obj-$(CONFIG_PPC_OF) += of_device.o 20 20 obj-$(CONFIG_PPC_RTAS) += rtas.o 21 - obj-$(CONFIG_RTAS_FW) += rtas_fw.o 21 + obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 22 + obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 22 23 obj-$(CONFIG_IBMVIO) += vio.o 23 24 24 25 ifeq ($(CONFIG_PPC_MERGE),y)
+18 -1
arch/powerpc/kernel/rtas.c
··· 43 43 unsigned long rtas_rmo_buf; 44 44 45 45 /* 46 + * If non-NULL, this gets called when the kernel terminates. 47 + * This is done like this so rtas_flash can be a module. 48 + */ 49 + void (*rtas_flash_term_hook)(int); 50 + EXPORT_SYMBOL(rtas_flash_term_hook); 51 + 52 + /* 46 53 * call_rtas_display_status and call_rtas_display_status_delay 47 54 * are designed only for very early low-level debugging, which 48 55 * is why the token is hard-coded to 10. ··· 213 206 214 207 spin_unlock(&progress_lock); 215 208 } 209 + EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */ 216 210 217 211 int rtas_token(const char *service) 218 212 { ··· 500 492 501 493 void rtas_restart(char *cmd) 502 494 { 495 + if (rtas_flash_term_hook) 496 + rtas_flash_term_hook(SYS_RESTART); 503 497 printk("RTAS system-reboot returned %d\n", 504 498 rtas_call(rtas_token("system-reboot"), 0, 1, NULL)); 505 499 for (;;); ··· 509 499 510 500 void rtas_power_off(void) 511 501 { 502 + if (rtas_flash_term_hook) 503 + rtas_flash_term_hook(SYS_POWER_OFF); 512 504 /* allow power on only with power button press */ 513 505 printk("RTAS power-off returned %d\n", 514 506 rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); ··· 519 507 520 508 void rtas_halt(void) 521 509 { 522 - rtas_power_off(); 510 + if (rtas_flash_term_hook) 511 + rtas_flash_term_hook(SYS_HALT); 512 + /* allow power on only with power button press */ 513 + printk("RTAS power-off returned %d\n", 514 + rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1)); 515 + for (;;); 523 516 } 524 517 525 518 /* Must be in the RMO region, so we place it here */
-136
arch/powerpc/kernel/rtas_fw.c
··· 1 - /* 2 - * 3 - * Procedures for firmware flash updates. 4 - * 5 - * Peter Bergner, IBM March 2001. 6 - * Copyright (C) 2001 IBM. 7 - * 8 - * This program is free software; you can redistribute it and/or 9 - * modify it under the terms of the GNU General Public License 10 - * as published by the Free Software Foundation; either version 11 - * 2 of the License, or (at your option) any later version. 12 - */ 13 - 14 - #include <stdarg.h> 15 - #include <linux/kernel.h> 16 - #include <linux/types.h> 17 - #include <linux/spinlock.h> 18 - #include <linux/module.h> 19 - #include <linux/init.h> 20 - 21 - #include <asm/prom.h> 22 - #include <asm/rtas.h> 23 - #include <asm/semaphore.h> 24 - #include <asm/machdep.h> 25 - #include <asm/page.h> 26 - #include <asm/param.h> 27 - #include <asm/system.h> 28 - #include <asm/abs_addr.h> 29 - #include <asm/udbg.h> 30 - #include <asm/delay.h> 31 - #include <asm/uaccess.h> 32 - #include <asm/systemcfg.h> 33 - 34 - struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; 35 - 36 - #define FLASH_BLOCK_LIST_VERSION (1UL) 37 - 38 - static void rtas_flash_firmware(void) 39 - { 40 - unsigned long image_size; 41 - struct flash_block_list *f, *next, *flist; 42 - unsigned long rtas_block_list; 43 - int i, status, update_token; 44 - 45 - update_token = rtas_token("ibm,update-flash-64-and-reboot"); 46 - if (update_token == RTAS_UNKNOWN_SERVICE) { 47 - printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n"); 48 - printk(KERN_ALERT "FLASH: firmware will not be flashed\n"); 49 - return; 50 - } 51 - 52 - /* NOTE: the "first" block list is a global var with no data 53 - * blocks in the kernel data segment. We do this because 54 - * we want to ensure this block_list addr is under 4GB. 55 - */ 56 - rtas_firmware_flash_list.num_blocks = 0; 57 - flist = (struct flash_block_list *)&rtas_firmware_flash_list; 58 - rtas_block_list = virt_to_abs(flist); 59 - if (rtas_block_list >= 4UL*1024*1024*1024) { 60 - printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); 61 - return; 62 - } 63 - 64 - printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n"); 65 - /* Update the block_list in place. */ 66 - image_size = 0; 67 - for (f = flist; f; f = next) { 68 - /* Translate data addrs to absolute */ 69 - for (i = 0; i < f->num_blocks; i++) { 70 - f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data); 71 - image_size += f->blocks[i].length; 72 - } 73 - next = f->next; 74 - /* Don't translate NULL pointer for last entry */ 75 - if (f->next) 76 - f->next = (struct flash_block_list *)virt_to_abs(f->next); 77 - else 78 - f->next = NULL; 79 - /* make num_blocks into the version/length field */ 80 - f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16); 81 - } 82 - 83 - printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); 84 - printk(KERN_ALERT "FLASH: performing flash and reboot\n"); 85 - rtas_progress("Flashing \n", 0x0); 86 - rtas_progress("Please Wait... ", 0x0); 87 - printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); 88 - status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); 89 - switch (status) { /* should only get "bad" status */ 90 - case 0: 91 - printk(KERN_ALERT "FLASH: success\n"); 92 - break; 93 - case -1: 94 - printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n"); 95 - break; 96 - case -3: 97 - printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n"); 98 - break; 99 - case -4: 100 - printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n"); 101 - break; 102 - default: 103 - printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status); 104 - break; 105 - } 106 - } 107 - 108 - void rtas_flash_bypass_warning(void) 109 - { 110 - printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n"); 111 - printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n"); 112 - } 113 - 114 - 115 - void rtas_fw_restart(char *cmd) 116 - { 117 - if (rtas_firmware_flash_list.next) 118 - rtas_flash_firmware(); 119 - rtas_restart(cmd); 120 - } 121 - 122 - void rtas_fw_power_off(void) 123 - { 124 - if (rtas_firmware_flash_list.next) 125 - rtas_flash_bypass_warning(); 126 - rtas_power_off(); 127 - } 128 - 129 - void rtas_fw_halt(void) 130 - { 131 - if (rtas_firmware_flash_list.next) 132 - rtas_flash_bypass_warning(); 133 - rtas_halt(); 134 - } 135 - 136 - EXPORT_SYMBOL(rtas_firmware_flash_list);
-9
arch/powerpc/platforms/pseries/Kconfig
··· 21 21 depends on PPC_PSERIES 22 22 default y if !EMBEDDED 23 23 24 - config RTAS_PROC 25 - bool "Proc interface to RTAS" 26 - depends on PPC_RTAS 27 - default y 28 - 29 - config RTAS_FLASH 30 - tristate "Firmware flash interface" 31 - depends on PPC64 && RTAS_PROC 32 - 33 24 config SCANLOG 34 25 tristate "Scanlog dump interface" 35 26 depends on RTAS_PROC && PPC_PSERIES
+1 -1
arch/powerpc/platforms/pseries/Makefile
··· 1 1 obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ 2 - setup.o iommu.o ras.o 2 + setup.o iommu.o ras.o rtasd.o 3 3 obj-$(CONFIG_SMP) += smp.o 4 4 obj-$(CONFIG_IBMVIO) += vio.o 5 5 obj-$(CONFIG_XICS) += xics.o
+3 -3
arch/powerpc/platforms/pseries/setup.c
··· 589 589 .pcibios_fixup = pSeries_final_fixup, 590 590 .pci_probe_mode = pSeries_pci_probe_mode, 591 591 .irq_bus_setup = pSeries_irq_bus_setup, 592 - .restart = rtas_fw_restart, 593 - .power_off = rtas_fw_power_off, 594 - .halt = rtas_fw_halt, 592 + .restart = rtas_restart, 593 + .power_off = rtas_power_off, 594 + .halt = rtas_halt, 595 595 .panic = rtas_os_term, 596 596 .cpu_die = pSeries_mach_cpu_die, 597 597 .get_boot_time = rtas_get_boot_time,
+1 -3
arch/ppc64/kernel/Makefile
··· 29 29 obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 30 30 endif 31 31 32 - obj-$(CONFIG_PPC_PSERIES) += rtasd.o udbg_16550.o 32 + obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o 33 33 34 34 obj-$(CONFIG_KEXEC) += machine_kexec.o 35 35 obj-$(CONFIG_EEH) += eeh.o 36 36 obj-$(CONFIG_PROC_FS) += proc_ppc64.o 37 - obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o 38 37 obj-$(CONFIG_SMP) += smp.o 39 38 obj-$(CONFIG_MODULES) += module.o 40 39 ifneq ($(CONFIG_PPC_MERGE),y) 41 40 obj-$(CONFIG_MODULES) += ppc_ksyms.o 42 41 endif 43 42 obj-$(CONFIG_PPC_RTAS) += rtas_pci.o 44 - obj-$(CONFIG_RTAS_PROC) += rtas-proc.o 45 43 obj-$(CONFIG_SCANLOG) += scanlog.o 46 44 obj-$(CONFIG_LPARCFG) += lparcfg.o 47 45 obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
arch/ppc64/kernel/rtas-proc.c arch/powerpc/kernel/rtas-proc.c
+111 -2
arch/ppc64/kernel/rtas_flash.c arch/powerpc/kernel/rtas_flash.c
··· 19 19 #include <asm/delay.h> 20 20 #include <asm/uaccess.h> 21 21 #include <asm/rtas.h> 22 + #include <asm/abs_addr.h> 22 23 23 24 #define MODULE_VERS "1.0" 24 25 #define MODULE_NAME "rtas_flash" ··· 72 71 #define VALIDATE_BUF_SIZE 4096 73 72 #define RTAS_MSG_MAXLEN 64 74 73 74 + struct flash_block { 75 + char *data; 76 + unsigned long length; 77 + }; 78 + 79 + /* This struct is very similar but not identical to 80 + * that needed by the rtas flash update. 81 + * All we need to do for rtas is rewrite num_blocks 82 + * into a version/length and translate the pointers 83 + * to absolute. 84 + */ 85 + #define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) 86 + struct flash_block_list { 87 + unsigned long num_blocks; 88 + struct flash_block_list *next; 89 + struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; 90 + }; 91 + struct flash_block_list_header { /* just the header of flash_block_list */ 92 + unsigned long num_blocks; 93 + struct flash_block_list *next; 94 + }; 95 + 96 + static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; 97 + 98 + #define FLASH_BLOCK_LIST_VERSION (1UL) 99 + 75 100 /* Local copy of the flash block list. 76 101 * We only allow one open of the flash proc file and create this 77 - * list as we go. This list will be put in the kernel's 78 - * rtas_firmware_flash_list global var once it is fully read. 102 + * list as we go. This list will be put in the 103 + * rtas_firmware_flash_list var once it is fully read. 79 104 * 80 105 * For convenience as we build the list we use virtual addrs, 81 106 * we do not fill in the version number, and the length field ··· 589 562 return 0; 590 563 } 591 564 565 + static void rtas_flash_firmware(int reboot_type) 566 + { 567 + unsigned long image_size; 568 + struct flash_block_list *f, *next, *flist; 569 + unsigned long rtas_block_list; 570 + int i, status, update_token; 571 + 572 + if (rtas_firmware_flash_list.next == NULL) 573 + return; /* nothing to do */ 574 + 575 + if (reboot_type != SYS_RESTART) { 576 + printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n"); 577 + printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n"); 578 + return; 579 + } 580 + 581 + update_token = rtas_token("ibm,update-flash-64-and-reboot"); 582 + if (update_token == RTAS_UNKNOWN_SERVICE) { 583 + printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot " 584 + "is not available -- not a service partition?\n"); 585 + printk(KERN_ALERT "FLASH: firmware will not be flashed\n"); 586 + return; 587 + } 588 + 589 + /* NOTE: the "first" block list is a global var with no data 590 + * blocks in the kernel data segment. We do this because 591 + * we want to ensure this block_list addr is under 4GB. 592 + */ 593 + rtas_firmware_flash_list.num_blocks = 0; 594 + flist = (struct flash_block_list *)&rtas_firmware_flash_list; 595 + rtas_block_list = virt_to_abs(flist); 596 + if (rtas_block_list >= 4UL*1024*1024*1024) { 597 + printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); 598 + return; 599 + } 600 + 601 + printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n"); 602 + /* Update the block_list in place. */ 603 + image_size = 0; 604 + for (f = flist; f; f = next) { 605 + /* Translate data addrs to absolute */ 606 + for (i = 0; i < f->num_blocks; i++) { 607 + f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data); 608 + image_size += f->blocks[i].length; 609 + } 610 + next = f->next; 611 + /* Don't translate NULL pointer for last entry */ 612 + if (f->next) 613 + f->next = (struct flash_block_list *)virt_to_abs(f->next); 614 + else 615 + f->next = NULL; 616 + /* make num_blocks into the version/length field */ 617 + f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16); 618 + } 619 + 620 + printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size); 621 + printk(KERN_ALERT "FLASH: performing flash and reboot\n"); 622 + rtas_progress("Flashing \n", 0x0); 623 + rtas_progress("Please Wait... ", 0x0); 624 + printk(KERN_ALERT "FLASH: this will take several minutes. Do not power off!\n"); 625 + status = rtas_call(update_token, 1, 1, NULL, rtas_block_list); 626 + switch (status) { /* should only get "bad" status */ 627 + case 0: 628 + printk(KERN_ALERT "FLASH: success\n"); 629 + break; 630 + case -1: 631 + printk(KERN_ALERT "FLASH: hardware error. Firmware may not be not flashed\n"); 632 + break; 633 + case -3: 634 + printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform. Firmware not flashed\n"); 635 + break; 636 + case -4: 637 + printk(KERN_ALERT "FLASH: flash failed when partially complete. System may not reboot\n"); 638 + break; 639 + default: 640 + printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status); 641 + break; 642 + } 643 + } 644 + 592 645 static void remove_flash_pde(struct proc_dir_entry *dp) 593 646 { 594 647 if (dp) { ··· 808 701 if (rc != 0) 809 702 goto cleanup; 810 703 704 + rtas_flash_term_hook = rtas_flash_firmware; 811 705 return 0; 812 706 813 707 cleanup: ··· 822 714 823 715 void __exit rtas_flash_cleanup(void) 824 716 { 717 + rtas_flash_term_hook = NULL; 825 718 remove_flash_pde(firmware_flash_pde); 826 719 remove_flash_pde(firmware_update_pde); 827 720 remove_flash_pde(validate_pde);
arch/ppc64/kernel/rtasd.c arch/powerpc/platforms/pseries/rtasd.c
+4 -24
include/asm-powerpc/rtas.h
··· 149 149 unsigned char buffer[1]; 150 150 }; 151 151 152 - struct flash_block { 153 - char *data; 154 - unsigned long length; 155 - }; 156 - 157 - /* This struct is very similar but not identical to 158 - * that needed by the rtas flash update. 159 - * All we need to do for rtas is rewrite num_blocks 160 - * into a version/length and translate the pointers 161 - * to absolute. 152 + /* 153 + * This can be set by the rtas_flash module so that it can get called 154 + * as the absolutely last thing before the kernel terminates. 162 155 */ 163 - #define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) 164 - struct flash_block_list { 165 - unsigned long num_blocks; 166 - struct flash_block_list *next; 167 - struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; 168 - }; 169 - struct flash_block_list_header { /* just the header of flash_block_list */ 170 - unsigned long num_blocks; 171 - struct flash_block_list *next; 172 - }; 173 - extern struct flash_block_list_header rtas_firmware_flash_list; 174 - void rtas_fw_restart(char *cmd); 175 - void rtas_fw_power_off(void); 176 - void rtas_fw_halt(void); 156 + extern void (*rtas_flash_term_hook)(int); 177 157 178 158 extern struct rtas_t rtas; 179 159