public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] i8k patch series
@ 2013-12-14 17:30 Guenter Roeck
  2013-12-14 17:30 ` [PATCH 01/14] i8k: Convert to use pr_ functions instead of printk Guenter Roeck
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

Clean up and simplify the driver, add support for additional temperature
sensors, fix a problem seen with multi-core CPU, and add support
for additional systems.

----------------------------------------------------------------
Guenter Roeck (14):
      i8k: Convert to use pr_ functions instead of printk
      i8k: Fix various checkpatch warnings and errors
      i8k: Convert to use to hwmon_device_register_with_groups hwmon API
      i8k: Support additional temperature sensors
      MAINTAINERS: Add myself as i8k maintainer
      i8k: Remove obsolete link to out-of-tree driver
      i8k: Drop driver version number and info message at startup
      i8k: Force SMM to run on CPU 0
      i8k: Add copyright
      i8k: Add support for Dell Studio laptops
      i8k: Add support for Dell XPS M140
      i8k: Use driver_data field of dmi_system_id to override fan multiplier
      i8k: Stop reading SMM BIOS version during driver probe
      i8k: Implement hwmon based fan speed control

 MAINTAINERS        |    2 +-
 drivers/char/i8k.c |  358 +++++++++++++++++++++++++++++-----------------------
 2 files changed, 201 insertions(+), 159 deletions(-)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 01/14] i8k: Convert to use pr_ functions instead of printk
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 02/14] i8k: Fix various checkpatch warnings and errors Guenter Roeck
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 40cc0cf2..0c48e7f 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -19,6 +19,8 @@
  * General Public License for more details.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/init.h>
@@ -535,7 +537,7 @@ static int __init i8k_init_hwmon(void)
 	if (IS_ERR(i8k_hwmon_dev)) {
 		err = PTR_ERR(i8k_hwmon_dev);
 		i8k_hwmon_dev = NULL;
-		printk(KERN_ERR "i8k: hwmon registration failed (%d)\n", err);
+		pr_err("hwmon registration failed (%d)\n", err);
 		return err;
 	}
 
@@ -682,8 +684,8 @@ static int __init i8k_probe(void)
 		if (!ignore_dmi && !force)
 			return -ENODEV;
 
-		printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
-		printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
+		pr_info("not running on a supported Dell system.\n");
+		pr_info("vendor=%s, model=%s, version=%s\n",
 			i8k_get_dmi_data(DMI_SYS_VENDOR),
 			i8k_get_dmi_data(DMI_PRODUCT_NAME),
 			i8k_get_dmi_data(DMI_BIOS_VERSION));
@@ -696,7 +698,7 @@ static int __init i8k_probe(void)
 	 */
 	if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
 	    i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
-		printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
+		pr_err("unable to get SMM Dell signature\n");
 		if (!force)
 			return -ENODEV;
 	}
@@ -706,7 +708,7 @@ static int __init i8k_probe(void)
 	 */
 	version = i8k_get_bios_version();
 	if (version <= 0) {
-		printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
+		pr_warn("unable to get SMM BIOS version\n");
 	} else {
 		buff[0] = (version >> 16) & 0xff;
 		buff[1] = (version >> 8) & 0xff;
@@ -722,7 +724,7 @@ static int __init i8k_probe(void)
 		 * Check if the two versions match.
 		 */
 		if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
-			printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
+			pr_warn("BIOS version mismatch: %s != %s\n",
 				buff, bios_version);
 	}
 
@@ -747,9 +749,8 @@ static int __init i8k_init(void)
 	if (err)
 		goto exit_remove_proc;
 
-	printk(KERN_INFO
-	       "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
-	       I8K_VERSION);
+	pr_info("Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
+		I8K_VERSION);
 
 	return 0;
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 02/14] i8k: Fix various checkpatch warnings and errors
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
  2013-12-14 17:30 ` [PATCH 01/14] i8k: Convert to use pr_ functions instead of printk Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 03/14] i8k: Convert to use to hwmon_device_register_with_groups hwmon API Guenter Roeck
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

Fix:
WARNING: Use #include <linux/uaccess.h> instead of <asm/uaccess.h>
WARNING: Use #include <linux/io.h> instead of <asm/io.h>
WARNING: __packed is preferred over __attribute__((packed))
WARNING: externs should be avoided in .c files
ERROR: spaces required around that ':' (ctx:ExV)
ERROR: do not use assignment in if condition
WARNING: line over 80 characters
WARNING: __initdata should be placed after i8k_dmi_table[]
ERROR: code indent should use tabs where possible
WARNING: please, no spaces at the start of a line

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 0c48e7f..71da6b7 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -31,8 +31,8 @@
 #include <linux/mutex.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
 
 #include <linux/i8k.h>
 
@@ -105,11 +105,11 @@ static const struct file_operations i8k_fops = {
 
 struct smm_regs {
 	unsigned int eax;
-	unsigned int ebx __attribute__ ((packed));
-	unsigned int ecx __attribute__ ((packed));
-	unsigned int edx __attribute__ ((packed));
-	unsigned int esi __attribute__ ((packed));
-	unsigned int edi __attribute__ ((packed));
+	unsigned int ebx __packed;
+	unsigned int ecx __packed;
+	unsigned int edx __packed;
+	unsigned int esi __packed;
+	unsigned int edi __packed;
 };
 
 static inline const char *i8k_get_dmi_data(int field)
@@ -150,7 +150,7 @@ static int i8k_smm(struct smm_regs *regs)
 		"pushfq\n\t"
 		"popq %%rax\n\t"
 		"andl $1,%%eax\n"
-		:"=a"(rc)
+		: "=a"(rc)
 		:    "a"(regs)
 		:    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #else
@@ -176,7 +176,7 @@ static int i8k_smm(struct smm_regs *regs)
 	    "lahf\n\t"
 	    "shrl $8,%%eax\n\t"
 	    "andl $1,%%eax\n"
-	    :"=a"(rc)
+	    : "=a"(rc)
 	    :    "a"(regs)
 	    :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #endif
@@ -205,7 +205,8 @@ static int i8k_get_fn_status(void)
 	struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
 	int rc;
 
-	if ((rc = i8k_smm(&regs)) < 0)
+	rc = i8k_smm(&regs);
+	if (rc < 0)
 		return rc;
 
 	switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
@@ -228,7 +229,8 @@ static int i8k_get_power_status(void)
 	struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
 	int rc;
 
-	if ((rc = i8k_smm(&regs)) < 0)
+	rc = i8k_smm(&regs);
+	if (rc < 0)
 		return rc;
 
 	return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
@@ -282,7 +284,8 @@ static int i8k_get_temp(int sensor)
 	static int prev;
 #endif
 	regs.ebx = sensor & 0xff;
-	if ((rc = i8k_smm(&regs)) < 0)
+	rc = i8k_smm(&regs);
+	if (rc < 0)
 		return rc;
 
 	temp = regs.eax & 0xff;
@@ -311,7 +314,8 @@ static int i8k_get_dell_signature(int req_fn)
 	struct smm_regs regs = { .eax = req_fn, };
 	int rc;
 
-	if ((rc = i8k_smm(&regs)) < 0)
+	rc = i8k_smm(&regs);
+	if (rc < 0)
 		return rc;
 
 	return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
@@ -335,7 +339,8 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
 
 	case I8K_MACHINE_ID:
 		memset(buff, 0, 16);
-		strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
+		strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
+			sizeof(buff));
 		break;
 
 	case I8K_FN_STATUS:
@@ -609,7 +614,7 @@ static void __exit i8k_exit_hwmon(void)
 	hwmon_device_unregister(i8k_hwmon_dev);
 }
 
-static struct dmi_system_id __initdata i8k_dmi_table[] = {
+static struct dmi_system_id i8k_dmi_table[] __initdata = {
 	{
 		.ident = "Dell Inspiron",
 		.matches = {
@@ -666,7 +671,7 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
 		},
 	},
-        { }
+	{ }
 };
 
 /*
@@ -691,7 +696,8 @@ static int __init i8k_probe(void)
 			i8k_get_dmi_data(DMI_BIOS_VERSION));
 	}
 
-	strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
+	strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
+		sizeof(bios_version));
 
 	/*
 	 * Get SMM Dell signature
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 03/14] i8k: Convert to use to hwmon_device_register_with_groups hwmon API
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
  2013-12-14 17:30 ` [PATCH 01/14] i8k: Convert to use pr_ functions instead of printk Guenter Roeck
  2013-12-14 17:30 ` [PATCH 02/14] i8k: Fix various checkpatch warnings and errors Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 04/14] i8k: Support additional temperature sensors Guenter Roeck
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck,
	Jean Delvare

Simplify code and fix race condition caused by registering
hwmon device prior to creating sysfs attributes.

Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |  132 +++++++++++++++++++++-------------------------------
 1 file changed, 54 insertions(+), 78 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 71da6b7..d2acbb8 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -66,6 +66,11 @@
 static DEFINE_MUTEX(i8k_mutex);
 static char bios_version[4];
 static struct device *i8k_hwmon_dev;
+static u32 i8k_hwmon_flags;
+
+#define I8K_HWMON_HAVE_TEMP1	(1 << 0)
+#define I8K_HWMON_HAVE_FAN1	(1 << 1)
+#define I8K_HWMON_HAVE_FAN2	(1 << 2)
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -502,8 +507,7 @@ static ssize_t i8k_hwmon_show_label(struct device *dev,
 				    struct device_attribute *devattr,
 				    char *buf)
 {
-	static const char *labels[4] = {
-		"i8k",
+	static const char *labels[3] = {
 		"CPU",
 		"Left Fan",
 		"Right Fan",
@@ -518,100 +522,72 @@ static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
 			  I8K_FAN_LEFT);
 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
 			  I8K_FAN_RIGHT);
-static SENSOR_DEVICE_ATTR(name, S_IRUGO, i8k_hwmon_show_label, NULL, 0);
-static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
-static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
-static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
+
+static struct attribute *i8k_attrs[] = {
+	&dev_attr_temp1_input.attr,			/* 0 */
+	&sensor_dev_attr_temp1_label.dev_attr.attr,	/* 1 */
+	&sensor_dev_attr_fan1_input.dev_attr.attr,	/* 2 */
+	&sensor_dev_attr_fan1_label.dev_attr.attr,	/* 3 */
+	&sensor_dev_attr_fan2_input.dev_attr.attr,	/* 4 */
+	&sensor_dev_attr_fan2_label.dev_attr.attr,	/* 5 */
+	NULL
+};
 
-static void i8k_hwmon_remove_files(struct device *dev)
+static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
+			      int index)
 {
-	device_remove_file(dev, &dev_attr_temp1_input);
-	device_remove_file(dev, &sensor_dev_attr_fan1_input.dev_attr);
-	device_remove_file(dev, &sensor_dev_attr_fan2_input.dev_attr);
-	device_remove_file(dev, &sensor_dev_attr_temp1_label.dev_attr);
-	device_remove_file(dev, &sensor_dev_attr_fan1_label.dev_attr);
-	device_remove_file(dev, &sensor_dev_attr_fan2_label.dev_attr);
-	device_remove_file(dev, &sensor_dev_attr_name.dev_attr);
+	if ((index == 0 || index == 1) &&
+	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
+		return 0;
+	if ((index == 2 || index == 3) &&
+	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
+		return 0;
+	if ((index == 4 || index == 5) &&
+	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
+		return 0;
+
+	return attr->mode;
 }
 
+static const struct attribute_group i8k_group = {
+	.attrs = i8k_attrs,
+	.is_visible = i8k_is_visible,
+};
+__ATTRIBUTE_GROUPS(i8k);
+
 static int __init i8k_init_hwmon(void)
 {
 	int err;
 
-	i8k_hwmon_dev = hwmon_device_register(NULL);
-	if (IS_ERR(i8k_hwmon_dev)) {
-		err = PTR_ERR(i8k_hwmon_dev);
-		i8k_hwmon_dev = NULL;
-		pr_err("hwmon registration failed (%d)\n", err);
-		return err;
-	}
-
-	/* Required name attribute */
-	err = device_create_file(i8k_hwmon_dev,
-				 &sensor_dev_attr_name.dev_attr);
-	if (err)
-		goto exit_unregister;
+	i8k_hwmon_flags = 0;
 
 	/* CPU temperature attributes, if temperature reading is OK */
 	err = i8k_get_temp(0);
-	if (err < 0) {
-		dev_dbg(i8k_hwmon_dev,
-			"Not creating temperature attributes (%d)\n", err);
-	} else {
-		err = device_create_file(i8k_hwmon_dev, &dev_attr_temp1_input);
-		if (err)
-			goto exit_remove_files;
-		err = device_create_file(i8k_hwmon_dev,
-					 &sensor_dev_attr_temp1_label.dev_attr);
-		if (err)
-			goto exit_remove_files;
-	}
+	if (err >= 0)
+		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP1;
 
 	/* Left fan attributes, if left fan is present */
 	err = i8k_get_fan_status(I8K_FAN_LEFT);
-	if (err < 0) {
-		dev_dbg(i8k_hwmon_dev,
-			"Not creating %s fan attributes (%d)\n", "left", err);
-	} else {
-		err = device_create_file(i8k_hwmon_dev,
-					 &sensor_dev_attr_fan1_input.dev_attr);
-		if (err)
-			goto exit_remove_files;
-		err = device_create_file(i8k_hwmon_dev,
-					 &sensor_dev_attr_fan1_label.dev_attr);
-		if (err)
-			goto exit_remove_files;
-	}
+	if (err >= 0)
+		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
 
 	/* Right fan attributes, if right fan is present */
 	err = i8k_get_fan_status(I8K_FAN_RIGHT);
-	if (err < 0) {
-		dev_dbg(i8k_hwmon_dev,
-			"Not creating %s fan attributes (%d)\n", "right", err);
-	} else {
-		err = device_create_file(i8k_hwmon_dev,
-					 &sensor_dev_attr_fan2_input.dev_attr);
-		if (err)
-			goto exit_remove_files;
-		err = device_create_file(i8k_hwmon_dev,
-					 &sensor_dev_attr_fan2_label.dev_attr);
-		if (err)
-			goto exit_remove_files;
-	}
+	if (err >= 0)
+		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
 
+	i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "i8k", NULL,
+							  i8k_groups);
+	if (IS_ERR(i8k_hwmon_dev)) {
+		err = PTR_ERR(i8k_hwmon_dev);
+		i8k_hwmon_dev = NULL;
+		pr_err("hwmon registration failed (%d)\n", err);
+		return err;
+	}
 	return 0;
-
- exit_remove_files:
-	i8k_hwmon_remove_files(i8k_hwmon_dev);
- exit_unregister:
-	hwmon_device_unregister(i8k_hwmon_dev);
-	return err;
-}
-
-static void __exit i8k_exit_hwmon(void)
-{
-	i8k_hwmon_remove_files(i8k_hwmon_dev);
-	hwmon_device_unregister(i8k_hwmon_dev);
 }
 
 static struct dmi_system_id i8k_dmi_table[] __initdata = {
@@ -767,7 +743,7 @@ static int __init i8k_init(void)
 
 static void __exit i8k_exit(void)
 {
-	i8k_exit_hwmon();
+	hwmon_device_unregister(i8k_hwmon_dev);
 	remove_proc_entry("i8k", NULL);
 }
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 04/14] i8k: Support additional temperature sensors
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (2 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 03/14] i8k: Convert to use to hwmon_device_register_with_groups hwmon API Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 05/14] MAINTAINERS: Add myself as i8k maintainer Guenter Roeck
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck,
	Jean Delvare

The SMM API suggests that more than one temperature sensor is supported,
so add support for them. Currently only supported for hwmon interface.

Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   64 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 45 insertions(+), 19 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index d2acbb8..ef56bb0 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -69,8 +69,11 @@ static struct device *i8k_hwmon_dev;
 static u32 i8k_hwmon_flags;
 
 #define I8K_HWMON_HAVE_TEMP1	(1 << 0)
-#define I8K_HWMON_HAVE_FAN1	(1 << 1)
-#define I8K_HWMON_HAVE_FAN2	(1 << 2)
+#define I8K_HWMON_HAVE_TEMP2	(1 << 1)
+#define I8K_HWMON_HAVE_TEMP3	(1 << 2)
+#define I8K_HWMON_HAVE_TEMP4	(1 << 3)
+#define I8K_HWMON_HAVE_FAN1	(1 << 4)
+#define I8K_HWMON_HAVE_FAN2	(1 << 5)
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -286,7 +289,7 @@ static int i8k_get_temp(int sensor)
 	int temp;
 
 #ifdef I8K_TEMPERATURE_BUG
-	static int prev;
+	static int prev[4];
 #endif
 	regs.ebx = sensor & 0xff;
 	rc = i8k_smm(&regs);
@@ -304,10 +307,10 @@ static int i8k_get_temp(int sensor)
 	 # 1003655139 00000054 00005c52
 	 */
 	if (temp > I8K_MAX_TEMP) {
-		temp = prev;
-		prev = I8K_MAX_TEMP;
+		temp = prev[sensor];
+		prev[sensor] = I8K_MAX_TEMP;
 	} else {
-		prev = temp;
+		prev[sensor] = temp;
 	}
 #endif
 
@@ -482,12 +485,13 @@ static ssize_t i8k_hwmon_show_temp(struct device *dev,
 				   struct device_attribute *devattr,
 				   char *buf)
 {
-	int cpu_temp;
+	int index = to_sensor_dev_attr(devattr)->index;
+	int temp;
 
-	cpu_temp = i8k_get_temp(0);
-	if (cpu_temp < 0)
-		return cpu_temp;
-	return sprintf(buf, "%d\n", cpu_temp * 1000);
+	temp = i8k_get_temp(index);
+	if (temp < 0)
+		return temp;
+	return sprintf(buf, "%d\n", temp * 1000);
 }
 
 static ssize_t i8k_hwmon_show_fan(struct device *dev,
@@ -517,7 +521,10 @@ static ssize_t i8k_hwmon_show_label(struct device *dev,
 	return sprintf(buf, "%s\n", labels[index]);
 }
 
-static DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 3);
 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
 			  I8K_FAN_LEFT);
 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
@@ -527,12 +534,15 @@ static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
 static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
 
 static struct attribute *i8k_attrs[] = {
-	&dev_attr_temp1_input.attr,			/* 0 */
+	&sensor_dev_attr_temp1_input.dev_attr.attr,	/* 0 */
 	&sensor_dev_attr_temp1_label.dev_attr.attr,	/* 1 */
-	&sensor_dev_attr_fan1_input.dev_attr.attr,	/* 2 */
-	&sensor_dev_attr_fan1_label.dev_attr.attr,	/* 3 */
-	&sensor_dev_attr_fan2_input.dev_attr.attr,	/* 4 */
-	&sensor_dev_attr_fan2_label.dev_attr.attr,	/* 5 */
+	&sensor_dev_attr_temp2_input.dev_attr.attr,	/* 2 */
+	&sensor_dev_attr_temp3_input.dev_attr.attr,	/* 3 */
+	&sensor_dev_attr_temp4_input.dev_attr.attr,	/* 4 */
+	&sensor_dev_attr_fan1_input.dev_attr.attr,	/* 5 */
+	&sensor_dev_attr_fan1_label.dev_attr.attr,	/* 6 */
+	&sensor_dev_attr_fan2_input.dev_attr.attr,	/* 7 */
+	&sensor_dev_attr_fan2_label.dev_attr.attr,	/* 8 */
 	NULL
 };
 
@@ -542,10 +552,16 @@ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
 	if ((index == 0 || index == 1) &&
 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
 		return 0;
-	if ((index == 2 || index == 3) &&
+	if (index == 2 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2))
+		return 0;
+	if (index == 3 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3))
+		return 0;
+	if (index == 4 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
+		return 0;
+	if ((index == 5 || index == 6) &&
 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
 		return 0;
-	if ((index == 4 || index == 5) &&
+	if ((index == 7 || index == 8) &&
 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
 		return 0;
 
@@ -568,6 +584,16 @@ static int __init i8k_init_hwmon(void)
 	err = i8k_get_temp(0);
 	if (err >= 0)
 		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP1;
+	/* check for additional temperature sensors */
+	err = i8k_get_temp(1);
+	if (err >= 0)
+		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP2;
+	err = i8k_get_temp(2);
+	if (err >= 0)
+		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP3;
+	err = i8k_get_temp(3);
+	if (err >= 0)
+		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
 
 	/* Left fan attributes, if left fan is present */
 	err = i8k_get_fan_status(I8K_FAN_LEFT);
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 05/14] MAINTAINERS: Add myself as i8k maintainer
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (3 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 04/14] i8k: Support additional temperature sensors Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 06/14] i8k: Remove obsolete link to out-of-tree driver Guenter Roeck
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

I have a couple of Dell laptops running Linux, so I have a vested
interest to keep this driver supported.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 MAINTAINERS |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 13c15c8..7bc4772 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2618,7 +2618,7 @@ S:	Maintained
 F:	drivers/platform/x86/dell-laptop.c
 
 DELL LAPTOP SMM DRIVER
-S:	Orphan
+M:	Guenter Roeck <linux@roeck-us.net>
 F:	drivers/char/i8k.c
 F:	include/uapi/linux/i8k.h
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 06/14] i8k: Remove obsolete link to out-of-tree driver
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (4 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 05/14] MAINTAINERS: Add myself as i8k maintainer Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 07/14] i8k: Drop driver version number and info message at startup Guenter Roeck
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

Accessing the link returns a page not found error.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index ef56bb0..5b3682c 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -1,7 +1,5 @@
 /*
  * i8k.c -- Linux driver for accessing the SMM BIOS on Dell laptops.
- *	    See http://www.debian.org/~dz/i8k/ for more information
- *	    and for latest version of this driver.
  *
  * Copyright (C) 2001  Massimo Dal Zotto <dz@debian.org>
  *
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 07/14] i8k: Drop driver version number and info message at startup
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (5 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 06/14] i8k: Remove obsolete link to out-of-tree driver Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 08/14] i8k: Force SMM to run on CPU 0 Guenter Roeck
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

The driver version number is long since obsolete, so drop it.
Also, drop the info message at driver startup to reduce boot noise.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |    5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 5b3682c..ad0acef 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -34,8 +34,6 @@
 
 #include <linux/i8k.h>
 
-#define I8K_VERSION		"1.14 21/02/2005"
-
 #define I8K_SMM_FN_STATUS	0x0025
 #define I8K_SMM_POWER_STATUS	0x0069
 #define I8K_SMM_SET_FAN		0x01a3
@@ -755,9 +753,6 @@ static int __init i8k_init(void)
 	if (err)
 		goto exit_remove_proc;
 
-	pr_info("Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
-		I8K_VERSION);
-
 	return 0;
 
  exit_remove_proc:
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 08/14] i8k: Force SMM to run on CPU 0
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (6 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 07/14] i8k: Drop driver version number and info message at startup Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 09/14] i8k: Add copyright Guenter Roeck
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck,
	Jean Delvare

On Studio 1555 with dual-core CPU, reading sensor attributes
exported by this driver resulted in random failures combined
with system hangups and forced logouts. Information in
drivers/firmware/dcdbas.c suggests that SMM accesses must
run on CPU 0. With this patch, the problems are gone,
suggesting that this is in fact the case.

Code derived from drivers/firmware/dcdbas.c.

Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index ad0acef..264be2b 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -31,6 +31,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 
 #include <linux/i8k.h>
 
@@ -130,6 +131,17 @@ static int i8k_smm(struct smm_regs *regs)
 {
 	int rc;
 	int eax = regs->eax;
+	cpumask_var_t old_mask;
+
+	/* SMM requires CPU 0 */
+	if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
+		return -ENOMEM;
+	cpumask_copy(old_mask, &current->cpus_allowed);
+	set_cpus_allowed_ptr(current, cpumask_of(0));
+	if (smp_processor_id() != 0) {
+		rc = -EBUSY;
+		goto out;
+	}
 
 #if defined(CONFIG_X86_64)
 	asm volatile("pushq %%rax\n\t"
@@ -185,9 +197,12 @@ static int i8k_smm(struct smm_regs *regs)
 	    :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 #endif
 	if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
-		return -EINVAL;
+		rc = -EINVAL;
 
-	return 0;
+out:
+	set_cpus_allowed_ptr(current, old_mask);
+	free_cpumask_var(old_mask);
+	return rc;
 }
 
 /*
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 09/14] i8k: Add copyright
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (7 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 08/14] i8k: Force SMM to run on CPU 0 Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 10/14] i8k: Add support for Dell Studio laptops Guenter Roeck
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

I made enough changes to the driver to warrant adding a copyright notice.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 264be2b..6aed11f 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -5,6 +5,7 @@
  *
  * Hwmon integration:
  * Copyright (C) 2011  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2013  Guenter Roeck <linux@roeck-us.net>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 10/14] i8k: Add support for Dell Studio laptops
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (8 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 09/14] i8k: Add copyright Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 11/14] i8k: Add support for Dell XPS M140 Guenter Roeck
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

Tested with Dell Studio 1555.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 6aed11f..b35ccaa 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -685,6 +685,13 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
 		},
 	},
+	{
+		.ident = "Dell Studio",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
+		},
+	},
 	{ }
 };
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 11/14] i8k: Add support for Dell XPS M140
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (9 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 10/14] i8k: Add support for Dell Studio laptops Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 12/14] i8k: Use driver_data field of dmi_system_id to override fan multiplier Guenter Roeck
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index b35ccaa..bd11dac 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -692,6 +692,13 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
 		},
 	},
+	{
+		.ident = "Dell XPS M140",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
+		},
+	},
 	{ }
 };
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 12/14] i8k: Use driver_data field of dmi_system_id to override fan multiplier
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (10 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 11/14] i8k: Add support for Dell XPS M140 Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 13/14] i8k: Stop reading SMM BIOS version during driver probe Guenter Roeck
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

At least on Studio 1555 and XPS M140, the fan speed is reported directly,
not with the default speed multiplier of 30. Information on the web
suggests that this may be true for other models as well, though it is
unknown at this time which systems may be affected.

Use the driver_data field of dmi_system_id to override the default fan
multiplier value for the two systems known to use a multiplier of 1.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index bd11dac..67e4256 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -65,6 +65,7 @@ static DEFINE_MUTEX(i8k_mutex);
 static char bios_version[4];
 static struct device *i8k_hwmon_dev;
 static u32 i8k_hwmon_flags;
+static int i8k_fan_mult;
 
 #define I8K_HWMON_HAVE_TEMP1	(1 << 0)
 #define I8K_HWMON_HAVE_TEMP2	(1 << 1)
@@ -275,7 +276,7 @@ static int i8k_get_fan_speed(int fan)
 	struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
 
 	regs.ebx = fan & 0xff;
-	return i8k_smm(&regs) ? : (regs.eax & 0xffff) * fan_mult;
+	return i8k_smm(&regs) ? : (regs.eax & 0xffff) * i8k_fan_mult;
 }
 
 /*
@@ -691,6 +692,7 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
 		},
+		.driver_data = (void *)1,	/* fan multiplier override */
 	},
 	{
 		.ident = "Dell XPS M140",
@@ -698,6 +700,7 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
 		},
+		.driver_data = (void *)1,	/* fan multiplier override */
 	},
 	{ }
 };
@@ -709,6 +712,7 @@ static int __init i8k_probe(void)
 {
 	char buff[4];
 	int version;
+	const struct dmi_system_id *id;
 
 	/*
 	 * Get DMI information
@@ -762,6 +766,11 @@ static int __init i8k_probe(void)
 				buff, bios_version);
 	}
 
+	i8k_fan_mult = fan_mult;
+	id = dmi_first_match(i8k_dmi_table);
+	if (id && fan_mult == I8K_FAN_MULT && id->driver_data)
+		i8k_fan_mult = (unsigned long)id->driver_data;
+
 	return 0;
 }
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 13/14] i8k: Stop reading SMM BIOS version during driver probe
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (11 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 12/14] i8k: Use driver_data field of dmi_system_id to override fan multiplier Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:30 ` [PATCH 14/14] i8k: Implement hwmon based fan speed control Guenter Roeck
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

This doesn't work on Studio, XPS, Vostro, and Precision laptops,
and it doesn't provide any value except to cause confusion when
it does not work. Drop it and always use DMI BIOS version instead.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   42 ++----------------------------------------
 1 file changed, 2 insertions(+), 40 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 67e4256..ce826d9 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -44,7 +44,6 @@
 #define I8K_SMM_GET_TEMP	0x10a3
 #define I8K_SMM_GET_DELL_SIG1	0xfea3
 #define I8K_SMM_GET_DELL_SIG2	0xffa3
-#define I8K_SMM_BIOS_VERSION	0x00a6
 
 #define I8K_FAN_MULT		30
 #define I8K_MAX_TEMP		127
@@ -208,17 +207,6 @@ out:
 }
 
 /*
- * Read the bios version. Return the version as an integer corresponding
- * to the ascii value, for example "A17" is returned as 0x00413137.
- */
-static int i8k_get_bios_version(void)
-{
-	struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
-
-	return i8k_smm(&regs) ? : regs.eax;
-}
-
-/*
  * Read the Fn key status.
  */
 static int i8k_get_fn_status(void)
@@ -355,7 +343,8 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
 
 	switch (cmd) {
 	case I8K_BIOS_VERSION:
-		val = i8k_get_bios_version();
+		val = (bios_version[0] << 16) |
+				(bios_version[1] << 8) | bios_version[2];
 		break;
 
 	case I8K_MACHINE_ID:
@@ -710,8 +699,6 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
  */
 static int __init i8k_probe(void)
 {
-	char buff[4];
-	int version;
 	const struct dmi_system_id *id;
 
 	/*
@@ -741,31 +728,6 @@ static int __init i8k_probe(void)
 			return -ENODEV;
 	}
 
-	/*
-	 * Get SMM BIOS version.
-	 */
-	version = i8k_get_bios_version();
-	if (version <= 0) {
-		pr_warn("unable to get SMM BIOS version\n");
-	} else {
-		buff[0] = (version >> 16) & 0xff;
-		buff[1] = (version >> 8) & 0xff;
-		buff[2] = (version) & 0xff;
-		buff[3] = '\0';
-		/*
-		 * If DMI BIOS version is unknown use SMM BIOS version.
-		 */
-		if (!dmi_get_system_info(DMI_BIOS_VERSION))
-			strlcpy(bios_version, buff, sizeof(bios_version));
-
-		/*
-		 * Check if the two versions match.
-		 */
-		if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
-			pr_warn("BIOS version mismatch: %s != %s\n",
-				buff, bios_version);
-	}
-
 	i8k_fan_mult = fan_mult;
 	id = dmi_first_match(i8k_dmi_table);
 	if (id && fan_mult == I8K_FAN_MULT && id->driver_data)
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH 14/14] i8k: Implement hwmon based fan speed control
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (12 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 13/14] i8k: Stop reading SMM BIOS version during driver probe Guenter Roeck
@ 2013-12-14 17:30 ` Guenter Roeck
  2013-12-14 17:38 ` [PATCH 00/12] i8k patch series Guenter Roeck
  2013-12-14 18:45 ` Arnd Bergmann
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:30 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck,
	Jean Delvare

Fan speed can be set to off, slow, and fast, which can be exported
to userspace through the hwmon ABI as pwm1 / pwm2.

Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/char/i8k.c |   49 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index ce826d9..70c8df2 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -509,6 +509,39 @@ static ssize_t i8k_hwmon_show_fan(struct device *dev,
 	return sprintf(buf, "%d\n", fan_speed);
 }
 
+static ssize_t i8k_hwmon_show_pwm(struct device *dev,
+				  struct device_attribute *devattr,
+				  char *buf)
+{
+	int index = to_sensor_dev_attr(devattr)->index;
+	int status;
+
+	status = i8k_get_fan_status(index);
+	if (status < 0)
+		return -EIO;
+	return sprintf(buf, "%d\n", clamp_val(status * 128, 0, 255));
+}
+
+static ssize_t i8k_hwmon_set_pwm(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int index = to_sensor_dev_attr(attr)->index;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	val = clamp_val(DIV_ROUND_CLOSEST(val, 128), 0, 2);
+
+	mutex_lock(&i8k_mutex);
+	err = i8k_set_fan(index, val);
+	mutex_unlock(&i8k_mutex);
+
+	return err < 0 ? -EIO : count;
+}
+
 static ssize_t i8k_hwmon_show_label(struct device *dev,
 				    struct device_attribute *devattr,
 				    char *buf)
@@ -529,8 +562,12 @@ static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2);
 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 3);
 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
 			  I8K_FAN_LEFT);
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
+			  i8k_hwmon_set_pwm, I8K_FAN_LEFT);
 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
 			  I8K_FAN_RIGHT);
+static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
+			  i8k_hwmon_set_pwm, I8K_FAN_RIGHT);
 static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 0);
 static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
 static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
@@ -542,9 +579,11 @@ static struct attribute *i8k_attrs[] = {
 	&sensor_dev_attr_temp3_input.dev_attr.attr,	/* 3 */
 	&sensor_dev_attr_temp4_input.dev_attr.attr,	/* 4 */
 	&sensor_dev_attr_fan1_input.dev_attr.attr,	/* 5 */
-	&sensor_dev_attr_fan1_label.dev_attr.attr,	/* 6 */
-	&sensor_dev_attr_fan2_input.dev_attr.attr,	/* 7 */
-	&sensor_dev_attr_fan2_label.dev_attr.attr,	/* 8 */
+	&sensor_dev_attr_pwm1.dev_attr.attr,		/* 6 */
+	&sensor_dev_attr_fan1_label.dev_attr.attr,	/* 7 */
+	&sensor_dev_attr_fan2_input.dev_attr.attr,	/* 8 */
+	&sensor_dev_attr_pwm2.dev_attr.attr,		/* 9 */
+	&sensor_dev_attr_fan2_label.dev_attr.attr,	/* 10 */
 	NULL
 };
 
@@ -560,10 +599,10 @@ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
 		return 0;
 	if (index == 4 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
 		return 0;
-	if ((index == 5 || index == 6) &&
+	if (index >= 5 && index <= 7 &&
 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
 		return 0;
-	if ((index == 7 || index == 8) &&
+	if (index >= 8 && index <= 10 &&
 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
 		return 0;
 
-- 
1.7.9.7


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH 00/12] i8k patch series
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (13 preceding siblings ...)
  2013-12-14 17:30 ` [PATCH 14/14] i8k: Implement hwmon based fan speed control Guenter Roeck
@ 2013-12-14 17:38 ` Guenter Roeck
  2013-12-14 18:45 ` Arnd Bergmann
  15 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 17:38 UTC (permalink / raw)
  To: Arnd Bergmann, Greg Kroah-Hartman
  Cc: Andrew Morton, lm-sensors, linux-kernel, Guenter Roeck

On 12/14/2013 09:30 AM, Guenter Roeck wrote:
> Clean up and simplify the driver, add support for additional temperature
> sensors, fix a problem seen with multi-core CPU, and add support
> for additional systems.
>
Sigh. Headline should have read 00/14, obviously.

Guenter

> ----------------------------------------------------------------
> Guenter Roeck (14):
>        i8k: Convert to use pr_ functions instead of printk
>        i8k: Fix various checkpatch warnings and errors
>        i8k: Convert to use to hwmon_device_register_with_groups hwmon API
>        i8k: Support additional temperature sensors
>        MAINTAINERS: Add myself as i8k maintainer
>        i8k: Remove obsolete link to out-of-tree driver
>        i8k: Drop driver version number and info message at startup
>        i8k: Force SMM to run on CPU 0
>        i8k: Add copyright
>        i8k: Add support for Dell Studio laptops
>        i8k: Add support for Dell XPS M140
>        i8k: Use driver_data field of dmi_system_id to override fan multiplier
>        i8k: Stop reading SMM BIOS version during driver probe
>        i8k: Implement hwmon based fan speed control
>
>   MAINTAINERS        |    2 +-
>   drivers/char/i8k.c |  358 +++++++++++++++++++++++++++++-----------------------
>   2 files changed, 201 insertions(+), 159 deletions(-)
>
>


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 00/12] i8k patch series
  2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
                   ` (14 preceding siblings ...)
  2013-12-14 17:38 ` [PATCH 00/12] i8k patch series Guenter Roeck
@ 2013-12-14 18:45 ` Arnd Bergmann
  2013-12-14 19:03   ` [lm-sensors] " Jean Delvare
  15 siblings, 1 reply; 19+ messages in thread
From: Arnd Bergmann @ 2013-12-14 18:45 UTC (permalink / raw)
  To: Guenter Roeck; +Cc: Greg Kroah-Hartman, Andrew Morton, lm-sensors, linux-kernel

On Saturday 14 December 2013, Guenter Roeck wrote:
> Clean up and simplify the driver, add support for additional temperature
> sensors, fix a problem seen with multi-core CPU, and add support
> for additional systems.
> 
> ----------------------------------------------------------------
> Guenter Roeck (14):
>       i8k: Convert to use pr_ functions instead of printk
>       i8k: Fix various checkpatch warnings and errors
>       i8k: Convert to use to hwmon_device_register_with_groups hwmon API
>       i8k: Support additional temperature sensors
>       MAINTAINERS: Add myself as i8k maintainer
>       i8k: Remove obsolete link to out-of-tree driver
>       i8k: Drop driver version number and info message at startup
>       i8k: Force SMM to run on CPU 0
>       i8k: Add copyright
>       i8k: Add support for Dell Studio laptops
>       i8k: Add support for Dell XPS M140
>       i8k: Use driver_data field of dmi_system_id to override fan multiplier
>       i8k: Stop reading SMM BIOS version during driver probe
>       i8k: Implement hwmon based fan speed control
> 
>  MAINTAINERS        |    2 +-
>  drivers/char/i8k.c |  358 +++++++++++++++++++++++++++++-----------------------
>  2 files changed, 201 insertions(+), 159 deletions(-)
> 

All changes in this patch set look good to me.

Acked-by: Arnd Bergmann <arnd@arndb.de>

I wonder if it makes sense to move the driver to drivers/platform/x86/, which
has a bunch of similar ones already.

	Arnd

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] i8k patch series
  2013-12-14 18:45 ` Arnd Bergmann
@ 2013-12-14 19:03   ` Jean Delvare
  2013-12-14 19:50     ` Guenter Roeck
  0 siblings, 1 reply; 19+ messages in thread
From: Jean Delvare @ 2013-12-14 19:03 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Guenter Roeck, Greg Kroah-Hartman, Andrew Morton, linux-kernel,
	lm-sensors

On Sat, 14 Dec 2013 19:45:19 +0100, Arnd Bergmann wrote:
> On Saturday 14 December 2013, Guenter Roeck wrote:
> > Clean up and simplify the driver, add support for additional temperature
> > sensors, fix a problem seen with multi-core CPU, and add support
> > for additional systems.
> > 
> > ----------------------------------------------------------------
> > Guenter Roeck (14):
> >       i8k: Convert to use pr_ functions instead of printk
> >       i8k: Fix various checkpatch warnings and errors
> >       i8k: Convert to use to hwmon_device_register_with_groups hwmon API
> >       i8k: Support additional temperature sensors
> >       MAINTAINERS: Add myself as i8k maintainer
> >       i8k: Remove obsolete link to out-of-tree driver
> >       i8k: Drop driver version number and info message at startup
> >       i8k: Force SMM to run on CPU 0
> >       i8k: Add copyright
> >       i8k: Add support for Dell Studio laptops
> >       i8k: Add support for Dell XPS M140
> >       i8k: Use driver_data field of dmi_system_id to override fan multiplier
> >       i8k: Stop reading SMM BIOS version during driver probe
> >       i8k: Implement hwmon based fan speed control
> > 
> >  MAINTAINERS        |    2 +-
> >  drivers/char/i8k.c |  358 +++++++++++++++++++++++++++++-----------------------
> >  2 files changed, 201 insertions(+), 159 deletions(-)
> > 
> 
> All changes in this patch set look good to me.
> 
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> 
> I wonder if it makes sense to move the driver to drivers/platform/x86/, which
> has a bunch of similar ones already.

That would be a good idea IMHO.

-- 
Jean Delvare

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] i8k patch series
  2013-12-14 19:03   ` [lm-sensors] " Jean Delvare
@ 2013-12-14 19:50     ` Guenter Roeck
  0 siblings, 0 replies; 19+ messages in thread
From: Guenter Roeck @ 2013-12-14 19:50 UTC (permalink / raw)
  To: Jean Delvare, Arnd Bergmann
  Cc: Greg Kroah-Hartman, Andrew Morton, linux-kernel, lm-sensors,
	Matthew Garrett, platform-driver-x86@vger.kernel.org

On 12/14/2013 11:03 AM, Jean Delvare wrote:
> On Sat, 14 Dec 2013 19:45:19 +0100, Arnd Bergmann wrote:
>> On Saturday 14 December 2013, Guenter Roeck wrote:
>>> Clean up and simplify the driver, add support for additional temperature
>>> sensors, fix a problem seen with multi-core CPU, and add support
>>> for additional systems.
>>>
>>> ----------------------------------------------------------------
>>> Guenter Roeck (14):
>>>        i8k: Convert to use pr_ functions instead of printk
>>>        i8k: Fix various checkpatch warnings and errors
>>>        i8k: Convert to use to hwmon_device_register_with_groups hwmon API
>>>        i8k: Support additional temperature sensors
>>>        MAINTAINERS: Add myself as i8k maintainer
>>>        i8k: Remove obsolete link to out-of-tree driver
>>>        i8k: Drop driver version number and info message at startup
>>>        i8k: Force SMM to run on CPU 0
>>>        i8k: Add copyright
>>>        i8k: Add support for Dell Studio laptops
>>>        i8k: Add support for Dell XPS M140
>>>        i8k: Use driver_data field of dmi_system_id to override fan multiplier
>>>        i8k: Stop reading SMM BIOS version during driver probe
>>>        i8k: Implement hwmon based fan speed control
>>>
>>>   MAINTAINERS        |    2 +-
>>>   drivers/char/i8k.c |  358 +++++++++++++++++++++++++++++-----------------------
>>>   2 files changed, 201 insertions(+), 159 deletions(-)
>>>
>>
>> All changes in this patch set look good to me.
>>
>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>
>> I wonder if it makes sense to move the driver to drivers/platform/x86/, which
>> has a bunch of similar ones already.
>
> That would be a good idea IMHO.
>

I agree; drivers/char doesn't seem to be a good location. Guess it is mostly historic
that it is there in the first place. Maybe it can even use the API provided by the
dell-laptop driver if I can ever figure out how that works.

Copying the platform-x86 mailing list and Matthew for additional input.

Thanks,
Guenter


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2013-12-14 19:50 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-14 17:30 [PATCH 00/12] i8k patch series Guenter Roeck
2013-12-14 17:30 ` [PATCH 01/14] i8k: Convert to use pr_ functions instead of printk Guenter Roeck
2013-12-14 17:30 ` [PATCH 02/14] i8k: Fix various checkpatch warnings and errors Guenter Roeck
2013-12-14 17:30 ` [PATCH 03/14] i8k: Convert to use to hwmon_device_register_with_groups hwmon API Guenter Roeck
2013-12-14 17:30 ` [PATCH 04/14] i8k: Support additional temperature sensors Guenter Roeck
2013-12-14 17:30 ` [PATCH 05/14] MAINTAINERS: Add myself as i8k maintainer Guenter Roeck
2013-12-14 17:30 ` [PATCH 06/14] i8k: Remove obsolete link to out-of-tree driver Guenter Roeck
2013-12-14 17:30 ` [PATCH 07/14] i8k: Drop driver version number and info message at startup Guenter Roeck
2013-12-14 17:30 ` [PATCH 08/14] i8k: Force SMM to run on CPU 0 Guenter Roeck
2013-12-14 17:30 ` [PATCH 09/14] i8k: Add copyright Guenter Roeck
2013-12-14 17:30 ` [PATCH 10/14] i8k: Add support for Dell Studio laptops Guenter Roeck
2013-12-14 17:30 ` [PATCH 11/14] i8k: Add support for Dell XPS M140 Guenter Roeck
2013-12-14 17:30 ` [PATCH 12/14] i8k: Use driver_data field of dmi_system_id to override fan multiplier Guenter Roeck
2013-12-14 17:30 ` [PATCH 13/14] i8k: Stop reading SMM BIOS version during driver probe Guenter Roeck
2013-12-14 17:30 ` [PATCH 14/14] i8k: Implement hwmon based fan speed control Guenter Roeck
2013-12-14 17:38 ` [PATCH 00/12] i8k patch series Guenter Roeck
2013-12-14 18:45 ` Arnd Bergmann
2013-12-14 19:03   ` [lm-sensors] " Jean Delvare
2013-12-14 19:50     ` Guenter Roeck

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox