aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-06 18:30:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-06 18:30:54 -0500
commitf70f5b9dc74ca7d0a64c4ead3fb28da09dc1b234 (patch)
tree01f79ae109966d2ec515358481c151cda549d9ab /arch/sparc
parentb69fc2efc9205d58c820eb2eb1caa6bf873b4b0d (diff)
parent09798eb9479da3413bdf96e7d22a84d8b21e05e1 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6: (25 commits) atyfb: Fix bootup hangs on sparc64. sparc: update copyright in piggyback.c sparc: unify strip command in boot/Makefile sparc: rename piggyback_32 to piggyback sparc: fix tftpboot.img for sparc64 on little-endian host sparc: add $BITS to piggyback arguments sparc: remove obsolete ELF support in piggyback_32.c sparc: additional comments to piggyback_32.c sparc: use _start for the start entry (like 64 bit does) sparc: use trapbase in setup_arch sparc: refactor piggy_32.c Added support for ampopts in APBUART driver. Used in AMP systems. APBUART: added raw AMBA vendor/device number to match against. SPARC/LEON: avoid AMBAPP name duplicates in openprom fs when REG is missing SPARC/LEON: added support for selecting Timer Core and Timer within core LEON: added raw AMBA vendor/device number to find TIMER, IRQCTRL SPARC/LEON: added support for IRQAMP IRQ Controller SPARC/LEON: find IRQCTRL and Timer via OF-Tree, instead of hardcoded. sparc: fix sparse warnings in arch/sparc/prom for 32 bit build sparc: remove unused prom tree functions ...
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/boot/Makefile28
-rw-r--r--arch/sparc/boot/piggyback.c272
-rw-r--r--arch/sparc/boot/piggyback_32.c137
-rw-r--r--arch/sparc/boot/piggyback_64.c110
-rw-r--r--arch/sparc/include/asm/leon.h12
-rw-r--r--arch/sparc/include/asm/leon_amba.h6
-rw-r--r--arch/sparc/include/asm/oplib_32.h48
-rw-r--r--arch/sparc/include/asm/oplib_64.h4
-rw-r--r--arch/sparc/kernel/head_32.S3
-rw-r--r--arch/sparc/kernel/leon_kernel.c114
-rw-r--r--arch/sparc/kernel/prom_32.c27
-rw-r--r--arch/sparc/kernel/setup_32.c3
-rw-r--r--arch/sparc/mm/sun4c.c8
-rw-r--r--arch/sparc/prom/Makefile2
-rw-r--r--arch/sparc/prom/bootstr_32.c3
-rw-r--r--arch/sparc/prom/console_32.c7
-rw-r--r--arch/sparc/prom/console_64.c2
-rw-r--r--arch/sparc/prom/devmap.c53
-rw-r--r--arch/sparc/prom/init_64.c3
-rw-r--r--arch/sparc/prom/misc_32.c2
-rw-r--r--arch/sparc/prom/mp.c78
-rw-r--r--arch/sparc/prom/palloc.c43
-rw-r--r--arch/sparc/prom/ranges.c6
-rw-r--r--arch/sparc/prom/tree_32.c50
24 files changed, 442 insertions, 579 deletions
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile
index 97e3feb9ff1b..a2c5898c1ab1 100644
--- a/arch/sparc/boot/Makefile
+++ b/arch/sparc/boot/Makefile
@@ -6,25 +6,24 @@
6ROOT_IMG := /usr/src/root.img 6ROOT_IMG := /usr/src/root.img
7ELFTOAOUT := elftoaout 7ELFTOAOUT := elftoaout
8 8
9hostprogs-y := piggyback_32 piggyback_64 btfixupprep 9hostprogs-y := piggyback btfixupprep
10targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout 10targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout
11clean-files := System.map 11clean-files := System.map
12 12
13quiet_cmd_elftoaout = ELFTOAOUT $@ 13quiet_cmd_elftoaout = ELFTOAOUT $@
14 cmd_elftoaout = $(ELFTOAOUT) $(obj)/image -o $@ 14 cmd_elftoaout = $(ELFTOAOUT) $(obj)/image -o $@
15quiet_cmd_piggy = PIGGY $@
16 cmd_piggy = $(obj)/piggyback $(BITS) $@ System.map $(ROOT_IMG)
17quiet_cmd_strip = STRIP $@
18 cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $< -o $@
15 19
16ifeq ($(CONFIG_SPARC32),y) 20ifeq ($(CONFIG_SPARC32),y)
17quiet_cmd_piggy = PIGGY $@
18 cmd_piggy = $(obj)/piggyback_32 $@ System.map $(ROOT_IMG)
19quiet_cmd_btfix = BTFIX $@ 21quiet_cmd_btfix = BTFIX $@
20 cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ 22 cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@
21quiet_cmd_sysmap = SYSMAP $(obj)/System.map 23quiet_cmd_sysmap = SYSMAP $(obj)/System.map
22 cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap 24 cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
23quiet_cmd_image = LD $@ 25quiet_cmd_image = LD $@
24 cmd_image = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) -o $@ 26 cmd_image = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) -o $@
25quiet_cmd_strip = STRIP $@
26 cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start $(obj)/image -o $@
27
28 27
29define rule_image 28define rule_image
30 $(if $($(quiet)cmd_image), \ 29 $(if $($(quiet)cmd_image), \
@@ -57,10 +56,7 @@ $(obj)/image: $(obj)/btfix.o FORCE
57 56
58$(obj)/zImage: $(obj)/image 57$(obj)/zImage: $(obj)/image
59 $(call if_changed,strip) 58 $(call if_changed,strip)
60 59 @echo ' kernel: $@ is ready'
61$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_32 System.map $(ROOT_IMG) FORCE
62 $(call if_changed,elftoaout)
63 $(call if_changed,piggy)
64 60
65$(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE 61$(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE
66 $(call if_changed,btfix) 62 $(call if_changed,btfix)
@@ -68,11 +64,6 @@ $(obj)/btfix.S: $(obj)/btfixupprep vmlinux FORCE
68endif 64endif
69 65
70ifeq ($(CONFIG_SPARC64),y) 66ifeq ($(CONFIG_SPARC64),y)
71quiet_cmd_piggy = PIGGY $@
72 cmd_piggy = $(obj)/piggyback_64 $@ System.map $(ROOT_IMG)
73quiet_cmd_strip = STRIP $@
74 cmd_strip = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start vmlinux -o $@
75
76 67
77# Actual linking 68# Actual linking
78$(obj)/image: vmlinux FORCE 69$(obj)/image: vmlinux FORCE
@@ -81,10 +72,6 @@ $(obj)/image: vmlinux FORCE
81 72
82$(obj)/zImage: $(obj)/image 73$(obj)/zImage: $(obj)/image
83 $(call if_changed,gzip) 74 $(call if_changed,gzip)
84
85$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE
86 $(call if_changed,elftoaout)
87 $(call if_changed,piggy)
88 @echo ' kernel: $@ is ready' 75 @echo ' kernel: $@ is ready'
89 76
90$(obj)/vmlinux.aout: vmlinux FORCE 77$(obj)/vmlinux.aout: vmlinux FORCE
@@ -92,3 +79,6 @@ $(obj)/vmlinux.aout: vmlinux FORCE
92 @echo ' kernel: $@ is ready' 79 @echo ' kernel: $@ is ready'
93endif 80endif
94 81
82$(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE
83 $(call if_changed,elftoaout)
84 $(call if_changed,piggy)
diff --git a/arch/sparc/boot/piggyback.c b/arch/sparc/boot/piggyback.c
new file mode 100644
index 000000000000..c0a798fcf030
--- /dev/null
+++ b/arch/sparc/boot/piggyback.c
@@ -0,0 +1,272 @@
1/*
2 Simple utility to make a single-image install kernel with initial ramdisk
3 for Sparc tftpbooting without need to set up nfs.
4
5 Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 Pete Zaitcev <zaitcev@yahoo.com> endian fixes for cross-compiles, 2000.
7 Copyright (C) 2011 Sam Ravnborg <sam@ravnborg.org>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23#include <dirent.h>
24#include <stdlib.h>
25#include <string.h>
26#include <unistd.h>
27#include <ctype.h>
28#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31
32#include <sys/types.h>
33#include <sys/stat.h>
34
35/*
36 * Note: run this on an a.out kernel (use elftoaout for it),
37 * as PROM looks for a.out image only.
38 */
39
40#define AOUT_TEXT_OFFSET 32
41
42static int is64bit = 0;
43
44/* align to power-of-two size */
45static int align(int n)
46{
47 if (is64bit)
48 return (n + 0x1fff) & ~0x1fff;
49 else
50 return (n + 0xfff) & ~0xfff;
51}
52
53/* read two bytes as big endian */
54static unsigned short ld2(char *p)
55{
56 return (p[0] << 8) | p[1];
57}
58
59/* save 4 bytes as big endian */
60static void st4(char *p, unsigned int x)
61{
62 p[0] = x >> 24;
63 p[1] = x >> 16;
64 p[2] = x >> 8;
65 p[3] = x;
66}
67
68static void die(const char *str)
69{
70 perror(str);
71 exit(1);
72}
73
74static void usage(void)
75{
76 /* fs_img.gz is an image of initial ramdisk. */
77 fprintf(stderr, "Usage: piggyback bits vmlinux.aout System.map fs_img.gz\n");
78 fprintf(stderr, "\tKernel image will be modified in place.\n");
79 exit(1);
80}
81
82static int start_line(const char *line)
83{
84 if (strcmp(line + 8, " T _start\n") == 0)
85 return 1;
86 else if (strcmp(line + 16, " T _start\n") == 0)
87 return 1;
88 return 0;
89}
90
91static int end_line(const char *line)
92{
93 if (strcmp(line + 8, " A _end\n") == 0)
94 return 1;
95 else if (strcmp (line + 16, " A _end\n") == 0)
96 return 1;
97 return 0;
98}
99
100/*
101 * Find address for start and end in System.map.
102 * The file looks like this:
103 * f0004000 T _start
104 * f0379f79 A _end
105 * 1234567890123456
106 * ^coloumn 1
107 * There is support for 64 bit addresses too.
108 *
109 * Return 0 if either start or end is not found
110 */
111static int get_start_end(const char *filename, unsigned int *start,
112 unsigned int *end)
113{
114 FILE *map;
115 char buffer[1024];
116
117 *start = 0;
118 *end = 0;
119 map = fopen(filename, "r");
120 if (!map)
121 die(filename);
122 while (fgets(buffer, 1024, map)) {
123 if (start_line(buffer))
124 *start = strtoul(buffer, NULL, 16);
125 else if (end_line(buffer))
126 *end = strtoul(buffer, NULL, 16);
127 }
128 fclose (map);
129
130 if (*start == 0 || *end == 0)
131 return 0;
132
133 return 1;
134}
135
136#define LOOKBACK (128 * 4)
137#define BUFSIZE 1024
138/*
139 * Find the HdrS entry from head_32/head_64.
140 * We check if it is at the beginning of the file (sparc64 case)
141 * and if not we search for it.
142 * When we search do so in steps of 4 as HdrS is on a 4-byte aligned
143 * address (it is on same alignment as sparc instructions)
144 * Return the offset to the HdrS entry (as off_t)
145 */
146static off_t get_hdrs_offset(int kernelfd, const char *filename)
147{
148 char buffer[BUFSIZE];
149 off_t offset;
150 int i;
151
152 if (lseek(kernelfd, 0, SEEK_SET) < 0)
153 die("lseek");
154 if (read(kernelfd, buffer, BUFSIZE) != BUFSIZE)
155 die(filename);
156
157 if (buffer[40] == 'H' && buffer[41] == 'd' &&
158 buffer[42] == 'r' && buffer[43] == 'S') {
159 return 40;
160 } else {
161 /* Find the gokernel label */
162 /* Decode offset from branch instruction */
163 offset = ld2(buffer + AOUT_TEXT_OFFSET + 2) << 2;
164 /* Go back 512 bytes so we do not miss HdrS */
165 offset -= LOOKBACK;
166 /* skip a.out header */
167 offset += AOUT_TEXT_OFFSET;
168 if (lseek(kernelfd, offset, SEEK_SET) < 0)
169 die("lseek");
170 if (read(kernelfd, buffer, BUFSIZE) != BUFSIZE)
171 die(filename);
172
173 for (i = 0; i < LOOKBACK; i += 4) {
174 if (buffer[i + 0] == 'H' && buffer[i + 1] == 'd' &&
175 buffer[i + 2] == 'r' && buffer[i + 3] == 'S') {
176 return offset + i;
177 }
178 }
179 }
180 fprintf (stderr, "Couldn't find headers signature in %s\n", filename);
181 exit(1);
182}
183
184int main(int argc,char **argv)
185{
186 static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 };
187 char buffer[1024];
188 unsigned int i, start, end;
189 off_t offset;
190 struct stat s;
191 int image, tail;
192
193 if (argc != 5)
194 usage();
195 if (strcmp(argv[1], "64") == 0)
196 is64bit = 1;
197 if (stat (argv[4], &s) < 0)
198 die(argv[4]);
199
200 if (!get_start_end(argv[3], &start, &end)) {
201 fprintf(stderr, "Could not determine start and end from %s\n",
202 argv[3]);
203 exit(1);
204 }
205 if ((image = open(argv[2], O_RDWR)) < 0)
206 die(argv[2]);
207 if (read(image, buffer, 512) != 512)
208 die(argv[2]);
209 if (memcmp(buffer, aout_magic, 4) != 0) {
210 fprintf (stderr, "Not a.out. Don't blame me.\n");
211 exit(1);
212 }
213 /*
214 * We need to fill in values for
215 * sparc_ramdisk_image + sparc_ramdisk_size
216 * To locate these symbols search for the "HdrS" text which appear
217 * in the image a little before the gokernel symbol.
218 * See definition of these in init_32.S
219 */
220
221 offset = get_hdrs_offset(image, argv[2]);
222 /* skip HdrS + LINUX_VERSION_CODE + HdrS version */
223 offset += 10;
224
225 if (lseek(image, offset, 0) < 0)
226 die("lseek");
227
228 /*
229 * root_flags = 0
230 * root_dev = 1 (RAMDISK_MAJOR)
231 * ram_flags = 0
232 * sparc_ramdisk_image = "PAGE aligned address after _end")
233 * sparc_ramdisk_size = size of image
234 */
235 st4(buffer, 0);
236 st4(buffer + 4, 0x01000000);
237 st4(buffer + 8, align(end + 32));
238 st4(buffer + 12, s.st_size);
239
240 if (write(image, buffer + 2, 14) != 14)
241 die(argv[2]);
242
243 /* For sparc64 update a_text and clear a_data + a_bss */
244 if (is64bit)
245 {
246 if (lseek(image, 4, 0) < 0)
247 die("lseek");
248 /* a_text */
249 st4(buffer, align(end + 32 + 8191) - (start & ~0x3fffffUL) +
250 s.st_size);
251 /* a_data */
252 st4(buffer + 4, 0);
253 /* a_bss */
254 st4(buffer + 8, 0);
255 if (write(image, buffer, 12) != 12)
256 die(argv[2]);
257 }
258
259 /* seek page aligned boundary in the image file and add boot image */
260 if (lseek(image, AOUT_TEXT_OFFSET - start + align(end + 32), 0) < 0)
261 die("lseek");
262 if ((tail = open(argv[4], O_RDONLY)) < 0)
263 die(argv[4]);
264 while ((i = read(tail, buffer, 1024)) > 0)
265 if (write(image, buffer, i) != i)
266 die(argv[2]);
267 if (close(image) < 0)
268 die("close");
269 if (close(tail) < 0)
270 die("close");
271 return 0;
272}
diff --git a/arch/sparc/boot/piggyback_32.c b/arch/sparc/boot/piggyback_32.c
deleted file mode 100644
index ac944aec7301..000000000000
--- a/arch/sparc/boot/piggyback_32.c
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 Simple utility to make a single-image install kernel with initial ramdisk
3 for Sparc tftpbooting without need to set up nfs.
4
5 Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 Pete Zaitcev <zaitcev@yahoo.com> endian fixes for cross-compiles, 2000.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22#include <stdio.h>
23#include <string.h>
24#include <ctype.h>
25#include <errno.h>
26#include <fcntl.h>
27#include <dirent.h>
28#include <unistd.h>
29#include <stdlib.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32
33/*
34 * Note: run this on an a.out kernel (use elftoaout for it),
35 * as PROM looks for a.out image only.
36 */
37
38static unsigned short ld2(char *p)
39{
40 return (p[0] << 8) | p[1];
41}
42
43static unsigned int ld4(char *p)
44{
45 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
46}
47
48static void st4(char *p, unsigned int x)
49{
50 p[0] = x >> 24;
51 p[1] = x >> 16;
52 p[2] = x >> 8;
53 p[3] = x;
54}
55
56static void usage(void)
57{
58 /* fs_img.gz is an image of initial ramdisk. */
59 fprintf(stderr, "Usage: piggyback vmlinux.aout System.map fs_img.gz\n");
60 fprintf(stderr, "\tKernel image will be modified in place.\n");
61 exit(1);
62}
63
64static void die(char *str)
65{
66 perror (str);
67 exit(1);
68}
69
70int main(int argc,char **argv)
71{
72 static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 };
73 char buffer[1024], *q, *r;
74 unsigned int i, j, k, start, end, offset;
75 FILE *map;
76 struct stat s;
77 int image, tail;
78
79 if (argc != 4) usage();
80 start = end = 0;
81 if (stat (argv[3], &s) < 0) die (argv[3]);
82 map = fopen (argv[2], "r");
83 if (!map) die(argv[2]);
84 while (fgets (buffer, 1024, map)) {
85 if (!strcmp (buffer + 8, " T start\n") || !strcmp (buffer + 16, " T start\n"))
86 start = strtoul (buffer, NULL, 16);
87 else if (!strcmp (buffer + 8, " A _end\n") || !strcmp (buffer + 16, " A _end\n"))
88 end = strtoul (buffer, NULL, 16);
89 }
90 fclose (map);
91 if (!start || !end) {
92 fprintf (stderr, "Could not determine start and end from System.map\n");
93 exit(1);
94 }
95 if ((image = open(argv[1],O_RDWR)) < 0) die(argv[1]);
96 if (read(image,buffer,512) != 512) die(argv[1]);
97 if (memcmp (buffer, "\177ELF", 4) == 0) {
98 q = buffer + ld4(buffer + 28);
99 i = ld4(q + 4) + ld4(buffer + 24) - ld4(q + 8);
100 if (lseek(image,i,0) < 0) die("lseek");
101 if (read(image,buffer,512) != 512) die(argv[1]);
102 j = 0;
103 } else if (memcmp(buffer, aout_magic, 4) == 0) {
104 i = j = 32;
105 } else {
106 fprintf (stderr, "Not ELF nor a.out. Don't blame me.\n");
107 exit(1);
108 }
109 k = i;
110 i += (ld2(buffer + j + 2)<<2) - 512;
111 if (lseek(image,i,0) < 0) die("lseek");
112 if (read(image,buffer,1024) != 1024) die(argv[1]);
113 for (q = buffer, r = q + 512; q < r; q += 4) {
114 if (*q == 'H' && q[1] == 'd' && q[2] == 'r' && q[3] == 'S')
115 break;
116 }
117 if (q == r) {
118 fprintf (stderr, "Couldn't find headers signature in the kernel.\n");
119 exit(1);
120 }
121 offset = i + (q - buffer) + 10;
122 if (lseek(image, offset, 0) < 0) die ("lseek");
123
124 st4(buffer, 0);
125 st4(buffer + 4, 0x01000000);
126 st4(buffer + 8, (end + 32 + 4095) & ~4095);
127 st4(buffer + 12, s.st_size);
128
129 if (write(image,buffer+2,14) != 14) die (argv[1]);
130 if (lseek(image, k - start + ((end + 32 + 4095) & ~4095), 0) < 0) die ("lseek");
131 if ((tail = open(argv[3],O_RDONLY)) < 0) die(argv[3]);
132 while ((i = read (tail,buffer,1024)) > 0)
133 if (write(image,buffer,i) != i) die (argv[1]);
134 if (close(image) < 0) die("close");
135 if (close(tail) < 0) die("close");
136 return 0;
137}
diff --git a/arch/sparc/boot/piggyback_64.c b/arch/sparc/boot/piggyback_64.c
deleted file mode 100644
index a26a686cb5aa..000000000000
--- a/arch/sparc/boot/piggyback_64.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2 Simple utility to make a single-image install kernel with initial ramdisk
3 for Sparc64 tftpbooting without need to set up nfs.
4
5 Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include <stdio.h>
22#include <string.h>
23#include <ctype.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <dirent.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31
32/* Note: run this on an a.out kernel (use elftoaout for it), as PROM looks for a.out image onlly
33 usage: piggyback vmlinux System.map tail, where tail is gzipped fs of the initial ramdisk */
34
35static void die(char *str)
36{
37 perror (str);
38 exit(1);
39}
40
41int main(int argc,char **argv)
42{
43 char buffer [1024], *q, *r;
44 unsigned int i, j, k, start, end, offset;
45 FILE *map;
46 struct stat s;
47 int image, tail;
48
49 start = end = 0;
50 if (stat (argv[3], &s) < 0) die (argv[3]);
51 map = fopen (argv[2], "r");
52 if (!map) die(argv[2]);
53 while (fgets (buffer, 1024, map)) {
54 if (!strcmp (buffer + 19, "_start\n"))
55 start = strtoul (buffer + 8, NULL, 16);
56 else if (!strcmp (buffer + 19, "_end\n"))
57 end = strtoul (buffer + 8, NULL, 16);
58 }
59 fclose (map);
60 if ((image = open(argv[1],O_RDWR)) < 0) die(argv[1]);
61 if (read(image,buffer,512) != 512) die(argv[1]);
62 if (!memcmp (buffer, "\177ELF", 4)) {
63 unsigned int *p = (unsigned int *)(buffer + *(unsigned int *)(buffer + 28));
64
65 i = p[1] + *(unsigned int *)(buffer + 24) - p[2];
66 if (lseek(image,i,0) < 0) die("lseek");
67 if (read(image,buffer,512) != 512) die(argv[1]);
68 j = 0;
69 } else if (*(unsigned int *)buffer == 0x01030107) {
70 i = j = 32;
71 } else {
72 fprintf (stderr, "Not ELF nor a.out. Don't blame me.\n");
73 exit(1);
74 }
75 k = i;
76 if (j == 32 && buffer[40] == 'H' && buffer[41] == 'd' && buffer[42] == 'r' && buffer[43] == 'S') {
77 offset = 40 + 10;
78 } else {
79 i += ((*(unsigned short *)(buffer + j + 2))<<2) - 512;
80 if (lseek(image,i,0) < 0) die("lseek");
81 if (read(image,buffer,1024) != 1024) die(argv[1]);
82 for (q = buffer, r = q + 512; q < r; q += 4) {
83 if (*q == 'H' && q[1] == 'd' && q[2] == 'r' && q[3] == 'S')
84 break;
85 }
86 if (q == r) {
87 fprintf (stderr, "Couldn't find headers signature in the kernel.\n");
88 exit(1);
89 }
90 offset = i + (q - buffer) + 10;
91 }
92 if (lseek(image, offset, 0) < 0) die ("lseek");
93 *(unsigned *)buffer = 0;
94 *(unsigned *)(buffer + 4) = 0x01000000;
95 *(unsigned *)(buffer + 8) = ((end + 32 + 8191) & ~8191);
96 *(unsigned *)(buffer + 12) = s.st_size;
97 if (write(image,buffer+2,14) != 14) die (argv[1]);
98 if (lseek(image, 4, 0) < 0) die ("lseek");
99 *(unsigned *)buffer = ((end + 32 + 8191) & ~8191) - (start & ~0x3fffffUL) + s.st_size;
100 *(unsigned *)(buffer + 4) = 0;
101 *(unsigned *)(buffer + 8) = 0;
102 if (write(image,buffer,12) != 12) die (argv[1]);
103 if (lseek(image, k - start + ((end + 32 + 8191) & ~8191), 0) < 0) die ("lseek");
104 if ((tail = open(argv[3],O_RDONLY)) < 0) die(argv[3]);
105 while ((i = read (tail,buffer,1024)) > 0)
106 if (write(image,buffer,i) != i) die (argv[1]);
107 if (close(image) < 0) die("close");
108 if (close(tail) < 0) die("close");
109 return 0;
110}
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
index 3ea5964c43b4..8580d1764f90 100644
--- a/arch/sparc/include/asm/leon.h
+++ b/arch/sparc/include/asm/leon.h
@@ -224,6 +224,18 @@ static inline void sparc_leon3_disable_cache(void)
224 "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2"); 224 "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
225}; 225};
226 226
227static inline unsigned long sparc_leon3_asr17(void)
228{
229 u32 asr17;
230 __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17));
231 return asr17;
232};
233
234static inline int sparc_leon3_cpuid(void)
235{
236 return sparc_leon3_asr17() >> 28;
237}
238
227#endif /*!__ASSEMBLY__*/ 239#endif /*!__ASSEMBLY__*/
228 240
229#ifdef CONFIG_SMP 241#ifdef CONFIG_SMP
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h
index 618e88821795..263c719e96f5 100644
--- a/arch/sparc/include/asm/leon_amba.h
+++ b/arch/sparc/include/asm/leon_amba.h
@@ -100,9 +100,8 @@ struct leon3_irqctrl_regs_map {
100 u32 mpbroadcast; 100 u32 mpbroadcast;
101 u32 notused02; 101 u32 notused02;
102 u32 notused03; 102 u32 notused03;
103 u32 notused10; 103 u32 ampctrl;
104 u32 notused11; 104 u32 icsel[2];
105 u32 notused12;
106 u32 notused13; 105 u32 notused13;
107 u32 notused20; 106 u32 notused20;
108 u32 notused21; 107 u32 notused21;
@@ -112,6 +111,7 @@ struct leon3_irqctrl_regs_map {
112 u32 force[16]; 111 u32 force[16];
113 /* Extended IRQ registers */ 112 /* Extended IRQ registers */
114 u32 intid[16]; /* 0xc0 */ 113 u32 intid[16]; /* 0xc0 */
114 u32 unused[(0x1000-0x100)/4];
115}; 115};
116 116
117struct leon3_apbuart_regs_map { 117struct leon3_apbuart_regs_map {
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 9e5c64084b86..71e5e9aeb67e 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -48,18 +48,6 @@ extern void prom_init(struct linux_romvec *rom_ptr);
48/* Boot argument acquisition, returns the boot command line string. */ 48/* Boot argument acquisition, returns the boot command line string. */
49extern char *prom_getbootargs(void); 49extern char *prom_getbootargs(void);
50 50
51/* Device utilities. */
52
53/* Map and unmap devices in IO space at virtual addresses. Note that the
54 * virtual address you pass is a request and the prom may put your mappings
55 * somewhere else, so check your return value as that is where your new
56 * mappings really are!
57 *
58 * Another note, these are only available on V2 or higher proms!
59 */
60extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
61extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
62
63/* Miscellaneous routines, don't really fit in any category per se. */ 51/* Miscellaneous routines, don't really fit in any category per se. */
64 52
65/* Reboot the machine with the command line passed. */ 53/* Reboot the machine with the command line passed. */
@@ -76,7 +64,7 @@ extern void prom_cmdline(void);
76/* Enter the prom, with no chance of continuation for the stand-alone 64/* Enter the prom, with no chance of continuation for the stand-alone
77 * which calls this. 65 * which calls this.
78 */ 66 */
79extern void prom_halt(void) __attribute__ ((noreturn)); 67extern void __noreturn prom_halt(void);
80 68
81/* Set the PROM 'sync' callback function to the passed function pointer. 69/* Set the PROM 'sync' callback function to the passed function pointer.
82 * When the user gives the 'sync' command at the prom prompt while the 70 * When the user gives the 'sync' command at the prom prompt while the
@@ -117,25 +105,6 @@ extern void prom_write(const char *buf, unsigned int len);
117extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table, 105extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
118 int context, char *program_counter); 106 int context, char *program_counter);
119 107
120/* Stop the CPU with the passed device tree node. */
121extern int prom_stopcpu(int cpunode);
122
123/* Idle the CPU with the passed device tree node. */
124extern int prom_idlecpu(int cpunode);
125
126/* Re-Start the CPU with the passed device tree node. */
127extern int prom_restartcpu(int cpunode);
128
129/* PROM memory allocation facilities... */
130
131/* Allocated at possibly the given virtual address a chunk of the
132 * indicated size.
133 */
134extern char *prom_alloc(char *virt_hint, unsigned int size);
135
136/* Free a previously allocated chunk. */
137extern void prom_free(char *virt_addr, unsigned int size);
138
139/* Sun4/sun4c specific memory-management startup hook. */ 108/* Sun4/sun4c specific memory-management startup hook. */
140 109
141/* Map the passed segment in the given context at the passed 110/* Map the passed segment in the given context at the passed
@@ -144,6 +113,8 @@ extern void prom_free(char *virt_addr, unsigned int size);
144extern void prom_putsegment(int context, unsigned long virt_addr, 113extern void prom_putsegment(int context, unsigned long virt_addr,
145 int physical_segment); 114 int physical_segment);
146 115
116/* Initialize the memory lists based upon the prom version. */
117void prom_meminit(void);
147 118
148/* PROM device tree traversal functions... */ 119/* PROM device tree traversal functions... */
149 120
@@ -178,19 +149,11 @@ extern int prom_getbool(phandle node, char *prop);
178/* Acquire a string property, null string on error. */ 149/* Acquire a string property, null string on error. */
179extern void prom_getstring(phandle node, char *prop, char *buf, int bufsize); 150extern void prom_getstring(phandle node, char *prop, char *buf, int bufsize);
180 151
181/* Does the passed node have the given "name"? YES=1 NO=0 */
182extern int prom_nodematch(phandle thisnode, char *name);
183
184/* Search all siblings starting at the passed node for "name" matching 152/* Search all siblings starting at the passed node for "name" matching
185 * the given string. Returns the node on success, zero on failure. 153 * the given string. Returns the node on success, zero on failure.
186 */ 154 */
187extern phandle prom_searchsiblings(phandle node_start, char *name); 155extern phandle prom_searchsiblings(phandle node_start, char *name);
188 156
189/* Return the first property type, as a string, for the given node.
190 * Returns a null string on error.
191 */
192extern char *prom_firstprop(phandle node, char *buffer);
193
194/* Returns the next property after the passed property for the given 157/* Returns the next property after the passed property for the given
195 * node. Returns null string on failure. 158 * node. Returns null string on failure.
196 */ 159 */
@@ -199,9 +162,6 @@ extern char *prom_nextprop(phandle node, char *prev_property, char *buffer);
199/* Returns phandle of the path specified */ 162/* Returns phandle of the path specified */
200extern phandle prom_finddevice(char *name); 163extern phandle prom_finddevice(char *name);
201 164
202/* Returns 1 if the specified node has given property. */
203extern int prom_node_has_property(phandle node, char *property);
204
205/* Set the indicated property at the given node with the passed value. 165/* Set the indicated property at the given node with the passed value.
206 * Returns the number of bytes of your value that the prom took. 166 * Returns the number of bytes of your value that the prom took.
207 */ 167 */
@@ -219,6 +179,8 @@ extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nr
219extern void prom_apply_generic_ranges(phandle node, phandle parent, 179extern void prom_apply_generic_ranges(phandle node, phandle parent,
220 struct linux_prom_registers *sbusregs, int nregs); 180 struct linux_prom_registers *sbusregs, int nregs);
221 181
182void prom_ranges_init(void);
183
222/* CPU probing helpers. */ 184/* CPU probing helpers. */
223int cpu_find_by_instance(int instance, phandle *prom_node, int *mid); 185int cpu_find_by_instance(int instance, phandle *prom_node, int *mid);
224int cpu_find_by_mid(int mid, phandle *prom_node); 186int cpu_find_by_mid(int mid, phandle *prom_node);
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index 8cd0df34e82b..97a90475c314 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -18,8 +18,8 @@ extern char prom_version[];
18 */ 18 */
19extern phandle prom_root_node; 19extern phandle prom_root_node;
20 20
21/* PROM stdin and stdout */ 21/* PROM stdout */
22extern int prom_stdin, prom_stdout; 22extern int prom_stdout;
23 23
24/* /chosen node of the prom device tree, this stays constant after 24/* /chosen node of the prom device tree, this stays constant after
25 * initialization is complete. 25 * initialization is complete.
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 21bb2590d4ae..59423491cef8 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -73,12 +73,11 @@ sun4e_notsup:
73 73
74 /* The Sparc trap table, bootloader gives us control at _start. */ 74 /* The Sparc trap table, bootloader gives us control at _start. */
75 __HEAD 75 __HEAD
76 .globl start, _stext, _start, __stext 76 .globl _stext, _start, __stext
77 .globl trapbase 77 .globl trapbase
78_start: /* danger danger */ 78_start: /* danger danger */
79__stext: 79__stext:
80_stext: 80_stext:
81start:
82trapbase: 81trapbase:
83#ifdef CONFIG_SMP 82#ifdef CONFIG_SMP
84trapbase_cpu0: 83trapbase_cpu0:
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index f01c42661ee5..fdab7f854f80 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -23,15 +23,16 @@
23#include "prom.h" 23#include "prom.h"
24#include "irq.h" 24#include "irq.h"
25 25
26struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */ 26struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address */
27struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */ 27struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address */
28struct amba_apb_device leon_percpu_timer_dev[16]; 28struct amba_apb_device leon_percpu_timer_dev[16];
29 29
30int leondebug_irq_disable; 30int leondebug_irq_disable;
31int leon_debug_irqout; 31int leon_debug_irqout;
32static int dummy_master_l10_counter; 32static int dummy_master_l10_counter;
33 33
34unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */ 34unsigned long leon3_gptimer_irq; /* interrupt controller irq number */
35unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */
35unsigned int sparc_leon_eirq; 36unsigned int sparc_leon_eirq;
36#define LEON_IMASK ((&leon3_irqctrl_regs->mask[0])) 37#define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
37 38
@@ -105,21 +106,79 @@ static void leon_disable_irq(unsigned int irq_nr)
105void __init leon_init_timers(irq_handler_t counter_fn) 106void __init leon_init_timers(irq_handler_t counter_fn)
106{ 107{
107 int irq; 108 int irq;
109 struct device_node *rootnp, *np, *nnp;
110 struct property *pp;
111 int len;
112 int cpu, icsel;
113 int ampopts;
108 114
109 leondebug_irq_disable = 0; 115 leondebug_irq_disable = 0;
110 leon_debug_irqout = 0; 116 leon_debug_irqout = 0;
111 master_l10_counter = (unsigned int *)&dummy_master_l10_counter; 117 master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
112 dummy_master_l10_counter = 0; 118 dummy_master_l10_counter = 0;
113 119
114 if (leon3_gptimer_regs && leon3_irqctrl_regs) { 120 /*Find IRQMP IRQ Controller Registers base address otherwise bail out.*/
115 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); 121 rootnp = of_find_node_by_path("/ambapp0");
116 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, 122 if (!rootnp)
117 (((1000000 / HZ) - 1))); 123 goto bad;
118 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); 124 np = of_find_node_by_name(rootnp, "GAISLER_IRQMP");
125 if (!np) {
126 np = of_find_node_by_name(rootnp, "01_00d");
127 if (!np)
128 goto bad;
129 }
130 pp = of_find_property(np, "reg", &len);
131 if (!pp)
132 goto bad;
133 leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value;
134
135 /* Find GPTIMER Timer Registers base address otherwise bail out. */
136 nnp = rootnp;
137 do {
138 np = of_find_node_by_name(nnp, "GAISLER_GPTIMER");
139 if (!np) {
140 np = of_find_node_by_name(nnp, "01_011");
141 if (!np)
142 goto bad;
143 }
144
145 ampopts = 0;
146 pp = of_find_property(np, "ampopts", &len);
147 if (pp) {
148 ampopts = *(int *)pp->value;
149 if (ampopts == 0) {
150 /* Skip this instance, resource already
151 * allocated by other OS */
152 nnp = np;
153 continue;
154 }
155 }
156
157 /* Select Timer-Instance on Timer Core. Default is zero */
158 leon3_gptimer_idx = ampopts & 0x7;
159
160 pp = of_find_property(np, "reg", &len);
161 if (pp)
162 leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)
163 pp->value;
164 pp = of_find_property(np, "interrupts", &len);
165 if (pp)
166 leon3_gptimer_irq = *(unsigned int *)pp->value;
167 } while (0);
168
169 if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
170 LEON3_BYPASS_STORE_PA(
171 &leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
172 LEON3_BYPASS_STORE_PA(
173 &leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
174 (((1000000 / HZ) - 1)));
175 LEON3_BYPASS_STORE_PA(
176 &leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
119 177
120#ifdef CONFIG_SMP 178#ifdef CONFIG_SMP
121 leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs; 179 leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
122 leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1; 180 leon_percpu_timer_dev[0].irq = leon3_gptimer_irq + 1 +
181 leon3_gptimer_idx;
123 182
124 if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) & 183 if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
125 (1<<LEON3_GPTIMER_SEPIRQ))) { 184 (1<<LEON3_GPTIMER_SEPIRQ))) {
@@ -127,17 +186,33 @@ void __init leon_init_timers(irq_handler_t counter_fn)
127 BUG(); 186 BUG();
128 } 187 }
129 188
130 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); 189 LEON3_BYPASS_STORE_PA(
131 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1))); 190 &leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
132 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); 191 LEON3_BYPASS_STORE_PA(
192 &leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld,
193 (((1000000/HZ) - 1)));
194 LEON3_BYPASS_STORE_PA(
195 &leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
133# endif 196# endif
134 197
198 /*
199 * The IRQ controller may (if implemented) consist of multiple
200 * IRQ controllers, each mapped on a 4Kb boundary.
201 * Each CPU may be routed to different IRQCTRLs, however
202 * we assume that all CPUs (in SMP system) is routed to the
203 * same IRQ Controller, and for non-SMP only one IRQCTRL is
204 * accessed anyway.
205 * In AMP systems, Linux must run on CPU0 for the time being.
206 */
207 cpu = sparc_leon3_cpuid();
208 icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]);
209 icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
210 leon3_irqctrl_regs += icsel;
135 } else { 211 } else {
136 printk(KERN_ERR "No Timer/irqctrl found\n"); 212 goto bad;
137 BUG();
138 } 213 }
139 214
140 irq = request_irq(leon3_gptimer_irq, 215 irq = request_irq(leon3_gptimer_irq+leon3_gptimer_idx,
141 counter_fn, 216 counter_fn,
142 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); 217 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
143 218
@@ -169,13 +244,13 @@ void __init leon_init_timers(irq_handler_t counter_fn)
169# endif 244# endif
170 245
171 if (leon3_gptimer_regs) { 246 if (leon3_gptimer_regs) {
172 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 247 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
173 LEON3_GPTIMER_EN | 248 LEON3_GPTIMER_EN |
174 LEON3_GPTIMER_RL | 249 LEON3_GPTIMER_RL |
175 LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); 250 LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
176 251
177#ifdef CONFIG_SMP 252#ifdef CONFIG_SMP
178 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 253 LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
179 LEON3_GPTIMER_EN | 254 LEON3_GPTIMER_EN |
180 LEON3_GPTIMER_RL | 255 LEON3_GPTIMER_RL |
181 LEON3_GPTIMER_LD | 256 LEON3_GPTIMER_LD |
@@ -183,6 +258,11 @@ void __init leon_init_timers(irq_handler_t counter_fn)
183#endif 258#endif
184 259
185 } 260 }
261 return;
262bad:
263 printk(KERN_ERR "No Timer/irqctrl found\n");
264 BUG();
265 return;
186} 266}
187 267
188void leon_clear_clock_irq(void) 268void leon_clear_clock_irq(void)
diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c
index 0a37e8cfd160..05fb25330583 100644
--- a/arch/sparc/kernel/prom_32.c
+++ b/arch/sparc/kernel/prom_32.c
@@ -136,18 +136,29 @@ static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
136/* "name:vendor:device@irq,addrlo" */ 136/* "name:vendor:device@irq,addrlo" */
137static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf) 137static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
138{ 138{
139 struct amba_prom_registers *regs; unsigned int *intr; 139 struct amba_prom_registers *regs;
140 unsigned int *device, *vendor; 140 unsigned int *intr, *device, *vendor, reg0;
141 struct property *prop; 141 struct property *prop;
142 int interrupt = 0;
142 143
144 /* In order to get a unique ID in the device tree (multiple AMBA devices
145 * may have the same name) the node number is printed
146 */
143 prop = of_find_property(dp, "reg", NULL); 147 prop = of_find_property(dp, "reg", NULL);
144 if (!prop) 148 if (!prop) {
145 return; 149 reg0 = (unsigned int)dp->phandle;
146 regs = prop->value; 150 } else {
151 regs = prop->value;
152 reg0 = regs->phys_addr;
153 }
154
155 /* Not all cores have Interrupt */
147 prop = of_find_property(dp, "interrupts", NULL); 156 prop = of_find_property(dp, "interrupts", NULL);
148 if (!prop) 157 if (!prop)
149 return; 158 intr = &interrupt; /* IRQ0 does not exist */
150 intr = prop->value; 159 else
160 intr = prop->value;
161
151 prop = of_find_property(dp, "vendor", NULL); 162 prop = of_find_property(dp, "vendor", NULL);
152 if (!prop) 163 if (!prop)
153 return; 164 return;
@@ -159,7 +170,7 @@ static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
159 170
160 sprintf(tmp_buf, "%s:%d:%d@%x,%x", 171 sprintf(tmp_buf, "%s:%d:%d@%x,%x",
161 dp->name, *vendor, *device, 172 dp->name, *vendor, *device,
162 *intr, regs->phys_addr); 173 *intr, reg0);
163} 174}
164 175
165static void __init __build_path_component(struct device_node *dp, char *tmp_buf) 176static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index b22ce6100403..648f2161b851 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -185,7 +185,6 @@ static void __init boot_flags_init(char *commands)
185 185
186extern void sun4c_probe_vac(void); 186extern void sun4c_probe_vac(void);
187extern char cputypval; 187extern char cputypval;
188extern unsigned long start, end;
189 188
190extern unsigned short root_flags; 189extern unsigned short root_flags;
191extern unsigned short root_dev; 190extern unsigned short root_dev;
@@ -210,7 +209,7 @@ void __init setup_arch(char **cmdline_p)
210 int i; 209 int i;
211 unsigned long highest_paddr; 210 unsigned long highest_paddr;
212 211
213 sparc_ttable = (struct tt_entry *) &start; 212 sparc_ttable = (struct tt_entry *) &trapbase;
214 213
215 /* Initialize PROM console and command line. */ 214 /* Initialize PROM console and command line. */
216 *cmdline_p = prom_getbootargs(); 215 *cmdline_p = prom_getbootargs();
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ddd0d86e508e..b5137cc2aba3 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -435,16 +435,14 @@ void __init sun4c_probe_memerr_reg(void)
435 435
436static inline void sun4c_init_ss2_cache_bug(void) 436static inline void sun4c_init_ss2_cache_bug(void)
437{ 437{
438 extern unsigned long start;
439
440 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) || 438 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) ||
441 (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || 439 (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) ||
442 (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) { 440 (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) {
443 /* Whee.. */ 441 /* Whee.. */
444 printk("SS2 cache bug detected, uncaching trap table page\n"); 442 printk("SS2 cache bug detected, uncaching trap table page\n");
445 sun4c_flush_page((unsigned int) &start); 443 sun4c_flush_page((unsigned int) &_start);
446 sun4c_put_pte(((unsigned long) &start), 444 sun4c_put_pte(((unsigned long) &_start),
447 (sun4c_get_pte((unsigned long) &start) | _SUN4C_PAGE_NOCACHE)); 445 (sun4c_get_pte((unsigned long) &_start) | _SUN4C_PAGE_NOCACHE));
448 } 446 }
449} 447}
450 448
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile
index 816c0fa12dc0..8287bbe88768 100644
--- a/arch/sparc/prom/Makefile
+++ b/arch/sparc/prom/Makefile
@@ -5,12 +5,10 @@ asflags := -ansi
5ccflags := -Werror 5ccflags := -Werror
6 6
7lib-y := bootstr_$(BITS).o 7lib-y := bootstr_$(BITS).o
8lib-$(CONFIG_SPARC32) += devmap.o
9lib-y += init_$(BITS).o 8lib-y += init_$(BITS).o
10lib-$(CONFIG_SPARC32) += memory.o 9lib-$(CONFIG_SPARC32) += memory.o
11lib-y += misc_$(BITS).o 10lib-y += misc_$(BITS).o
12lib-$(CONFIG_SPARC32) += mp.o 11lib-$(CONFIG_SPARC32) += mp.o
13lib-$(CONFIG_SPARC32) += palloc.o
14lib-$(CONFIG_SPARC32) += ranges.o 12lib-$(CONFIG_SPARC32) += ranges.o
15lib-$(CONFIG_SPARC32) += segment.o 13lib-$(CONFIG_SPARC32) += segment.o
16lib-y += console_$(BITS).o 14lib-y += console_$(BITS).o
diff --git a/arch/sparc/prom/bootstr_32.c b/arch/sparc/prom/bootstr_32.c
index 916831da7e67..f5ec32e0d419 100644
--- a/arch/sparc/prom/bootstr_32.c
+++ b/arch/sparc/prom/bootstr_32.c
@@ -29,7 +29,8 @@ prom_getbootargs(void)
29 /* Start from 1 and go over fd(0,0,0)kernel */ 29 /* Start from 1 and go over fd(0,0,0)kernel */
30 for(iter = 1; iter < 8; iter++) { 30 for(iter = 1; iter < 8; iter++) {
31 arg = (*(romvec->pv_v0bootargs))->argv[iter]; 31 arg = (*(romvec->pv_v0bootargs))->argv[iter];
32 if(arg == 0) break; 32 if (arg == NULL)
33 break;
33 while(*arg != 0) { 34 while(*arg != 0) {
34 /* Leave place for space and null. */ 35 /* Leave place for space and null. */
35 if(cp >= barg_buf + BARG_LEN-2){ 36 if(cp >= barg_buf + BARG_LEN-2){
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c
index 48863108a44c..b05e3db5fa63 100644
--- a/arch/sparc/prom/console_32.c
+++ b/arch/sparc/prom/console_32.c
@@ -27,13 +27,14 @@ static int prom_nbputchar(const char *buf)
27 spin_lock_irqsave(&prom_lock, flags); 27 spin_lock_irqsave(&prom_lock, flags);
28 switch(prom_vers) { 28 switch(prom_vers) {
29 case PROM_V0: 29 case PROM_V0:
30 i = (*(romvec->pv_nbputchar))(*buf); 30 if ((*(romvec->pv_nbputchar))(*buf))
31 i = 1;
31 break; 32 break;
32 case PROM_V2: 33 case PROM_V2:
33 case PROM_V3: 34 case PROM_V3:
34 if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, 35 if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
35 buf, 0x1) == 1) 36 buf, 0x1) == 1)
36 i = 0; 37 i = 1;
37 break; 38 break;
38 default: 39 default:
39 break; 40 break;
@@ -47,7 +48,7 @@ void prom_console_write_buf(const char *buf, int len)
47{ 48{
48 while (len) { 49 while (len) {
49 int n = prom_nbputchar(buf); 50 int n = prom_nbputchar(buf);
50 if (n) 51 if (n < 0)
51 continue; 52 continue;
52 len--; 53 len--;
53 buf++; 54 buf++;
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c
index ed39e75828bd..9de6c8cfe04a 100644
--- a/arch/sparc/prom/console_64.c
+++ b/arch/sparc/prom/console_64.c
@@ -13,8 +13,6 @@
13#include <asm/system.h> 13#include <asm/system.h>
14#include <linux/string.h> 14#include <linux/string.h>
15 15
16extern int prom_stdin, prom_stdout;
17
18static int __prom_console_write_buf(const char *buf, int len) 16static int __prom_console_write_buf(const char *buf, int len)
19{ 17{
20 unsigned long args[7]; 18 unsigned long args[7];
diff --git a/arch/sparc/prom/devmap.c b/arch/sparc/prom/devmap.c
deleted file mode 100644
index 46157d2aba0d..000000000000
--- a/arch/sparc/prom/devmap.c
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * promdevmap.c: Map device/IO areas to virtual addresses.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#include <linux/types.h>
8#include <linux/kernel.h>
9#include <linux/sched.h>
10
11#include <asm/openprom.h>
12#include <asm/oplib.h>
13
14extern void restore_current(void);
15
16/* Just like the routines in palloc.c, these should not be used
17 * by the kernel at all. Bootloader facility mainly. And again,
18 * this is only available on V2 proms and above.
19 */
20
21/* Map physical device address 'paddr' in IO space 'ios' of size
22 * 'num_bytes' to a virtual address, with 'vhint' being a hint to
23 * the prom as to where you would prefer the mapping. We return
24 * where the prom actually mapped it.
25 */
26char *
27prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes)
28{
29 unsigned long flags;
30 char *ret;
31
32 spin_lock_irqsave(&prom_lock, flags);
33 if((num_bytes == 0) || (paddr == 0)) ret = (char *) 0x0;
34 else
35 ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr,
36 num_bytes);
37 restore_current();
38 spin_unlock_irqrestore(&prom_lock, flags);
39 return ret;
40}
41
42/* Unmap an IO/device area that was mapped using the above routine. */
43void
44prom_unmapio(char *vaddr, unsigned int num_bytes)
45{
46 unsigned long flags;
47
48 if(num_bytes == 0x0) return;
49 spin_lock_irqsave(&prom_lock, flags);
50 (*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes);
51 restore_current();
52 spin_unlock_irqrestore(&prom_lock, flags);
53}
diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c
index 3ff911e7d25b..9c6ac4b81ded 100644
--- a/arch/sparc/prom/init_64.c
+++ b/arch/sparc/prom/init_64.c
@@ -18,7 +18,7 @@
18char prom_version[80]; 18char prom_version[80];
19 19
20/* The root node of the prom device tree. */ 20/* The root node of the prom device tree. */
21int prom_stdin, prom_stdout; 21int prom_stdout;
22phandle prom_chosen_node; 22phandle prom_chosen_node;
23 23
24/* You must call prom_init() before you attempt to use any of the 24/* You must call prom_init() before you attempt to use any of the
@@ -38,7 +38,6 @@ void __init prom_init(void *cif_handler, void *cif_stack)
38 if (!prom_chosen_node || prom_chosen_node == -1) 38 if (!prom_chosen_node || prom_chosen_node == -1)
39 prom_halt(); 39 prom_halt();
40 40
41 prom_stdin = prom_getint(prom_chosen_node, "stdin");
42 prom_stdout = prom_getint(prom_chosen_node, "stdout"); 41 prom_stdout = prom_getint(prom_chosen_node, "stdout");
43 42
44 node = prom_finddevice("/openprom"); 43 node = prom_finddevice("/openprom");
diff --git a/arch/sparc/prom/misc_32.c b/arch/sparc/prom/misc_32.c
index 4d61c540bb3d..8c278c311ba4 100644
--- a/arch/sparc/prom/misc_32.c
+++ b/arch/sparc/prom/misc_32.c
@@ -70,7 +70,7 @@ prom_cmdline(void)
70/* Drop into the prom, but completely terminate the program. 70/* Drop into the prom, but completely terminate the program.
71 * No chance of continuing. 71 * No chance of continuing.
72 */ 72 */
73void 73void __noreturn
74prom_halt(void) 74prom_halt(void)
75{ 75{
76 unsigned long flags; 76 unsigned long flags;
diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c
index 4c4dc79f65af..97c44c9ddbc8 100644
--- a/arch/sparc/prom/mp.c
+++ b/arch/sparc/prom/mp.c
@@ -41,81 +41,3 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha
41 41
42 return ret; 42 return ret;
43} 43}
44
45/* Stop CPU with device prom-tree node 'cpunode'.
46 * XXX Again, what does the return value really mean? XXX
47 */
48int
49prom_stopcpu(int cpunode)
50{
51 int ret;
52 unsigned long flags;
53
54 spin_lock_irqsave(&prom_lock, flags);
55 switch(prom_vers) {
56 case PROM_V0:
57 case PROM_V2:
58 default:
59 ret = -1;
60 break;
61 case PROM_V3:
62 ret = (*(romvec->v3_cpustop))(cpunode);
63 break;
64 };
65 restore_current();
66 spin_unlock_irqrestore(&prom_lock, flags);
67
68 return ret;
69}
70
71/* Make CPU with device prom-tree node 'cpunode' idle.
72 * XXX Return value, anyone? XXX
73 */
74int
75prom_idlecpu(int cpunode)
76{
77 int ret;
78 unsigned long flags;
79
80 spin_lock_irqsave(&prom_lock, flags);
81 switch(prom_vers) {
82 case PROM_V0:
83 case PROM_V2:
84 default:
85 ret = -1;
86 break;
87 case PROM_V3:
88 ret = (*(romvec->v3_cpuidle))(cpunode);
89 break;
90 };
91 restore_current();
92 spin_unlock_irqrestore(&prom_lock, flags);
93
94 return ret;
95}
96
97/* Resume the execution of CPU with nodeid 'cpunode'.
98 * XXX Come on, somebody has to know... XXX
99 */
100int
101prom_restartcpu(int cpunode)
102{
103 int ret;
104 unsigned long flags;
105
106 spin_lock_irqsave(&prom_lock, flags);
107 switch(prom_vers) {
108 case PROM_V0:
109 case PROM_V2:
110 default:
111 ret = -1;
112 break;
113 case PROM_V3:
114 ret = (*(romvec->v3_cpuresume))(cpunode);
115 break;
116 };
117 restore_current();
118 spin_unlock_irqrestore(&prom_lock, flags);
119
120 return ret;
121}
diff --git a/arch/sparc/prom/palloc.c b/arch/sparc/prom/palloc.c
deleted file mode 100644
index 2e2a88b211fb..000000000000
--- a/arch/sparc/prom/palloc.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * palloc.c: Memory allocation from the Sun PROM.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#include <asm/openprom.h>
8#include <asm/oplib.h>
9
10/* You should not call these routines after memory management
11 * has been initialized in the kernel, if fact you should not
12 * use these if at all possible in the kernel. They are mainly
13 * to be used for a bootloader for temporary allocations which
14 * it will free before jumping into the kernel it has loaded.
15 *
16 * Also, these routines don't work on V0 proms, only V2 and later.
17 */
18
19/* Allocate a chunk of memory of size 'num_bytes' giving a suggestion
20 * of virtual_hint as the preferred virtual base address of this chunk.
21 * There are no guarantees that you will get the allocation, or that
22 * the prom will abide by your "hint". So check your return value.
23 */
24char *
25prom_alloc(char *virtual_hint, unsigned int num_bytes)
26{
27 if(prom_vers == PROM_V0) return (char *) 0x0;
28 if(num_bytes == 0x0) return (char *) 0x0;
29 return (*(romvec->pv_v2devops.v2_dumb_mem_alloc))(virtual_hint, num_bytes);
30}
31
32/* Free a previously allocated chunk back to the prom at virtual address
33 * 'vaddr' of size 'num_bytes'. NOTE: This vaddr is not the hint you
34 * used for the allocation, but the virtual address the prom actually
35 * returned to you. They may be have been the same, they may have not,
36 * doesn't matter.
37 */
38void
39prom_free(char *vaddr, unsigned int num_bytes)
40{
41 if((prom_vers == PROM_V0) || (num_bytes == 0x0)) return;
42 (*(romvec->pv_v2devops.v2_dumb_mem_free))(vaddr, num_bytes);
43}
diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c
index 541fc829c207..0857aa9e839d 100644
--- a/arch/sparc/prom/ranges.c
+++ b/arch/sparc/prom/ranges.c
@@ -13,8 +13,8 @@
13#include <asm/types.h> 13#include <asm/types.h>
14#include <asm/system.h> 14#include <asm/system.h>
15 15
16struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX]; 16static struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX];
17int num_obio_ranges; 17static int num_obio_ranges;
18 18
19/* Adjust register values based upon the ranges parameters. */ 19/* Adjust register values based upon the ranges parameters. */
20static void 20static void
@@ -35,7 +35,7 @@ prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
35 } 35 }
36} 36}
37 37
38void 38static void
39prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1, 39prom_adjust_ranges(struct linux_prom_ranges *ranges1, int nranges1,
40 struct linux_prom_ranges *ranges2, int nranges2) 40 struct linux_prom_ranges *ranges2, int nranges2)
41{ 41{
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index 535e2e69ac1d..bc8e4cb87a68 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -20,7 +20,7 @@ extern void restore_current(void);
20static char promlib_buf[128]; 20static char promlib_buf[128];
21 21
22/* Internal version of prom_getchild that does not alter return values. */ 22/* Internal version of prom_getchild that does not alter return values. */
23phandle __prom_getchild(phandle node) 23static phandle __prom_getchild(phandle node)
24{ 24{
25 unsigned long flags; 25 unsigned long flags;
26 phandle cnode; 26 phandle cnode;
@@ -52,7 +52,7 @@ phandle prom_getchild(phandle node)
52EXPORT_SYMBOL(prom_getchild); 52EXPORT_SYMBOL(prom_getchild);
53 53
54/* Internal version of prom_getsibling that does not alter return values. */ 54/* Internal version of prom_getsibling that does not alter return values. */
55phandle __prom_getsibling(phandle node) 55static phandle __prom_getsibling(phandle node)
56{ 56{
57 unsigned long flags; 57 unsigned long flags;
58 phandle cnode; 58 phandle cnode;
@@ -177,20 +177,6 @@ void prom_getstring(phandle node, char *prop, char *user_buf, int ubuf_size)
177EXPORT_SYMBOL(prom_getstring); 177EXPORT_SYMBOL(prom_getstring);
178 178
179 179
180/* Does the device at node 'node' have name 'name'?
181 * YES = 1 NO = 0
182 */
183int prom_nodematch(phandle node, char *name)
184{
185 int error;
186
187 static char namebuf[128];
188 error = prom_getproperty(node, "name", namebuf, sizeof(namebuf));
189 if (error == -1) return 0;
190 if(strcmp(namebuf, name) == 0) return 1;
191 return 0;
192}
193
194/* Search siblings at 'node_start' for a node with name 180/* Search siblings at 'node_start' for a node with name
195 * 'nodename'. Return node if successful, zero if not. 181 * 'nodename'. Return node if successful, zero if not.
196 */ 182 */
@@ -214,7 +200,7 @@ phandle prom_searchsiblings(phandle node_start, char *nodename)
214EXPORT_SYMBOL(prom_searchsiblings); 200EXPORT_SYMBOL(prom_searchsiblings);
215 201
216/* Interal version of nextprop that does not alter return values. */ 202/* Interal version of nextprop that does not alter return values. */
217char *__prom_nextprop(phandle node, char * oprop) 203static char *__prom_nextprop(phandle node, char * oprop)
218{ 204{
219 unsigned long flags; 205 unsigned long flags;
220 char *prop; 206 char *prop;
@@ -227,17 +213,6 @@ char *__prom_nextprop(phandle node, char * oprop)
227 return prop; 213 return prop;
228} 214}
229 215
230/* Return the first property name for node 'node'. */
231/* buffer is unused argument, but as v9 uses it, we need to have the same interface */
232char *prom_firstprop(phandle node, char *bufer)
233{
234 if (node == 0 || node == -1)
235 return "";
236
237 return __prom_nextprop(node, "");
238}
239EXPORT_SYMBOL(prom_firstprop);
240
241/* Return the property type string after property type 'oprop' 216/* Return the property type string after property type 'oprop'
242 * at node 'node' . Returns empty string if no more 217 * at node 'node' . Returns empty string if no more
243 * property types for this node. 218 * property types for this node.
@@ -299,19 +274,6 @@ phandle prom_finddevice(char *name)
299} 274}
300EXPORT_SYMBOL(prom_finddevice); 275EXPORT_SYMBOL(prom_finddevice);
301 276
302int prom_node_has_property(phandle node, char *prop)
303{
304 char *current_property = "";
305
306 do {
307 current_property = prom_nextprop(node, current_property, NULL);
308 if(!strcmp(current_property, prop))
309 return 1;
310 } while (*current_property);
311 return 0;
312}
313EXPORT_SYMBOL(prom_node_has_property);
314
315/* Set property 'pname' at node 'node' to value 'value' which has a length 277/* Set property 'pname' at node 'node' to value 'value' which has a length
316 * of 'size' bytes. Return the number of bytes the prom accepted. 278 * of 'size' bytes. Return the number of bytes the prom accepted.
317 */ 279 */
@@ -320,8 +282,10 @@ int prom_setprop(phandle node, const char *pname, char *value, int size)
320 unsigned long flags; 282 unsigned long flags;
321 int ret; 283 int ret;
322 284
323 if(size == 0) return 0; 285 if (size == 0)
324 if((pname == 0) || (value == 0)) return 0; 286 return 0;
287 if ((pname == NULL) || (value == NULL))
288 return 0;
325 spin_lock_irqsave(&prom_lock, flags); 289 spin_lock_irqsave(&prom_lock, flags);
326 ret = prom_nodeops->no_setprop(node, pname, value, size); 290 ret = prom_nodeops->no_setprop(node, pname, value, size);
327 restore_current(); 291 restore_current();