Add missing patch that touched many files, including thinkpad-acpi and
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.28-rc1 / 0002-ACPI-thinkpad-acpi-attempt-to-preserve-fan-state-o.patch
blobf26c96b6f0b6deefe272bfb23e012b7351418e1c
1 From 75700e53cd14ccc7a5a42547497dff11fe209186 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Sat, 18 Oct 2008 14:23:52 -0300
4 Subject: ACPI: thinkpad-acpi: attempt to preserve fan state on resume
6 Attempt to preserve fan state across sleep and hibernation if the fan
7 control mode is enabled.
9 For safety reasons, only the PWM OFF (fan at 100%) or maximum
10 closed-loop level (level 7) are preserved. If the fan state was set
11 to anything else, it will not be restored.
13 Also, should the fan be at PWM OFF mode at resume, it will be left at
14 that state (but this is extremely unlikely, no ThinkPad firmware was
15 ever reported to do this).
17 For reference, the known states used for fan control upon resume by
18 the firmware are either "auto" or "level 7" depending on whether the
19 laptop wakes due to normal conditions or a thermal emergency.
21 Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=11331
23 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
24 Cc: Richard Hartmann <richih.mailinglist@gmail.com>
25 Signed-off-by: Len Brown <len.brown@intel.com>
26 ---
27 drivers/misc/thinkpad_acpi.c | 48 ++++++++++++++++++++++++++++++++++++++++++
28 1 files changed, 48 insertions(+), 0 deletions(-)
30 diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
31 index 6b93007..1dcf066 100644
32 --- a/drivers/misc/thinkpad_acpi.c
33 +++ b/drivers/misc/thinkpad_acpi.c
34 @@ -5983,6 +5983,52 @@ static void fan_exit(void)
35 flush_workqueue(tpacpi_wq);
38 +static void fan_suspend(pm_message_t state)
40 + if (!fan_control_allowed)
41 + return;
43 + /* Store fan status in cache */
44 + fan_get_status_safe(NULL);
45 + if (tp_features.fan_ctrl_status_undef)
46 + fan_control_desired_level = TP_EC_FAN_AUTO;
49 +static void fan_resume(void)
51 + u8 saved_fan_level;
52 + u8 current_level = 7;
53 + bool do_set = false;
55 + /* DSDT *always* updates status on resume */
56 + tp_features.fan_ctrl_status_undef = 0;
58 + saved_fan_level = fan_control_desired_level;
59 + if (!fan_control_allowed ||
60 + (fan_get_status_safe(&current_level) < 0))
61 + return;
63 + switch (fan_control_access_mode) {
64 + case TPACPI_FAN_WR_ACPI_SFAN:
65 + do_set = (saved_fan_level > current_level);
66 + break;
67 + case TPACPI_FAN_WR_ACPI_FANS:
68 + case TPACPI_FAN_WR_TPEC:
69 + do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) ||
70 + (saved_fan_level == 7 &&
71 + !(current_level & TP_EC_FAN_FULLSPEED)));
72 + break;
73 + default:
74 + return;
75 + }
76 + if (do_set) {
77 + printk(TPACPI_NOTICE
78 + "restoring fan level to 0x%02x\n",
79 + saved_fan_level);
80 + fan_set_level_safe(saved_fan_level);
81 + }
84 static int fan_read(char *p)
86 int len = 0;
87 @@ -6174,6 +6220,8 @@ static struct ibm_struct fan_driver_data = {
88 .read = fan_read,
89 .write = fan_write,
90 .exit = fan_exit,
91 + .suspend = fan_suspend,
92 + .resume = fan_resume,
95 /****************************************************************************
96 --
97 1.5.6.5