diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-18 13:34:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-18 13:34:24 -0400 |
commit | 6fbe85f914ad08cc43408a40ad18a561222e1b93 (patch) | |
tree | 320da01ba20dcbf6d31d80d35b1217193d663814 /arch | |
parent | a9a5cd5d2a57fb76dbae2115450f777b69beccf7 (diff) | |
parent | f39224a8c1828bdd327539da72a53d8a13595838 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge:
powerpc: Use correct sequence for putting CPU into nap mode
[PATCH] spufs: fix context-switch decrementer code
[PATCH] powerpc32: Set cpu explicitly in kernel compiles
[PATCH] powerpc/pseries: bugfix: balance calls to pci_device_put
[PATCH] powerpc: Fix machine detection in prom_init.c
[PATCH] ppc32: Fix string comparing in platform_notify_map
[PATCH] powerpc: Avoid __initcall warnings
[PATCH] powerpc: Ensure runlatch is off in the idle loop
powerpc: Fix CHRP booting - needs a define_machine call
powerpc: iSeries has only 256 IRQs
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/Kconfig | 6 | ||||
-rw-r--r-- | arch/powerpc/Makefile | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 35 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 49 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_6xx.S | 63 | ||||
-rw-r--r-- | arch/powerpc/kernel/idle_power4.S | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 36 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas-proc.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/switch.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/chrp/chrp.h | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/chrp/pci.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/chrp/setup.c | 44 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/setup.c | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/rtasd.c | 2 | ||||
-rw-r--r-- | arch/ppc/syslib/ppc_sys.c | 9 |
20 files changed, 176 insertions, 120 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 167e70e95556..6729c98b66f9 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -366,6 +366,7 @@ config PPC_PMAC64 | |||
366 | select U3_DART | 366 | select U3_DART |
367 | select MPIC_BROKEN_U3 | 367 | select MPIC_BROKEN_U3 |
368 | select GENERIC_TBSYNC | 368 | select GENERIC_TBSYNC |
369 | select PPC_970_NAP | ||
369 | default y | 370 | default y |
370 | 371 | ||
371 | config PPC_PREP | 372 | config PPC_PREP |
@@ -383,6 +384,7 @@ config PPC_MAPLE | |||
383 | select MPIC_BROKEN_U3 | 384 | select MPIC_BROKEN_U3 |
384 | select GENERIC_TBSYNC | 385 | select GENERIC_TBSYNC |
385 | select PPC_UDBG_16550 | 386 | select PPC_UDBG_16550 |
387 | select PPC_970_NAP | ||
386 | default n | 388 | default n |
387 | help | 389 | help |
388 | This option enables support for the Maple 970FX Evaluation Board. | 390 | This option enables support for the Maple 970FX Evaluation Board. |
@@ -457,6 +459,10 @@ config PPC_MPC106 | |||
457 | bool | 459 | bool |
458 | default n | 460 | default n |
459 | 461 | ||
462 | config PPC_970_NAP | ||
463 | bool | ||
464 | default n | ||
465 | |||
460 | source "drivers/cpufreq/Kconfig" | 466 | source "drivers/cpufreq/Kconfig" |
461 | 467 | ||
462 | config CPU_FREQ_PMAC | 468 | config CPU_FREQ_PMAC |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6ec84d37a337..ed5b26aa8be3 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -104,6 +104,10 @@ ifndef CONFIG_FSL_BOOKE | |||
104 | CFLAGS += -mstring | 104 | CFLAGS += -mstring |
105 | endif | 105 | endif |
106 | 106 | ||
107 | ifeq ($(CONFIG_6xx),y) | ||
108 | CFLAGS += -mcpu=powerpc | ||
109 | endif | ||
110 | |||
107 | cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge | 111 | cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge |
108 | cpu-as-$(CONFIG_4xx) += -Wa,-m405 | 112 | cpu-as-$(CONFIG_4xx) += -Wa,-m405 |
109 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec | 113 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 0cc0995b81b0..803858e86160 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -20,7 +20,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | |||
20 | firmware.o sysfs.o | 20 | firmware.o sysfs.o |
21 | obj-$(CONFIG_PPC64) += vdso64/ | 21 | obj-$(CONFIG_PPC64) += vdso64/ |
22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
23 | obj-$(CONFIG_POWER4) += idle_power4.o | 23 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o | 24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o |
25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 54b48f330051..8f85c5e8a55a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -91,6 +91,7 @@ int main(void) | |||
91 | #endif /* CONFIG_PPC64 */ | 91 | #endif /* CONFIG_PPC64 */ |
92 | 92 | ||
93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
94 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); | ||
94 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); | 95 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); |
95 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | 96 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); |
96 | #ifdef CONFIG_PPC32 | 97 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index b3a979467225..8866fd26c6b9 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -128,37 +128,36 @@ transfer_to_handler: | |||
128 | stw r12,4(r11) | 128 | stw r12,4(r11) |
129 | #endif | 129 | #endif |
130 | b 3f | 130 | b 3f |
131 | |||
131 | 2: /* if from kernel, check interrupted DOZE/NAP mode and | 132 | 2: /* if from kernel, check interrupted DOZE/NAP mode and |
132 | * check for stack overflow | 133 | * check for stack overflow |
133 | */ | 134 | */ |
135 | lwz r9,THREAD_INFO-THREAD(r12) | ||
136 | cmplw r1,r9 /* if r1 <= current->thread_info */ | ||
137 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
138 | 5: | ||
134 | #ifdef CONFIG_6xx | 139 | #ifdef CONFIG_6xx |
135 | mfspr r11,SPRN_HID0 | 140 | tophys(r9,r9) /* check local flags */ |
136 | mtcr r11 | 141 | lwz r12,TI_LOCAL_FLAGS(r9) |
137 | BEGIN_FTR_SECTION | 142 | mtcrf 0x01,r12 |
138 | bt- 8,4f /* Check DOZE */ | 143 | bt- 31-TLF_NAPPING,4f |
139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
140 | BEGIN_FTR_SECTION | ||
141 | bt- 9,4f /* Check NAP */ | ||
142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
143 | #endif /* CONFIG_6xx */ | 144 | #endif /* CONFIG_6xx */ |
144 | .globl transfer_to_handler_cont | 145 | .globl transfer_to_handler_cont |
145 | transfer_to_handler_cont: | 146 | transfer_to_handler_cont: |
146 | lwz r11,THREAD_INFO-THREAD(r12) | ||
147 | cmplw r1,r11 /* if r1 <= current->thread_info */ | ||
148 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
149 | 3: | 147 | 3: |
150 | mflr r9 | 148 | mflr r9 |
151 | lwz r11,0(r9) /* virtual address of handler */ | 149 | lwz r11,0(r9) /* virtual address of handler */ |
152 | lwz r9,4(r9) /* where to go when done */ | 150 | lwz r9,4(r9) /* where to go when done */ |
153 | FIX_SRR1(r10,r12) | ||
154 | mtspr SPRN_SRR0,r11 | 151 | mtspr SPRN_SRR0,r11 |
155 | mtspr SPRN_SRR1,r10 | 152 | mtspr SPRN_SRR1,r10 |
156 | mtlr r9 | 153 | mtlr r9 |
157 | SYNC | 154 | SYNC |
158 | RFI /* jump to handler, enable MMU */ | 155 | RFI /* jump to handler, enable MMU */ |
159 | 156 | ||
160 | #ifdef CONFIG_6xx | 157 | #ifdef CONFIG_6xx |
161 | 4: b power_save_6xx_restore | 158 | 4: rlwinm r12,r12,0,~_TLF_NAPPING |
159 | stw r12,TI_LOCAL_FLAGS(r9) | ||
160 | b power_save_6xx_restore | ||
162 | #endif | 161 | #endif |
163 | 162 | ||
164 | /* | 163 | /* |
@@ -167,10 +166,10 @@ transfer_to_handler_cont: | |||
167 | */ | 166 | */ |
168 | stack_ovf: | 167 | stack_ovf: |
169 | /* sometimes we use a statically-allocated stack, which is OK. */ | 168 | /* sometimes we use a statically-allocated stack, which is OK. */ |
170 | lis r11,_end@h | 169 | lis r12,_end@h |
171 | ori r11,r11,_end@l | 170 | ori r12,r12,_end@l |
172 | cmplw r1,r11 | 171 | cmplw r1,r12 |
173 | ble 3b /* r1 <= &_end is OK */ | 172 | ble 5b /* r1 <= &_end is OK */ |
174 | SAVE_NVGPRS(r11) | 173 | SAVE_NVGPRS(r11) |
175 | addi r3,r1,STACK_FRAME_OVERHEAD | 174 | addi r3,r1,STACK_FRAME_OVERHEAD |
176 | lis r1,init_thread_union@ha | 175 | lis r1,init_thread_union@ha |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index a5ae04a57c78..b7d140430a41 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -376,11 +376,28 @@ label##_common: \ | |||
376 | bl hdlr; \ | 376 | bl hdlr; \ |
377 | b .ret_from_except | 377 | b .ret_from_except |
378 | 378 | ||
379 | /* | ||
380 | * Like STD_EXCEPTION_COMMON, but for exceptions that can occur | ||
381 | * in the idle task and therefore need the special idle handling. | ||
382 | */ | ||
383 | #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \ | ||
384 | .align 7; \ | ||
385 | .globl label##_common; \ | ||
386 | label##_common: \ | ||
387 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | ||
388 | FINISH_NAP; \ | ||
389 | DISABLE_INTS; \ | ||
390 | bl .save_nvgprs; \ | ||
391 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
392 | bl hdlr; \ | ||
393 | b .ret_from_except | ||
394 | |||
379 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ | 395 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ |
380 | .align 7; \ | 396 | .align 7; \ |
381 | .globl label##_common; \ | 397 | .globl label##_common; \ |
382 | label##_common: \ | 398 | label##_common: \ |
383 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | 399 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ |
400 | FINISH_NAP; \ | ||
384 | DISABLE_INTS; \ | 401 | DISABLE_INTS; \ |
385 | bl .ppc64_runlatch_on; \ | 402 | bl .ppc64_runlatch_on; \ |
386 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 403 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -388,6 +405,25 @@ label##_common: \ | |||
388 | b .ret_from_except_lite | 405 | b .ret_from_except_lite |
389 | 406 | ||
390 | /* | 407 | /* |
408 | * When the idle code in power4_idle puts the CPU into NAP mode, | ||
409 | * it has to do so in a loop, and relies on the external interrupt | ||
410 | * and decrementer interrupt entry code to get it out of the loop. | ||
411 | * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags | ||
412 | * to signal that it is in the loop and needs help to get out. | ||
413 | */ | ||
414 | #ifdef CONFIG_PPC_970_NAP | ||
415 | #define FINISH_NAP \ | ||
416 | BEGIN_FTR_SECTION \ | ||
417 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
418 | ld r9,TI_LOCAL_FLAGS(r11); \ | ||
419 | andi. r10,r9,_TLF_NAPPING; \ | ||
420 | bnel power4_fixup_nap; \ | ||
421 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
422 | #else | ||
423 | #define FINISH_NAP | ||
424 | #endif | ||
425 | |||
426 | /* | ||
391 | * Start of pSeries system interrupt routines | 427 | * Start of pSeries system interrupt routines |
392 | */ | 428 | */ |
393 | . = 0x100 | 429 | . = 0x100 |
@@ -772,6 +808,7 @@ hardware_interrupt_iSeries_masked: | |||
772 | .globl machine_check_common | 808 | .globl machine_check_common |
773 | machine_check_common: | 809 | machine_check_common: |
774 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) | 810 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) |
811 | FINISH_NAP | ||
775 | DISABLE_INTS | 812 | DISABLE_INTS |
776 | bl .save_nvgprs | 813 | bl .save_nvgprs |
777 | addi r3,r1,STACK_FRAME_OVERHEAD | 814 | addi r3,r1,STACK_FRAME_OVERHEAD |
@@ -783,7 +820,7 @@ machine_check_common: | |||
783 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 820 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
784 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 821 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
785 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 822 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
786 | STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception) | 823 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) |
787 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 824 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) |
788 | #ifdef CONFIG_ALTIVEC | 825 | #ifdef CONFIG_ALTIVEC |
789 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) | 826 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) |
@@ -1034,6 +1071,7 @@ unrecov_slb: | |||
1034 | .globl hardware_interrupt_entry | 1071 | .globl hardware_interrupt_entry |
1035 | hardware_interrupt_common: | 1072 | hardware_interrupt_common: |
1036 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) | 1073 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) |
1074 | FINISH_NAP | ||
1037 | hardware_interrupt_entry: | 1075 | hardware_interrupt_entry: |
1038 | DISABLE_INTS | 1076 | DISABLE_INTS |
1039 | bl .ppc64_runlatch_on | 1077 | bl .ppc64_runlatch_on |
@@ -1041,6 +1079,15 @@ hardware_interrupt_entry: | |||
1041 | bl .do_IRQ | 1079 | bl .do_IRQ |
1042 | b .ret_from_except_lite | 1080 | b .ret_from_except_lite |
1043 | 1081 | ||
1082 | #ifdef CONFIG_PPC_970_NAP | ||
1083 | power4_fixup_nap: | ||
1084 | andc r9,r9,r10 | ||
1085 | std r9,TI_LOCAL_FLAGS(r11) | ||
1086 | ld r10,_LINK(r1) /* make idle task do the */ | ||
1087 | std r10,_NIP(r1) /* equivalent of a blr */ | ||
1088 | blr | ||
1089 | #endif | ||
1090 | |||
1044 | .align 7 | 1091 | .align 7 |
1045 | .globl alignment_common | 1092 | .globl alignment_common |
1046 | alignment_common: | 1093 | alignment_common: |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index e9f321d74d85..d491052c8e0c 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -50,9 +50,9 @@ void cpu_idle(void) | |||
50 | 50 | ||
51 | set_thread_flag(TIF_POLLING_NRFLAG); | 51 | set_thread_flag(TIF_POLLING_NRFLAG); |
52 | while (1) { | 52 | while (1) { |
53 | ppc64_runlatch_off(); | ||
54 | |||
55 | while (!need_resched() && !cpu_should_die()) { | 53 | while (!need_resched() && !cpu_should_die()) { |
54 | ppc64_runlatch_off(); | ||
55 | |||
56 | if (ppc_md.power_save) { | 56 | if (ppc_md.power_save) { |
57 | clear_thread_flag(TIF_POLLING_NRFLAG); | 57 | clear_thread_flag(TIF_POLLING_NRFLAG); |
58 | /* | 58 | /* |
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index 12a4efbaa08f..b45fa0e37212 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <asm/ppc_asm.h> | 22 | #include <asm/ppc_asm.h> |
23 | #include <asm/asm-offsets.h> | 23 | #include <asm/asm-offsets.h> |
24 | 24 | ||
25 | #undef DEBUG | ||
26 | |||
27 | .text | 25 | .text |
28 | 26 | ||
29 | /* | 27 | /* |
@@ -109,12 +107,6 @@ BEGIN_FTR_SECTION | |||
109 | dcbf 0,r4 | 107 | dcbf 0,r4 |
110 | dcbf 0,r4 | 108 | dcbf 0,r4 |
111 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | 109 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) |
112 | #ifdef DEBUG | ||
113 | lis r6,nap_enter_count@ha | ||
114 | lwz r4,nap_enter_count@l(r6) | ||
115 | addi r4,r4,1 | ||
116 | stw r4,nap_enter_count@l(r6) | ||
117 | #endif | ||
118 | 2: | 110 | 2: |
119 | BEGIN_FTR_SECTION | 111 | BEGIN_FTR_SECTION |
120 | /* Go to low speed mode on some 750FX */ | 112 | /* Go to low speed mode on some 750FX */ |
@@ -144,48 +136,42 @@ BEGIN_FTR_SECTION | |||
144 | DSSALL | 136 | DSSALL |
145 | sync | 137 | sync |
146 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 138 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
139 | rlwinm r9,r1,0,0,31-THREAD_SHIFT /* current thread_info */ | ||
140 | lwz r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
141 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
142 | stw r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
147 | mfmsr r7 | 143 | mfmsr r7 |
148 | ori r7,r7,MSR_EE | 144 | ori r7,r7,MSR_EE |
149 | oris r7,r7,MSR_POW@h | 145 | oris r7,r7,MSR_POW@h |
150 | sync | 146 | 1: sync |
151 | isync | ||
152 | mtmsr r7 | 147 | mtmsr r7 |
153 | isync | 148 | isync |
154 | sync | 149 | b 1b |
155 | blr | 150 | |
156 | |||
157 | /* | 151 | /* |
158 | * Return from NAP/DOZE mode, restore some CPU specific registers, | 152 | * Return from NAP/DOZE mode, restore some CPU specific registers, |
159 | * we are called with DR/IR still off and r2 containing physical | 153 | * we are called with DR/IR still off and r2 containing physical |
160 | * address of current. | 154 | * address of current. R11 points to the exception frame (physical |
155 | * address). We have to preserve r10. | ||
161 | */ | 156 | */ |
162 | _GLOBAL(power_save_6xx_restore) | 157 | _GLOBAL(power_save_6xx_restore) |
163 | mfspr r11,SPRN_HID0 | 158 | lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */ |
164 | rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ | 159 | stw r9,_NIP(r11) /* make it do a blr */ |
165 | cror 4*cr1+eq,4*cr0+eq,4*cr0+eq | ||
166 | BEGIN_FTR_SECTION | ||
167 | rlwinm r11,r11,0,9,7 /* Clear DOZE */ | ||
168 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
169 | mtspr SPRN_HID0, r11 | ||
170 | 160 | ||
171 | #ifdef DEBUG | 161 | #ifdef CONFIG_SMP |
172 | beq cr1,1f | 162 | mfspr r12,SPRN_SPRG3 |
173 | lis r11,(nap_return_count-KERNELBASE)@ha | 163 | lwz r11,TI_CPU(r12) /* get cpu number * 4 */ |
174 | lwz r9,nap_return_count@l(r11) | ||
175 | addi r9,r9,1 | ||
176 | stw r9,nap_return_count@l(r11) | ||
177 | 1: | ||
178 | #endif | ||
179 | |||
180 | rlwinm r9,r1,0,0,18 | ||
181 | tophys(r9,r9) | ||
182 | lwz r11,TI_CPU(r9) | ||
183 | slwi r11,r11,2 | 164 | slwi r11,r11,2 |
165 | #else | ||
166 | li r11,0 | ||
167 | #endif | ||
184 | /* Todo make sure all these are in the same page | 168 | /* Todo make sure all these are in the same page |
185 | * and load r22 (@ha part + CPU offset) only once | 169 | * and load r11 (@ha part + CPU offset) only once |
186 | */ | 170 | */ |
187 | BEGIN_FTR_SECTION | 171 | BEGIN_FTR_SECTION |
188 | beq cr1,1f | 172 | mfspr r9,SPRN_HID0 |
173 | andis. r9,r9,HID0_NAP@h | ||
174 | beq 1f | ||
189 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha | 175 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha |
190 | lwz r9,nap_save_msscr0@l(r9) | 176 | lwz r9,nap_save_msscr0@l(r9) |
191 | mtspr SPRN_MSSCR0, r9 | 177 | mtspr SPRN_MSSCR0, r9 |
@@ -210,10 +196,3 @@ _GLOBAL(nap_save_hid1) | |||
210 | 196 | ||
211 | _GLOBAL(powersave_lowspeed) | 197 | _GLOBAL(powersave_lowspeed) |
212 | .long 0 | 198 | .long 0 |
213 | |||
214 | #ifdef DEBUG | ||
215 | _GLOBAL(nap_enter_count) | ||
216 | .space 4 | ||
217 | _GLOBAL(nap_return_count) | ||
218 | .space 4 | ||
219 | #endif | ||
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 6dad1c02496e..d85c7c938eed 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -35,12 +35,16 @@ BEGIN_FTR_SECTION | |||
35 | DSSALL | 35 | DSSALL |
36 | sync | 36 | sync |
37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
38 | clrrdi r9,r1,THREAD_SHIFT /* current thread_info */ | ||
39 | ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
40 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
41 | std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
38 | mfmsr r7 | 42 | mfmsr r7 |
39 | ori r7,r7,MSR_EE | 43 | ori r7,r7,MSR_EE |
40 | oris r7,r7,MSR_POW@h | 44 | oris r7,r7,MSR_POW@h |
41 | sync | 45 | 1: sync |
42 | isync | 46 | isync |
43 | mtmsrd r7 | 47 | mtmsrd r7 |
44 | isync | 48 | isync |
45 | sync | 49 | b 1b |
46 | blr | 50 | |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bb5c9501234c..57d560c68897 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -272,18 +272,26 @@ unsigned int virt_irq_to_real_map[NR_IRQS]; | |||
272 | * Don't use virtual irqs 0, 1, 2 for devices. | 272 | * Don't use virtual irqs 0, 1, 2 for devices. |
273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, | 273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, |
274 | * and 2 is the XICS IPI interrupt. | 274 | * and 2 is the XICS IPI interrupt. |
275 | * We limit virtual irqs to 17 less than NR_IRQS so that when we | 275 | * We limit virtual irqs to __irq_offet_value less than virt_irq_max so |
276 | * offset them by 16 (to reserve the first 16 for ISA interrupts) | 276 | * that when we offset them we don't end up with an interrupt |
277 | * we don't end up with an interrupt number >= NR_IRQS. | 277 | * number >= virt_irq_max. |
278 | */ | 278 | */ |
279 | #define MIN_VIRT_IRQ 3 | 279 | #define MIN_VIRT_IRQ 3 |
280 | #define MAX_VIRT_IRQ (NR_IRQS - NUM_ISA_INTERRUPTS - 1) | 280 | |
281 | #define NR_VIRT_IRQS (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1) | 281 | unsigned int virt_irq_max; |
282 | static unsigned int max_virt_irq; | ||
283 | static unsigned int nr_virt_irqs; | ||
282 | 284 | ||
283 | void | 285 | void |
284 | virt_irq_init(void) | 286 | virt_irq_init(void) |
285 | { | 287 | { |
286 | int i; | 288 | int i; |
289 | |||
290 | if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1))) | ||
291 | virt_irq_max = NR_IRQS - 1; | ||
292 | max_virt_irq = virt_irq_max - __irq_offset_value; | ||
293 | nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1; | ||
294 | |||
287 | for (i = 0; i < NR_IRQS; i++) | 295 | for (i = 0; i < NR_IRQS; i++) |
288 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; | 296 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; |
289 | } | 297 | } |
@@ -308,17 +316,17 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
308 | return real_irq; | 316 | return real_irq; |
309 | } | 317 | } |
310 | 318 | ||
311 | /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */ | 319 | /* map to a number between MIN_VIRT_IRQ and max_virt_irq */ |
312 | virq = real_irq; | 320 | virq = real_irq; |
313 | if (virq > MAX_VIRT_IRQ) | 321 | if (virq > max_virt_irq) |
314 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 322 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
315 | 323 | ||
316 | /* search for this number or a free slot */ | 324 | /* search for this number or a free slot */ |
317 | first_virq = virq; | 325 | first_virq = virq; |
318 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { | 326 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { |
319 | if (virt_irq_to_real_map[virq] == real_irq) | 327 | if (virt_irq_to_real_map[virq] == real_irq) |
320 | return virq; | 328 | return virq; |
321 | if (++virq > MAX_VIRT_IRQ) | 329 | if (++virq > max_virt_irq) |
322 | virq = MIN_VIRT_IRQ; | 330 | virq = MIN_VIRT_IRQ; |
323 | if (virq == first_virq) | 331 | if (virq == first_virq) |
324 | goto nospace; /* oops, no free slots */ | 332 | goto nospace; /* oops, no free slots */ |
@@ -330,8 +338,8 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
330 | nospace: | 338 | nospace: |
331 | if (!warned) { | 339 | if (!warned) { |
332 | printk(KERN_CRIT "Interrupt table is full\n"); | 340 | printk(KERN_CRIT "Interrupt table is full\n"); |
333 | printk(KERN_CRIT "Increase NR_IRQS (currently %d) " | 341 | printk(KERN_CRIT "Increase virt_irq_max (currently %d) " |
334 | "in your kernel sources and rebuild.\n", NR_IRQS); | 342 | "in your kernel sources and rebuild.\n", virt_irq_max); |
335 | warned = 1; | 343 | warned = 1; |
336 | } | 344 | } |
337 | return NO_IRQ; | 345 | return NO_IRQ; |
@@ -349,8 +357,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
349 | 357 | ||
350 | virq = real_irq; | 358 | virq = real_irq; |
351 | 359 | ||
352 | if (virq > MAX_VIRT_IRQ) | 360 | if (virq > max_virt_irq) |
353 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 361 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
354 | 362 | ||
355 | first_virq = virq; | 363 | first_virq = virq; |
356 | 364 | ||
@@ -360,7 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
360 | 368 | ||
361 | virq++; | 369 | virq++; |
362 | 370 | ||
363 | if (virq >= MAX_VIRT_IRQ) | 371 | if (virq >= max_virt_irq) |
364 | virq = 0; | 372 | virq = 0; |
365 | 373 | ||
366 | } while (first_virq != virq); | 374 | } while (first_virq != virq); |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d66c5e77fcff..7e4d54821a07 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -1528,12 +1528,11 @@ static int __init prom_find_machine_type(void) | |||
1528 | * non-IBM designs ! | 1528 | * non-IBM designs ! |
1529 | * - it has /rtas | 1529 | * - it has /rtas |
1530 | */ | 1530 | */ |
1531 | len = prom_getprop(_prom->root, "model", | 1531 | len = prom_getprop(_prom->root, "device_type", |
1532 | compat, sizeof(compat)-1); | 1532 | compat, sizeof(compat)-1); |
1533 | if (len <= 0) | 1533 | if (len <= 0) |
1534 | return PLATFORM_GENERIC; | 1534 | return PLATFORM_GENERIC; |
1535 | compat[len] = 0; | 1535 | if (strncmp(compat, RELOC("chrp"), 4)) |
1536 | if (strcmp(compat, "chrp")) | ||
1537 | return PLATFORM_GENERIC; | 1536 | return PLATFORM_GENERIC; |
1538 | 1537 | ||
1539 | /* Default to pSeries. We need to know if we are running LPAR */ | 1538 | /* Default to pSeries. We need to know if we are running LPAR */ |
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 456286cf1d14..9c9ad1fa9cce 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c | |||
@@ -258,11 +258,11 @@ static int __init proc_rtas_init(void) | |||
258 | struct proc_dir_entry *entry; | 258 | struct proc_dir_entry *entry; |
259 | 259 | ||
260 | if (!machine_is(pseries)) | 260 | if (!machine_is(pseries)) |
261 | return 1; | 261 | return -ENODEV; |
262 | 262 | ||
263 | rtas_node = of_find_node_by_name(NULL, "rtas"); | 263 | rtas_node = of_find_node_by_name(NULL, "rtas"); |
264 | if (rtas_node == NULL) | 264 | if (rtas_node == NULL) |
265 | return 1; | 265 | return -ENODEV; |
266 | 266 | ||
267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); | 267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); |
268 | if (entry) | 268 | if (entry) |
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 97898d5d34e5..1726bfe38ee0 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -1297,7 +1297,7 @@ static inline void setup_decr(struct spu_state *csa, struct spu *spu) | |||
1297 | cycles_t resume_time = get_cycles(); | 1297 | cycles_t resume_time = get_cycles(); |
1298 | cycles_t delta_time = resume_time - csa->suspend_time; | 1298 | cycles_t delta_time = resume_time - csa->suspend_time; |
1299 | 1299 | ||
1300 | csa->lscsa->decr.slot[0] = delta_time; | 1300 | csa->lscsa->decr.slot[0] -= delta_time; |
1301 | } | 1301 | } |
1302 | } | 1302 | } |
1303 | 1303 | ||
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 63f0aee4c158..996c28744e96 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h | |||
@@ -9,3 +9,4 @@ extern long chrp_time_init(void); | |||
9 | 9 | ||
10 | extern void chrp_find_bridges(void); | 10 | extern void chrp_find_bridges(void); |
11 | extern void chrp_event_scan(unsigned long); | 11 | extern void chrp_event_scan(unsigned long); |
12 | extern void chrp_pcibios_fixup(void); | ||
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 8ef279ad36ad..ac224876ce59 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/grackle.h> | 23 | #include <asm/grackle.h> |
24 | #include <asm/rtas.h> | 24 | #include <asm/rtas.h> |
25 | 25 | ||
26 | #include "chrp.h" | ||
27 | |||
26 | /* LongTrail */ | 28 | /* LongTrail */ |
27 | void __iomem *gg2_pci_config_base; | 29 | void __iomem *gg2_pci_config_base; |
28 | 30 | ||
@@ -314,6 +316,6 @@ chrp_find_bridges(void) | |||
314 | } | 316 | } |
315 | 317 | ||
316 | /* Do not fixup interrupts from OF tree on pegasos */ | 318 | /* Do not fixup interrupts from OF tree on pegasos */ |
317 | if (is_pegasos == 0) | 319 | if (is_pegasos) |
318 | ppc_md.pcibios_fixup = chrp_pcibios_fixup; | 320 | ppc_md.pcibios_fixup = NULL; |
319 | } | 321 | } |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 23a201718704..18d89f38796b 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -440,8 +440,6 @@ void __init chrp_init_IRQ(void) | |||
440 | 440 | ||
441 | if (_chrp_type == _CHRP_Pegasos) | 441 | if (_chrp_type == _CHRP_Pegasos) |
442 | ppc_md.get_irq = i8259_irq; | 442 | ppc_md.get_irq = i8259_irq; |
443 | else | ||
444 | ppc_md.get_irq = mpic_get_irq; | ||
445 | 443 | ||
446 | #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) | 444 | #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) |
447 | /* see if there is a keyboard in the device tree | 445 | /* see if there is a keyboard in the device tree |
@@ -528,26 +526,24 @@ static int __init chrp_probe(void) | |||
528 | /* Assume we have an 8259... */ | 526 | /* Assume we have an 8259... */ |
529 | __irq_offset_value = NUM_ISA_INTERRUPTS; | 527 | __irq_offset_value = NUM_ISA_INTERRUPTS; |
530 | 528 | ||
531 | ppc_md.setup_arch = chrp_setup_arch; | 529 | return 1; |
532 | ppc_md.show_cpuinfo = chrp_show_cpuinfo; | ||
533 | |||
534 | ppc_md.init_IRQ = chrp_init_IRQ; | ||
535 | ppc_md.init = chrp_init2; | ||
536 | |||
537 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
538 | |||
539 | ppc_md.restart = rtas_restart; | ||
540 | ppc_md.power_off = rtas_power_off; | ||
541 | ppc_md.halt = rtas_halt; | ||
542 | |||
543 | ppc_md.time_init = chrp_time_init; | ||
544 | ppc_md.calibrate_decr = generic_calibrate_decr; | ||
545 | |||
546 | /* this may get overridden with rtas routines later... */ | ||
547 | ppc_md.set_rtc_time = chrp_set_rtc_time; | ||
548 | ppc_md.get_rtc_time = chrp_get_rtc_time; | ||
549 | |||
550 | #ifdef CONFIG_SMP | ||
551 | smp_ops = &chrp_smp_ops; | ||
552 | #endif /* CONFIG_SMP */ | ||
553 | } | 530 | } |
531 | |||
532 | define_machine(chrp) { | ||
533 | .name = "CHRP", | ||
534 | .probe = chrp_probe, | ||
535 | .setup_arch = chrp_setup_arch, | ||
536 | .init = chrp_init2, | ||
537 | .show_cpuinfo = chrp_show_cpuinfo, | ||
538 | .init_IRQ = chrp_init_IRQ, | ||
539 | .get_irq = mpic_get_irq, | ||
540 | .pcibios_fixup = chrp_pcibios_fixup, | ||
541 | .restart = rtas_restart, | ||
542 | .power_off = rtas_power_off, | ||
543 | .halt = rtas_halt, | ||
544 | .time_init = chrp_time_init, | ||
545 | .set_rtc_time = chrp_set_rtc_time, | ||
546 | .get_rtc_time = chrp_get_rtc_time, | ||
547 | .calibrate_decr = generic_calibrate_decr, | ||
548 | .phys_mem_access_prot = pci_phys_mem_access_prot, | ||
549 | }; | ||
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 6ce8a404ba6b..a6fd9bedb074 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <asm/iseries/hv_lp_event.h> | 54 | #include <asm/iseries/hv_lp_event.h> |
55 | #include <asm/iseries/lpar_map.h> | 55 | #include <asm/iseries/lpar_map.h> |
56 | #include <asm/udbg.h> | 56 | #include <asm/udbg.h> |
57 | #include <asm/irq.h> | ||
57 | 58 | ||
58 | #include "naca.h" | 59 | #include "naca.h" |
59 | #include "setup.h" | 60 | #include "setup.h" |
@@ -684,6 +685,12 @@ static int __init iseries_probe(void) | |||
684 | powerpc_firmware_features |= FW_FEATURE_ISERIES; | 685 | powerpc_firmware_features |= FW_FEATURE_ISERIES; |
685 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 686 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
686 | 687 | ||
688 | /* | ||
689 | * The Hypervisor only allows us up to 256 interrupt | ||
690 | * sources (the irq number is passed in a u8). | ||
691 | */ | ||
692 | virt_irq_max = 255; | ||
693 | |||
687 | return 1; | 694 | return 1; |
688 | } | 695 | } |
689 | 696 | ||
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 780fb27a0099..32eaddfa5470 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -957,8 +957,10 @@ static void eeh_remove_device(struct pci_dev *dev) | |||
957 | pci_addr_cache_remove_device(dev); | 957 | pci_addr_cache_remove_device(dev); |
958 | 958 | ||
959 | dn = pci_device_to_OF_node(dev); | 959 | dn = pci_device_to_OF_node(dev); |
960 | PCI_DN(dn)->pcidev = NULL; | 960 | if (PCI_DN(dn)->pcidev) { |
961 | pci_dev_put (dev); | 961 | PCI_DN(dn)->pcidev = NULL; |
962 | pci_dev_put (dev); | ||
963 | } | ||
962 | } | 964 | } |
963 | 965 | ||
964 | void eeh_remove_bus_device(struct pci_dev *dev) | 966 | void eeh_remove_bus_device(struct pci_dev *dev) |
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index fcc4d561a236..e0000ce769e5 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c | |||
@@ -488,7 +488,7 @@ static int __init rtas_init(void) | |||
488 | /* No RTAS */ | 488 | /* No RTAS */ |
489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { | 489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { |
490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); | 490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); |
491 | return 1; | 491 | return -ENODEV; |
492 | } | 492 | } |
493 | 493 | ||
494 | entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); | 494 | entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); |
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c index 60c724e11584..7662c4e6e7d6 100644 --- a/arch/ppc/syslib/ppc_sys.c +++ b/arch/ppc/syslib/ppc_sys.c | |||
@@ -156,12 +156,13 @@ void platform_notify_map(const struct platform_notify_dev_map *map, | |||
156 | while (map->bus_id != NULL) { | 156 | while (map->bus_id != NULL) { |
157 | idx = -1; | 157 | idx = -1; |
158 | s = strrchr(dev->bus_id, '.'); | 158 | s = strrchr(dev->bus_id, '.'); |
159 | if (s != NULL) | 159 | if (s != NULL) { |
160 | idx = (int)simple_strtol(s + 1, NULL, 10); | 160 | idx = (int)simple_strtol(s + 1, NULL, 10); |
161 | else | 161 | len = s - dev->bus_id; |
162 | } else { | ||
162 | s = dev->bus_id; | 163 | s = dev->bus_id; |
163 | 164 | len = strlen(dev->bus_id); | |
164 | len = s - dev->bus_id; | 165 | } |
165 | 166 | ||
166 | if (!strncmp(dev->bus_id, map->bus_id, len)) { | 167 | if (!strncmp(dev->bus_id, map->bus_id, len)) { |
167 | pdev = container_of(dev, struct platform_device, dev); | 168 | pdev = container_of(dev, struct platform_device, dev); |