aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/macintosh
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2006-09-19 01:56:44 -0400
committerDmitry Torokhov <dtor@insightbb.com>2006-09-19 01:56:44 -0400
commit0612ec48762bf8712db1925b2e67246d2237ebab (patch)
tree01b0d69c9c9915015c0f23ad4263646dd5413e99 /drivers/macintosh
parent4263cf0fac28122c8381b6f4f9441a43cd93c81f (diff)
parent47a5c6fa0e204a2b63309c648bb2fde36836c826 (diff)
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/Kconfig14
-rw-r--r--drivers/macintosh/adbhid.c14
-rw-r--r--drivers/macintosh/macio_asic.c2
-rw-r--r--drivers/macintosh/smu.c53
-rw-r--r--drivers/macintosh/therm_pm72.c218
-rw-r--r--drivers/macintosh/therm_pm72.h33
-rw-r--r--drivers/macintosh/via-pmu-backlight.c121
-rw-r--r--drivers/macintosh/via-pmu-led.c2
-rw-r--r--drivers/macintosh/via-pmu.c51
9 files changed, 394 insertions, 114 deletions
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 54f3f6b94efc..d5d649f5ccdb 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -90,6 +90,15 @@ config ADB_PMU_LED
90 and the ide-disk LED trigger and configure appropriately through 90 and the ide-disk LED trigger and configure appropriately through
91 sysfs. 91 sysfs.
92 92
93config ADB_PMU_LED_IDE
94 bool "Use front LED as IDE LED by default"
95 depends on ADB_PMU_LED
96 select LEDS_TRIGGERS
97 select LEDS_TRIGGER_IDE_DISK
98 help
99 This option makes the front LED default to the IDE trigger
100 so that it blinks on IDE activity.
101
93config PMAC_SMU 102config PMAC_SMU
94 bool "Support for SMU based PowerMacs" 103 bool "Support for SMU based PowerMacs"
95 depends on PPC_PMAC64 104 depends on PPC_PMAC64
@@ -100,7 +109,7 @@ config PMAC_SMU
100 109
101config PMAC_APM_EMU 110config PMAC_APM_EMU
102 tristate "APM emulation" 111 tristate "APM emulation"
103 depends on PPC_PMAC && PPC32 && PM 112 depends on PPC_PMAC && PPC32 && PM && ADB_PMU
104 113
105config PMAC_MEDIABAY 114config PMAC_MEDIABAY
106 bool "Support PowerBook hotswap media bay" 115 bool "Support PowerBook hotswap media bay"
@@ -113,7 +122,8 @@ config PMAC_MEDIABAY
113 122
114config PMAC_BACKLIGHT 123config PMAC_BACKLIGHT
115 bool "Backlight control for LCD screens" 124 bool "Backlight control for LCD screens"
116 depends on ADB_PMU && (BROKEN || !PPC64) 125 depends on ADB_PMU && FB = y && (BROKEN || !PPC64)
126 select FB_BACKLIGHT
117 help 127 help
118 Say Y here to enable Macintosh specific extensions of the generic 128 Say Y here to enable Macintosh specific extensions of the generic
119 backlight code. With this enabled, the brightness keys on older 129 backlight code. With this enabled, the brightness keys on older
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 545be1ed6927..c69d23bb255e 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -45,14 +45,11 @@
45#include <linux/pmu.h> 45#include <linux/pmu.h>
46 46
47#include <asm/machdep.h> 47#include <asm/machdep.h>
48#include <asm/backlight.h>
48#ifdef CONFIG_PPC_PMAC 49#ifdef CONFIG_PPC_PMAC
49#include <asm/pmac_feature.h> 50#include <asm/pmac_feature.h>
50#endif 51#endif
51 52
52#ifdef CONFIG_PMAC_BACKLIGHT
53#include <asm/backlight.h>
54#endif
55
56MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>"); 53MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>");
57 54
58#define KEYB_KEYREG 0 /* register # for key up/down data */ 55#define KEYB_KEYREG 0 /* register # for key up/down data */
@@ -237,11 +234,6 @@ static struct adb_ids keyboard_ids;
237static struct adb_ids mouse_ids; 234static struct adb_ids mouse_ids;
238static struct adb_ids buttons_ids; 235static struct adb_ids buttons_ids;
239 236
240#ifdef CONFIG_PMAC_BACKLIGHT
241/* Exported to via-pmu.c */
242int disable_kernel_backlight = 0;
243#endif /* CONFIG_PMAC_BACKLIGHT */
244
245/* Kind of keyboard, see Apple technote 1152 */ 237/* Kind of keyboard, see Apple technote 1152 */
246#define ADB_KEYBOARD_UNKNOWN 0 238#define ADB_KEYBOARD_UNKNOWN 0
247#define ADB_KEYBOARD_ANSI 0x0100 239#define ADB_KEYBOARD_ANSI 0x0100
@@ -527,7 +519,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
527 519
528 case 0xa: /* brightness decrease */ 520 case 0xa: /* brightness decrease */
529#ifdef CONFIG_PMAC_BACKLIGHT 521#ifdef CONFIG_PMAC_BACKLIGHT
530 if (!disable_kernel_backlight && down) 522 if (down)
531 pmac_backlight_key_down(); 523 pmac_backlight_key_down();
532#endif 524#endif
533 input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); 525 input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
@@ -535,7 +527,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
535 527
536 case 0x9: /* brightness increase */ 528 case 0x9: /* brightness increase */
537#ifdef CONFIG_PMAC_BACKLIGHT 529#ifdef CONFIG_PMAC_BACKLIGHT
538 if (!disable_kernel_backlight && down) 530 if (down)
539 pmac_backlight_key_up(); 531 pmac_backlight_key_up();
540#endif 532#endif
541 input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down); 533 input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 80c0c665b5f6..82657bc86d19 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -330,7 +330,7 @@ static void macio_create_fixup_irq(struct macio_dev *dev, int index,
330{ 330{
331 unsigned int irq; 331 unsigned int irq;
332 332
333 irq = irq_create_mapping(NULL, line, 0); 333 irq = irq_create_mapping(NULL, line);
334 if (irq != NO_IRQ) { 334 if (irq != NO_IRQ) {
335 dev->interrupt[index].start = irq; 335 dev->interrupt[index].start = irq;
336 dev->interrupt[index].flags = IORESOURCE_IRQ; 336 dev->interrupt[index].flags = IORESOURCE_IRQ;
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index f139a74696fe..00ef46898147 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -75,9 +75,11 @@ struct smu_device {
75 struct of_device *of_dev; 75 struct of_device *of_dev;
76 int doorbell; /* doorbell gpio */ 76 int doorbell; /* doorbell gpio */
77 u32 __iomem *db_buf; /* doorbell buffer */ 77 u32 __iomem *db_buf; /* doorbell buffer */
78 int db_irq; 78 struct device_node *db_node;
79 unsigned int db_irq;
79 int msg; 80 int msg;
80 int msg_irq; 81 struct device_node *msg_node;
82 unsigned int msg_irq;
81 struct smu_cmd_buf *cmd_buf; /* command buffer virtual */ 83 struct smu_cmd_buf *cmd_buf; /* command buffer virtual */
82 u32 cmd_buf_abs; /* command buffer absolute */ 84 u32 cmd_buf_abs; /* command buffer absolute */
83 struct list_head cmd_list; 85 struct list_head cmd_list;
@@ -93,6 +95,7 @@ struct smu_device {
93 */ 95 */
94static struct smu_device *smu; 96static struct smu_device *smu;
95static DEFINE_MUTEX(smu_part_access); 97static DEFINE_MUTEX(smu_part_access);
98static int smu_irq_inited;
96 99
97static void smu_i2c_retry(unsigned long data); 100static void smu_i2c_retry(unsigned long data);
98 101
@@ -257,6 +260,10 @@ int smu_queue_cmd(struct smu_cmd *cmd)
257 smu_start_cmd(); 260 smu_start_cmd();
258 spin_unlock_irqrestore(&smu->lock, flags); 261 spin_unlock_irqrestore(&smu->lock, flags);
259 262
263 /* Workaround for early calls when irq isn't available */
264 if (!smu_irq_inited || smu->db_irq == NO_IRQ)
265 smu_spinwait_cmd(cmd);
266
260 return 0; 267 return 0;
261} 268}
262EXPORT_SYMBOL(smu_queue_cmd); 269EXPORT_SYMBOL(smu_queue_cmd);
@@ -478,14 +485,15 @@ int __init smu_init (void)
478 smu->cmd_buf_abs = (u32)smu_cmdbuf_abs; 485 smu->cmd_buf_abs = (u32)smu_cmdbuf_abs;
479 smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs); 486 smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs);
480 487
481 np = of_find_node_by_name(NULL, "smu-doorbell"); 488 smu->db_node = of_find_node_by_name(NULL, "smu-doorbell");
482 if (np == NULL) { 489 if (smu->db_node == NULL) {
483 printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); 490 printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n");
484 goto fail; 491 goto fail;
485 } 492 }
486 data = (u32 *)get_property(np, "reg", NULL); 493 data = (u32 *)get_property(smu->db_node, "reg", NULL);
487 if (data == NULL) { 494 if (data == NULL) {
488 of_node_put(np); 495 of_node_put(smu->db_node);
496 smu->db_node = NULL;
489 printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); 497 printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n");
490 goto fail; 498 goto fail;
491 } 499 }
@@ -497,25 +505,21 @@ int __init smu_init (void)
497 smu->doorbell = *data; 505 smu->doorbell = *data;
498 if (smu->doorbell < 0x50) 506 if (smu->doorbell < 0x50)
499 smu->doorbell += 0x50; 507 smu->doorbell += 0x50;
500 smu->db_irq = irq_of_parse_and_map(np, 0);
501
502 of_node_put(np);
503 508
504 /* Now look for the smu-interrupt GPIO */ 509 /* Now look for the smu-interrupt GPIO */
505 do { 510 do {
506 np = of_find_node_by_name(NULL, "smu-interrupt"); 511 smu->msg_node = of_find_node_by_name(NULL, "smu-interrupt");
507 if (np == NULL) 512 if (smu->msg_node == NULL)
508 break; 513 break;
509 data = (u32 *)get_property(np, "reg", NULL); 514 data = (u32 *)get_property(smu->msg_node, "reg", NULL);
510 if (data == NULL) { 515 if (data == NULL) {
511 of_node_put(np); 516 of_node_put(smu->msg_node);
517 smu->msg_node = NULL;
512 break; 518 break;
513 } 519 }
514 smu->msg = *data; 520 smu->msg = *data;
515 if (smu->msg < 0x50) 521 if (smu->msg < 0x50)
516 smu->msg += 0x50; 522 smu->msg += 0x50;
517 smu->msg_irq = irq_of_parse_and_map(np, 0);
518 of_node_put(np);
519 } while(0); 523 } while(0);
520 524
521 /* Doorbell buffer is currently hard-coded, I didn't find a proper 525 /* Doorbell buffer is currently hard-coded, I didn't find a proper
@@ -547,6 +551,19 @@ static int smu_late_init(void)
547 smu->i2c_timer.function = smu_i2c_retry; 551 smu->i2c_timer.function = smu_i2c_retry;
548 smu->i2c_timer.data = (unsigned long)smu; 552 smu->i2c_timer.data = (unsigned long)smu;
549 553
554 if (smu->db_node) {
555 smu->db_irq = irq_of_parse_and_map(smu->db_node, 0);
556 if (smu->db_irq == NO_IRQ)
557 printk(KERN_ERR "smu: failed to map irq for node %s\n",
558 smu->db_node->full_name);
559 }
560 if (smu->msg_node) {
561 smu->msg_irq = irq_of_parse_and_map(smu->msg_node, 0);
562 if (smu->msg_irq == NO_IRQ)
563 printk(KERN_ERR "smu: failed to map irq for node %s\n",
564 smu->msg_node->full_name);
565 }
566
550 /* 567 /*
551 * Try to request the interrupts 568 * Try to request the interrupts
552 */ 569 */
@@ -571,6 +588,7 @@ static int smu_late_init(void)
571 } 588 }
572 } 589 }
573 590
591 smu_irq_inited = 1;
574 return 0; 592 return 0;
575} 593}
576/* This has to be before arch_initcall as the low i2c stuff relies on the 594/* This has to be before arch_initcall as the low i2c stuff relies on the
@@ -742,6 +760,11 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
742 if (fail && --cmd->retries > 0) { 760 if (fail && --cmd->retries > 0) {
743 DPRINTK("SMU: i2c failure, starting timer...\n"); 761 DPRINTK("SMU: i2c failure, starting timer...\n");
744 BUG_ON(cmd != smu->cmd_i2c_cur); 762 BUG_ON(cmd != smu->cmd_i2c_cur);
763 if (!smu_irq_inited) {
764 mdelay(5);
765 smu_i2c_retry(0);
766 return;
767 }
745 mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5)); 768 mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5));
746 return; 769 return;
747 } 770 }
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index c1fe0b368f76..20bf67244e2c 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -95,6 +95,17 @@
95 * - Use min/max macros here or there 95 * - Use min/max macros here or there
96 * - Latest darwin updated U3H min fan speed to 20% PWM 96 * - Latest darwin updated U3H min fan speed to 20% PWM
97 * 97 *
98 * July. 06, 2006 : 1.3
99 * - Fix setting of RPM fans on Xserve G5 (they were going too fast)
100 * - Add missing slots fan control loop for Xserve G5
101 * - Lower fixed slots fan speed from 50% to 40% on desktop G5s. We
102 * still can't properly implement the control loop for these, so let's
103 * reduce the noise a little bit, it appears that 40% still gives us
104 * a pretty good air flow
105 * - Add code to "tickle" the FCU regulary so it doesn't think that
106 * we are gone while in fact, the machine just didn't need any fan
107 * speed change lately
108 *
98 */ 109 */
99 110
100#include <linux/types.h> 111#include <linux/types.h>
@@ -121,7 +132,7 @@
121 132
122#include "therm_pm72.h" 133#include "therm_pm72.h"
123 134
124#define VERSION "1.2b2" 135#define VERSION "1.3"
125 136
126#undef DEBUG 137#undef DEBUG
127 138
@@ -146,6 +157,7 @@ static struct basckside_pid_params backside_params;
146static struct backside_pid_state backside_state; 157static struct backside_pid_state backside_state;
147static struct drives_pid_state drives_state; 158static struct drives_pid_state drives_state;
148static struct dimm_pid_state dimms_state; 159static struct dimm_pid_state dimms_state;
160static struct slots_pid_state slots_state;
149static int state; 161static int state;
150static int cpu_count; 162static int cpu_count;
151static int cpu_pid_type; 163static int cpu_pid_type;
@@ -154,7 +166,8 @@ static struct completion ctrl_complete;
154static int critical_state; 166static int critical_state;
155static int rackmac; 167static int rackmac;
156static s32 dimm_output_clamp; 168static s32 dimm_output_clamp;
157 169static int fcu_rpm_shift;
170static int fcu_tickle_ticks;
158static DECLARE_MUTEX(driver_lock); 171static DECLARE_MUTEX(driver_lock);
159 172
160/* 173/*
@@ -495,13 +508,20 @@ static int start_fcu(void)
495 rc = fan_write_reg(0x2e, &buf, 1); 508 rc = fan_write_reg(0x2e, &buf, 1);
496 if (rc < 0) 509 if (rc < 0)
497 return -EIO; 510 return -EIO;
511 rc = fan_read_reg(0, &buf, 1);
512 if (rc < 0)
513 return -EIO;
514 fcu_rpm_shift = (buf == 1) ? 2 : 3;
515 printk(KERN_DEBUG "FCU Initialized, RPM fan shift is %d\n",
516 fcu_rpm_shift);
517
498 return 0; 518 return 0;
499} 519}
500 520
501static int set_rpm_fan(int fan_index, int rpm) 521static int set_rpm_fan(int fan_index, int rpm)
502{ 522{
503 unsigned char buf[2]; 523 unsigned char buf[2];
504 int rc, id; 524 int rc, id, min, max;
505 525
506 if (fcu_fans[fan_index].type != FCU_FAN_RPM) 526 if (fcu_fans[fan_index].type != FCU_FAN_RPM)
507 return -EINVAL; 527 return -EINVAL;
@@ -509,12 +529,15 @@ static int set_rpm_fan(int fan_index, int rpm)
509 if (id == FCU_FAN_ABSENT_ID) 529 if (id == FCU_FAN_ABSENT_ID)
510 return -EINVAL; 530 return -EINVAL;
511 531
512 if (rpm < 300) 532 min = 2400 >> fcu_rpm_shift;
513 rpm = 300; 533 max = 56000 >> fcu_rpm_shift;
514 else if (rpm > 8191) 534
515 rpm = 8191; 535 if (rpm < min)
516 buf[0] = rpm >> 5; 536 rpm = min;
517 buf[1] = rpm << 3; 537 else if (rpm > max)
538 rpm = max;
539 buf[0] = rpm >> (8 - fcu_rpm_shift);
540 buf[1] = rpm << fcu_rpm_shift;
518 rc = fan_write_reg(0x10 + (id * 2), buf, 2); 541 rc = fan_write_reg(0x10 + (id * 2), buf, 2);
519 if (rc < 0) 542 if (rc < 0)
520 return -EIO; 543 return -EIO;
@@ -551,7 +574,7 @@ static int get_rpm_fan(int fan_index, int programmed)
551 if (rc != 2) 574 if (rc != 2)
552 return -EIO; 575 return -EIO;
553 576
554 return (buf[0] << 5) | buf[1] >> 3; 577 return (buf[0] << (8 - fcu_rpm_shift)) | buf[1] >> fcu_rpm_shift;
555} 578}
556 579
557static int set_pwm_fan(int fan_index, int pwm) 580static int set_pwm_fan(int fan_index, int pwm)
@@ -609,6 +632,26 @@ static int get_pwm_fan(int fan_index)
609 return (buf[0] * 1000) / 2559; 632 return (buf[0] * 1000) / 2559;
610} 633}
611 634
635static void tickle_fcu(void)
636{
637 int pwm;
638
639 pwm = get_pwm_fan(SLOTS_FAN_PWM_INDEX);
640
641 DBG("FCU Tickle, slots fan is: %d\n", pwm);
642 if (pwm < 0)
643 pwm = 100;
644
645 if (!rackmac) {
646 pwm = SLOTS_FAN_DEFAULT_PWM;
647 } else if (pwm < SLOTS_PID_OUTPUT_MIN)
648 pwm = SLOTS_PID_OUTPUT_MIN;
649
650 /* That is hopefully enough to make the FCU happy */
651 set_pwm_fan(SLOTS_FAN_PWM_INDEX, pwm);
652}
653
654
612/* 655/*
613 * Utility routine to read the CPU calibration EEPROM data 656 * Utility routine to read the CPU calibration EEPROM data
614 * from the device-tree 657 * from the device-tree
@@ -715,6 +758,9 @@ BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
715BUILD_SHOW_FUNC_FIX(drives_temperature, drives_state.last_temp) 758BUILD_SHOW_FUNC_FIX(drives_temperature, drives_state.last_temp)
716BUILD_SHOW_FUNC_INT(drives_fan_rpm, drives_state.rpm) 759BUILD_SHOW_FUNC_INT(drives_fan_rpm, drives_state.rpm)
717 760
761BUILD_SHOW_FUNC_FIX(slots_temperature, slots_state.last_temp)
762BUILD_SHOW_FUNC_INT(slots_fan_pwm, slots_state.pwm)
763
718BUILD_SHOW_FUNC_FIX(dimms_temperature, dimms_state.last_temp) 764BUILD_SHOW_FUNC_FIX(dimms_temperature, dimms_state.last_temp)
719 765
720static DEVICE_ATTR(cpu0_temperature,S_IRUGO,show_cpu0_temperature,NULL); 766static DEVICE_ATTR(cpu0_temperature,S_IRUGO,show_cpu0_temperature,NULL);
@@ -735,6 +781,9 @@ static DEVICE_ATTR(backside_fan_pwm,S_IRUGO,show_backside_fan_pwm,NULL);
735static DEVICE_ATTR(drives_temperature,S_IRUGO,show_drives_temperature,NULL); 781static DEVICE_ATTR(drives_temperature,S_IRUGO,show_drives_temperature,NULL);
736static DEVICE_ATTR(drives_fan_rpm,S_IRUGO,show_drives_fan_rpm,NULL); 782static DEVICE_ATTR(drives_fan_rpm,S_IRUGO,show_drives_fan_rpm,NULL);
737 783
784static DEVICE_ATTR(slots_temperature,S_IRUGO,show_slots_temperature,NULL);
785static DEVICE_ATTR(slots_fan_pwm,S_IRUGO,show_slots_fan_pwm,NULL);
786
738static DEVICE_ATTR(dimms_temperature,S_IRUGO,show_dimms_temperature,NULL); 787static DEVICE_ATTR(dimms_temperature,S_IRUGO,show_dimms_temperature,NULL);
739 788
740/* 789/*
@@ -1076,6 +1125,9 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
1076 fan_min = dimm_output_clamp; 1125 fan_min = dimm_output_clamp;
1077 fan_min = max(fan_min, (int)state->mpu.rminn_intake_fan); 1126 fan_min = max(fan_min, (int)state->mpu.rminn_intake_fan);
1078 1127
1128 DBG(" CPU min mpu = %d, min dimm = %d\n",
1129 state->mpu.rminn_intake_fan, dimm_output_clamp);
1130
1079 state->rpm = max(state->rpm, (int)fan_min); 1131 state->rpm = max(state->rpm, (int)fan_min);
1080 state->rpm = min(state->rpm, (int)state->mpu.rmaxn_intake_fan); 1132 state->rpm = min(state->rpm, (int)state->mpu.rmaxn_intake_fan);
1081 state->intake_rpm = state->rpm; 1133 state->intake_rpm = state->rpm;
@@ -1374,7 +1426,8 @@ static void do_monitor_drives(struct drives_pid_state *state)
1374 DBG(" current rpm: %d\n", state->rpm); 1426 DBG(" current rpm: %d\n", state->rpm);
1375 1427
1376 /* Get some sensor readings */ 1428 /* Get some sensor readings */
1377 temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor, DS1775_TEMP)) << 8; 1429 temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor,
1430 DS1775_TEMP)) << 8;
1378 state->last_temp = temp; 1431 state->last_temp = temp;
1379 DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp), 1432 DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp),
1380 FIX32TOPRINT(DRIVES_PID_INPUT_TARGET)); 1433 FIX32TOPRINT(DRIVES_PID_INPUT_TARGET));
@@ -1575,7 +1628,7 @@ static int init_dimms_state(struct dimm_pid_state *state)
1575} 1628}
1576 1629
1577/* 1630/*
1578 * Dispose of the state data for the drives control loop 1631 * Dispose of the state data for the DIMM control loop
1579 */ 1632 */
1580static void dispose_dimms_state(struct dimm_pid_state *state) 1633static void dispose_dimms_state(struct dimm_pid_state *state)
1581{ 1634{
@@ -1588,6 +1641,127 @@ static void dispose_dimms_state(struct dimm_pid_state *state)
1588 state->monitor = NULL; 1641 state->monitor = NULL;
1589} 1642}
1590 1643
1644/*
1645 * Slots fan control loop
1646 */
1647static void do_monitor_slots(struct slots_pid_state *state)
1648{
1649 s32 temp, integral, derivative;
1650 s64 integ_p, deriv_p, prop_p, sum;
1651 int i, rc;
1652
1653 if (--state->ticks != 0)
1654 return;
1655 state->ticks = SLOTS_PID_INTERVAL;
1656
1657 DBG("slots:\n");
1658
1659 /* Check fan status */
1660 rc = get_pwm_fan(SLOTS_FAN_PWM_INDEX);
1661 if (rc < 0) {
1662 printk(KERN_WARNING "Error %d reading slots fan !\n", rc);
1663 /* XXX What do we do now ? */
1664 } else
1665 state->pwm = rc;
1666 DBG(" current pwm: %d\n", state->pwm);
1667
1668 /* Get some sensor readings */
1669 temp = le16_to_cpu(i2c_smbus_read_word_data(state->monitor,
1670 DS1775_TEMP)) << 8;
1671 state->last_temp = temp;
1672 DBG(" temp: %d.%03d, target: %d.%03d\n", FIX32TOPRINT(temp),
1673 FIX32TOPRINT(SLOTS_PID_INPUT_TARGET));
1674
1675 /* Store temperature and error in history array */
1676 state->cur_sample = (state->cur_sample + 1) % SLOTS_PID_HISTORY_SIZE;
1677 state->sample_history[state->cur_sample] = temp;
1678 state->error_history[state->cur_sample] = temp - SLOTS_PID_INPUT_TARGET;
1679
1680 /* If first loop, fill the history table */
1681 if (state->first) {
1682 for (i = 0; i < (SLOTS_PID_HISTORY_SIZE - 1); i++) {
1683 state->cur_sample = (state->cur_sample + 1) %
1684 SLOTS_PID_HISTORY_SIZE;
1685 state->sample_history[state->cur_sample] = temp;
1686 state->error_history[state->cur_sample] =
1687 temp - SLOTS_PID_INPUT_TARGET;
1688 }
1689 state->first = 0;
1690 }
1691
1692 /* Calculate the integral term */
1693 sum = 0;
1694 integral = 0;
1695 for (i = 0; i < SLOTS_PID_HISTORY_SIZE; i++)
1696 integral += state->error_history[i];
1697 integral *= SLOTS_PID_INTERVAL;
1698 DBG(" integral: %08x\n", integral);
1699 integ_p = ((s64)SLOTS_PID_G_r) * (s64)integral;
1700 DBG(" integ_p: %d\n", (int)(integ_p >> 36));
1701 sum += integ_p;
1702
1703 /* Calculate the derivative term */
1704 derivative = state->error_history[state->cur_sample] -
1705 state->error_history[(state->cur_sample + SLOTS_PID_HISTORY_SIZE - 1)
1706 % SLOTS_PID_HISTORY_SIZE];
1707 derivative /= SLOTS_PID_INTERVAL;
1708 deriv_p = ((s64)SLOTS_PID_G_d) * (s64)derivative;
1709 DBG(" deriv_p: %d\n", (int)(deriv_p >> 36));
1710 sum += deriv_p;
1711
1712 /* Calculate the proportional term */
1713 prop_p = ((s64)SLOTS_PID_G_p) * (s64)(state->error_history[state->cur_sample]);
1714 DBG(" prop_p: %d\n", (int)(prop_p >> 36));
1715 sum += prop_p;
1716
1717 /* Scale sum */
1718 sum >>= 36;
1719
1720 DBG(" sum: %d\n", (int)sum);
1721 state->pwm = (s32)sum;
1722
1723 state->pwm = max(state->pwm, SLOTS_PID_OUTPUT_MIN);
1724 state->pwm = min(state->pwm, SLOTS_PID_OUTPUT_MAX);
1725
1726 DBG("** DRIVES PWM: %d\n", (int)state->pwm);
1727 set_pwm_fan(SLOTS_FAN_PWM_INDEX, state->pwm);
1728}
1729
1730/*
1731 * Initialize the state structure for the slots bay fan control loop
1732 */
1733static int init_slots_state(struct slots_pid_state *state)
1734{
1735 state->ticks = 1;
1736 state->first = 1;
1737 state->pwm = 50;
1738
1739 state->monitor = attach_i2c_chip(XSERVE_SLOTS_LM75, "slots_temp");
1740 if (state->monitor == NULL)
1741 return -ENODEV;
1742
1743 device_create_file(&of_dev->dev, &dev_attr_slots_temperature);
1744 device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
1745
1746 return 0;
1747}
1748
1749/*
1750 * Dispose of the state data for the slots control loop
1751 */
1752static void dispose_slots_state(struct slots_pid_state *state)
1753{
1754 if (state->monitor == NULL)
1755 return;
1756
1757 device_remove_file(&of_dev->dev, &dev_attr_slots_temperature);
1758 device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
1759
1760 detach_i2c_chip(state->monitor);
1761 state->monitor = NULL;
1762}
1763
1764
1591static int call_critical_overtemp(void) 1765static int call_critical_overtemp(void)
1592{ 1766{
1593 char *argv[] = { critical_overtemp_path, NULL }; 1767 char *argv[] = { critical_overtemp_path, NULL };
@@ -1617,14 +1791,17 @@ static int main_control_loop(void *x)
1617 goto out; 1791 goto out;
1618 } 1792 }
1619 1793
1620 /* Set the PCI fan once for now */ 1794 /* Set the PCI fan once for now on non-RackMac */
1621 set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM); 1795 if (!rackmac)
1796 set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
1622 1797
1623 /* Initialize ADCs */ 1798 /* Initialize ADCs */
1624 initialize_adc(&cpu_state[0]); 1799 initialize_adc(&cpu_state[0]);
1625 if (cpu_state[1].monitor != NULL) 1800 if (cpu_state[1].monitor != NULL)
1626 initialize_adc(&cpu_state[1]); 1801 initialize_adc(&cpu_state[1]);
1627 1802
1803 fcu_tickle_ticks = FCU_TICKLE_TICKS;
1804
1628 up(&driver_lock); 1805 up(&driver_lock);
1629 1806
1630 while (state == state_attached) { 1807 while (state == state_attached) {
@@ -1634,6 +1811,12 @@ static int main_control_loop(void *x)
1634 1811
1635 down(&driver_lock); 1812 down(&driver_lock);
1636 1813
1814 /* Tickle the FCU just in case */
1815 if (--fcu_tickle_ticks < 0) {
1816 fcu_tickle_ticks = FCU_TICKLE_TICKS;
1817 tickle_fcu();
1818 }
1819
1637 /* First, we always calculate the new DIMMs state on an Xserve */ 1820 /* First, we always calculate the new DIMMs state on an Xserve */
1638 if (rackmac) 1821 if (rackmac)
1639 do_monitor_dimms(&dimms_state); 1822 do_monitor_dimms(&dimms_state);
@@ -1654,7 +1837,9 @@ static int main_control_loop(void *x)
1654 } 1837 }
1655 /* Then, the rest */ 1838 /* Then, the rest */
1656 do_monitor_backside(&backside_state); 1839 do_monitor_backside(&backside_state);
1657 if (!rackmac) 1840 if (rackmac)
1841 do_monitor_slots(&slots_state);
1842 else
1658 do_monitor_drives(&drives_state); 1843 do_monitor_drives(&drives_state);
1659 up(&driver_lock); 1844 up(&driver_lock);
1660 1845
@@ -1696,6 +1881,7 @@ static void dispose_control_loops(void)
1696 dispose_cpu_state(&cpu_state[1]); 1881 dispose_cpu_state(&cpu_state[1]);
1697 dispose_backside_state(&backside_state); 1882 dispose_backside_state(&backside_state);
1698 dispose_drives_state(&drives_state); 1883 dispose_drives_state(&drives_state);
1884 dispose_slots_state(&slots_state);
1699 dispose_dimms_state(&dimms_state); 1885 dispose_dimms_state(&dimms_state);
1700} 1886}
1701 1887
@@ -1745,6 +1931,8 @@ static int create_control_loops(void)
1745 goto fail; 1931 goto fail;
1746 if (rackmac && init_dimms_state(&dimms_state)) 1932 if (rackmac && init_dimms_state(&dimms_state))
1747 goto fail; 1933 goto fail;
1934 if (rackmac && init_slots_state(&slots_state))
1935 goto fail;
1748 if (!rackmac && init_drives_state(&drives_state)) 1936 if (!rackmac && init_drives_state(&drives_state))
1749 goto fail; 1937 goto fail;
1750 1938
diff --git a/drivers/macintosh/therm_pm72.h b/drivers/macintosh/therm_pm72.h
index fc7e9b7ecaf2..393cc9df94e1 100644
--- a/drivers/macintosh/therm_pm72.h
+++ b/drivers/macintosh/therm_pm72.h
@@ -105,6 +105,7 @@ static char * critical_overtemp_path = "/sbin/critical_overtemp";
105#define DRIVES_DALLAS_ID 0x94 105#define DRIVES_DALLAS_ID 0x94
106#define BACKSIDE_MAX_ID 0x98 106#define BACKSIDE_MAX_ID 0x98
107#define XSERVE_DIMMS_LM87 0x25a 107#define XSERVE_DIMMS_LM87 0x25a
108#define XSERVE_SLOTS_LM75 0x290
108 109
109/* 110/*
110 * Some MAX6690, DS1775, LM87 register definitions 111 * Some MAX6690, DS1775, LM87 register definitions
@@ -198,7 +199,7 @@ struct drives_pid_state
198 199
199#define SLOTS_FAN_PWM_DEFAULT_ID 2 200#define SLOTS_FAN_PWM_DEFAULT_ID 2
200#define SLOTS_FAN_PWM_INDEX 2 201#define SLOTS_FAN_PWM_INDEX 2
201#define SLOTS_FAN_DEFAULT_PWM 50 /* Do better here ! */ 202#define SLOTS_FAN_DEFAULT_PWM 40 /* Do better here ! */
202 203
203 204
204/* 205/*
@@ -206,7 +207,7 @@ struct drives_pid_state
206 */ 207 */
207#define DIMM_PID_G_d 0 208#define DIMM_PID_G_d 0
208#define DIMM_PID_G_p 0 209#define DIMM_PID_G_p 0
209#define DIMM_PID_G_r 0x6553600 210#define DIMM_PID_G_r 0x06553600
210#define DIMM_PID_INPUT_TARGET 3276800 211#define DIMM_PID_INPUT_TARGET 3276800
211#define DIMM_PID_INTERVAL 1 212#define DIMM_PID_INTERVAL 1
212#define DIMM_PID_OUTPUT_MAX 14000 213#define DIMM_PID_OUTPUT_MAX 14000
@@ -226,6 +227,31 @@ struct dimm_pid_state
226}; 227};
227 228
228 229
230/*
231 * PID factors for the Xserve Slots control loop
232 */
233#define SLOTS_PID_G_d 0
234#define SLOTS_PID_G_p 0
235#define SLOTS_PID_G_r 0x00100000
236#define SLOTS_PID_INPUT_TARGET 3200000
237#define SLOTS_PID_INTERVAL 1
238#define SLOTS_PID_OUTPUT_MAX 100
239#define SLOTS_PID_OUTPUT_MIN 20
240#define SLOTS_PID_HISTORY_SIZE 20
241
242struct slots_pid_state
243{
244 int ticks;
245 struct i2c_client * monitor;
246 s32 sample_history[SLOTS_PID_HISTORY_SIZE];
247 s32 error_history[SLOTS_PID_HISTORY_SIZE];
248 int cur_sample;
249 s32 last_temp;
250 int first;
251 int pwm;
252};
253
254
229 255
230/* Desktops */ 256/* Desktops */
231 257
@@ -283,6 +309,9 @@ struct cpu_pid_state
283 s32 pump_max; 309 s32 pump_max;
284}; 310};
285 311
312/* Tickle FCU every 10 seconds */
313#define FCU_TICKLE_TICKS 10
314
286/* 315/*
287 * Driver state 316 * Driver state
288 */ 317 */
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index b42d05f2aaff..a82f313d9dc9 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -15,19 +15,51 @@
15 15
16#define MAX_PMU_LEVEL 0xFF 16#define MAX_PMU_LEVEL 0xFF
17 17
18static struct device_node *vias;
19static struct backlight_properties pmu_backlight_data; 18static struct backlight_properties pmu_backlight_data;
19static spinlock_t pmu_backlight_lock;
20static int sleeping;
21static u8 bl_curve[FB_BACKLIGHT_LEVELS];
20 22
21static int pmu_backlight_get_level_brightness(struct fb_info *info, 23static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
22 int level) 24{
25 unsigned int i, flat, count, range = (max - min);
26
27 bl_curve[0] = off;
28
29 for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
30 bl_curve[flat] = min;
31
32 count = FB_BACKLIGHT_LEVELS * 15 / 16;
33 for (i = 0; i < count; ++i)
34 bl_curve[flat + i] = min + (range * (i + 1) / count);
35}
36
37static int pmu_backlight_curve_lookup(int value)
38{
39 int level = (FB_BACKLIGHT_LEVELS - 1);
40 int i, max = 0;
41
42 /* Look for biggest value */
43 for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
44 max = max((int)bl_curve[i], max);
45
46 /* Look for nearest value */
47 for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
48 int diff = abs(bl_curve[i] - value);
49 if (diff < max) {
50 max = diff;
51 level = i;
52 }
53 }
54 return level;
55}
56
57static int pmu_backlight_get_level_brightness(int level)
23{ 58{
24 int pmulevel; 59 int pmulevel;
25 60
26 /* Get and convert the value */ 61 /* Get and convert the value */
27 mutex_lock(&info->bl_mutex); 62 pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
28 pmulevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
29 mutex_unlock(&info->bl_mutex);
30
31 if (pmulevel < 0) 63 if (pmulevel < 0)
32 pmulevel = 0; 64 pmulevel = 0;
33 else if (pmulevel > MAX_PMU_LEVEL) 65 else if (pmulevel > MAX_PMU_LEVEL)
@@ -38,25 +70,37 @@ static int pmu_backlight_get_level_brightness(struct fb_info *info,
38 70
39static int pmu_backlight_update_status(struct backlight_device *bd) 71static int pmu_backlight_update_status(struct backlight_device *bd)
40{ 72{
41 struct fb_info *info = class_get_devdata(&bd->class_dev);
42 struct adb_request req; 73 struct adb_request req;
43 int pmulevel, level = bd->props->brightness; 74 unsigned long flags;
75 int level = bd->props->brightness;
76
77 spin_lock_irqsave(&pmu_backlight_lock, flags);
44 78
45 if (vias == NULL) 79 /* Don't update brightness when sleeping */
46 return -ENODEV; 80 if (sleeping)
81 goto out;
47 82
48 if (bd->props->power != FB_BLANK_UNBLANK || 83 if (bd->props->power != FB_BLANK_UNBLANK ||
49 bd->props->fb_blank != FB_BLANK_UNBLANK) 84 bd->props->fb_blank != FB_BLANK_UNBLANK)
50 level = 0; 85 level = 0;
51 86
52 pmulevel = pmu_backlight_get_level_brightness(info, level); 87 if (level > 0) {
88 int pmulevel = pmu_backlight_get_level_brightness(level);
53 89
54 pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); 90 pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
55 pmu_wait_complete(&req); 91 pmu_wait_complete(&req);
92
93 pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
94 PMU_POW_BACKLIGHT | PMU_POW_ON);
95 pmu_wait_complete(&req);
96 } else {
97 pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
98 PMU_POW_BACKLIGHT | PMU_POW_OFF);
99 pmu_wait_complete(&req);
100 }
56 101
57 pmu_request(&req, NULL, 2, PMU_POWER_CTRL, 102out:
58 PMU_POW_BACKLIGHT | (level > 0 ? PMU_POW_ON : PMU_POW_OFF)); 103 spin_unlock_irqrestore(&pmu_backlight_lock, flags);
59 pmu_wait_complete(&req);
60 104
61 return 0; 105 return 0;
62} 106}
@@ -73,15 +117,23 @@ static struct backlight_properties pmu_backlight_data = {
73 .max_brightness = (FB_BACKLIGHT_LEVELS - 1), 117 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
74}; 118};
75 119
76void __init pmu_backlight_init(struct device_node *in_vias) 120#ifdef CONFIG_PM
121void pmu_backlight_set_sleep(int sleep)
122{
123 unsigned long flags;
124
125 spin_lock_irqsave(&pmu_backlight_lock, flags);
126 sleeping = sleep;
127 spin_unlock_irqrestore(&pmu_backlight_lock, flags);
128}
129#endif /* CONFIG_PM */
130
131void __init pmu_backlight_init()
77{ 132{
78 struct backlight_device *bd; 133 struct backlight_device *bd;
79 struct fb_info *info;
80 char name[10]; 134 char name[10];
81 int level, autosave; 135 int level, autosave;
82 136
83 vias = in_vias;
84
85 /* Special case for the old PowerBook since I can't test on it */ 137 /* Special case for the old PowerBook since I can't test on it */
86 autosave = 138 autosave =
87 machine_is_compatible("AAPL,3400/2400") || 139 machine_is_compatible("AAPL,3400/2400") ||
@@ -93,27 +145,14 @@ void __init pmu_backlight_init(struct device_node *in_vias)
93 !machine_is_compatible("PowerBook1,1")) 145 !machine_is_compatible("PowerBook1,1"))
94 return; 146 return;
95 147
96 /* Actually, this is a hack, but I don't know of a better way 148 snprintf(name, sizeof(name), "pmubl");
97 * to get the first framebuffer device.
98 */
99 info = registered_fb[0];
100 if (!info) {
101 printk("pmubl: No framebuffer found\n");
102 goto error;
103 }
104
105 snprintf(name, sizeof(name), "pmubl%d", info->node);
106 149
107 bd = backlight_device_register(name, info, &pmu_backlight_data); 150 bd = backlight_device_register(name, NULL, &pmu_backlight_data);
108 if (IS_ERR(bd)) { 151 if (IS_ERR(bd)) {
109 printk("pmubl: Backlight registration failed\n"); 152 printk("pmubl: Backlight registration failed\n");
110 goto error; 153 goto error;
111 } 154 }
112 155 pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
113 mutex_lock(&info->bl_mutex);
114 info->bl_dev = bd;
115 fb_bl_default_curve(info, 0x7F, 0x46, 0x0E);
116 mutex_unlock(&info->bl_mutex);
117 156
118 level = pmu_backlight_data.max_brightness; 157 level = pmu_backlight_data.max_brightness;
119 158
@@ -123,18 +162,16 @@ void __init pmu_backlight_init(struct device_node *in_vias)
123 pmu_request(&req, NULL, 2, 0xd9, 0); 162 pmu_request(&req, NULL, 2, 0xd9, 0);
124 pmu_wait_complete(&req); 163 pmu_wait_complete(&req);
125 164
126 mutex_lock(&info->bl_mutex); 165 level = pmu_backlight_curve_lookup(
127 level = pmac_backlight_curve_lookup(info,
128 (req.reply[0] >> 4) * 166 (req.reply[0] >> 4) *
129 pmu_backlight_data.max_brightness / 15); 167 pmu_backlight_data.max_brightness / 15);
130 mutex_unlock(&info->bl_mutex);
131 } 168 }
132 169
133 up(&bd->sem); 170 down(&bd->sem);
134 bd->props->brightness = level; 171 bd->props->brightness = level;
135 bd->props->power = FB_BLANK_UNBLANK; 172 bd->props->power = FB_BLANK_UNBLANK;
136 bd->props->update_status(bd); 173 bd->props->update_status(bd);
137 down(&bd->sem); 174 up(&bd->sem);
138 175
139 mutex_lock(&pmac_backlight_mutex); 176 mutex_lock(&pmac_backlight_mutex);
140 if (!pmac_backlight) 177 if (!pmac_backlight)
diff --git a/drivers/macintosh/via-pmu-led.c b/drivers/macintosh/via-pmu-led.c
index af8375ed0f5e..5189d5454b1f 100644
--- a/drivers/macintosh/via-pmu-led.c
+++ b/drivers/macintosh/via-pmu-led.c
@@ -74,7 +74,7 @@ static void pmu_led_set(struct led_classdev *led_cdev,
74 74
75static struct led_classdev pmu_led = { 75static struct led_classdev pmu_led = {
76 .name = "pmu-front-led", 76 .name = "pmu-front-led",
77#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK 77#ifdef CONFIG_ADB_PMU_LED_IDE
78 .default_trigger = "ide-disk", 78 .default_trigger = "ide-disk",
79#endif 79#endif
80 .brightness_set = pmu_led_set, 80 .brightness_set = pmu_led_set,
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 06ca80bfd6b9..14610a63f580 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -16,7 +16,6 @@
16 * a sleep or a freq. switch 16 * a sleep or a freq. switch
17 * - Move sleep code out of here to pmac_pm, merge into new 17 * - Move sleep code out of here to pmac_pm, merge into new
18 * common PM infrastructure 18 * common PM infrastructure
19 * - Move backlight code out as well
20 * - Save/Restore PCI space properly 19 * - Save/Restore PCI space properly
21 * 20 *
22 */ 21 */
@@ -60,9 +59,7 @@
60#include <asm/mmu_context.h> 59#include <asm/mmu_context.h>
61#include <asm/cputable.h> 60#include <asm/cputable.h>
62#include <asm/time.h> 61#include <asm/time.h>
63#ifdef CONFIG_PMAC_BACKLIGHT
64#include <asm/backlight.h> 62#include <asm/backlight.h>
65#endif
66 63
67#include "via-pmu-event.h" 64#include "via-pmu-event.h"
68 65
@@ -177,10 +174,6 @@ static int query_batt_timer = BATTERY_POLLING_COUNT;
177static struct adb_request batt_req; 174static struct adb_request batt_req;
178static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES]; 175static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES];
179 176
180#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
181extern int disable_kernel_backlight;
182#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
183
184int __fake_sleep; 177int __fake_sleep;
185int asleep; 178int asleep;
186BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); 179BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
@@ -466,7 +459,7 @@ static int __init via_pmu_dev_init(void)
466 459
467#ifdef CONFIG_PMAC_BACKLIGHT 460#ifdef CONFIG_PMAC_BACKLIGHT
468 /* Initialize backlight */ 461 /* Initialize backlight */
469 pmu_backlight_init(vias); 462 pmu_backlight_init();
470#endif 463#endif
471 464
472#ifdef CONFIG_PPC32 465#ifdef CONFIG_PPC32
@@ -1403,11 +1396,8 @@ next:
1403 else if ((1 << pirq) & PMU_INT_SNDBRT) { 1396 else if ((1 << pirq) & PMU_INT_SNDBRT) {
1404#ifdef CONFIG_PMAC_BACKLIGHT 1397#ifdef CONFIG_PMAC_BACKLIGHT
1405 if (len == 3) 1398 if (len == 3)
1406#ifdef CONFIG_INPUT_ADBHID 1399 pmac_backlight_set_legacy_brightness_pmu(data[1] >> 4);
1407 if (!disable_kernel_backlight) 1400#endif
1408#endif /* CONFIG_INPUT_ADBHID */
1409 pmac_backlight_set_legacy_brightness(data[1] >> 4);
1410#endif /* CONFIG_PMAC_BACKLIGHT */
1411 } 1401 }
1412 /* Tick interrupt */ 1402 /* Tick interrupt */
1413 else if ((1 << pirq) & PMU_INT_TICK) { 1403 else if ((1 << pirq) & PMU_INT_TICK) {
@@ -2005,6 +1995,8 @@ restore_via_state(void)
2005 out_8(&via[IER], IER_SET | SR_INT | CB1_INT); 1995 out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
2006} 1996}
2007 1997
1998extern void pmu_backlight_set_sleep(int sleep);
1999
2008static int 2000static int
2009pmac_suspend_devices(void) 2001pmac_suspend_devices(void)
2010{ 2002{
@@ -2042,6 +2034,11 @@ pmac_suspend_devices(void)
2042 return -EBUSY; 2034 return -EBUSY;
2043 } 2035 }
2044 2036
2037#ifdef CONFIG_PMAC_BACKLIGHT
2038 /* Tell backlight code not to muck around with the chip anymore */
2039 pmu_backlight_set_sleep(1);
2040#endif
2041
2045 /* Call platform functions marked "on sleep" */ 2042 /* Call platform functions marked "on sleep" */
2046 pmac_pfunc_i2c_suspend(); 2043 pmac_pfunc_i2c_suspend();
2047 pmac_pfunc_base_suspend(); 2044 pmac_pfunc_base_suspend();
@@ -2100,6 +2097,11 @@ pmac_wakeup_devices(void)
2100{ 2097{
2101 mdelay(100); 2098 mdelay(100);
2102 2099
2100#ifdef CONFIG_PMAC_BACKLIGHT
2101 /* Tell backlight code it can use the chip again */
2102 pmu_backlight_set_sleep(0);
2103#endif
2104
2103 /* Power back up system devices (including the PIC) */ 2105 /* Power back up system devices (including the PIC) */
2104 device_power_up(); 2106 device_power_up();
2105 2107
@@ -2414,7 +2416,7 @@ struct pmu_private {
2414 spinlock_t lock; 2416 spinlock_t lock;
2415#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) 2417#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
2416 int backlight_locker; 2418 int backlight_locker;
2417#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ 2419#endif
2418}; 2420};
2419 2421
2420static LIST_HEAD(all_pmu_pvt); 2422static LIST_HEAD(all_pmu_pvt);
@@ -2464,7 +2466,7 @@ pmu_open(struct inode *inode, struct file *file)
2464 spin_lock_irqsave(&all_pvt_lock, flags); 2466 spin_lock_irqsave(&all_pvt_lock, flags);
2465#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) 2467#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
2466 pp->backlight_locker = 0; 2468 pp->backlight_locker = 0;
2467#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ 2469#endif
2468 list_add(&pp->list, &all_pmu_pvt); 2470 list_add(&pp->list, &all_pmu_pvt);
2469 spin_unlock_irqrestore(&all_pvt_lock, flags); 2471 spin_unlock_irqrestore(&all_pvt_lock, flags);
2470 file->private_data = pp; 2472 file->private_data = pp;
@@ -2559,13 +2561,12 @@ pmu_release(struct inode *inode, struct file *file)
2559 spin_lock_irqsave(&all_pvt_lock, flags); 2561 spin_lock_irqsave(&all_pvt_lock, flags);
2560 list_del(&pp->list); 2562 list_del(&pp->list);
2561 spin_unlock_irqrestore(&all_pvt_lock, flags); 2563 spin_unlock_irqrestore(&all_pvt_lock, flags);
2564
2562#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) 2565#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
2563 if (pp->backlight_locker) { 2566 if (pp->backlight_locker)
2564 spin_lock_irqsave(&pmu_lock, flags); 2567 pmac_backlight_enable();
2565 disable_kernel_backlight--; 2568#endif
2566 spin_unlock_irqrestore(&pmu_lock, flags); 2569
2567 }
2568#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
2569 kfree(pp); 2570 kfree(pp);
2570 } 2571 }
2571 unlock_kernel(); 2572 unlock_kernel();
@@ -2642,18 +2643,18 @@ pmu_ioctl(struct inode * inode, struct file *filp,
2642#ifdef CONFIG_INPUT_ADBHID 2643#ifdef CONFIG_INPUT_ADBHID
2643 case PMU_IOC_GRAB_BACKLIGHT: { 2644 case PMU_IOC_GRAB_BACKLIGHT: {
2644 struct pmu_private *pp = filp->private_data; 2645 struct pmu_private *pp = filp->private_data;
2645 unsigned long flags;
2646 2646
2647 if (pp->backlight_locker) 2647 if (pp->backlight_locker)
2648 return 0; 2648 return 0;
2649
2649 pp->backlight_locker = 1; 2650 pp->backlight_locker = 1;
2650 spin_lock_irqsave(&pmu_lock, flags); 2651 pmac_backlight_disable();
2651 disable_kernel_backlight++; 2652
2652 spin_unlock_irqrestore(&pmu_lock, flags);
2653 return 0; 2653 return 0;
2654 } 2654 }
2655#endif /* CONFIG_INPUT_ADBHID */ 2655#endif /* CONFIG_INPUT_ADBHID */
2656#endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */ 2656#endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */
2657
2657 case PMU_IOC_GET_MODEL: 2658 case PMU_IOC_GET_MODEL:
2658 return put_user(pmu_kind, argp); 2659 return put_user(pmu_kind, argp);
2659 case PMU_IOC_HAS_ADB: 2660 case PMU_IOC_HAS_ADB: