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)
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  */
12 #include <linux/config.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/smp.h>
18 #include <linux/smp_lock.h>
19 #include <linux/stddef.h>
20 #include <linux/unistd.h>
21 #include <linux/ptrace.h>
22 #include <linux/slab.h>
23 
24 #include <asm/pgtable.h>
25 #include <asm/uaccess.h>
26 #include <asm/system.h>
27 #include <asm/io.h>
28 #include <asm/processor.h>
29 #include <asm/mmu.h>
30 #include <asm/cache.h>
31 #include <asm/cputable.h>
32 
33 unsigned long zero_paged_on;
34 unsigned long powersave_nap;
35 unsigned long powersave_lowspeed;
36 
37 extern void power_save(void);
38 
idled(void)39 int idled(void)
40 {
41 	int do_power_save = 0;
42 
43 	/* Check if CPU can powersave (get rid of that soon!) */
44 	if (cur_cpu_spec[smp_processor_id()]->cpu_features &
45 		(CPU_FTR_CAN_DOZE | CPU_FTR_CAN_NAP))
46 		do_power_save = 1;
47 
48 	/* endless loop with no priority at all */
49 	current->nice = 20;
50 	current->counter = -100;
51 	init_idle();
52 	for (;;) {
53 #ifdef CONFIG_SMP
54 		if (!do_power_save) {
55 			/*
56 			 * Deal with another CPU just having chosen a thread to
57 			 * run here:
58 			 */
59 			int oldval = xchg(&current->need_resched, -1);
60 
61 			if (!oldval) {
62 				while(current->need_resched == -1)
63 					; /* Do Nothing */
64 			}
65 		}
66 #endif
67 		if (do_power_save && !current->need_resched)
68 			power_save();
69 
70 		if (current->need_resched) {
71 			schedule();
72 			check_pgt_cache();
73 		}
74 	}
75 	return 0;
76 }
77 
78 /*
79  * SMP entry into the idle task - calls the same thing as the
80  * non-smp versions. -- Cort
81  */
cpu_idle(void)82 int cpu_idle(void)
83 {
84 	idled();
85 	return 0;
86 }
87