[ALSA] timer: remove list_entry() type casts
[linux-2.6] / arch / powerpc / platforms / pseries / rtas-fw.c
1 /*
2  *
3  * Procedures for firmware flash updates on pSeries systems.
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 #include "rtas-fw.h"
35
36 struct flash_block_list_header rtas_firmware_flash_list = {0, NULL};
37
38 #define FLASH_BLOCK_LIST_VERSION (1UL)
39
40 static void rtas_flash_firmware(void)
41 {
42         unsigned long image_size;
43         struct flash_block_list *f, *next, *flist;
44         unsigned long rtas_block_list;
45         int i, status, update_token;
46
47         update_token = rtas_token("ibm,update-flash-64-and-reboot");
48         if (update_token == RTAS_UNKNOWN_SERVICE) {
49                 printk(KERN_ALERT "FLASH: ibm,update-flash-64-and-reboot is not available -- not a service partition?\n");
50                 printk(KERN_ALERT "FLASH: firmware will not be flashed\n");
51                 return;
52         }
53
54         /* NOTE: the "first" block list is a global var with no data
55          * blocks in the kernel data segment.  We do this because
56          * we want to ensure this block_list addr is under 4GB.
57          */
58         rtas_firmware_flash_list.num_blocks = 0;
59         flist = (struct flash_block_list *)&rtas_firmware_flash_list;
60         rtas_block_list = virt_to_abs(flist);
61         if (rtas_block_list >= 4UL*1024*1024*1024) {
62                 printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
63                 return;
64         }
65
66         printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n");
67         /* Update the block_list in place. */
68         image_size = 0;
69         for (f = flist; f; f = next) {
70                 /* Translate data addrs to absolute */
71                 for (i = 0; i < f->num_blocks; i++) {
72                         f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
73                         image_size += f->blocks[i].length;
74                 }
75                 next = f->next;
76                 /* Don't translate NULL pointer for last entry */
77                 if (f->next)
78                         f->next = (struct flash_block_list *)virt_to_abs(f->next);
79                 else
80                         f->next = NULL;
81                 /* make num_blocks into the version/length field */
82                 f->num_blocks = (FLASH_BLOCK_LIST_VERSION << 56) | ((f->num_blocks+1)*16);
83         }
84
85         printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
86         printk(KERN_ALERT "FLASH: performing flash and reboot\n");
87         rtas_progress("Flashing        \n", 0x0);
88         rtas_progress("Please Wait...  ", 0x0);
89         printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
90         status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
91         switch (status) {       /* should only get "bad" status */
92             case 0:
93                 printk(KERN_ALERT "FLASH: success\n");
94                 break;
95             case -1:
96                 printk(KERN_ALERT "FLASH: hardware error.  Firmware may not be not flashed\n");
97                 break;
98             case -3:
99                 printk(KERN_ALERT "FLASH: image is corrupt or not correct for this platform.  Firmware not flashed\n");
100                 break;
101             case -4:
102                 printk(KERN_ALERT "FLASH: flash failed when partially complete.  System may not reboot\n");
103                 break;
104             default:
105                 printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status);
106                 break;
107         }
108 }
109
110 void rtas_flash_bypass_warning(void)
111 {
112         printk(KERN_ALERT "FLASH: firmware flash requires a reboot\n");
113         printk(KERN_ALERT "FLASH: the firmware image will NOT be flashed\n");
114 }
115
116
117 void rtas_fw_restart(char *cmd)
118 {
119         if (rtas_firmware_flash_list.next)
120                 rtas_flash_firmware();
121         rtas_restart(cmd);
122 }
123
124 void rtas_fw_power_off(void)
125 {
126         if (rtas_firmware_flash_list.next)
127                 rtas_flash_bypass_warning();
128         rtas_power_off();
129 }
130
131 void rtas_fw_halt(void)
132 {
133         if (rtas_firmware_flash_list.next)
134                 rtas_flash_bypass_warning();
135         rtas_halt();
136 }
137
138 EXPORT_SYMBOL(rtas_firmware_flash_list);