diff options
| author | Paul Mackerras <paulus@samba.org> | 2006-03-26 23:03:03 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-03-26 23:03:03 -0500 |
| commit | a0652fc9a28c3ef8cd59264bfcb089c44d1b0e06 (patch) | |
| tree | a28527b65237b3067553a993f5ad06dfb24df044 | |
| parent | 55aab8cd3a498201b769a19de861c77516bdfd45 (diff) | |
powerpc: Unify the 32 and 64 bit idle loops
This unifies the 32-bit (ARCH=ppc and ARCH=powerpc) and 64-bit idle
loops. It brings over the concept of having a ppc_md.power_save
function from 32-bit to ARCH=powerpc, which lets us get rid of
native_idle(). With this we will also be able to simplify the idle
handling for pSeries and cell.
Signed-off-by: Paul Mackerras <paulus@samba.org>
| -rw-r--r-- | arch/powerpc/kernel/Makefile | 6 | ||||
| -rw-r--r-- | arch/powerpc/kernel/entry_32.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/idle.c (renamed from arch/powerpc/kernel/idle_64.c) | 79 | ||||
| -rw-r--r-- | arch/powerpc/kernel/idle_6xx.S | 15 | ||||
| -rw-r--r-- | arch/powerpc/kernel/idle_power4.S | 15 | ||||
| -rw-r--r-- | arch/powerpc/kernel/setup_32.c | 7 | ||||
| -rw-r--r-- | arch/powerpc/kernel/setup_64.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/platforms/maple/setup.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 2 | ||||
| -rw-r--r-- | arch/ppc/Makefile | 2 | ||||
| -rw-r--r-- | arch/ppc/kernel/Makefile | 4 | ||||
| -rw-r--r-- | arch/ppc/kernel/entry.S | 8 | ||||
| -rw-r--r-- | arch/ppc/kernel/idle.c | 112 | ||||
| -rw-r--r-- | arch/ppc/kernel/idle_6xx.S | 233 | ||||
| -rw-r--r-- | arch/ppc/kernel/idle_power4.S | 91 | ||||
| -rw-r--r-- | include/asm-powerpc/machdep.h | 13 | ||||
| -rw-r--r-- | include/asm-powerpc/reg.h | 4 | ||||
| -rw-r--r-- | include/asm-ppc/machdep.h | 2 |
18 files changed, 74 insertions, 535 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 80e9fe2632b8..f2c47e907037 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -12,12 +12,12 @@ endif | |||
| 12 | 12 | ||
| 13 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ | 13 | obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ |
| 14 | irq.o align.o signal_32.o pmc.o vdso.o \ | 14 | irq.o align.o signal_32.o pmc.o vdso.o \ |
| 15 | init_task.o process.o systbl.o | 15 | init_task.o process.o systbl.o idle.o |
| 16 | obj-y += vdso32/ | 16 | obj-y += vdso32/ |
| 17 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | 17 | obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ |
| 18 | signal_64.o ptrace32.o \ | 18 | signal_64.o ptrace32.o \ |
| 19 | paca.o cpu_setup_power4.o \ | 19 | paca.o cpu_setup_power4.o \ |
| 20 | firmware.o sysfs.o idle_64.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_POWER4) += idle_power4.o |
| @@ -34,6 +34,7 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o | |||
| 34 | obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o | 34 | obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o |
| 35 | obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o | 35 | obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o |
| 36 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 36 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
| 37 | obj-$(CONFIG_6xx) += idle_6xx.o | ||
| 37 | 38 | ||
| 38 | ifeq ($(CONFIG_PPC_MERGE),y) | 39 | ifeq ($(CONFIG_PPC_MERGE),y) |
| 39 | 40 | ||
| @@ -51,7 +52,6 @@ obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o | |||
| 51 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o | 52 | obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o |
| 52 | obj-$(CONFIG_MODULES) += ppc_ksyms.o | 53 | obj-$(CONFIG_MODULES) += ppc_ksyms.o |
| 53 | obj-$(CONFIG_BOOTX_TEXT) += btext.o | 54 | obj-$(CONFIG_BOOTX_TEXT) += btext.o |
| 54 | obj-$(CONFIG_6xx) += idle_6xx.o | ||
| 55 | obj-$(CONFIG_SMP) += smp.o | 55 | obj-$(CONFIG_SMP) += smp.o |
| 56 | obj-$(CONFIG_KPROBES) += kprobes.o | 56 | obj-$(CONFIG_KPROBES) += kprobes.o |
| 57 | obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o | 57 | obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 4827ca1ec89b..b3a979467225 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
| @@ -135,10 +135,10 @@ transfer_to_handler: | |||
| 135 | mfspr r11,SPRN_HID0 | 135 | mfspr r11,SPRN_HID0 |
| 136 | mtcr r11 | 136 | mtcr r11 |
| 137 | BEGIN_FTR_SECTION | 137 | BEGIN_FTR_SECTION |
| 138 | bt- 8,power_save_6xx_restore /* Check DOZE */ | 138 | bt- 8,4f /* Check DOZE */ |
| 139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | 139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) |
| 140 | BEGIN_FTR_SECTION | 140 | BEGIN_FTR_SECTION |
| 141 | bt- 9,power_save_6xx_restore /* Check NAP */ | 141 | bt- 9,4f /* Check NAP */ |
| 142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | 142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) |
| 143 | #endif /* CONFIG_6xx */ | 143 | #endif /* CONFIG_6xx */ |
| 144 | .globl transfer_to_handler_cont | 144 | .globl transfer_to_handler_cont |
| @@ -157,6 +157,10 @@ transfer_to_handler_cont: | |||
| 157 | SYNC | 157 | SYNC |
| 158 | RFI /* jump to handler, enable MMU */ | 158 | RFI /* jump to handler, enable MMU */ |
| 159 | 159 | ||
| 160 | #ifdef CONFIG_6xx | ||
| 161 | 4: b power_save_6xx_restore | ||
| 162 | #endif | ||
| 163 | |||
| 160 | /* | 164 | /* |
| 161 | * On kernel stack overflow, load up an initial stack pointer | 165 | * On kernel stack overflow, load up an initial stack pointer |
| 162 | * and call StackOverflow(regs), which should not return. | 166 | * and call StackOverflow(regs), which should not return. |
diff --git a/arch/powerpc/kernel/idle_64.c b/arch/powerpc/kernel/idle.c index b879d3057ef8..e9f321d74d85 100644 --- a/arch/powerpc/kernel/idle_64.c +++ b/arch/powerpc/kernel/idle.c | |||
| @@ -2,13 +2,17 @@ | |||
| 2 | * Idle daemon for PowerPC. Idle daemon will handle any action | 2 | * Idle daemon for PowerPC. Idle daemon will handle any action |
| 3 | * that needs to be taken when the system becomes idle. | 3 | * that needs to be taken when the system becomes idle. |
| 4 | * | 4 | * |
| 5 | * Originally Written by Cort Dougan (cort@cs.nmt.edu) | 5 | * Originally written by Cort Dougan (cort@cs.nmt.edu). |
| 6 | * Subsequent 32-bit hacking by Tom Rini, Armin Kuster, | ||
| 7 | * Paul Mackerras and others. | ||
| 6 | * | 8 | * |
| 7 | * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com> | 9 | * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com> |
| 8 | * | 10 | * |
| 9 | * Additional shared processor, SMT, and firmware support | 11 | * Additional shared processor, SMT, and firmware support |
| 10 | * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com> | 12 | * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com> |
| 11 | * | 13 | * |
| 14 | * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org> | ||
| 15 | * | ||
| 12 | * This program is free software; you can redistribute it and/or | 16 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License | 17 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version | 18 | * as published by the Free Software Foundation; either version |
| @@ -29,18 +33,43 @@ | |||
| 29 | #include <asm/machdep.h> | 33 | #include <asm/machdep.h> |
| 30 | #include <asm/smp.h> | 34 | #include <asm/smp.h> |
| 31 | 35 | ||
| 32 | extern void power4_idle(void); | 36 | #ifdef CONFIG_HOTPLUG_CPU |
| 37 | #define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \ | ||
| 38 | system_state == SYSTEM_RUNNING) | ||
| 39 | #else | ||
| 40 | #define cpu_should_die() 0 | ||
| 41 | #endif | ||
| 33 | 42 | ||
| 34 | void default_idle(void) | 43 | /* |
| 44 | * The body of the idle task. | ||
| 45 | */ | ||
| 46 | void cpu_idle(void) | ||
| 35 | { | 47 | { |
| 36 | unsigned int cpu = smp_processor_id(); | 48 | if (ppc_md.idle_loop) |
| 37 | set_thread_flag(TIF_POLLING_NRFLAG); | 49 | ppc_md.idle_loop(); /* doesn't return */ |
| 38 | 50 | ||
| 51 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 39 | while (1) { | 52 | while (1) { |
| 40 | if (!need_resched()) { | 53 | ppc64_runlatch_off(); |
| 41 | while (!need_resched() && !cpu_is_offline(cpu)) { | ||
| 42 | ppc64_runlatch_off(); | ||
| 43 | 54 | ||
| 55 | while (!need_resched() && !cpu_should_die()) { | ||
| 56 | if (ppc_md.power_save) { | ||
| 57 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
| 58 | /* | ||
| 59 | * smp_mb is so clearing of TIF_POLLING_NRFLAG | ||
| 60 | * is ordered w.r.t. need_resched() test. | ||
| 61 | */ | ||
| 62 | smp_mb(); | ||
| 63 | local_irq_disable(); | ||
| 64 | |||
| 65 | /* check again after disabling irqs */ | ||
| 66 | if (!need_resched() && !cpu_should_die()) | ||
| 67 | ppc_md.power_save(); | ||
| 68 | |||
| 69 | local_irq_enable(); | ||
| 70 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 71 | |||
| 72 | } else { | ||
| 44 | /* | 73 | /* |
| 45 | * Go into low thread priority and possibly | 74 | * Go into low thread priority and possibly |
| 46 | * low power mode. | 75 | * low power mode. |
| @@ -48,46 +77,18 @@ void default_idle(void) | |||
| 48 | HMT_low(); | 77 | HMT_low(); |
| 49 | HMT_very_low(); | 78 | HMT_very_low(); |
| 50 | } | 79 | } |
| 51 | |||
| 52 | HMT_medium(); | ||
| 53 | } | 80 | } |
| 54 | 81 | ||
| 82 | HMT_medium(); | ||
| 55 | ppc64_runlatch_on(); | 83 | ppc64_runlatch_on(); |
| 84 | if (cpu_should_die()) | ||
| 85 | cpu_die(); | ||
| 56 | preempt_enable_no_resched(); | 86 | preempt_enable_no_resched(); |
| 57 | schedule(); | 87 | schedule(); |
| 58 | preempt_disable(); | 88 | preempt_disable(); |
| 59 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) | ||
| 60 | cpu_die(); | ||
| 61 | } | 89 | } |
| 62 | } | 90 | } |
| 63 | 91 | ||
| 64 | void native_idle(void) | ||
| 65 | { | ||
| 66 | while (1) { | ||
| 67 | ppc64_runlatch_off(); | ||
| 68 | |||
| 69 | if (!need_resched()) | ||
| 70 | power4_idle(); | ||
| 71 | |||
| 72 | if (need_resched()) { | ||
| 73 | ppc64_runlatch_on(); | ||
| 74 | preempt_enable_no_resched(); | ||
| 75 | schedule(); | ||
| 76 | preempt_disable(); | ||
| 77 | } | ||
| 78 | |||
| 79 | if (cpu_is_offline(smp_processor_id()) && | ||
| 80 | system_state == SYSTEM_RUNNING) | ||
| 81 | cpu_die(); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | void cpu_idle(void) | ||
| 86 | { | ||
| 87 | BUG_ON(NULL == ppc_md.idle_loop); | ||
| 88 | ppc_md.idle_loop(); | ||
| 89 | } | ||
| 90 | |||
| 91 | int powersave_nap; | 92 | int powersave_nap; |
| 92 | 93 | ||
| 93 | #ifdef CONFIG_SYSCTL | 94 | #ifdef CONFIG_SYSCTL |
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index 444fdcc769f1..1647ea361ef7 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S | |||
| @@ -87,19 +87,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | |||
| 87 | cmpwi 0,r3,0 | 87 | cmpwi 0,r3,0 |
| 88 | beqlr | 88 | beqlr |
| 89 | 89 | ||
| 90 | /* Clear MSR:EE */ | ||
| 91 | mfmsr r7 | ||
| 92 | rlwinm r0,r7,0,17,15 | ||
| 93 | mtmsr r0 | ||
| 94 | |||
| 95 | /* Check current_thread_info()->flags */ | ||
| 96 | rlwinm r4,r1,0,0,18 | ||
| 97 | lwz r4,TI_FLAGS(r4) | ||
| 98 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 99 | beq 1f | ||
| 100 | mtmsr r7 /* out of line this ? */ | ||
| 101 | blr | ||
| 102 | 1: | ||
| 103 | /* Some pre-nap cleanups needed on some CPUs */ | 90 | /* Some pre-nap cleanups needed on some CPUs */ |
| 104 | andis. r0,r3,HID0_NAP@h | 91 | andis. r0,r3,HID0_NAP@h |
| 105 | beq 2f | 92 | beq 2f |
| @@ -220,8 +207,6 @@ _GLOBAL(nap_save_msscr0) | |||
| 220 | _GLOBAL(nap_save_hid1) | 207 | _GLOBAL(nap_save_hid1) |
| 221 | .space 4*NR_CPUS | 208 | .space 4*NR_CPUS |
| 222 | 209 | ||
| 223 | _GLOBAL(powersave_nap) | ||
| 224 | .long 0 | ||
| 225 | _GLOBAL(powersave_lowspeed) | 210 | _GLOBAL(powersave_lowspeed) |
| 226 | .long 0 | 211 | .long 0 |
| 227 | 212 | ||
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index c16b4afab582..692cf2ebe0f4 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
| @@ -49,21 +49,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) | |||
| 49 | cmpwi 0,r4,0 | 49 | cmpwi 0,r4,0 |
| 50 | beqlr | 50 | beqlr |
| 51 | 51 | ||
| 52 | /* Clear MSR:EE */ | ||
| 53 | mfmsr r7 | ||
| 54 | li r4,0 | ||
| 55 | ori r4,r4,MSR_EE | ||
| 56 | andc r0,r7,r4 | ||
| 57 | mtmsrd r0 | ||
| 58 | |||
| 59 | /* Check current_thread_info()->flags */ | ||
| 60 | clrrdi r4,r1,THREAD_SHIFT | ||
| 61 | ld r4,TI_FLAGS(r4) | ||
| 62 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 63 | beq 1f | ||
| 64 | mtmsrd r7 /* out of line this ? */ | ||
| 65 | blr | ||
| 66 | 1: | ||
| 67 | /* Go to NAP now */ | 52 | /* Go to NAP now */ |
| 68 | BEGIN_FTR_SECTION | 53 | BEGIN_FTR_SECTION |
| 69 | DSSALL | 54 | DSSALL |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 676f894c3380..e39f830317a8 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
| @@ -53,9 +53,6 @@ | |||
| 53 | extern void platform_init(void); | 53 | extern void platform_init(void); |
| 54 | extern void bootx_init(unsigned long r4, unsigned long phys); | 54 | extern void bootx_init(unsigned long r4, unsigned long phys); |
| 55 | 55 | ||
| 56 | extern void ppc6xx_idle(void); | ||
| 57 | extern void power4_idle(void); | ||
| 58 | |||
| 59 | boot_infos_t *boot_infos; | 56 | boot_infos_t *boot_infos; |
| 60 | struct ide_machdep_calls ppc_ide_md; | 57 | struct ide_machdep_calls ppc_ide_md; |
| 61 | 58 | ||
| @@ -194,7 +191,9 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) | |||
| 194 | platform_init(); | 191 | platform_init(); |
| 195 | 192 | ||
| 196 | #ifdef CONFIG_6xx | 193 | #ifdef CONFIG_6xx |
| 197 | ppc_md.power_save = ppc6xx_idle; | 194 | if (cpu_has_feature(CPU_FTR_CAN_DOZE) || |
| 195 | cpu_has_feature(CPU_FTR_CAN_NAP)) | ||
| 196 | ppc_md.power_save = ppc6xx_idle; | ||
| 198 | #endif | 197 | #endif |
| 199 | 198 | ||
| 200 | if (ppc_md.progress) | 199 | if (ppc_md.progress) |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 6c9b093c23a5..5b63a861ef43 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -607,12 +607,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 607 | 607 | ||
| 608 | ppc_md.setup_arch(); | 608 | ppc_md.setup_arch(); |
| 609 | 609 | ||
| 610 | /* Use the default idle loop if the platform hasn't provided one. */ | ||
| 611 | if (NULL == ppc_md.idle_loop) { | ||
| 612 | ppc_md.idle_loop = default_idle; | ||
| 613 | printk(KERN_INFO "Using default idle loop\n"); | ||
| 614 | } | ||
| 615 | |||
| 616 | paging_init(); | 610 | paging_init(); |
| 617 | ppc64_boot_msg(0x15, "Setup Done"); | 611 | ppc64_boot_msg(0x15, "Setup Done"); |
| 618 | } | 612 | } |
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index ec5c1e10c407..137d6063182b 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
| @@ -290,7 +290,7 @@ struct machdep_calls __initdata maple_md = { | |||
| 290 | .get_rtc_time = maple_get_rtc_time, | 290 | .get_rtc_time = maple_get_rtc_time, |
| 291 | .calibrate_decr = generic_calibrate_decr, | 291 | .calibrate_decr = generic_calibrate_decr, |
| 292 | .progress = maple_progress, | 292 | .progress = maple_progress, |
| 293 | .idle_loop = native_idle, | 293 | .power_save = power4_idle, |
| 294 | #ifdef CONFIG_KEXEC | 294 | #ifdef CONFIG_KEXEC |
| 295 | .machine_kexec = default_machine_kexec, | 295 | .machine_kexec = default_machine_kexec, |
| 296 | .machine_kexec_prepare = default_machine_kexec_prepare, | 296 | .machine_kexec_prepare = default_machine_kexec_prepare, |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 385aab90c4d2..c2696d00672a 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
| @@ -733,7 +733,7 @@ struct machdep_calls __initdata pmac_md = { | |||
| 733 | .progress = udbg_progress, | 733 | .progress = udbg_progress, |
| 734 | #ifdef CONFIG_PPC64 | 734 | #ifdef CONFIG_PPC64 |
| 735 | .pci_probe_mode = pmac_pci_probe_mode, | 735 | .pci_probe_mode = pmac_pci_probe_mode, |
| 736 | .idle_loop = native_idle, | 736 | .power_save = power4_idle, |
| 737 | .enable_pmcs = power4_enable_pmcs, | 737 | .enable_pmcs = power4_enable_pmcs, |
| 738 | #ifdef CONFIG_KEXEC | 738 | #ifdef CONFIG_KEXEC |
| 739 | .machine_kexec = default_machine_kexec, | 739 | .machine_kexec = default_machine_kexec, |
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 9fbdf54ba2be..cde5fa87f455 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile | |||
| @@ -59,8 +59,6 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o | |||
| 59 | head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o | 59 | head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o |
| 60 | head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o | 60 | head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o |
| 61 | 61 | ||
| 62 | head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o | ||
| 63 | head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o | ||
| 64 | head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o | 62 | head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o |
| 65 | 63 | ||
| 66 | core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ | 64 | core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ |
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index e399bbb969a4..1b2c7458a3d0 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
| @@ -8,10 +8,9 @@ extra-$(CONFIG_40x) := head_4xx.o | |||
| 8 | extra-$(CONFIG_44x) := head_44x.o | 8 | extra-$(CONFIG_44x) := head_44x.o |
| 9 | extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o | 9 | extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o |
| 10 | extra-$(CONFIG_8xx) := head_8xx.o | 10 | extra-$(CONFIG_8xx) := head_8xx.o |
| 11 | extra-$(CONFIG_6xx) += idle_6xx.o | ||
| 12 | extra-y += vmlinux.lds | 11 | extra-y += vmlinux.lds |
| 13 | 12 | ||
| 14 | obj-y := entry.o traps.o idle.o time.o misc.o \ | 13 | obj-y := entry.o traps.o time.o misc.o \ |
| 15 | setup.o \ | 14 | setup.o \ |
| 16 | ppc_htab.o | 15 | ppc_htab.o |
| 17 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 16 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
| @@ -35,7 +34,6 @@ endif | |||
| 35 | # These are here while we do the architecture merge | 34 | # These are here while we do the architecture merge |
| 36 | 35 | ||
| 37 | else | 36 | else |
| 38 | obj-y := idle.o | ||
| 39 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 37 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
| 40 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o | 38 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o |
| 41 | obj-$(CONFIG_MODULES) += module.o | 39 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 3a2815978488..fa8d49789ef1 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
| @@ -135,10 +135,10 @@ transfer_to_handler: | |||
| 135 | mfspr r11,SPRN_HID0 | 135 | mfspr r11,SPRN_HID0 |
| 136 | mtcr r11 | 136 | mtcr r11 |
| 137 | BEGIN_FTR_SECTION | 137 | BEGIN_FTR_SECTION |
| 138 | bt- 8,power_save_6xx_restore /* Check DOZE */ | 138 | bt- 8,4f /* Check DOZE */ |
| 139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | 139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) |
| 140 | BEGIN_FTR_SECTION | 140 | BEGIN_FTR_SECTION |
| 141 | bt- 9,power_save_6xx_restore /* Check NAP */ | 141 | bt- 9,4f /* Check NAP */ |
| 142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | 142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) |
| 143 | #endif /* CONFIG_6xx */ | 143 | #endif /* CONFIG_6xx */ |
| 144 | .globl transfer_to_handler_cont | 144 | .globl transfer_to_handler_cont |
| @@ -157,6 +157,10 @@ transfer_to_handler_cont: | |||
| 157 | SYNC | 157 | SYNC |
| 158 | RFI /* jump to handler, enable MMU */ | 158 | RFI /* jump to handler, enable MMU */ |
| 159 | 159 | ||
| 160 | #ifdef CONFIG_6xx | ||
| 161 | 4: b power_save_6xx_restore | ||
| 162 | #endif | ||
| 163 | |||
| 160 | /* | 164 | /* |
| 161 | * On kernel stack overflow, load up an initial stack pointer | 165 | * On kernel stack overflow, load up an initial stack pointer |
| 162 | * and call StackOverflow(regs), which should not return. | 166 | * and call StackOverflow(regs), which should not return. |
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c deleted file mode 100644 index 1be3ca5bae40..000000000000 --- a/arch/ppc/kernel/idle.c +++ /dev/null | |||
| @@ -1,112 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Idle daemon for PowerPC. Idle daemon will handle any action | ||
| 3 | * that needs to be taken when the system becomes idle. | ||
| 4 | * | ||
| 5 | * Written by Cort Dougan (cort@cs.nmt.edu). Subsequently hacked | ||
| 6 | * on by Tom Rini, Armin Kuster, Paul Mackerras and others. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License | ||
| 10 | * as published by the Free Software Foundation; either version | ||
| 11 | * 2 of the License, or (at your option) any later version. | ||
| 12 | */ | ||
| 13 | #include <linux/config.h> | ||
| 14 | #include <linux/errno.h> | ||
| 15 | #include <linux/sched.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/mm.h> | ||
| 18 | #include <linux/smp.h> | ||
| 19 | #include <linux/smp_lock.h> | ||
| 20 | #include <linux/stddef.h> | ||
| 21 | #include <linux/unistd.h> | ||
| 22 | #include <linux/ptrace.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/sysctl.h> | ||
| 25 | #include <linux/cpu.h> | ||
| 26 | |||
| 27 | #include <asm/pgtable.h> | ||
| 28 | #include <asm/uaccess.h> | ||
| 29 | #include <asm/system.h> | ||
| 30 | #include <asm/io.h> | ||
| 31 | #include <asm/mmu.h> | ||
| 32 | #include <asm/cache.h> | ||
| 33 | #include <asm/cputable.h> | ||
| 34 | #include <asm/machdep.h> | ||
| 35 | #include <asm/smp.h> | ||
| 36 | |||
| 37 | void default_idle(void) | ||
| 38 | { | ||
| 39 | void (*powersave)(void); | ||
| 40 | |||
| 41 | powersave = ppc_md.power_save; | ||
| 42 | |||
| 43 | if (!need_resched()) { | ||
| 44 | if (powersave != NULL) | ||
| 45 | powersave(); | ||
| 46 | #ifdef CONFIG_SMP | ||
| 47 | else { | ||
| 48 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
| 49 | while (!need_resched() && | ||
| 50 | !cpu_is_offline(smp_processor_id())) | ||
| 51 | barrier(); | ||
| 52 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
| 53 | } | ||
| 54 | #endif | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | /* | ||
| 59 | * The body of the idle task. | ||
| 60 | */ | ||
| 61 | void cpu_idle(void) | ||
| 62 | { | ||
| 63 | int cpu = smp_processor_id(); | ||
| 64 | |||
| 65 | for (;;) { | ||
| 66 | while (!need_resched()) { | ||
| 67 | if (ppc_md.idle != NULL) | ||
| 68 | ppc_md.idle(); | ||
| 69 | else | ||
| 70 | default_idle(); | ||
| 71 | } | ||
| 72 | |||
| 73 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) | ||
| 74 | cpu_die(); | ||
| 75 | preempt_enable_no_resched(); | ||
| 76 | schedule(); | ||
| 77 | preempt_disable(); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | #if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx) | ||
| 82 | /* | ||
| 83 | * Register the sysctl to set/clear powersave_nap. | ||
| 84 | */ | ||
| 85 | extern int powersave_nap; | ||
| 86 | |||
| 87 | static ctl_table powersave_nap_ctl_table[]={ | ||
| 88 | { | ||
| 89 | .ctl_name = KERN_PPC_POWERSAVE_NAP, | ||
| 90 | .procname = "powersave-nap", | ||
| 91 | .data = &powersave_nap, | ||
| 92 | .maxlen = sizeof(int), | ||
| 93 | .mode = 0644, | ||
| 94 | .proc_handler = &proc_dointvec, | ||
| 95 | }, | ||
| 96 | { 0, }, | ||
| 97 | }; | ||
| 98 | static ctl_table powersave_nap_sysctl_root[] = { | ||
| 99 | { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, }, | ||
| 100 | { 0,}, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static int __init | ||
| 104 | register_powersave_nap_sysctl(void) | ||
| 105 | { | ||
| 106 | register_sysctl_table(powersave_nap_sysctl_root, 0); | ||
| 107 | |||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | __initcall(register_powersave_nap_sysctl); | ||
| 112 | #endif | ||
diff --git a/arch/ppc/kernel/idle_6xx.S b/arch/ppc/kernel/idle_6xx.S deleted file mode 100644 index 1a2194cf6828..000000000000 --- a/arch/ppc/kernel/idle_6xx.S +++ /dev/null | |||
| @@ -1,233 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file contains the power_save function for 6xx & 7xxx CPUs | ||
| 3 | * rewritten in assembler | ||
| 4 | * | ||
| 5 | * Warning ! This code assumes that if your machine has a 750fx | ||
| 6 | * it will have PLL 1 set to low speed mode (used during NAP/DOZE). | ||
| 7 | * if this is not the case some additional changes will have to | ||
| 8 | * be done to check a runtime var (a bit like powersave-nap) | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License | ||
| 12 | * as published by the Free Software Foundation; either version | ||
| 13 | * 2 of the License, or (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/config.h> | ||
| 17 | #include <linux/threads.h> | ||
| 18 | #include <asm/processor.h> | ||
| 19 | #include <asm/page.h> | ||
| 20 | #include <asm/cputable.h> | ||
| 21 | #include <asm/thread_info.h> | ||
| 22 | #include <asm/ppc_asm.h> | ||
| 23 | #include <asm/asm-offsets.h> | ||
| 24 | |||
| 25 | #undef DEBUG | ||
| 26 | |||
| 27 | .text | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Init idle, called at early CPU setup time from head.S for each CPU | ||
| 31 | * Make sure no rest of NAP mode remains in HID0, save default | ||
| 32 | * values for some CPU specific registers. Called with r24 | ||
| 33 | * containing CPU number and r3 reloc offset | ||
| 34 | */ | ||
| 35 | _GLOBAL(init_idle_6xx) | ||
| 36 | BEGIN_FTR_SECTION | ||
| 37 | mfspr r4,SPRN_HID0 | ||
| 38 | rlwinm r4,r4,0,10,8 /* Clear NAP */ | ||
| 39 | mtspr SPRN_HID0, r4 | ||
| 40 | b 1f | ||
| 41 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
| 42 | blr | ||
| 43 | 1: | ||
| 44 | slwi r5,r24,2 | ||
| 45 | add r5,r5,r3 | ||
| 46 | BEGIN_FTR_SECTION | ||
| 47 | mfspr r4,SPRN_MSSCR0 | ||
| 48 | addis r6,r5, nap_save_msscr0@ha | ||
| 49 | stw r4,nap_save_msscr0@l(r6) | ||
| 50 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | ||
| 51 | BEGIN_FTR_SECTION | ||
| 52 | mfspr r4,SPRN_HID1 | ||
| 53 | addis r6,r5,nap_save_hid1@ha | ||
| 54 | stw r4,nap_save_hid1@l(r6) | ||
| 55 | END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) | ||
| 56 | blr | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Here is the power_save_6xx function. This could eventually be | ||
| 60 | * split into several functions & changing the function pointer | ||
| 61 | * depending on the various features. | ||
| 62 | */ | ||
| 63 | _GLOBAL(ppc6xx_idle) | ||
| 64 | /* Check if we can nap or doze, put HID0 mask in r3 | ||
| 65 | */ | ||
| 66 | lis r3, 0 | ||
| 67 | BEGIN_FTR_SECTION | ||
| 68 | lis r3,HID0_DOZE@h | ||
| 69 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
| 70 | BEGIN_FTR_SECTION | ||
| 71 | /* We must dynamically check for the NAP feature as it | ||
| 72 | * can be cleared by CPU init after the fixups are done | ||
| 73 | */ | ||
| 74 | lis r4,cur_cpu_spec@ha | ||
| 75 | lwz r4,cur_cpu_spec@l(r4) | ||
| 76 | lwz r4,CPU_SPEC_FEATURES(r4) | ||
| 77 | andi. r0,r4,CPU_FTR_CAN_NAP | ||
| 78 | beq 1f | ||
| 79 | /* Now check if user or arch enabled NAP mode */ | ||
| 80 | lis r4,powersave_nap@ha | ||
| 81 | lwz r4,powersave_nap@l(r4) | ||
| 82 | cmpwi 0,r4,0 | ||
| 83 | beq 1f | ||
| 84 | lis r3,HID0_NAP@h | ||
| 85 | 1: | ||
| 86 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
| 87 | cmpwi 0,r3,0 | ||
| 88 | beqlr | ||
| 89 | |||
| 90 | /* Clear MSR:EE */ | ||
| 91 | mfmsr r7 | ||
| 92 | rlwinm r0,r7,0,17,15 | ||
| 93 | mtmsr r0 | ||
| 94 | |||
| 95 | /* Check current_thread_info()->flags */ | ||
| 96 | rlwinm r4,r1,0,0,18 | ||
| 97 | lwz r4,TI_FLAGS(r4) | ||
| 98 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 99 | beq 1f | ||
| 100 | mtmsr r7 /* out of line this ? */ | ||
| 101 | blr | ||
| 102 | 1: | ||
| 103 | /* Some pre-nap cleanups needed on some CPUs */ | ||
| 104 | andis. r0,r3,HID0_NAP@h | ||
| 105 | beq 2f | ||
| 106 | BEGIN_FTR_SECTION | ||
| 107 | /* Disable L2 prefetch on some 745x and try to ensure | ||
| 108 | * L2 prefetch engines are idle. As explained by errata | ||
| 109 | * text, we can't be sure they are, we just hope very hard | ||
| 110 | * that well be enough (sic !). At least I noticed Apple | ||
| 111 | * doesn't even bother doing the dcbf's here... | ||
| 112 | */ | ||
| 113 | mfspr r4,SPRN_MSSCR0 | ||
| 114 | rlwinm r4,r4,0,0,29 | ||
| 115 | sync | ||
| 116 | mtspr SPRN_MSSCR0,r4 | ||
| 117 | sync | ||
| 118 | isync | ||
| 119 | lis r4,KERNELBASE@h | ||
| 120 | dcbf 0,r4 | ||
| 121 | dcbf 0,r4 | ||
| 122 | dcbf 0,r4 | ||
| 123 | dcbf 0,r4 | ||
| 124 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | ||
| 125 | #ifdef DEBUG | ||
| 126 | lis r6,nap_enter_count@ha | ||
| 127 | lwz r4,nap_enter_count@l(r6) | ||
| 128 | addi r4,r4,1 | ||
| 129 | stw r4,nap_enter_count@l(r6) | ||
| 130 | #endif | ||
| 131 | 2: | ||
| 132 | BEGIN_FTR_SECTION | ||
| 133 | /* Go to low speed mode on some 750FX */ | ||
| 134 | lis r4,powersave_lowspeed@ha | ||
| 135 | lwz r4,powersave_lowspeed@l(r4) | ||
| 136 | cmpwi 0,r4,0 | ||
| 137 | beq 1f | ||
| 138 | mfspr r4,SPRN_HID1 | ||
| 139 | oris r4,r4,0x0001 | ||
| 140 | mtspr SPRN_HID1,r4 | ||
| 141 | 1: | ||
| 142 | END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) | ||
| 143 | |||
| 144 | /* Go to NAP or DOZE now */ | ||
| 145 | mfspr r4,SPRN_HID0 | ||
| 146 | lis r5,(HID0_NAP|HID0_SLEEP)@h | ||
| 147 | BEGIN_FTR_SECTION | ||
| 148 | oris r5,r5,HID0_DOZE@h | ||
| 149 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
| 150 | andc r4,r4,r5 | ||
| 151 | or r4,r4,r3 | ||
| 152 | BEGIN_FTR_SECTION | ||
| 153 | oris r4,r4,HID0_DPM@h /* that should be done once for all */ | ||
| 154 | END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) | ||
| 155 | mtspr SPRN_HID0,r4 | ||
| 156 | BEGIN_FTR_SECTION | ||
| 157 | DSSALL | ||
| 158 | sync | ||
| 159 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
| 160 | ori r7,r7,MSR_EE /* Could be ommited (already set) */ | ||
| 161 | oris r7,r7,MSR_POW@h | ||
| 162 | sync | ||
| 163 | isync | ||
| 164 | mtmsr r7 | ||
| 165 | isync | ||
| 166 | sync | ||
| 167 | blr | ||
| 168 | |||
| 169 | /* | ||
| 170 | * Return from NAP/DOZE mode, restore some CPU specific registers, | ||
| 171 | * we are called with DR/IR still off and r2 containing physical | ||
| 172 | * address of current. | ||
| 173 | */ | ||
| 174 | _GLOBAL(power_save_6xx_restore) | ||
| 175 | mfspr r11,SPRN_HID0 | ||
| 176 | rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ | ||
| 177 | cror 4*cr1+eq,4*cr0+eq,4*cr0+eq | ||
| 178 | BEGIN_FTR_SECTION | ||
| 179 | rlwinm r11,r11,0,9,7 /* Clear DOZE */ | ||
| 180 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
| 181 | mtspr SPRN_HID0, r11 | ||
| 182 | |||
| 183 | #ifdef DEBUG | ||
| 184 | beq cr1,1f | ||
| 185 | lis r11,(nap_return_count-KERNELBASE)@ha | ||
| 186 | lwz r9,nap_return_count@l(r11) | ||
| 187 | addi r9,r9,1 | ||
| 188 | stw r9,nap_return_count@l(r11) | ||
| 189 | 1: | ||
| 190 | #endif | ||
| 191 | |||
| 192 | rlwinm r9,r1,0,0,18 | ||
| 193 | tophys(r9,r9) | ||
| 194 | lwz r11,TI_CPU(r9) | ||
| 195 | slwi r11,r11,2 | ||
| 196 | /* Todo make sure all these are in the same page | ||
| 197 | * and load r22 (@ha part + CPU offset) only once | ||
| 198 | */ | ||
| 199 | BEGIN_FTR_SECTION | ||
| 200 | beq cr1,1f | ||
| 201 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha | ||
| 202 | lwz r9,nap_save_msscr0@l(r9) | ||
| 203 | mtspr SPRN_MSSCR0, r9 | ||
| 204 | sync | ||
| 205 | isync | ||
| 206 | 1: | ||
| 207 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | ||
| 208 | BEGIN_FTR_SECTION | ||
| 209 | addis r9,r11,(nap_save_hid1-KERNELBASE)@ha | ||
| 210 | lwz r9,nap_save_hid1@l(r9) | ||
| 211 | mtspr SPRN_HID1, r9 | ||
| 212 | END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) | ||
| 213 | b transfer_to_handler_cont | ||
| 214 | |||
| 215 | .data | ||
| 216 | |||
| 217 | _GLOBAL(nap_save_msscr0) | ||
| 218 | .space 4*NR_CPUS | ||
| 219 | |||
| 220 | _GLOBAL(nap_save_hid1) | ||
| 221 | .space 4*NR_CPUS | ||
| 222 | |||
| 223 | _GLOBAL(powersave_nap) | ||
| 224 | .long 0 | ||
| 225 | _GLOBAL(powersave_lowspeed) | ||
| 226 | .long 0 | ||
| 227 | |||
| 228 | #ifdef DEBUG | ||
| 229 | _GLOBAL(nap_enter_count) | ||
| 230 | .space 4 | ||
| 231 | _GLOBAL(nap_return_count) | ||
| 232 | .space 4 | ||
| 233 | #endif | ||
diff --git a/arch/ppc/kernel/idle_power4.S b/arch/ppc/kernel/idle_power4.S deleted file mode 100644 index cc0d535365cd..000000000000 --- a/arch/ppc/kernel/idle_power4.S +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This file contains the power_save function for 6xx & 7xxx CPUs | ||
| 3 | * rewritten in assembler | ||
| 4 | * | ||
| 5 | * Warning ! This code assumes that if your machine has a 750fx | ||
| 6 | * it will have PLL 1 set to low speed mode (used during NAP/DOZE). | ||
| 7 | * if this is not the case some additional changes will have to | ||
| 8 | * be done to check a runtime var (a bit like powersave-nap) | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License | ||
| 12 | * as published by the Free Software Foundation; either version | ||
| 13 | * 2 of the License, or (at your option) any later version. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/config.h> | ||
| 17 | #include <linux/threads.h> | ||
| 18 | #include <asm/processor.h> | ||
| 19 | #include <asm/page.h> | ||
| 20 | #include <asm/cputable.h> | ||
| 21 | #include <asm/thread_info.h> | ||
| 22 | #include <asm/ppc_asm.h> | ||
| 23 | #include <asm/asm-offsets.h> | ||
| 24 | |||
| 25 | #undef DEBUG | ||
| 26 | |||
| 27 | .text | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Init idle, called at early CPU setup time from head.S for each CPU | ||
| 31 | * So nothing for now. Called with r24 containing CPU number and r3 | ||
| 32 | * reloc offset | ||
| 33 | */ | ||
| 34 | .globl init_idle_power4 | ||
| 35 | init_idle_power4: | ||
| 36 | blr | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Here is the power_save_6xx function. This could eventually be | ||
| 40 | * split into several functions & changing the function pointer | ||
| 41 | * depending on the various features. | ||
| 42 | */ | ||
| 43 | .globl power4_idle | ||
| 44 | power4_idle: | ||
| 45 | BEGIN_FTR_SECTION | ||
| 46 | blr | ||
| 47 | END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) | ||
| 48 | /* We must dynamically check for the NAP feature as it | ||
| 49 | * can be cleared by CPU init after the fixups are done | ||
| 50 | */ | ||
| 51 | lis r4,cur_cpu_spec@ha | ||
| 52 | lwz r4,cur_cpu_spec@l(r4) | ||
| 53 | lwz r4,CPU_SPEC_FEATURES(r4) | ||
| 54 | andi. r0,r4,CPU_FTR_CAN_NAP | ||
| 55 | beqlr | ||
| 56 | /* Now check if user or arch enabled NAP mode */ | ||
| 57 | lis r4,powersave_nap@ha | ||
| 58 | lwz r4,powersave_nap@l(r4) | ||
| 59 | cmpwi 0,r4,0 | ||
| 60 | beqlr | ||
| 61 | |||
| 62 | /* Clear MSR:EE */ | ||
| 63 | mfmsr r7 | ||
| 64 | rlwinm r0,r7,0,17,15 | ||
| 65 | mtmsr r0 | ||
| 66 | |||
| 67 | /* Check current_thread_info()->flags */ | ||
| 68 | rlwinm r4,r1,0,0,18 | ||
| 69 | lwz r4,TI_FLAGS(r4) | ||
| 70 | andi. r0,r4,_TIF_NEED_RESCHED | ||
| 71 | beq 1f | ||
| 72 | mtmsr r7 /* out of line this ? */ | ||
| 73 | blr | ||
| 74 | 1: | ||
| 75 | /* Go to NAP now */ | ||
| 76 | BEGIN_FTR_SECTION | ||
| 77 | DSSALL | ||
| 78 | sync | ||
| 79 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
| 80 | ori r7,r7,MSR_EE /* Could be ommited (already set) */ | ||
| 81 | oris r7,r7,MSR_POW@h | ||
| 82 | sync | ||
| 83 | isync | ||
| 84 | mtmsr r7 | ||
| 85 | isync | ||
| 86 | sync | ||
| 87 | blr | ||
| 88 | |||
| 89 | .globl powersave_nap | ||
| 90 | powersave_nap: | ||
| 91 | .long 0 | ||
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 5348b820788c..21c8dc90d175 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
| @@ -158,6 +158,12 @@ struct machdep_calls { | |||
| 158 | /* Idle loop for this platform, leave empty for default idle loop */ | 158 | /* Idle loop for this platform, leave empty for default idle loop */ |
| 159 | void (*idle_loop)(void); | 159 | void (*idle_loop)(void); |
| 160 | 160 | ||
| 161 | /* | ||
| 162 | * Function for waiting for work with reduced power in idle loop; | ||
| 163 | * called with interrupts disabled. | ||
| 164 | */ | ||
| 165 | void (*power_save)(void); | ||
| 166 | |||
| 161 | /* Function to enable performance monitor counters for this | 167 | /* Function to enable performance monitor counters for this |
| 162 | platform, called once per cpu. */ | 168 | platform, called once per cpu. */ |
| 163 | void (*enable_pmcs)(void); | 169 | void (*enable_pmcs)(void); |
| @@ -170,9 +176,6 @@ struct machdep_calls { | |||
| 170 | May be NULL. */ | 176 | May be NULL. */ |
| 171 | void (*init)(void); | 177 | void (*init)(void); |
| 172 | 178 | ||
| 173 | void (*idle)(void); | ||
| 174 | void (*power_save)(void); | ||
| 175 | |||
| 176 | void (*heartbeat)(void); | 179 | void (*heartbeat)(void); |
| 177 | unsigned long heartbeat_reset; | 180 | unsigned long heartbeat_reset; |
| 178 | unsigned long heartbeat_count; | 181 | unsigned long heartbeat_count; |
| @@ -242,8 +245,8 @@ struct machdep_calls { | |||
| 242 | #endif /* CONFIG_KEXEC */ | 245 | #endif /* CONFIG_KEXEC */ |
| 243 | }; | 246 | }; |
| 244 | 247 | ||
| 245 | extern void default_idle(void); | 248 | extern void power4_idle(void); |
| 246 | extern void native_idle(void); | 249 | extern void ppc6xx_idle(void); |
| 247 | 250 | ||
| 248 | extern struct machdep_calls ppc_md; | 251 | extern struct machdep_calls ppc_md; |
| 249 | extern char cmd_line[COMMAND_LINE_SIZE]; | 252 | extern char cmd_line[COMMAND_LINE_SIZE]; |
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 72bfe3af0460..bd467bf5cf5a 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h | |||
| @@ -622,6 +622,10 @@ extern void ppc64_runlatch_off(void); | |||
| 622 | extern unsigned long scom970_read(unsigned int address); | 622 | extern unsigned long scom970_read(unsigned int address); |
| 623 | extern void scom970_write(unsigned int address, unsigned long value); | 623 | extern void scom970_write(unsigned int address, unsigned long value); |
| 624 | 624 | ||
| 625 | #else | ||
| 626 | #define ppc64_runlatch_on() | ||
| 627 | #define ppc64_runlatch_off() | ||
| 628 | |||
| 625 | #endif /* CONFIG_PPC64 */ | 629 | #endif /* CONFIG_PPC64 */ |
| 626 | 630 | ||
| 627 | #define __get_SP() ({unsigned long sp; \ | 631 | #define __get_SP() ({unsigned long sp; \ |
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index a3e8a45e45a9..ebbef64e8985 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h | |||
| @@ -44,7 +44,7 @@ struct machdep_calls { | |||
| 44 | void (*power_off)(void); | 44 | void (*power_off)(void); |
| 45 | void (*halt)(void); | 45 | void (*halt)(void); |
| 46 | 46 | ||
| 47 | void (*idle)(void); | 47 | void (*idle_loop)(void); |
| 48 | void (*power_save)(void); | 48 | void (*power_save)(void); |
| 49 | 49 | ||
| 50 | long (*time_init)(void); /* Optional, may be NULL */ | 50 | long (*time_init)(void); /* Optional, may be NULL */ |
