diff options
Diffstat (limited to 'arch/powerpc/platforms/powermac')
-rw-r--r-- | arch/powerpc/platforms/powermac/backlight.c | 58 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/bootx_init.c | 50 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/cpufreq_64.c | 78 |
3 files changed, 139 insertions, 47 deletions
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index 74eed6b74cd..d6641549105 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c | |||
@@ -10,19 +10,32 @@ | |||
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/fb.h> | 11 | #include <linux/fb.h> |
12 | #include <linux/backlight.h> | 12 | #include <linux/backlight.h> |
13 | #include <linux/adb.h> | ||
14 | #include <linux/pmu.h> | ||
15 | #include <asm/atomic.h> | ||
13 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
14 | #include <asm/backlight.h> | 17 | #include <asm/backlight.h> |
15 | 18 | ||
16 | #define OLD_BACKLIGHT_MAX 15 | 19 | #define OLD_BACKLIGHT_MAX 15 |
17 | 20 | ||
18 | static void pmac_backlight_key_worker(void *data); | 21 | static void pmac_backlight_key_worker(void *data); |
22 | static void pmac_backlight_set_legacy_worker(void *data); | ||
23 | |||
19 | static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); | 24 | static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); |
25 | static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL); | ||
20 | 26 | ||
21 | /* Although this variable is used in interrupt context, it makes no sense to | 27 | /* Although these variables are used in interrupt context, it makes no sense to |
22 | * protect it. No user is able to produce enough key events per second and | 28 | * protect them. No user is able to produce enough key events per second and |
23 | * notice the errors that might happen. | 29 | * notice the errors that might happen. |
24 | */ | 30 | */ |
25 | static int pmac_backlight_key_queued; | 31 | static int pmac_backlight_key_queued; |
32 | static int pmac_backlight_set_legacy_queued; | ||
33 | |||
34 | /* The via-pmu code allows the backlight to be grabbed, in which case the | ||
35 | * in-kernel control of the brightness needs to be disabled. This should | ||
36 | * only be used by really old PowerBooks. | ||
37 | */ | ||
38 | static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0); | ||
26 | 39 | ||
27 | /* Protect the pmac_backlight variable */ | 40 | /* Protect the pmac_backlight variable */ |
28 | DEFINE_MUTEX(pmac_backlight_mutex); | 41 | DEFINE_MUTEX(pmac_backlight_mutex); |
@@ -82,6 +95,9 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value) | |||
82 | 95 | ||
83 | static void pmac_backlight_key_worker(void *data) | 96 | static void pmac_backlight_key_worker(void *data) |
84 | { | 97 | { |
98 | if (atomic_read(&kernel_backlight_disabled)) | ||
99 | return; | ||
100 | |||
85 | mutex_lock(&pmac_backlight_mutex); | 101 | mutex_lock(&pmac_backlight_mutex); |
86 | if (pmac_backlight) { | 102 | if (pmac_backlight) { |
87 | struct backlight_properties *props; | 103 | struct backlight_properties *props; |
@@ -107,8 +123,12 @@ static void pmac_backlight_key_worker(void *data) | |||
107 | mutex_unlock(&pmac_backlight_mutex); | 123 | mutex_unlock(&pmac_backlight_mutex); |
108 | } | 124 | } |
109 | 125 | ||
126 | /* This function is called in interrupt context */ | ||
110 | void pmac_backlight_key(int direction) | 127 | void pmac_backlight_key(int direction) |
111 | { | 128 | { |
129 | if (atomic_read(&kernel_backlight_disabled)) | ||
130 | return; | ||
131 | |||
112 | /* we can receive multiple interrupts here, but the scheduled work | 132 | /* we can receive multiple interrupts here, but the scheduled work |
113 | * will run only once, with the last value | 133 | * will run only once, with the last value |
114 | */ | 134 | */ |
@@ -116,7 +136,7 @@ void pmac_backlight_key(int direction) | |||
116 | schedule_work(&pmac_backlight_key_work); | 136 | schedule_work(&pmac_backlight_key_work); |
117 | } | 137 | } |
118 | 138 | ||
119 | int pmac_backlight_set_legacy_brightness(int brightness) | 139 | static int __pmac_backlight_set_legacy_brightness(int brightness) |
120 | { | 140 | { |
121 | int error = -ENXIO; | 141 | int error = -ENXIO; |
122 | 142 | ||
@@ -145,6 +165,28 @@ int pmac_backlight_set_legacy_brightness(int brightness) | |||
145 | return error; | 165 | return error; |
146 | } | 166 | } |
147 | 167 | ||
168 | static void pmac_backlight_set_legacy_worker(void *data) | ||
169 | { | ||
170 | if (atomic_read(&kernel_backlight_disabled)) | ||
171 | return; | ||
172 | |||
173 | __pmac_backlight_set_legacy_brightness(pmac_backlight_set_legacy_queued); | ||
174 | } | ||
175 | |||
176 | /* This function is called in interrupt context */ | ||
177 | void pmac_backlight_set_legacy_brightness_pmu(int brightness) { | ||
178 | if (atomic_read(&kernel_backlight_disabled)) | ||
179 | return; | ||
180 | |||
181 | pmac_backlight_set_legacy_queued = brightness; | ||
182 | schedule_work(&pmac_backlight_set_legacy_work); | ||
183 | } | ||
184 | |||
185 | int pmac_backlight_set_legacy_brightness(int brightness) | ||
186 | { | ||
187 | return __pmac_backlight_set_legacy_brightness(brightness); | ||
188 | } | ||
189 | |||
148 | int pmac_backlight_get_legacy_brightness() | 190 | int pmac_backlight_get_legacy_brightness() |
149 | { | 191 | { |
150 | int result = -ENXIO; | 192 | int result = -ENXIO; |
@@ -167,6 +209,16 @@ int pmac_backlight_get_legacy_brightness() | |||
167 | return result; | 209 | return result; |
168 | } | 210 | } |
169 | 211 | ||
212 | void pmac_backlight_disable() | ||
213 | { | ||
214 | atomic_inc(&kernel_backlight_disabled); | ||
215 | } | ||
216 | |||
217 | void pmac_backlight_enable() | ||
218 | { | ||
219 | atomic_dec(&kernel_backlight_disabled); | ||
220 | } | ||
221 | |||
170 | EXPORT_SYMBOL_GPL(pmac_backlight); | 222 | EXPORT_SYMBOL_GPL(pmac_backlight); |
171 | EXPORT_SYMBOL_GPL(pmac_backlight_mutex); | 223 | EXPORT_SYMBOL_GPL(pmac_backlight_mutex); |
172 | EXPORT_SYMBOL_GPL(pmac_has_backlight_type); | 224 | EXPORT_SYMBOL_GPL(pmac_has_backlight_type); |
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index 871b002c9f9..9d73d0234c5 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c | |||
@@ -181,13 +181,18 @@ static void __init bootx_add_chosen_props(unsigned long base, | |||
181 | } | 181 | } |
182 | 182 | ||
183 | static void __init bootx_add_display_props(unsigned long base, | 183 | static void __init bootx_add_display_props(unsigned long base, |
184 | unsigned long *mem_end) | 184 | unsigned long *mem_end, |
185 | int has_real_node) | ||
185 | { | 186 | { |
186 | boot_infos_t *bi = bootx_info; | 187 | boot_infos_t *bi = bootx_info; |
187 | u32 tmp; | 188 | u32 tmp; |
188 | 189 | ||
189 | bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end); | 190 | if (has_real_node) { |
190 | bootx_dt_add_prop("linux,opened", NULL, 0, mem_end); | 191 | bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end); |
192 | bootx_dt_add_prop("linux,opened", NULL, 0, mem_end); | ||
193 | } else | ||
194 | bootx_dt_add_prop("linux,bootx-noscreen", NULL, 0, mem_end); | ||
195 | |||
191 | tmp = bi->dispDeviceDepth; | 196 | tmp = bi->dispDeviceDepth; |
192 | bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end); | 197 | bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end); |
193 | tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0]; | 198 | tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0]; |
@@ -241,11 +246,6 @@ static void __init bootx_scan_dt_build_strings(unsigned long base, | |||
241 | DBG(" detected display ! adding properties names !\n"); | 246 | DBG(" detected display ! adding properties names !\n"); |
242 | bootx_dt_add_string("linux,boot-display", mem_end); | 247 | bootx_dt_add_string("linux,boot-display", mem_end); |
243 | bootx_dt_add_string("linux,opened", mem_end); | 248 | bootx_dt_add_string("linux,opened", mem_end); |
244 | bootx_dt_add_string("linux,bootx-depth", mem_end); | ||
245 | bootx_dt_add_string("linux,bootx-width", mem_end); | ||
246 | bootx_dt_add_string("linux,bootx-height", mem_end); | ||
247 | bootx_dt_add_string("linux,bootx-linebytes", mem_end); | ||
248 | bootx_dt_add_string("linux,bootx-addr", mem_end); | ||
249 | strncpy(bootx_disp_path, namep, 255); | 249 | strncpy(bootx_disp_path, namep, 255); |
250 | } | 250 | } |
251 | 251 | ||
@@ -329,10 +329,13 @@ static void __init bootx_scan_dt_build_struct(unsigned long base, | |||
329 | ppp = &pp->next; | 329 | ppp = &pp->next; |
330 | } | 330 | } |
331 | 331 | ||
332 | if (node == bootx_node_chosen) | 332 | if (node == bootx_node_chosen) { |
333 | bootx_add_chosen_props(base, mem_end); | 333 | bootx_add_chosen_props(base, mem_end); |
334 | if (node == bootx_info->dispDeviceRegEntryOffset) | 334 | if (bootx_info->dispDeviceRegEntryOffset == 0) |
335 | bootx_add_display_props(base, mem_end); | 335 | bootx_add_display_props(base, mem_end, 0); |
336 | } | ||
337 | else if (node == bootx_info->dispDeviceRegEntryOffset) | ||
338 | bootx_add_display_props(base, mem_end, 1); | ||
336 | 339 | ||
337 | /* do all our children */ | 340 | /* do all our children */ |
338 | cpp = &np->child; | 341 | cpp = &np->child; |
@@ -374,6 +377,14 @@ static unsigned long __init bootx_flatten_dt(unsigned long start) | |||
374 | mem_end += 4; | 377 | mem_end += 4; |
375 | bootx_dt_strend = mem_end; | 378 | bootx_dt_strend = mem_end; |
376 | bootx_scan_dt_build_strings(base, 4, &mem_end); | 379 | bootx_scan_dt_build_strings(base, 4, &mem_end); |
380 | /* Add some strings */ | ||
381 | bootx_dt_add_string("linux,bootx-noscreen", &mem_end); | ||
382 | bootx_dt_add_string("linux,bootx-depth", &mem_end); | ||
383 | bootx_dt_add_string("linux,bootx-width", &mem_end); | ||
384 | bootx_dt_add_string("linux,bootx-height", &mem_end); | ||
385 | bootx_dt_add_string("linux,bootx-linebytes", &mem_end); | ||
386 | bootx_dt_add_string("linux,bootx-addr", &mem_end); | ||
387 | /* Wrap up strings */ | ||
377 | hdr->off_dt_strings = bootx_dt_strbase - mem_start; | 388 | hdr->off_dt_strings = bootx_dt_strbase - mem_start; |
378 | hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase; | 389 | hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase; |
379 | 390 | ||
@@ -400,8 +411,15 @@ static unsigned long __init bootx_flatten_dt(unsigned long start) | |||
400 | DBG("End of boot params: %x\n", mem_end); | 411 | DBG("End of boot params: %x\n", mem_end); |
401 | rsvmap[0] = mem_start; | 412 | rsvmap[0] = mem_start; |
402 | rsvmap[1] = mem_end; | 413 | rsvmap[1] = mem_end; |
403 | rsvmap[2] = 0; | 414 | if (bootx_info->ramDisk) { |
404 | rsvmap[3] = 0; | 415 | rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk; |
416 | rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize; | ||
417 | rsvmap[4] = 0; | ||
418 | rsvmap[5] = 0; | ||
419 | } else { | ||
420 | rsvmap[2] = 0; | ||
421 | rsvmap[3] = 0; | ||
422 | } | ||
405 | 423 | ||
406 | return (unsigned long)hdr; | 424 | return (unsigned long)hdr; |
407 | } | 425 | } |
@@ -471,6 +489,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) | |||
471 | if (bi->dispDeviceDepth == 16) | 489 | if (bi->dispDeviceDepth == 16) |
472 | bi->dispDeviceDepth = 15; | 490 | bi->dispDeviceDepth = 15; |
473 | 491 | ||
492 | |||
474 | #ifdef CONFIG_BOOTX_TEXT | 493 | #ifdef CONFIG_BOOTX_TEXT |
475 | ptr = (unsigned long)bi->logicalDisplayBase; | 494 | ptr = (unsigned long)bi->logicalDisplayBase; |
476 | ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes; | 495 | ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes; |
@@ -508,6 +527,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) | |||
508 | #ifdef CONFIG_BOOTX_TEXT | 527 | #ifdef CONFIG_BOOTX_TEXT |
509 | btext_welcome(bi); | 528 | btext_welcome(bi); |
510 | #endif | 529 | #endif |
530 | |||
511 | /* New BootX enters kernel with MMU off, i/os are not allowed | 531 | /* New BootX enters kernel with MMU off, i/os are not allowed |
512 | * here. This hack will have been done by the boostrap anyway. | 532 | * here. This hack will have been done by the boostrap anyway. |
513 | */ | 533 | */ |
@@ -530,12 +550,12 @@ void __init bootx_init(unsigned long r3, unsigned long r4) | |||
530 | */ | 550 | */ |
531 | if (bi->version < 5) { | 551 | if (bi->version < 5) { |
532 | space = bi->deviceTreeOffset + bi->deviceTreeSize; | 552 | space = bi->deviceTreeOffset + bi->deviceTreeSize; |
533 | if (bi->ramDisk) | 553 | if (bi->ramDisk >= space) |
534 | space = bi->ramDisk + bi->ramDiskSize; | 554 | space = bi->ramDisk + bi->ramDiskSize; |
535 | } else | 555 | } else |
536 | space = bi->totalParamsSize; | 556 | space = bi->totalParamsSize; |
537 | 557 | ||
538 | bootx_printf("Total space used by parameters & ramdisk: %x \n", space); | 558 | bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space); |
539 | 559 | ||
540 | /* New BootX will have flushed all TLBs and enters kernel with | 560 | /* New BootX will have flushed all TLBs and enters kernel with |
541 | * MMU switched OFF, so this should not be useful anymore. | 561 | * MMU switched OFF, so this should not be useful anymore. |
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index f08a1451613..7b1156ea534 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * that is iMac G5 and latest single CPU desktop. | 10 | * that is iMac G5 and latest single CPU desktop. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #undef DEBUG | ||
14 | |||
13 | #include <linux/module.h> | 15 | #include <linux/module.h> |
14 | #include <linux/types.h> | 16 | #include <linux/types.h> |
15 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
@@ -30,13 +32,7 @@ | |||
30 | #include <asm/smu.h> | 32 | #include <asm/smu.h> |
31 | #include <asm/pmac_pfunc.h> | 33 | #include <asm/pmac_pfunc.h> |
32 | 34 | ||
33 | #undef DEBUG | 35 | #define DBG(fmt...) pr_debug(fmt) |
34 | |||
35 | #ifdef DEBUG | ||
36 | #define DBG(fmt...) printk(fmt) | ||
37 | #else | ||
38 | #define DBG(fmt...) | ||
39 | #endif | ||
40 | 36 | ||
41 | /* see 970FX user manual */ | 37 | /* see 970FX user manual */ |
42 | 38 | ||
@@ -82,8 +78,6 @@ static struct freq_attr* g5_cpu_freqs_attr[] = { | |||
82 | /* Power mode data is an array of the 32 bits PCR values to use for | 78 | /* Power mode data is an array of the 32 bits PCR values to use for |
83 | * the various frequencies, retrieved from the device-tree | 79 | * the various frequencies, retrieved from the device-tree |
84 | */ | 80 | */ |
85 | static u32 *g5_pmode_data; | ||
86 | static int g5_pmode_max; | ||
87 | static int g5_pmode_cur; | 81 | static int g5_pmode_cur; |
88 | 82 | ||
89 | static void (*g5_switch_volt)(int speed_mode); | 83 | static void (*g5_switch_volt)(int speed_mode); |
@@ -93,6 +87,11 @@ static int (*g5_query_freq)(void); | |||
93 | static DEFINE_MUTEX(g5_switch_mutex); | 87 | static DEFINE_MUTEX(g5_switch_mutex); |
94 | 88 | ||
95 | 89 | ||
90 | #ifdef CONFIG_PMAC_SMU | ||
91 | |||
92 | static u32 *g5_pmode_data; | ||
93 | static int g5_pmode_max; | ||
94 | |||
96 | static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ | 95 | static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ |
97 | static int g5_fvt_count; /* number of op. points */ | 96 | static int g5_fvt_count; /* number of op. points */ |
98 | static int g5_fvt_cur; /* current op. point */ | 97 | static int g5_fvt_cur; /* current op. point */ |
@@ -210,6 +209,16 @@ static int g5_scom_query_freq(void) | |||
210 | } | 209 | } |
211 | 210 | ||
212 | /* | 211 | /* |
212 | * Fake voltage switching for platforms with missing support | ||
213 | */ | ||
214 | |||
215 | static void g5_dummy_switch_volt(int speed_mode) | ||
216 | { | ||
217 | } | ||
218 | |||
219 | #endif /* CONFIG_PMAC_SMU */ | ||
220 | |||
221 | /* | ||
213 | * Platform function based voltage switching for PowerMac7,2 & 7,3 | 222 | * Platform function based voltage switching for PowerMac7,2 & 7,3 |
214 | */ | 223 | */ |
215 | 224 | ||
@@ -248,6 +257,9 @@ static int g5_pfunc_switch_freq(int speed_mode) | |||
248 | struct pmf_args args; | 257 | struct pmf_args args; |
249 | u32 done = 0; | 258 | u32 done = 0; |
250 | unsigned long timeout; | 259 | unsigned long timeout; |
260 | int rc; | ||
261 | |||
262 | DBG("g5_pfunc_switch_freq(%d)\n", speed_mode); | ||
251 | 263 | ||
252 | /* If frequency is going up, first ramp up the voltage */ | 264 | /* If frequency is going up, first ramp up the voltage */ |
253 | if (speed_mode < g5_pmode_cur) | 265 | if (speed_mode < g5_pmode_cur) |
@@ -255,9 +267,12 @@ static int g5_pfunc_switch_freq(int speed_mode) | |||
255 | 267 | ||
256 | /* Do it */ | 268 | /* Do it */ |
257 | if (speed_mode == CPUFREQ_HIGH) | 269 | if (speed_mode == CPUFREQ_HIGH) |
258 | pmf_call_one(pfunc_cpu_setfreq_high, NULL); | 270 | rc = pmf_call_one(pfunc_cpu_setfreq_high, NULL); |
259 | else | 271 | else |
260 | pmf_call_one(pfunc_cpu_setfreq_low, NULL); | 272 | rc = pmf_call_one(pfunc_cpu_setfreq_low, NULL); |
273 | |||
274 | if (rc) | ||
275 | printk(KERN_WARNING "cpufreq: pfunc switch error %d\n", rc); | ||
261 | 276 | ||
262 | /* It's an irq GPIO so we should be able to just block here, | 277 | /* It's an irq GPIO so we should be able to just block here, |
263 | * I'll do that later after I've properly tested the IRQ code for | 278 | * I'll do that later after I've properly tested the IRQ code for |
@@ -296,13 +311,6 @@ static int g5_pfunc_query_freq(void) | |||
296 | return val ? CPUFREQ_HIGH : CPUFREQ_LOW; | 311 | return val ? CPUFREQ_HIGH : CPUFREQ_LOW; |
297 | } | 312 | } |
298 | 313 | ||
299 | /* | ||
300 | * Fake voltage switching for platforms with missing support | ||
301 | */ | ||
302 | |||
303 | static void g5_dummy_switch_volt(int speed_mode) | ||
304 | { | ||
305 | } | ||
306 | 314 | ||
307 | /* | 315 | /* |
308 | * Common interface to the cpufreq core | 316 | * Common interface to the cpufreq core |
@@ -375,6 +383,8 @@ static struct cpufreq_driver g5_cpufreq_driver = { | |||
375 | }; | 383 | }; |
376 | 384 | ||
377 | 385 | ||
386 | #ifdef CONFIG_PMAC_SMU | ||
387 | |||
378 | static int __init g5_neo2_cpufreq_init(struct device_node *cpus) | 388 | static int __init g5_neo2_cpufreq_init(struct device_node *cpus) |
379 | { | 389 | { |
380 | struct device_node *cpunode; | 390 | struct device_node *cpunode; |
@@ -525,6 +535,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) | |||
525 | return rc; | 535 | return rc; |
526 | } | 536 | } |
527 | 537 | ||
538 | #endif /* CONFIG_PMAC_SMU */ | ||
539 | |||
540 | |||
528 | static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | 541 | static int __init g5_pm72_cpufreq_init(struct device_node *cpus) |
529 | { | 542 | { |
530 | struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; | 543 | struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; |
@@ -533,6 +546,9 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | |||
533 | u64 max_freq, min_freq, ih, il; | 546 | u64 max_freq, min_freq, ih, il; |
534 | int has_volt = 1, rc = 0; | 547 | int has_volt = 1, rc = 0; |
535 | 548 | ||
549 | DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and" | ||
550 | " RackMac3,1...\n"); | ||
551 | |||
536 | /* Get first CPU node */ | 552 | /* Get first CPU node */ |
537 | for (cpunode = NULL; | 553 | for (cpunode = NULL; |
538 | (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { | 554 | (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { |
@@ -636,6 +652,15 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | |||
636 | */ | 652 | */ |
637 | ih = *((u32 *)(eeprom + 0x10)); | 653 | ih = *((u32 *)(eeprom + 0x10)); |
638 | il = *((u32 *)(eeprom + 0x20)); | 654 | il = *((u32 *)(eeprom + 0x20)); |
655 | |||
656 | /* Check for machines with no useful settings */ | ||
657 | if (il == ih) { | ||
658 | printk(KERN_WARNING "cpufreq: No low frequency mode available" | ||
659 | " on this model !\n"); | ||
660 | rc = -ENODEV; | ||
661 | goto bail; | ||
662 | } | ||
663 | |||
639 | min_freq = 0; | 664 | min_freq = 0; |
640 | if (ih != 0 && il != 0) | 665 | if (ih != 0 && il != 0) |
641 | min_freq = (max_freq * il) / ih; | 666 | min_freq = (max_freq * il) / ih; |
@@ -643,7 +668,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | |||
643 | /* Sanity check */ | 668 | /* Sanity check */ |
644 | if (min_freq >= max_freq || min_freq < 1000) { | 669 | if (min_freq >= max_freq || min_freq < 1000) { |
645 | printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n"); | 670 | printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n"); |
646 | rc = -ENODEV; | 671 | rc = -ENXIO; |
647 | goto bail; | 672 | goto bail; |
648 | } | 673 | } |
649 | g5_cpu_freqs[0].frequency = max_freq; | 674 | g5_cpu_freqs[0].frequency = max_freq; |
@@ -690,16 +715,10 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) | |||
690 | return rc; | 715 | return rc; |
691 | } | 716 | } |
692 | 717 | ||
693 | static int __init g5_rm31_cpufreq_init(struct device_node *cpus) | ||
694 | { | ||
695 | /* NYI */ | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | static int __init g5_cpufreq_init(void) | 718 | static int __init g5_cpufreq_init(void) |
700 | { | 719 | { |
701 | struct device_node *cpus; | 720 | struct device_node *cpus; |
702 | int rc; | 721 | int rc = 0; |
703 | 722 | ||
704 | cpus = of_find_node_by_path("/cpus"); | 723 | cpus = of_find_node_by_path("/cpus"); |
705 | if (cpus == NULL) { | 724 | if (cpus == NULL) { |
@@ -708,12 +727,13 @@ static int __init g5_cpufreq_init(void) | |||
708 | } | 727 | } |
709 | 728 | ||
710 | if (machine_is_compatible("PowerMac7,2") || | 729 | if (machine_is_compatible("PowerMac7,2") || |
711 | machine_is_compatible("PowerMac7,3")) | 730 | machine_is_compatible("PowerMac7,3") || |
731 | machine_is_compatible("RackMac3,1")) | ||
712 | rc = g5_pm72_cpufreq_init(cpus); | 732 | rc = g5_pm72_cpufreq_init(cpus); |
713 | else if (machine_is_compatible("RackMac3,1")) | 733 | #ifdef CONFIG_PMAC_SMU |
714 | rc = g5_rm31_cpufreq_init(cpus); | ||
715 | else | 734 | else |
716 | rc = g5_neo2_cpufreq_init(cpus); | 735 | rc = g5_neo2_cpufreq_init(cpus); |
736 | #endif /* CONFIG_PMAC_SMU */ | ||
717 | 737 | ||
718 | of_node_put(cpus); | 738 | of_node_put(cpus); |
719 | return rc; | 739 | return rc; |