diff options
-rw-r--r-- | Documentation/thinkpad-acpi.txt | 15 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 30 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 2 |
3 files changed, 38 insertions, 9 deletions
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index eab4997efc0f..bca50d78a425 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt | |||
@@ -38,7 +38,7 @@ detailed description): | |||
38 | - Experimental: embedded controller register dump | 38 | - Experimental: embedded controller register dump |
39 | - LCD brightness control | 39 | - LCD brightness control |
40 | - Volume control | 40 | - Volume control |
41 | - Experimental: fan speed, fan enable/disable | 41 | - Fan control and monitoring: fan speed, fan enable/disable |
42 | - Experimental: WAN enable and disable | 42 | - Experimental: WAN enable and disable |
43 | 43 | ||
44 | A compatibility table by model and feature is maintained on the web | 44 | A compatibility table by model and feature is maintained on the web |
@@ -681,21 +681,20 @@ distinct. The unmute the volume after the mute command, use either the | |||
681 | up or down command (the level command will not unmute the volume). | 681 | up or down command (the level command will not unmute the volume). |
682 | The current volume level and mute state is shown in the file. | 682 | The current volume level and mute state is shown in the file. |
683 | 683 | ||
684 | EXPERIMENTAL: fan speed, fan enable/disable | 684 | Fan control and monitoring: fan speed, fan enable/disable |
685 | ------------------------------------------- | 685 | --------------------------------------------------------- |
686 | 686 | ||
687 | procfs: /proc/acpi/ibm/fan | 687 | procfs: /proc/acpi/ibm/fan |
688 | sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable | 688 | sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable |
689 | 689 | ||
690 | This feature is marked EXPERIMENTAL because the implementation | 690 | NOTE NOTE NOTE: fan control operations are disabled by default for |
691 | directly accesses hardware registers and may not work as expected. USE | 691 | safety reasons. To enable them, the module parameter "fan_control=1" |
692 | WITH CAUTION! To use this feature, you need to supply the | 692 | must be given to thinkpad-acpi. |
693 | experimental=1 parameter when loading the module. | ||
694 | 693 | ||
695 | This feature attempts to show the current fan speed, control mode and | 694 | This feature attempts to show the current fan speed, control mode and |
696 | other fan data that might be available. The speed is read directly | 695 | other fan data that might be available. The speed is read directly |
697 | from the hardware registers of the embedded controller. This is known | 696 | from the hardware registers of the embedded controller. This is known |
698 | to work on later R, T and X series ThinkPads but may show a bogus | 697 | to work on later R, T, X and Z series ThinkPads but may show a bogus |
699 | value on other models. | 698 | value on other models. |
700 | 699 | ||
701 | Fan levels: | 700 | Fan levels: |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index c0a023cc5ded..7dc3a2206195 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -2935,6 +2935,9 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv, | |||
2935 | if (parse_strtoul(buf, 120, &t)) | 2935 | if (parse_strtoul(buf, 120, &t)) |
2936 | return -EINVAL; | 2936 | return -EINVAL; |
2937 | 2937 | ||
2938 | if (!fan_control_allowed) | ||
2939 | return -EPERM; | ||
2940 | |||
2938 | fan_watchdog_maxinterval = t; | 2941 | fan_watchdog_maxinterval = t; |
2939 | fan_watchdog_reset(); | 2942 | fan_watchdog_reset(); |
2940 | 2943 | ||
@@ -3046,6 +3049,14 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
3046 | fan_control_access_mode != TPACPI_FAN_WR_NONE), | 3049 | fan_control_access_mode != TPACPI_FAN_WR_NONE), |
3047 | fan_status_access_mode, fan_control_access_mode); | 3050 | fan_status_access_mode, fan_control_access_mode); |
3048 | 3051 | ||
3052 | /* fan control master switch */ | ||
3053 | if (!fan_control_allowed) { | ||
3054 | fan_control_access_mode = TPACPI_FAN_WR_NONE; | ||
3055 | fan_control_commands = 0; | ||
3056 | dbg_printk(TPACPI_DBG_INIT, | ||
3057 | "fan control features disabled by parameter\n"); | ||
3058 | } | ||
3059 | |||
3049 | /* update fan_control_desired_level */ | 3060 | /* update fan_control_desired_level */ |
3050 | if (fan_status_access_mode != TPACPI_FAN_NONE) | 3061 | if (fan_status_access_mode != TPACPI_FAN_NONE) |
3051 | fan_get_status_safe(NULL); | 3062 | fan_get_status_safe(NULL); |
@@ -3203,6 +3214,9 @@ static void fan_watchdog_reset(void) | |||
3203 | 3214 | ||
3204 | static int fan_set_level(int level) | 3215 | static int fan_set_level(int level) |
3205 | { | 3216 | { |
3217 | if (!fan_control_allowed) | ||
3218 | return -EPERM; | ||
3219 | |||
3206 | switch (fan_control_access_mode) { | 3220 | switch (fan_control_access_mode) { |
3207 | case TPACPI_FAN_WR_ACPI_SFAN: | 3221 | case TPACPI_FAN_WR_ACPI_SFAN: |
3208 | if (level >= 0 && level <= 7) { | 3222 | if (level >= 0 && level <= 7) { |
@@ -3242,6 +3256,9 @@ static int fan_set_level_safe(int level) | |||
3242 | { | 3256 | { |
3243 | int rc; | 3257 | int rc; |
3244 | 3258 | ||
3259 | if (!fan_control_allowed) | ||
3260 | return -EPERM; | ||
3261 | |||
3245 | rc = mutex_lock_interruptible(&fan_mutex); | 3262 | rc = mutex_lock_interruptible(&fan_mutex); |
3246 | if (rc < 0) | 3263 | if (rc < 0) |
3247 | return rc; | 3264 | return rc; |
@@ -3262,6 +3279,9 @@ static int fan_set_enable(void) | |||
3262 | u8 s; | 3279 | u8 s; |
3263 | int rc; | 3280 | int rc; |
3264 | 3281 | ||
3282 | if (!fan_control_allowed) | ||
3283 | return -EPERM; | ||
3284 | |||
3265 | rc = mutex_lock_interruptible(&fan_mutex); | 3285 | rc = mutex_lock_interruptible(&fan_mutex); |
3266 | if (rc < 0) | 3286 | if (rc < 0) |
3267 | return rc; | 3287 | return rc; |
@@ -3315,6 +3335,9 @@ static int fan_set_disable(void) | |||
3315 | { | 3335 | { |
3316 | int rc; | 3336 | int rc; |
3317 | 3337 | ||
3338 | if (!fan_control_allowed) | ||
3339 | return -EPERM; | ||
3340 | |||
3318 | rc = mutex_lock_interruptible(&fan_mutex); | 3341 | rc = mutex_lock_interruptible(&fan_mutex); |
3319 | if (rc < 0) | 3342 | if (rc < 0) |
3320 | return rc; | 3343 | return rc; |
@@ -3351,6 +3374,9 @@ static int fan_set_speed(int speed) | |||
3351 | { | 3374 | { |
3352 | int rc; | 3375 | int rc; |
3353 | 3376 | ||
3377 | if (!fan_control_allowed) | ||
3378 | return -EPERM; | ||
3379 | |||
3354 | rc = mutex_lock_interruptible(&fan_mutex); | 3380 | rc = mutex_lock_interruptible(&fan_mutex); |
3355 | if (rc < 0) | 3381 | if (rc < 0) |
3356 | return rc; | 3382 | return rc; |
@@ -3558,7 +3584,6 @@ static struct ibm_struct fan_driver_data = { | |||
3558 | .read = fan_read, | 3584 | .read = fan_read, |
3559 | .write = fan_write, | 3585 | .write = fan_write, |
3560 | .exit = fan_exit, | 3586 | .exit = fan_exit, |
3561 | .flags.experimental = 1, | ||
3562 | }; | 3587 | }; |
3563 | 3588 | ||
3564 | /**************************************************************************** | 3589 | /**************************************************************************** |
@@ -3879,6 +3904,9 @@ module_param_named(debug, dbg_level, uint, 0); | |||
3879 | static int force_load; | 3904 | static int force_load; |
3880 | module_param(force_load, int, 0); | 3905 | module_param(force_load, int, 0); |
3881 | 3906 | ||
3907 | static int fan_control_allowed; | ||
3908 | module_param_named(fan_control, fan_control_allowed, int, 0); | ||
3909 | |||
3882 | #define IBM_PARAM(feature) \ | 3910 | #define IBM_PARAM(feature) \ |
3883 | module_param_call(feature, set_ibm_param, NULL, NULL, 0) | 3911 | module_param_call(feature, set_ibm_param, NULL, NULL, 0) |
3884 | 3912 | ||
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 8348fc653009..a9e709368256 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -375,6 +375,8 @@ enum fan_control_commands { | |||
375 | * and also watchdog cmd */ | 375 | * and also watchdog cmd */ |
376 | }; | 376 | }; |
377 | 377 | ||
378 | static int fan_control_allowed; | ||
379 | |||
378 | static enum fan_status_access_mode fan_status_access_mode; | 380 | static enum fan_status_access_mode fan_status_access_mode; |
379 | static enum fan_control_access_mode fan_control_access_mode; | 381 | static enum fan_control_access_mode fan_control_access_mode; |
380 | static enum fan_control_commands fan_control_commands; | 382 | static enum fan_control_commands fan_control_commands; |