diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-30 11:48:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-30 11:48:56 -0400 |
commit | 12829dcb10efc576c3739131a5d57fe7213632d9 (patch) | |
tree | 8b3084f7b3172820e6e87a219fe018f8e235ad38 /arch/ppc64 | |
parent | c60e81ee1cac32dae1f9bf623dcb6b3b2bde8eab (diff) | |
parent | 719d1cd86780c156f954fc34f34481adac197aec (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6
Diffstat (limited to 'arch/ppc64')
-rw-r--r-- | arch/ppc64/boot/Makefile | 5 | ||||
-rw-r--r-- | arch/ppc64/boot/main.c | 8 | ||||
-rw-r--r-- | arch/ppc64/boot/mknote.c | 43 | ||||
-rw-r--r-- | arch/ppc64/boot/piggyback.c | 83 | ||||
-rw-r--r-- | arch/ppc64/boot/prom.c | 16 | ||||
-rw-r--r-- | arch/ppc64/kernel/ItLpQueue.c | 294 | ||||
-rw-r--r-- | arch/ppc64/kernel/LparData.c | 11 | ||||
-rw-r--r-- | arch/ppc64/kernel/iSeries_proc.c | 48 | ||||
-rw-r--r-- | arch/ppc64/kernel/iSeries_setup.c | 43 | ||||
-rw-r--r-- | arch/ppc64/kernel/idle.c | 4 | ||||
-rw-r--r-- | arch/ppc64/kernel/irq.c | 7 | ||||
-rw-r--r-- | arch/ppc64/kernel/mf.c | 6 | ||||
-rw-r--r-- | arch/ppc64/kernel/nvram.c | 8 | ||||
-rw-r--r-- | arch/ppc64/kernel/pacaData.c | 212 | ||||
-rw-r--r-- | arch/ppc64/kernel/sysfs.c | 7 | ||||
-rw-r--r-- | arch/ppc64/kernel/time.c | 8 |
16 files changed, 285 insertions, 518 deletions
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d3e1d6af9203..683b2d43c15f 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile | |||
@@ -52,7 +52,7 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) | |||
52 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) | 52 | src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) |
53 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) | 53 | gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) |
54 | 54 | ||
55 | hostprogs-y := piggy addnote addRamDisk | 55 | hostprogs-y := addnote addRamDisk |
56 | targets += zImage zImage.initrd imagesize.c \ | 56 | targets += zImage zImage.initrd imagesize.c \ |
57 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ | 57 | $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ |
58 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ | 58 | $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ |
@@ -78,9 +78,6 @@ addsection = $(CROSS32OBJCOPY) $(1) \ | |||
78 | quiet_cmd_addnote = ADDNOTE $@ | 78 | quiet_cmd_addnote = ADDNOTE $@ |
79 | cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ | 79 | cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ |
80 | 80 | ||
81 | quiet_cmd_piggy = PIGGY $@ | ||
82 | cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ | ||
83 | |||
84 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE | 81 | $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE |
85 | $(call if_changed,gzip) | 82 | $(call if_changed,gzip) |
86 | 83 | ||
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index da12ea2ca464..199d9804f61c 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c | |||
@@ -17,7 +17,6 @@ | |||
17 | 17 | ||
18 | extern void *finddevice(const char *); | 18 | extern void *finddevice(const char *); |
19 | extern int getprop(void *, const char *, void *, int); | 19 | extern int getprop(void *, const char *, void *, int); |
20 | extern void printk(char *fmt, ...); | ||
21 | extern void printf(const char *fmt, ...); | 20 | extern void printf(const char *fmt, ...); |
22 | extern int sprintf(char *buf, const char *fmt, ...); | 21 | extern int sprintf(char *buf, const char *fmt, ...); |
23 | void gunzip(void *, int, unsigned char *, int *); | 22 | void gunzip(void *, int, unsigned char *, int *); |
@@ -147,10 +146,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr) | |||
147 | } | 146 | } |
148 | a1 = initrd.addr; | 147 | a1 = initrd.addr; |
149 | a2 = initrd.size; | 148 | a2 = initrd.size; |
150 | printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", | 149 | printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", |
151 | initrd.addr, (unsigned long)_initrd_start, initrd.size); | 150 | initrd.addr, (unsigned long)_initrd_start, initrd.size); |
152 | memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); | 151 | memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); |
153 | printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); | 152 | printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); |
154 | } | 153 | } |
155 | 154 | ||
156 | /* Eventually gunzip the kernel */ | 155 | /* Eventually gunzip the kernel */ |
@@ -201,9 +200,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr) | |||
201 | 200 | ||
202 | flush_cache((void *)vmlinux.addr, vmlinux.size); | 201 | flush_cache((void *)vmlinux.addr, vmlinux.size); |
203 | 202 | ||
204 | if (a1) | ||
205 | printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); | ||
206 | |||
207 | kernel_entry = (kernel_entry_t)vmlinux.addr; | 203 | kernel_entry = (kernel_entry_t)vmlinux.addr; |
208 | #ifdef DEBUG | 204 | #ifdef DEBUG |
209 | printf( "kernel:\n\r" | 205 | printf( "kernel:\n\r" |
diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c deleted file mode 100644 index 120cc1d89739..000000000000 --- a/arch/ppc64/boot/mknote.c +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Cort Dougan 1999. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * Generate a note section as per the CHRP specification. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <stdio.h> | ||
14 | |||
15 | #define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); | ||
16 | |||
17 | int main(void) | ||
18 | { | ||
19 | /* header */ | ||
20 | /* namesz */ | ||
21 | PL(strlen("PowerPC")+1); | ||
22 | /* descrsz */ | ||
23 | PL(6*4); | ||
24 | /* type */ | ||
25 | PL(0x1275); | ||
26 | /* name */ | ||
27 | printf("PowerPC"); printf("%c", 0); | ||
28 | |||
29 | /* descriptor */ | ||
30 | /* real-mode */ | ||
31 | PL(0xffffffff); | ||
32 | /* real-base */ | ||
33 | PL(0x00c00000); | ||
34 | /* real-size */ | ||
35 | PL(0xffffffff); | ||
36 | /* virt-base */ | ||
37 | PL(0xffffffff); | ||
38 | /* virt-size */ | ||
39 | PL(0xffffffff); | ||
40 | /* load-base */ | ||
41 | PL(0x4000); | ||
42 | return 0; | ||
43 | } | ||
diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c deleted file mode 100644 index 235c7a87269c..000000000000 --- a/arch/ppc64/boot/piggyback.c +++ /dev/null | |||
@@ -1,83 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 IBM Corp | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdio.h> | ||
10 | #include <unistd.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | extern long ce_exec_config[]; | ||
14 | |||
15 | int main(int argc, char *argv[]) | ||
16 | { | ||
17 | int i, cnt, pos, len; | ||
18 | unsigned int cksum, val; | ||
19 | unsigned char *lp; | ||
20 | unsigned char buf[8192]; | ||
21 | char *varname; | ||
22 | if (argc != 2) | ||
23 | { | ||
24 | fprintf(stderr, "usage: %s name <in-file >out-file\n", | ||
25 | argv[0]); | ||
26 | exit(1); | ||
27 | } | ||
28 | |||
29 | varname = strrchr(argv[1], '/'); | ||
30 | if (varname) | ||
31 | varname++; | ||
32 | else | ||
33 | varname = argv[1]; | ||
34 | |||
35 | fprintf(stdout, "#\n"); | ||
36 | fprintf(stdout, "# Miscellaneous data structures:\n"); | ||
37 | fprintf(stdout, "# WARNING - this file is automatically generated!\n"); | ||
38 | fprintf(stdout, "#\n"); | ||
39 | fprintf(stdout, "\n"); | ||
40 | fprintf(stdout, "\t.data\n"); | ||
41 | fprintf(stdout, "\t.globl %s_data\n", varname); | ||
42 | fprintf(stdout, "%s_data:\n", varname); | ||
43 | pos = 0; | ||
44 | cksum = 0; | ||
45 | while ((len = read(0, buf, sizeof(buf))) > 0) | ||
46 | { | ||
47 | cnt = 0; | ||
48 | lp = (unsigned char *)buf; | ||
49 | len = (len + 3) & ~3; /* Round up to longwords */ | ||
50 | for (i = 0; i < len; i += 4) | ||
51 | { | ||
52 | if (cnt == 0) | ||
53 | { | ||
54 | fprintf(stdout, "\t.long\t"); | ||
55 | } | ||
56 | fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); | ||
57 | val = *(unsigned long *)lp; | ||
58 | cksum ^= val; | ||
59 | lp += 4; | ||
60 | if (++cnt == 4) | ||
61 | { | ||
62 | cnt = 0; | ||
63 | fprintf(stdout, " # %x \n", pos+i-12); | ||
64 | fflush(stdout); | ||
65 | } else | ||
66 | { | ||
67 | fprintf(stdout, ","); | ||
68 | } | ||
69 | } | ||
70 | if (cnt) | ||
71 | { | ||
72 | fprintf(stdout, "0\n"); | ||
73 | } | ||
74 | pos += len; | ||
75 | } | ||
76 | fprintf(stdout, "\t.globl %s_len\n", varname); | ||
77 | fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); | ||
78 | fflush(stdout); | ||
79 | fclose(stdout); | ||
80 | fprintf(stderr, "cksum = %x\n", cksum); | ||
81 | exit(0); | ||
82 | } | ||
83 | |||
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index d5218b15824e..5e48b80ff5a0 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c | |||
@@ -40,7 +40,7 @@ void *finddevice(const char *name); | |||
40 | int getprop(void *phandle, const char *name, void *buf, int buflen); | 40 | int getprop(void *phandle, const char *name, void *buf, int buflen); |
41 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ | 41 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ |
42 | 42 | ||
43 | void printk(char *fmt, ...); | 43 | int printf(char *fmt, ...); |
44 | 44 | ||
45 | /* there is no convenient header to get this from... -- paulus */ | 45 | /* there is no convenient header to get this from... -- paulus */ |
46 | extern unsigned long strlen(const char *); | 46 | extern unsigned long strlen(const char *); |
@@ -220,7 +220,7 @@ readchar(void) | |||
220 | case 1: | 220 | case 1: |
221 | return ch; | 221 | return ch; |
222 | case -1: | 222 | case -1: |
223 | printk("read(stdin) returned -1\r\n"); | 223 | printf("read(stdin) returned -1\r\n"); |
224 | return -1; | 224 | return -1; |
225 | } | 225 | } |
226 | } | 226 | } |
@@ -627,18 +627,6 @@ int sprintf(char * buf, const char *fmt, ...) | |||
627 | 627 | ||
628 | static char sprint_buf[1024]; | 628 | static char sprint_buf[1024]; |
629 | 629 | ||
630 | void | ||
631 | printk(char *fmt, ...) | ||
632 | { | ||
633 | va_list args; | ||
634 | int n; | ||
635 | |||
636 | va_start(args, fmt); | ||
637 | n = vsprintf(sprint_buf, fmt, args); | ||
638 | va_end(args); | ||
639 | write(stdout, sprint_buf, n); | ||
640 | } | ||
641 | |||
642 | int | 630 | int |
643 | printf(char *fmt, ...) | 631 | printf(char *fmt, ...) |
644 | { | 632 | { |
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index cdea00d7707f..4231861288a3 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ItLpQueue.c | 2 | * ItLpQueue.c |
3 | * Copyright (C) 2001 Mike Corrigan IBM Corporation | 3 | * Copyright (C) 2001 Mike Corrigan IBM Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
@@ -11,156 +11,252 @@ | |||
11 | #include <linux/stddef.h> | 11 | #include <linux/stddef.h> |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/bootmem.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | #include <linux/proc_fs.h> | ||
14 | #include <asm/system.h> | 17 | #include <asm/system.h> |
15 | #include <asm/paca.h> | 18 | #include <asm/paca.h> |
16 | #include <asm/iSeries/ItLpQueue.h> | 19 | #include <asm/iSeries/ItLpQueue.h> |
17 | #include <asm/iSeries/HvLpEvent.h> | 20 | #include <asm/iSeries/HvLpEvent.h> |
18 | #include <asm/iSeries/HvCallEvent.h> | 21 | #include <asm/iSeries/HvCallEvent.h> |
19 | 22 | ||
20 | static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) | 23 | /* |
21 | { | 24 | * The LpQueue is used to pass event data from the hypervisor to |
22 | int t; | 25 | * the partition. This is where I/O interrupt events are communicated. |
23 | u32 * inUseP = &(lpQueue->xInUseWord); | 26 | * |
24 | 27 | * It is written to by the hypervisor so cannot end up in the BSS. | |
25 | __asm__ __volatile__("\n\ | 28 | */ |
26 | 1: lwarx %0,0,%2 \n\ | 29 | struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); |
27 | cmpwi 0,%0,0 \n\ | ||
28 | li %0,0 \n\ | ||
29 | bne- 2f \n\ | ||
30 | addi %0,%0,1 \n\ | ||
31 | stwcx. %0,0,%2 \n\ | ||
32 | bne- 1b \n\ | ||
33 | 2: eieio" | ||
34 | : "=&r" (t), "=m" (lpQueue->xInUseWord) | ||
35 | : "r" (inUseP), "m" (lpQueue->xInUseWord) | ||
36 | : "cc"); | ||
37 | |||
38 | return t; | ||
39 | } | ||
40 | 30 | ||
41 | static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) | 31 | DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); |
42 | { | 32 | |
43 | lpQueue->xInUseWord = 0; | 33 | static char *event_types[HvLpEvent_Type_NumTypes] = { |
44 | } | 34 | "Hypervisor", |
35 | "Machine Facilities", | ||
36 | "Session Manager", | ||
37 | "SPD I/O", | ||
38 | "Virtual Bus", | ||
39 | "PCI I/O", | ||
40 | "RIO I/O", | ||
41 | "Virtual Lan", | ||
42 | "Virtual I/O" | ||
43 | }; | ||
45 | 44 | ||
46 | /* Array of LpEvent handler functions */ | 45 | /* Array of LpEvent handler functions */ |
47 | extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; | 46 | extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; |
48 | unsigned long ItLpQueueInProcess = 0; | ||
49 | 47 | ||
50 | struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) | 48 | static struct HvLpEvent * get_next_hvlpevent(void) |
51 | { | 49 | { |
52 | struct HvLpEvent * nextLpEvent = | 50 | struct HvLpEvent * event; |
53 | (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; | 51 | event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; |
54 | if ( nextLpEvent->xFlags.xValid ) { | 52 | |
53 | if (event->xFlags.xValid) { | ||
55 | /* rmb() needed only for weakly consistent machines (regatta) */ | 54 | /* rmb() needed only for weakly consistent machines (regatta) */ |
56 | rmb(); | 55 | rmb(); |
57 | /* Set pointer to next potential event */ | 56 | /* Set pointer to next potential event */ |
58 | lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + | 57 | hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + |
59 | LpEventAlign ) / | 58 | LpEventAlign) / LpEventAlign) * LpEventAlign; |
60 | LpEventAlign ) * | 59 | |
61 | LpEventAlign; | ||
62 | /* Wrap to beginning if no room at end */ | 60 | /* Wrap to beginning if no room at end */ |
63 | if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) | 61 | if (hvlpevent_queue.xSlicCurEventPtr > |
64 | lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; | 62 | hvlpevent_queue.xSlicLastValidEventPtr) { |
63 | hvlpevent_queue.xSlicCurEventPtr = | ||
64 | hvlpevent_queue.xSlicEventStackPtr; | ||
65 | } | ||
66 | } else { | ||
67 | event = NULL; | ||
65 | } | 68 | } |
66 | else | ||
67 | nextLpEvent = NULL; | ||
68 | 69 | ||
69 | return nextLpEvent; | 70 | return event; |
70 | } | 71 | } |
71 | 72 | ||
72 | int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) | 73 | static unsigned long spread_lpevents = NR_CPUS; |
74 | |||
75 | int hvlpevent_is_pending(void) | ||
73 | { | 76 | { |
74 | int retval = 0; | 77 | struct HvLpEvent *next_event; |
75 | struct HvLpEvent * nextLpEvent; | 78 | |
76 | if ( lpQueue ) { | 79 | if (smp_processor_id() >= spread_lpevents) |
77 | nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; | 80 | return 0; |
78 | retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending; | 81 | |
79 | } | 82 | next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; |
80 | return retval; | 83 | |
84 | return next_event->xFlags.xValid | | ||
85 | hvlpevent_queue.xPlicOverflowIntPending; | ||
81 | } | 86 | } |
82 | 87 | ||
83 | void ItLpQueue_clearValid( struct HvLpEvent * event ) | 88 | static void hvlpevent_clear_valid(struct HvLpEvent * event) |
84 | { | 89 | { |
85 | /* Clear the valid bit of the event | 90 | /* Tell the Hypervisor that we're done with this event. |
86 | * Also clear bits within this event that might | 91 | * Also clear bits within this event that might look like valid bits. |
87 | * look like valid bits (on 64-byte boundaries) | 92 | * ie. on 64-byte boundaries. |
88 | */ | 93 | */ |
89 | unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / | 94 | struct HvLpEvent *tmp; |
90 | LpEventAlign ) - 1; | 95 | unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / |
91 | switch ( extra ) { | 96 | LpEventAlign) - 1; |
92 | case 3: | 97 | |
93 | ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; | 98 | switch (extra) { |
94 | case 2: | 99 | case 3: |
95 | ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; | 100 | tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); |
96 | case 1: | 101 | tmp->xFlags.xValid = 0; |
97 | ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; | 102 | case 2: |
98 | case 0: | 103 | tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); |
99 | ; | 104 | tmp->xFlags.xValid = 0; |
105 | case 1: | ||
106 | tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); | ||
107 | tmp->xFlags.xValid = 0; | ||
100 | } | 108 | } |
109 | |||
101 | mb(); | 110 | mb(); |
111 | |||
102 | event->xFlags.xValid = 0; | 112 | event->xFlags.xValid = 0; |
103 | } | 113 | } |
104 | 114 | ||
105 | unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) | 115 | void process_hvlpevents(struct pt_regs *regs) |
106 | { | 116 | { |
107 | unsigned numIntsProcessed = 0; | 117 | struct HvLpEvent * event; |
108 | struct HvLpEvent * nextLpEvent; | ||
109 | 118 | ||
110 | /* If we have recursed, just return */ | 119 | /* If we have recursed, just return */ |
111 | if ( !set_inUse( lpQueue ) ) | 120 | if (!spin_trylock(&hvlpevent_queue.lock)) |
112 | return 0; | 121 | return; |
113 | |||
114 | if (ItLpQueueInProcess == 0) | ||
115 | ItLpQueueInProcess = 1; | ||
116 | else | ||
117 | BUG(); | ||
118 | 122 | ||
119 | for (;;) { | 123 | for (;;) { |
120 | nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); | 124 | event = get_next_hvlpevent(); |
121 | if ( nextLpEvent ) { | 125 | if (event) { |
122 | /* Count events to return to caller | 126 | /* Call appropriate handler here, passing |
123 | * and count processed events in lpQueue | ||
124 | */ | ||
125 | ++numIntsProcessed; | ||
126 | lpQueue->xLpIntCount++; | ||
127 | /* Call appropriate handler here, passing | ||
128 | * a pointer to the LpEvent. The handler | 127 | * a pointer to the LpEvent. The handler |
129 | * must make a copy of the LpEvent if it | 128 | * must make a copy of the LpEvent if it |
130 | * needs it in a bottom half. (perhaps for | 129 | * needs it in a bottom half. (perhaps for |
131 | * an ACK) | 130 | * an ACK) |
132 | * | 131 | * |
133 | * Handlers are responsible for ACK processing | 132 | * Handlers are responsible for ACK processing |
134 | * | 133 | * |
135 | * The Hypervisor guarantees that LpEvents will | 134 | * The Hypervisor guarantees that LpEvents will |
136 | * only be delivered with types that we have | 135 | * only be delivered with types that we have |
137 | * registered for, so no type check is necessary | 136 | * registered for, so no type check is necessary |
138 | * here! | 137 | * here! |
139 | */ | 138 | */ |
140 | if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) | 139 | if (event->xType < HvLpEvent_Type_NumTypes) |
141 | lpQueue->xLpIntCountByType[nextLpEvent->xType]++; | 140 | __get_cpu_var(hvlpevent_counts)[event->xType]++; |
142 | if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && | 141 | if (event->xType < HvLpEvent_Type_NumTypes && |
143 | lpEventHandler[nextLpEvent->xType] ) | 142 | lpEventHandler[event->xType]) |
144 | lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); | 143 | lpEventHandler[event->xType](event, regs); |
145 | else | 144 | else |
146 | printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); | 145 | printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); |
147 | 146 | ||
148 | ItLpQueue_clearValid( nextLpEvent ); | 147 | hvlpevent_clear_valid(event); |
149 | } else if ( lpQueue->xPlicOverflowIntPending ) | 148 | } else if (hvlpevent_queue.xPlicOverflowIntPending) |
150 | /* | 149 | /* |
151 | * No more valid events. If overflow events are | 150 | * No more valid events. If overflow events are |
152 | * pending process them | 151 | * pending process them |
153 | */ | 152 | */ |
154 | HvCallEvent_getOverflowLpEvents( lpQueue->xIndex); | 153 | HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); |
155 | else | 154 | else |
156 | break; | 155 | break; |
157 | } | 156 | } |
158 | 157 | ||
159 | ItLpQueueInProcess = 0; | 158 | spin_unlock(&hvlpevent_queue.lock); |
160 | mb(); | 159 | } |
161 | clear_inUse( lpQueue ); | 160 | |
161 | static int set_spread_lpevents(char *str) | ||
162 | { | ||
163 | unsigned long val = simple_strtoul(str, NULL, 0); | ||
164 | |||
165 | /* | ||
166 | * The parameter is the number of processors to share in processing | ||
167 | * lp events. | ||
168 | */ | ||
169 | if (( val > 0) && (val <= NR_CPUS)) { | ||
170 | spread_lpevents = val; | ||
171 | printk("lpevent processing spread over %ld processors\n", val); | ||
172 | } else { | ||
173 | printk("invalid spread_lpevents %ld\n", val); | ||
174 | } | ||
162 | 175 | ||
163 | get_paca()->lpevent_count += numIntsProcessed; | 176 | return 1; |
177 | } | ||
178 | __setup("spread_lpevents=", set_spread_lpevents); | ||
179 | |||
180 | void setup_hvlpevent_queue(void) | ||
181 | { | ||
182 | void *eventStack; | ||
183 | |||
184 | /* | ||
185 | * Allocate a page for the Event Stack. The Hypervisor needs the | ||
186 | * absolute real address, so we subtract out the KERNELBASE and add | ||
187 | * in the absolute real address of the kernel load area. | ||
188 | */ | ||
189 | eventStack = alloc_bootmem_pages(LpEventStackSize); | ||
190 | memset(eventStack, 0, LpEventStackSize); | ||
191 | |||
192 | /* Invoke the hypervisor to initialize the event stack */ | ||
193 | HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); | ||
194 | |||
195 | hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; | ||
196 | hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; | ||
197 | hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + | ||
198 | (LpEventStackSize - LpEventMaxSize); | ||
199 | hvlpevent_queue.xIndex = 0; | ||
200 | } | ||
201 | |||
202 | static int proc_lpevents_show(struct seq_file *m, void *v) | ||
203 | { | ||
204 | int cpu, i; | ||
205 | unsigned long sum; | ||
206 | static unsigned long cpu_totals[NR_CPUS]; | ||
207 | |||
208 | /* FIXME: do we care that there's no locking here? */ | ||
209 | sum = 0; | ||
210 | for_each_online_cpu(cpu) { | ||
211 | cpu_totals[cpu] = 0; | ||
212 | for (i = 0; i < HvLpEvent_Type_NumTypes; i++) { | ||
213 | cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i]; | ||
214 | } | ||
215 | sum += cpu_totals[cpu]; | ||
216 | } | ||
217 | |||
218 | seq_printf(m, "LpEventQueue 0\n"); | ||
219 | seq_printf(m, " events processed:\t%lu\n", sum); | ||
220 | |||
221 | for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) { | ||
222 | sum = 0; | ||
223 | for_each_online_cpu(cpu) { | ||
224 | sum += per_cpu(hvlpevent_counts, cpu)[i]; | ||
225 | } | ||
226 | |||
227 | seq_printf(m, " %-20s %10lu\n", event_types[i], sum); | ||
228 | } | ||
229 | |||
230 | seq_printf(m, "\n events processed by processor:\n"); | ||
231 | |||
232 | for_each_online_cpu(cpu) { | ||
233 | seq_printf(m, " CPU%02d %10lu\n", cpu, cpu_totals[cpu]); | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int proc_lpevents_open(struct inode *inode, struct file *file) | ||
240 | { | ||
241 | return single_open(file, proc_lpevents_show, NULL); | ||
242 | } | ||
164 | 243 | ||
165 | return numIntsProcessed; | 244 | static struct file_operations proc_lpevents_operations = { |
245 | .open = proc_lpevents_open, | ||
246 | .read = seq_read, | ||
247 | .llseek = seq_lseek, | ||
248 | .release = single_release, | ||
249 | }; | ||
250 | |||
251 | static int __init proc_lpevents_init(void) | ||
252 | { | ||
253 | struct proc_dir_entry *e; | ||
254 | |||
255 | e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); | ||
256 | if (e) | ||
257 | e->proc_fops = &proc_lpevents_operations; | ||
258 | |||
259 | return 0; | ||
166 | } | 260 | } |
261 | __initcall(proc_lpevents_init); | ||
262 | |||
diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index badc5a443614..6ffcf67dd507 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c | |||
@@ -28,13 +28,6 @@ | |||
28 | #include <asm/iSeries/IoHriProcessorVpd.h> | 28 | #include <asm/iSeries/IoHriProcessorVpd.h> |
29 | #include <asm/iSeries/ItSpCommArea.h> | 29 | #include <asm/iSeries/ItSpCommArea.h> |
30 | 30 | ||
31 | /* The LpQueue is used to pass event data from the hypervisor to | ||
32 | * the partition. This is where I/O interrupt events are communicated. | ||
33 | */ | ||
34 | |||
35 | /* May be filled in by the hypervisor so cannot end up in the BSS */ | ||
36 | struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); | ||
37 | |||
38 | 31 | ||
39 | /* The HvReleaseData is the root of the information shared between | 32 | /* The HvReleaseData is the root of the information shared between |
40 | * the hypervisor and Linux. | 33 | * the hypervisor and Linux. |
@@ -200,7 +193,7 @@ struct ItVpdAreas itVpdAreas = { | |||
200 | 0,0,0, /* 13 - 15 */ | 193 | 0,0,0, /* 13 - 15 */ |
201 | sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ | 194 | sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ |
202 | 0,0,0,0,0,0, /* 17 - 22 */ | 195 | 0,0,0,0,0,0, /* 17 - 22 */ |
203 | sizeof(struct ItLpQueue),/* 23 length of Lp Queue */ | 196 | sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */ |
204 | 0,0 /* 24 - 25 */ | 197 | 0,0 /* 24 - 25 */ |
205 | }, | 198 | }, |
206 | .xSlicVpdAdrs = { /* VPD addresses */ | 199 | .xSlicVpdAdrs = { /* VPD addresses */ |
@@ -218,7 +211,7 @@ struct ItVpdAreas itVpdAreas = { | |||
218 | 0,0,0, /* 13 - 15 */ | 211 | 0,0,0, /* 13 - 15 */ |
219 | &xIoHriProcessorVpd, /* 16 Proc Vpd */ | 212 | &xIoHriProcessorVpd, /* 16 Proc Vpd */ |
220 | 0,0,0,0,0,0, /* 17 - 22 */ | 213 | 0,0,0,0,0,0, /* 17 - 22 */ |
221 | &xItLpQueue, /* 23 Lp Queue */ | 214 | &hvlpevent_queue, /* 23 Lp Queue */ |
222 | 0,0 | 215 | 0,0 |
223 | } | 216 | } |
224 | }; | 217 | }; |
diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 356bd9931fcc..0fe3116eba29 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c | |||
@@ -40,50 +40,6 @@ static int __init iseries_proc_create(void) | |||
40 | } | 40 | } |
41 | core_initcall(iseries_proc_create); | 41 | core_initcall(iseries_proc_create); |
42 | 42 | ||
43 | static char *event_types[9] = { | ||
44 | "Hypervisor\t\t", | ||
45 | "Machine Facilities\t", | ||
46 | "Session Manager\t", | ||
47 | "SPD I/O\t\t", | ||
48 | "Virtual Bus\t\t", | ||
49 | "PCI I/O\t\t", | ||
50 | "RIO I/O\t\t", | ||
51 | "Virtual Lan\t\t", | ||
52 | "Virtual I/O\t\t" | ||
53 | }; | ||
54 | |||
55 | static int proc_lpevents_show(struct seq_file *m, void *v) | ||
56 | { | ||
57 | unsigned int i; | ||
58 | |||
59 | seq_printf(m, "LpEventQueue 0\n"); | ||
60 | seq_printf(m, " events processed:\t%lu\n", | ||
61 | (unsigned long)xItLpQueue.xLpIntCount); | ||
62 | |||
63 | for (i = 0; i < 9; ++i) | ||
64 | seq_printf(m, " %s %10lu\n", event_types[i], | ||
65 | (unsigned long)xItLpQueue.xLpIntCountByType[i]); | ||
66 | |||
67 | seq_printf(m, "\n events processed by processor:\n"); | ||
68 | |||
69 | for_each_online_cpu(i) | ||
70 | seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int proc_lpevents_open(struct inode *inode, struct file *file) | ||
76 | { | ||
77 | return single_open(file, proc_lpevents_show, NULL); | ||
78 | } | ||
79 | |||
80 | static struct file_operations proc_lpevents_operations = { | ||
81 | .open = proc_lpevents_open, | ||
82 | .read = seq_read, | ||
83 | .llseek = seq_lseek, | ||
84 | .release = single_release, | ||
85 | }; | ||
86 | |||
87 | static unsigned long startTitan = 0; | 43 | static unsigned long startTitan = 0; |
88 | static unsigned long startTb = 0; | 44 | static unsigned long startTb = 0; |
89 | 45 | ||
@@ -148,10 +104,6 @@ static int __init iseries_proc_init(void) | |||
148 | { | 104 | { |
149 | struct proc_dir_entry *e; | 105 | struct proc_dir_entry *e; |
150 | 106 | ||
151 | e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); | ||
152 | if (e) | ||
153 | e->proc_fops = &proc_lpevents_operations; | ||
154 | |||
155 | e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); | 107 | e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); |
156 | if (e) | 108 | if (e) |
157 | e->proc_fops = &proc_titantod_operations; | 109 | e->proc_fops = &proc_titantod_operations; |
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 86966ce76b58..b3f770f6d402 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
25 | #include <linux/param.h> | 25 | #include <linux/param.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/bootmem.h> | ||
28 | #include <linux/initrd.h> | 27 | #include <linux/initrd.h> |
29 | #include <linux/seq_file.h> | 28 | #include <linux/seq_file.h> |
30 | #include <linux/kdev_t.h> | 29 | #include <linux/kdev_t.h> |
@@ -676,7 +675,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) | |||
676 | */ | 675 | */ |
677 | static void __init iSeries_setup_arch(void) | 676 | static void __init iSeries_setup_arch(void) |
678 | { | 677 | { |
679 | void *eventStack; | ||
680 | unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; | 678 | unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; |
681 | 679 | ||
682 | /* Add an eye catcher and the systemcfg layout version number */ | 680 | /* Add an eye catcher and the systemcfg layout version number */ |
@@ -685,24 +683,7 @@ static void __init iSeries_setup_arch(void) | |||
685 | systemcfg->version.minor = SYSTEMCFG_MINOR; | 683 | systemcfg->version.minor = SYSTEMCFG_MINOR; |
686 | 684 | ||
687 | /* Setup the Lp Event Queue */ | 685 | /* Setup the Lp Event Queue */ |
688 | 686 | setup_hvlpevent_queue(); | |
689 | /* Allocate a page for the Event Stack | ||
690 | * The hypervisor wants the absolute real address, so | ||
691 | * we subtract out the KERNELBASE and add in the | ||
692 | * absolute real address of the kernel load area | ||
693 | */ | ||
694 | eventStack = alloc_bootmem_pages(LpEventStackSize); | ||
695 | memset(eventStack, 0, LpEventStackSize); | ||
696 | |||
697 | /* Invoke the hypervisor to initialize the event stack */ | ||
698 | HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); | ||
699 | |||
700 | /* Initialize fields in our Lp Event Queue */ | ||
701 | xItLpQueue.xSlicEventStackPtr = (char *)eventStack; | ||
702 | xItLpQueue.xSlicCurEventPtr = (char *)eventStack; | ||
703 | xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + | ||
704 | (LpEventStackSize - LpEventMaxSize); | ||
705 | xItLpQueue.xIndex = 0; | ||
706 | 687 | ||
707 | /* Compute processor frequency */ | 688 | /* Compute processor frequency */ |
708 | procFreqHz = ((1UL << 34) * 1000000) / | 689 | procFreqHz = ((1UL << 34) * 1000000) / |
@@ -853,28 +834,6 @@ static int __init iSeries_src_init(void) | |||
853 | 834 | ||
854 | late_initcall(iSeries_src_init); | 835 | late_initcall(iSeries_src_init); |
855 | 836 | ||
856 | static int set_spread_lpevents(char *str) | ||
857 | { | ||
858 | unsigned long i; | ||
859 | unsigned long val = simple_strtoul(str, NULL, 0); | ||
860 | |||
861 | /* | ||
862 | * The parameter is the number of processors to share in processing | ||
863 | * lp events. | ||
864 | */ | ||
865 | if (( val > 0) && (val <= NR_CPUS)) { | ||
866 | for (i = 1; i < val; ++i) | ||
867 | paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; | ||
868 | |||
869 | printk("lpevent processing spread over %ld processors\n", val); | ||
870 | } else { | ||
871 | printk("invalid spread_lpevents %ld\n", val); | ||
872 | } | ||
873 | |||
874 | return 1; | ||
875 | } | ||
876 | __setup("spread_lpevents=", set_spread_lpevents); | ||
877 | |||
878 | #ifndef CONFIG_PCI | 837 | #ifndef CONFIG_PCI |
879 | void __init iSeries_init_IRQ(void) { } | 838 | void __init iSeries_init_IRQ(void) { } |
880 | #endif | 839 | #endif |
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index bdf13b4dc1c8..08952c7e6216 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c | |||
@@ -88,7 +88,7 @@ static int iSeries_idle(void) | |||
88 | 88 | ||
89 | while (1) { | 89 | while (1) { |
90 | if (lpaca->lppaca.shared_proc) { | 90 | if (lpaca->lppaca.shared_proc) { |
91 | if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) | 91 | if (hvlpevent_is_pending()) |
92 | process_iSeries_events(); | 92 | process_iSeries_events(); |
93 | if (!need_resched()) | 93 | if (!need_resched()) |
94 | yield_shared_processor(); | 94 | yield_shared_processor(); |
@@ -100,7 +100,7 @@ static int iSeries_idle(void) | |||
100 | 100 | ||
101 | while (!need_resched()) { | 101 | while (!need_resched()) { |
102 | HMT_medium(); | 102 | HMT_medium(); |
103 | if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) | 103 | if (hvlpevent_is_pending()) |
104 | process_iSeries_events(); | 104 | process_iSeries_events(); |
105 | HMT_low(); | 105 | HMT_low(); |
106 | } | 106 | } |
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index ffe300611f00..f41afe545045 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c | |||
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(irq_desc); | |||
66 | int distribute_irqs = 1; | 66 | int distribute_irqs = 1; |
67 | int __irq_offset_value; | 67 | int __irq_offset_value; |
68 | int ppc_spurious_interrupts; | 68 | int ppc_spurious_interrupts; |
69 | unsigned long lpevent_count; | ||
70 | u64 ppc64_interrupt_controller; | 69 | u64 ppc64_interrupt_controller; |
71 | 70 | ||
72 | int show_interrupts(struct seq_file *p, void *v) | 71 | int show_interrupts(struct seq_file *p, void *v) |
@@ -269,7 +268,6 @@ out: | |||
269 | void do_IRQ(struct pt_regs *regs) | 268 | void do_IRQ(struct pt_regs *regs) |
270 | { | 269 | { |
271 | struct paca_struct *lpaca; | 270 | struct paca_struct *lpaca; |
272 | struct ItLpQueue *lpq; | ||
273 | 271 | ||
274 | irq_enter(); | 272 | irq_enter(); |
275 | 273 | ||
@@ -295,9 +293,8 @@ void do_IRQ(struct pt_regs *regs) | |||
295 | iSeries_smp_message_recv(regs); | 293 | iSeries_smp_message_recv(regs); |
296 | } | 294 | } |
297 | #endif /* CONFIG_SMP */ | 295 | #endif /* CONFIG_SMP */ |
298 | lpq = lpaca->lpqueue_ptr; | 296 | if (hvlpevent_is_pending()) |
299 | if (lpq && ItLpQueue_isLpIntPending(lpq)) | 297 | process_hvlpevents(regs); |
300 | lpevent_count += ItLpQueue_process(lpq, regs); | ||
301 | 298 | ||
302 | irq_exit(); | 299 | irq_exit(); |
303 | 300 | ||
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d98bebf7042f..ef4a338ebd01 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c | |||
@@ -801,10 +801,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) | |||
801 | return rc; | 801 | return rc; |
802 | /* We need to poll here as we are not yet taking interrupts */ | 802 | /* We need to poll here as we are not yet taking interrupts */ |
803 | while (rtc_data.busy) { | 803 | while (rtc_data.busy) { |
804 | extern unsigned long lpevent_count; | 804 | if (hvlpevent_is_pending()) |
805 | struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; | 805 | process_hvlpevents(NULL); |
806 | if (lpq && ItLpQueue_isLpIntPending(lpq)) | ||
807 | lpevent_count += ItLpQueue_process(lpq, NULL); | ||
808 | } | 806 | } |
809 | return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); | 807 | return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); |
810 | } | 808 | } |
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index 4e71781a4414..4fb1a9f5060d 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c | |||
@@ -338,9 +338,8 @@ static int nvram_remove_os_partition(void) | |||
338 | */ | 338 | */ |
339 | static int nvram_create_os_partition(void) | 339 | static int nvram_create_os_partition(void) |
340 | { | 340 | { |
341 | struct list_head * p; | 341 | struct nvram_partition *part; |
342 | struct nvram_partition *part = NULL; | 342 | struct nvram_partition *new_part; |
343 | struct nvram_partition *new_part = NULL; | ||
344 | struct nvram_partition *free_part = NULL; | 343 | struct nvram_partition *free_part = NULL; |
345 | int seq_init[2] = { 0, 0 }; | 344 | int seq_init[2] = { 0, 0 }; |
346 | loff_t tmp_index; | 345 | loff_t tmp_index; |
@@ -349,8 +348,7 @@ static int nvram_create_os_partition(void) | |||
349 | 348 | ||
350 | /* Find a free partition that will give us the maximum needed size | 349 | /* Find a free partition that will give us the maximum needed size |
351 | If can't find one that will give us the minimum size needed */ | 350 | If can't find one that will give us the minimum size needed */ |
352 | list_for_each(p, &nvram_part->partition) { | 351 | list_for_each_entry(part, &nvram_part->partition, partition) { |
353 | part = list_entry(p, struct nvram_partition, partition); | ||
354 | if (part->header.signature != NVRAM_SIG_FREE) | 352 | if (part->header.signature != NVRAM_SIG_FREE) |
355 | continue; | 353 | continue; |
356 | 354 | ||
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index a3e0975c26c1..6316188737b6 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c | |||
@@ -42,21 +42,7 @@ extern unsigned long __toc_start; | |||
42 | * processors. The processor VPD array needs one entry per physical | 42 | * processors. The processor VPD array needs one entry per physical |
43 | * processor (not thread). | 43 | * processor (not thread). |
44 | */ | 44 | */ |
45 | #ifdef CONFIG_PPC_ISERIES | 45 | #define PACA_INIT_COMMON(number, start, asrr, asrv) \ |
46 | #define EXTRA_INITS(number, lpq) \ | ||
47 | .lppaca_ptr = &paca[number].lppaca, \ | ||
48 | .lpqueue_ptr = (lpq), /* &xItLpQueue, */ \ | ||
49 | .reg_save_ptr = &paca[number].reg_save, \ | ||
50 | .reg_save = { \ | ||
51 | .xDesc = 0xd397d9e2, /* "LpRS" */ \ | ||
52 | .xSize = sizeof(struct ItLpRegSave) \ | ||
53 | }, | ||
54 | #else | ||
55 | #define EXTRA_INITS(number, lpq) | ||
56 | #endif | ||
57 | |||
58 | #define PACAINITDATA(number,start,lpq,asrr,asrv) \ | ||
59 | { \ | ||
60 | .lock_token = 0x8000, \ | 46 | .lock_token = 0x8000, \ |
61 | .paca_index = (number), /* Paca Index */ \ | 47 | .paca_index = (number), /* Paca Index */ \ |
62 | .default_decr = 0x00ff0000, /* Initial Decr */ \ | 48 | .default_decr = 0x00ff0000, /* Initial Decr */ \ |
@@ -74,147 +60,79 @@ extern unsigned long __toc_start; | |||
74 | .end_of_quantum = 0xfffffffffffffffful, \ | 60 | .end_of_quantum = 0xfffffffffffffffful, \ |
75 | .slb_count = 64, \ | 61 | .slb_count = 64, \ |
76 | }, \ | 62 | }, \ |
77 | EXTRA_INITS((number), (lpq)) \ | ||
78 | } | ||
79 | 63 | ||
80 | struct paca_struct paca[] = { | ||
81 | #ifdef CONFIG_PPC_ISERIES | 64 | #ifdef CONFIG_PPC_ISERIES |
82 | PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR), | 65 | #define PACA_INIT_ISERIES(number) \ |
66 | .lppaca_ptr = &paca[number].lppaca, \ | ||
67 | .reg_save_ptr = &paca[number].reg_save, \ | ||
68 | .reg_save = { \ | ||
69 | .xDesc = 0xd397d9e2, /* "LpRS" */ \ | ||
70 | .xSize = sizeof(struct ItLpRegSave) \ | ||
71 | } | ||
72 | |||
73 | #define PACA_INIT(number) \ | ||
74 | { \ | ||
75 | PACA_INIT_COMMON(number, 0, 0, 0) \ | ||
76 | PACA_INIT_ISERIES(number) \ | ||
77 | } | ||
78 | |||
79 | #define BOOTCPU_PACA_INIT(number) \ | ||
80 | { \ | ||
81 | PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ | ||
82 | PACA_INIT_ISERIES(number) \ | ||
83 | } | ||
84 | |||
83 | #else | 85 | #else |
84 | PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR), | 86 | #define PACA_INIT(number) \ |
87 | { \ | ||
88 | PACA_INIT_COMMON(number, 0, 0, 0) \ | ||
89 | } | ||
90 | |||
91 | #define BOOTCPU_PACA_INIT(number) \ | ||
92 | { \ | ||
93 | PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ | ||
94 | } | ||
85 | #endif | 95 | #endif |
96 | |||
97 | struct paca_struct paca[] = { | ||
98 | BOOTCPU_PACA_INIT(0), | ||
86 | #if NR_CPUS > 1 | 99 | #if NR_CPUS > 1 |
87 | PACAINITDATA( 1, 0, NULL, 0, 0), | 100 | PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), |
88 | PACAINITDATA( 2, 0, NULL, 0, 0), | ||
89 | PACAINITDATA( 3, 0, NULL, 0, 0), | ||
90 | #if NR_CPUS > 4 | 101 | #if NR_CPUS > 4 |
91 | PACAINITDATA( 4, 0, NULL, 0, 0), | 102 | PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7), |
92 | PACAINITDATA( 5, 0, NULL, 0, 0), | ||
93 | PACAINITDATA( 6, 0, NULL, 0, 0), | ||
94 | PACAINITDATA( 7, 0, NULL, 0, 0), | ||
95 | #if NR_CPUS > 8 | 103 | #if NR_CPUS > 8 |
96 | PACAINITDATA( 8, 0, NULL, 0, 0), | 104 | PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11), |
97 | PACAINITDATA( 9, 0, NULL, 0, 0), | 105 | PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15), |
98 | PACAINITDATA(10, 0, NULL, 0, 0), | 106 | PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19), |
99 | PACAINITDATA(11, 0, NULL, 0, 0), | 107 | PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23), |
100 | PACAINITDATA(12, 0, NULL, 0, 0), | 108 | PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27), |
101 | PACAINITDATA(13, 0, NULL, 0, 0), | 109 | PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31), |
102 | PACAINITDATA(14, 0, NULL, 0, 0), | ||
103 | PACAINITDATA(15, 0, NULL, 0, 0), | ||
104 | PACAINITDATA(16, 0, NULL, 0, 0), | ||
105 | PACAINITDATA(17, 0, NULL, 0, 0), | ||
106 | PACAINITDATA(18, 0, NULL, 0, 0), | ||
107 | PACAINITDATA(19, 0, NULL, 0, 0), | ||
108 | PACAINITDATA(20, 0, NULL, 0, 0), | ||
109 | PACAINITDATA(21, 0, NULL, 0, 0), | ||
110 | PACAINITDATA(22, 0, NULL, 0, 0), | ||
111 | PACAINITDATA(23, 0, NULL, 0, 0), | ||
112 | PACAINITDATA(24, 0, NULL, 0, 0), | ||
113 | PACAINITDATA(25, 0, NULL, 0, 0), | ||
114 | PACAINITDATA(26, 0, NULL, 0, 0), | ||
115 | PACAINITDATA(27, 0, NULL, 0, 0), | ||
116 | PACAINITDATA(28, 0, NULL, 0, 0), | ||
117 | PACAINITDATA(29, 0, NULL, 0, 0), | ||
118 | PACAINITDATA(30, 0, NULL, 0, 0), | ||
119 | PACAINITDATA(31, 0, NULL, 0, 0), | ||
120 | #if NR_CPUS > 32 | 110 | #if NR_CPUS > 32 |
121 | PACAINITDATA(32, 0, NULL, 0, 0), | 111 | PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35), |
122 | PACAINITDATA(33, 0, NULL, 0, 0), | 112 | PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39), |
123 | PACAINITDATA(34, 0, NULL, 0, 0), | 113 | PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43), |
124 | PACAINITDATA(35, 0, NULL, 0, 0), | 114 | PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47), |
125 | PACAINITDATA(36, 0, NULL, 0, 0), | 115 | PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51), |
126 | PACAINITDATA(37, 0, NULL, 0, 0), | 116 | PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55), |
127 | PACAINITDATA(38, 0, NULL, 0, 0), | 117 | PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59), |
128 | PACAINITDATA(39, 0, NULL, 0, 0), | 118 | PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63), |
129 | PACAINITDATA(40, 0, NULL, 0, 0), | ||
130 | PACAINITDATA(41, 0, NULL, 0, 0), | ||
131 | PACAINITDATA(42, 0, NULL, 0, 0), | ||
132 | PACAINITDATA(43, 0, NULL, 0, 0), | ||
133 | PACAINITDATA(44, 0, NULL, 0, 0), | ||
134 | PACAINITDATA(45, 0, NULL, 0, 0), | ||
135 | PACAINITDATA(46, 0, NULL, 0, 0), | ||
136 | PACAINITDATA(47, 0, NULL, 0, 0), | ||
137 | PACAINITDATA(48, 0, NULL, 0, 0), | ||
138 | PACAINITDATA(49, 0, NULL, 0, 0), | ||
139 | PACAINITDATA(50, 0, NULL, 0, 0), | ||
140 | PACAINITDATA(51, 0, NULL, 0, 0), | ||
141 | PACAINITDATA(52, 0, NULL, 0, 0), | ||
142 | PACAINITDATA(53, 0, NULL, 0, 0), | ||
143 | PACAINITDATA(54, 0, NULL, 0, 0), | ||
144 | PACAINITDATA(55, 0, NULL, 0, 0), | ||
145 | PACAINITDATA(56, 0, NULL, 0, 0), | ||
146 | PACAINITDATA(57, 0, NULL, 0, 0), | ||
147 | PACAINITDATA(58, 0, NULL, 0, 0), | ||
148 | PACAINITDATA(59, 0, NULL, 0, 0), | ||
149 | PACAINITDATA(60, 0, NULL, 0, 0), | ||
150 | PACAINITDATA(61, 0, NULL, 0, 0), | ||
151 | PACAINITDATA(62, 0, NULL, 0, 0), | ||
152 | PACAINITDATA(63, 0, NULL, 0, 0), | ||
153 | #if NR_CPUS > 64 | 119 | #if NR_CPUS > 64 |
154 | PACAINITDATA(64, 0, NULL, 0, 0), | 120 | PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67), |
155 | PACAINITDATA(65, 0, NULL, 0, 0), | 121 | PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71), |
156 | PACAINITDATA(66, 0, NULL, 0, 0), | 122 | PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75), |
157 | PACAINITDATA(67, 0, NULL, 0, 0), | 123 | PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79), |
158 | PACAINITDATA(68, 0, NULL, 0, 0), | 124 | PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83), |
159 | PACAINITDATA(69, 0, NULL, 0, 0), | 125 | PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87), |
160 | PACAINITDATA(70, 0, NULL, 0, 0), | 126 | PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91), |
161 | PACAINITDATA(71, 0, NULL, 0, 0), | 127 | PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95), |
162 | PACAINITDATA(72, 0, NULL, 0, 0), | 128 | PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99), |
163 | PACAINITDATA(73, 0, NULL, 0, 0), | 129 | PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103), |
164 | PACAINITDATA(74, 0, NULL, 0, 0), | 130 | PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107), |
165 | PACAINITDATA(75, 0, NULL, 0, 0), | 131 | PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111), |
166 | PACAINITDATA(76, 0, NULL, 0, 0), | 132 | PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115), |
167 | PACAINITDATA(77, 0, NULL, 0, 0), | 133 | PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119), |
168 | PACAINITDATA(78, 0, NULL, 0, 0), | 134 | PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123), |
169 | PACAINITDATA(79, 0, NULL, 0, 0), | 135 | PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127), |
170 | PACAINITDATA(80, 0, NULL, 0, 0), | ||
171 | PACAINITDATA(81, 0, NULL, 0, 0), | ||
172 | PACAINITDATA(82, 0, NULL, 0, 0), | ||
173 | PACAINITDATA(83, 0, NULL, 0, 0), | ||
174 | PACAINITDATA(84, 0, NULL, 0, 0), | ||
175 | PACAINITDATA(85, 0, NULL, 0, 0), | ||
176 | PACAINITDATA(86, 0, NULL, 0, 0), | ||
177 | PACAINITDATA(87, 0, NULL, 0, 0), | ||
178 | PACAINITDATA(88, 0, NULL, 0, 0), | ||
179 | PACAINITDATA(89, 0, NULL, 0, 0), | ||
180 | PACAINITDATA(90, 0, NULL, 0, 0), | ||
181 | PACAINITDATA(91, 0, NULL, 0, 0), | ||
182 | PACAINITDATA(92, 0, NULL, 0, 0), | ||
183 | PACAINITDATA(93, 0, NULL, 0, 0), | ||
184 | PACAINITDATA(94, 0, NULL, 0, 0), | ||
185 | PACAINITDATA(95, 0, NULL, 0, 0), | ||
186 | PACAINITDATA(96, 0, NULL, 0, 0), | ||
187 | PACAINITDATA(97, 0, NULL, 0, 0), | ||
188 | PACAINITDATA(98, 0, NULL, 0, 0), | ||
189 | PACAINITDATA(99, 0, NULL, 0, 0), | ||
190 | PACAINITDATA(100, 0, NULL, 0, 0), | ||
191 | PACAINITDATA(101, 0, NULL, 0, 0), | ||
192 | PACAINITDATA(102, 0, NULL, 0, 0), | ||
193 | PACAINITDATA(103, 0, NULL, 0, 0), | ||
194 | PACAINITDATA(104, 0, NULL, 0, 0), | ||
195 | PACAINITDATA(105, 0, NULL, 0, 0), | ||
196 | PACAINITDATA(106, 0, NULL, 0, 0), | ||
197 | PACAINITDATA(107, 0, NULL, 0, 0), | ||
198 | PACAINITDATA(108, 0, NULL, 0, 0), | ||
199 | PACAINITDATA(109, 0, NULL, 0, 0), | ||
200 | PACAINITDATA(110, 0, NULL, 0, 0), | ||
201 | PACAINITDATA(111, 0, NULL, 0, 0), | ||
202 | PACAINITDATA(112, 0, NULL, 0, 0), | ||
203 | PACAINITDATA(113, 0, NULL, 0, 0), | ||
204 | PACAINITDATA(114, 0, NULL, 0, 0), | ||
205 | PACAINITDATA(115, 0, NULL, 0, 0), | ||
206 | PACAINITDATA(116, 0, NULL, 0, 0), | ||
207 | PACAINITDATA(117, 0, NULL, 0, 0), | ||
208 | PACAINITDATA(118, 0, NULL, 0, 0), | ||
209 | PACAINITDATA(119, 0, NULL, 0, 0), | ||
210 | PACAINITDATA(120, 0, NULL, 0, 0), | ||
211 | PACAINITDATA(121, 0, NULL, 0, 0), | ||
212 | PACAINITDATA(122, 0, NULL, 0, 0), | ||
213 | PACAINITDATA(123, 0, NULL, 0, 0), | ||
214 | PACAINITDATA(124, 0, NULL, 0, 0), | ||
215 | PACAINITDATA(125, 0, NULL, 0, 0), | ||
216 | PACAINITDATA(126, 0, NULL, 0, 0), | ||
217 | PACAINITDATA(127, 0, NULL, 0, 0), | ||
218 | #endif | 136 | #endif |
219 | #endif | 137 | #endif |
220 | #endif | 138 | #endif |
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index c8fa6569b2fd..2f704a2cafb1 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c | |||
@@ -400,7 +400,12 @@ static int __init topology_init(void) | |||
400 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 400 | struct cpu *c = &per_cpu(cpu_devices, cpu); |
401 | 401 | ||
402 | #ifdef CONFIG_NUMA | 402 | #ifdef CONFIG_NUMA |
403 | parent = &node_devices[cpu_to_node(cpu)]; | 403 | /* The node to which a cpu belongs can't be known |
404 | * until the cpu is made present. | ||
405 | */ | ||
406 | parent = NULL; | ||
407 | if (cpu_present(cpu)) | ||
408 | parent = &node_devices[cpu_to_node(cpu)]; | ||
404 | #endif | 409 | #endif |
405 | /* | 410 | /* |
406 | * For now, we just see if the system supports making | 411 | * For now, we just see if the system supports making |
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 2a532db9138a..909462e1adea 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
@@ -99,7 +99,6 @@ unsigned long tb_to_ns_shift; | |||
99 | struct gettimeofday_struct do_gtod; | 99 | struct gettimeofday_struct do_gtod; |
100 | 100 | ||
101 | extern unsigned long wall_jiffies; | 101 | extern unsigned long wall_jiffies; |
102 | extern unsigned long lpevent_count; | ||
103 | extern int smp_tb_synchronized; | 102 | extern int smp_tb_synchronized; |
104 | 103 | ||
105 | extern struct timezone sys_tz; | 104 | extern struct timezone sys_tz; |
@@ -367,11 +366,8 @@ int timer_interrupt(struct pt_regs * regs) | |||
367 | set_dec(next_dec); | 366 | set_dec(next_dec); |
368 | 367 | ||
369 | #ifdef CONFIG_PPC_ISERIES | 368 | #ifdef CONFIG_PPC_ISERIES |
370 | { | 369 | if (hvlpevent_is_pending()) |
371 | struct ItLpQueue *lpq = lpaca->lpqueue_ptr; | 370 | process_hvlpevents(regs); |
372 | if (lpq && ItLpQueue_isLpIntPending(lpq)) | ||
373 | lpevent_count += ItLpQueue_process(lpq, regs); | ||
374 | } | ||
375 | #endif | 371 | #endif |
376 | 372 | ||
377 | /* collect purr register values often, for accurate calculations */ | 373 | /* collect purr register values often, for accurate calculations */ |