ACPI: thinkpad-acpi: add a fan-control feature master toggle

Len Brown considers that an active by default fan control interface in
laptops may be too close to giving users enough rope.  There is a good
chance he is quite correct on this, especially if someone decides to use
that interface in applets and users are not aware of its risks.

This patch adds a master switch to thinkpad-acpi that enables or disables
the entire fan-control feature as a module parameter: "fan_control".  It
defaults to disabled.  Set it to non-zero to enable fan control.

Also, the patch removes the expermiental status from fan control, since it
is stable enough to not be called experimental, and the master switch makes
it safe enough to do so.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index c0a023c..7dc3a22 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -2935,6 +2935,9 @@
 	if (parse_strtoul(buf, 120, &t))
 		return -EINVAL;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	fan_watchdog_maxinterval = t;
 	fan_watchdog_reset();
 
@@ -3046,6 +3049,14 @@
 		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
 		fan_status_access_mode, fan_control_access_mode);
 
+	/* fan control master switch */
+	if (!fan_control_allowed) {
+		fan_control_access_mode = TPACPI_FAN_WR_NONE;
+		fan_control_commands = 0;
+		dbg_printk(TPACPI_DBG_INIT,
+			   "fan control features disabled by parameter\n");
+	}
+
 	/* update fan_control_desired_level */
 	if (fan_status_access_mode != TPACPI_FAN_NONE)
 		fan_get_status_safe(NULL);
@@ -3203,6 +3214,9 @@
 
 static int fan_set_level(int level)
 {
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	switch (fan_control_access_mode) {
 	case TPACPI_FAN_WR_ACPI_SFAN:
 		if (level >= 0 && level <= 7) {
@@ -3242,6 +3256,9 @@
 {
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3262,6 +3279,9 @@
 	u8 s;
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3315,6 +3335,9 @@
 {
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3351,6 +3374,9 @@
 {
 	int rc;
 
+	if (!fan_control_allowed)
+		return -EPERM;
+
 	rc = mutex_lock_interruptible(&fan_mutex);
 	if (rc < 0)
 		return rc;
@@ -3558,7 +3584,6 @@
 	.read = fan_read,
 	.write = fan_write,
 	.exit = fan_exit,
-	.flags.experimental = 1,
 };
 
 /****************************************************************************
@@ -3879,6 +3904,9 @@
 static int force_load;
 module_param(force_load, int, 0);
 
+static int fan_control_allowed;
+module_param_named(fan_control, fan_control_allowed, int, 0);
+
 #define IBM_PARAM(feature) \
 	module_param_call(feature, set_ibm_param, NULL, NULL, 0)