aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-20 18:48:19 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-20 18:48:19 -0500
commit9f67627a0fea99b080a190d2d24cc1e2634aa2f7 (patch)
tree24dcf714a8b502c7ef91086d9eb6164f68c7d52b /drivers/char
parent82b51734b4f228c76b6064b6e899d9d3d4c17c1a (diff)
parent6adb8efb024a7e413b93b22848fc13395b1a438a (diff)
Merge tag 'char-misc-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver patches from Greg KH: "Here's the big char/misc driver patches for 3.14-rc1. Lots of little things, and a new "big" driver, genwqe. Full details are in the shortlog" * tag 'char-misc-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (90 commits) mei: limit the number of consecutive resets mei: revamp mei reset state machine drivers/char: don't use module_init in non-modular ttyprintk.c VMCI: fix error handling path when registering guest driver extcon: gpio: Add power resume support Documentation: HOWTO: Updates on subsystem trees, patchwork, -next (vs. -mm) in ko_KR Documentation: HOWTO: update for 2.6.x -> 3.x versioning in ko_KR Documentation: HOWTO: update stable address in ko_KR Documentation: HOWTO: update LXR web link in ko_KR char: nwbutton: open-code interruptible_sleep_on mei: fix syntax in comments and debug output mei: nfc: mei_nfc_free has to be called under lock mei: use hbm idle state to prevent spurious resets mei: do not run reset flow from the interrupt thread misc: genwqe: fix return value check in genwqe_device_create() GenWQE: Fix warnings for sparc GenWQE: Fix compile problems for Alpha Documentation/misc-devices/mei/mei-amt-version.c: remove unneeded call of mei_deinit() GenWQE: Rework return code for flash-update ioctl sgi-xp: open-code interruptible_sleep_on_timeout ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/i8k.c358
-rw-r--r--drivers/char/lp.c2
-rw-r--r--drivers/char/nwbutton.c5
-rw-r--r--drivers/char/ttyprintk.c2
5 files changed, 208 insertions, 161 deletions
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index d79d692d05b8..896413b59aae 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -735,7 +735,7 @@ static struct pci_device_id agp_amd64_pci_table[] = {
735 735
736MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table); 736MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
737 737
738static DEFINE_PCI_DEVICE_TABLE(agp_amd64_pci_promisc_table) = { 738static const struct pci_device_id agp_amd64_pci_promisc_table[] = {
739 { PCI_DEVICE_CLASS(0, 0) }, 739 { PCI_DEVICE_CLASS(0, 0) },
740 { } 740 { }
741}; 741};
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index e6939e13e338..e210f858d3cb 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -1,12 +1,11 @@
1/* 1/*
2 * i8k.c -- Linux driver for accessing the SMM BIOS on Dell laptops. 2 * i8k.c -- Linux driver for accessing the SMM BIOS on Dell laptops.
3 * See http://www.debian.org/~dz/i8k/ for more information
4 * and for latest version of this driver.
5 * 3 *
6 * Copyright (C) 2001 Massimo Dal Zotto <dz@debian.org> 4 * Copyright (C) 2001 Massimo Dal Zotto <dz@debian.org>
7 * 5 *
8 * Hwmon integration: 6 * Hwmon integration:
9 * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org> 7 * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org>
8 * Copyright (C) 2013 Guenter Roeck <linux@roeck-us.net>
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
@@ -19,6 +18,8 @@
19 * General Public License for more details. 18 * General Public License for more details.
20 */ 19 */
21 20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/types.h> 24#include <linux/types.h>
24#include <linux/init.h> 25#include <linux/init.h>
@@ -29,13 +30,12 @@
29#include <linux/mutex.h> 30#include <linux/mutex.h>
30#include <linux/hwmon.h> 31#include <linux/hwmon.h>
31#include <linux/hwmon-sysfs.h> 32#include <linux/hwmon-sysfs.h>
32#include <asm/uaccess.h> 33#include <linux/uaccess.h>
33#include <asm/io.h> 34#include <linux/io.h>
35#include <linux/sched.h>
34 36
35#include <linux/i8k.h> 37#include <linux/i8k.h>
36 38
37#define I8K_VERSION "1.14 21/02/2005"
38
39#define I8K_SMM_FN_STATUS 0x0025 39#define I8K_SMM_FN_STATUS 0x0025
40#define I8K_SMM_POWER_STATUS 0x0069 40#define I8K_SMM_POWER_STATUS 0x0069
41#define I8K_SMM_SET_FAN 0x01a3 41#define I8K_SMM_SET_FAN 0x01a3
@@ -44,7 +44,6 @@
44#define I8K_SMM_GET_TEMP 0x10a3 44#define I8K_SMM_GET_TEMP 0x10a3
45#define I8K_SMM_GET_DELL_SIG1 0xfea3 45#define I8K_SMM_GET_DELL_SIG1 0xfea3
46#define I8K_SMM_GET_DELL_SIG2 0xffa3 46#define I8K_SMM_GET_DELL_SIG2 0xffa3
47#define I8K_SMM_BIOS_VERSION 0x00a6
48 47
49#define I8K_FAN_MULT 30 48#define I8K_FAN_MULT 30
50#define I8K_MAX_TEMP 127 49#define I8K_MAX_TEMP 127
@@ -64,6 +63,15 @@
64static DEFINE_MUTEX(i8k_mutex); 63static DEFINE_MUTEX(i8k_mutex);
65static char bios_version[4]; 64static char bios_version[4];
66static struct device *i8k_hwmon_dev; 65static struct device *i8k_hwmon_dev;
66static u32 i8k_hwmon_flags;
67static int i8k_fan_mult;
68
69#define I8K_HWMON_HAVE_TEMP1 (1 << 0)
70#define I8K_HWMON_HAVE_TEMP2 (1 << 1)
71#define I8K_HWMON_HAVE_TEMP3 (1 << 2)
72#define I8K_HWMON_HAVE_TEMP4 (1 << 3)
73#define I8K_HWMON_HAVE_FAN1 (1 << 4)
74#define I8K_HWMON_HAVE_FAN2 (1 << 5)
67 75
68MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); 76MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
69MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); 77MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -103,11 +111,11 @@ static const struct file_operations i8k_fops = {
103 111
104struct smm_regs { 112struct smm_regs {
105 unsigned int eax; 113 unsigned int eax;
106 unsigned int ebx __attribute__ ((packed)); 114 unsigned int ebx __packed;
107 unsigned int ecx __attribute__ ((packed)); 115 unsigned int ecx __packed;
108 unsigned int edx __attribute__ ((packed)); 116 unsigned int edx __packed;
109 unsigned int esi __attribute__ ((packed)); 117 unsigned int esi __packed;
110 unsigned int edi __attribute__ ((packed)); 118 unsigned int edi __packed;
111}; 119};
112 120
113static inline const char *i8k_get_dmi_data(int field) 121static inline const char *i8k_get_dmi_data(int field)
@@ -124,6 +132,17 @@ static int i8k_smm(struct smm_regs *regs)
124{ 132{
125 int rc; 133 int rc;
126 int eax = regs->eax; 134 int eax = regs->eax;
135 cpumask_var_t old_mask;
136
137 /* SMM requires CPU 0 */
138 if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
139 return -ENOMEM;
140 cpumask_copy(old_mask, &current->cpus_allowed);
141 set_cpus_allowed_ptr(current, cpumask_of(0));
142 if (smp_processor_id() != 0) {
143 rc = -EBUSY;
144 goto out;
145 }
127 146
128#if defined(CONFIG_X86_64) 147#if defined(CONFIG_X86_64)
129 asm volatile("pushq %%rax\n\t" 148 asm volatile("pushq %%rax\n\t"
@@ -148,7 +167,7 @@ static int i8k_smm(struct smm_regs *regs)
148 "pushfq\n\t" 167 "pushfq\n\t"
149 "popq %%rax\n\t" 168 "popq %%rax\n\t"
150 "andl $1,%%eax\n" 169 "andl $1,%%eax\n"
151 :"=a"(rc) 170 : "=a"(rc)
152 : "a"(regs) 171 : "a"(regs)
153 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); 172 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
154#else 173#else
@@ -174,25 +193,17 @@ static int i8k_smm(struct smm_regs *regs)
174 "lahf\n\t" 193 "lahf\n\t"
175 "shrl $8,%%eax\n\t" 194 "shrl $8,%%eax\n\t"
176 "andl $1,%%eax\n" 195 "andl $1,%%eax\n"
177 :"=a"(rc) 196 : "=a"(rc)
178 : "a"(regs) 197 : "a"(regs)
179 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); 198 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
180#endif 199#endif
181 if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax) 200 if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
182 return -EINVAL; 201 rc = -EINVAL;
183 202
184 return 0; 203out:
185} 204 set_cpus_allowed_ptr(current, old_mask);
186 205 free_cpumask_var(old_mask);
187/* 206 return rc;
188 * Read the bios version. Return the version as an integer corresponding
189 * to the ascii value, for example "A17" is returned as 0x00413137.
190 */
191static int i8k_get_bios_version(void)
192{
193 struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
194
195 return i8k_smm(&regs) ? : regs.eax;
196} 207}
197 208
198/* 209/*
@@ -203,7 +214,8 @@ static int i8k_get_fn_status(void)
203 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, }; 214 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
204 int rc; 215 int rc;
205 216
206 if ((rc = i8k_smm(&regs)) < 0) 217 rc = i8k_smm(&regs);
218 if (rc < 0)
207 return rc; 219 return rc;
208 220
209 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { 221 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
@@ -226,7 +238,8 @@ static int i8k_get_power_status(void)
226 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, }; 238 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
227 int rc; 239 int rc;
228 240
229 if ((rc = i8k_smm(&regs)) < 0) 241 rc = i8k_smm(&regs);
242 if (rc < 0)
230 return rc; 243 return rc;
231 244
232 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY; 245 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
@@ -251,7 +264,7 @@ static int i8k_get_fan_speed(int fan)
251 struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, }; 264 struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
252 265
253 regs.ebx = fan & 0xff; 266 regs.ebx = fan & 0xff;
254 return i8k_smm(&regs) ? : (regs.eax & 0xffff) * fan_mult; 267 return i8k_smm(&regs) ? : (regs.eax & 0xffff) * i8k_fan_mult;
255} 268}
256 269
257/* 270/*
@@ -277,10 +290,11 @@ static int i8k_get_temp(int sensor)
277 int temp; 290 int temp;
278 291
279#ifdef I8K_TEMPERATURE_BUG 292#ifdef I8K_TEMPERATURE_BUG
280 static int prev; 293 static int prev[4];
281#endif 294#endif
282 regs.ebx = sensor & 0xff; 295 regs.ebx = sensor & 0xff;
283 if ((rc = i8k_smm(&regs)) < 0) 296 rc = i8k_smm(&regs);
297 if (rc < 0)
284 return rc; 298 return rc;
285 299
286 temp = regs.eax & 0xff; 300 temp = regs.eax & 0xff;
@@ -294,10 +308,10 @@ static int i8k_get_temp(int sensor)
294 # 1003655139 00000054 00005c52 308 # 1003655139 00000054 00005c52
295 */ 309 */
296 if (temp > I8K_MAX_TEMP) { 310 if (temp > I8K_MAX_TEMP) {
297 temp = prev; 311 temp = prev[sensor];
298 prev = I8K_MAX_TEMP; 312 prev[sensor] = I8K_MAX_TEMP;
299 } else { 313 } else {
300 prev = temp; 314 prev[sensor] = temp;
301 } 315 }
302#endif 316#endif
303 317
@@ -309,7 +323,8 @@ static int i8k_get_dell_signature(int req_fn)
309 struct smm_regs regs = { .eax = req_fn, }; 323 struct smm_regs regs = { .eax = req_fn, };
310 int rc; 324 int rc;
311 325
312 if ((rc = i8k_smm(&regs)) < 0) 326 rc = i8k_smm(&regs);
327 if (rc < 0)
313 return rc; 328 return rc;
314 329
315 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1; 330 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
@@ -328,12 +343,14 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
328 343
329 switch (cmd) { 344 switch (cmd) {
330 case I8K_BIOS_VERSION: 345 case I8K_BIOS_VERSION:
331 val = i8k_get_bios_version(); 346 val = (bios_version[0] << 16) |
347 (bios_version[1] << 8) | bios_version[2];
332 break; 348 break;
333 349
334 case I8K_MACHINE_ID: 350 case I8K_MACHINE_ID:
335 memset(buff, 0, 16); 351 memset(buff, 0, 16);
336 strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff)); 352 strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
353 sizeof(buff));
337 break; 354 break;
338 355
339 case I8K_FN_STATUS: 356 case I8K_FN_STATUS:
@@ -470,12 +487,13 @@ static ssize_t i8k_hwmon_show_temp(struct device *dev,
470 struct device_attribute *devattr, 487 struct device_attribute *devattr,
471 char *buf) 488 char *buf)
472{ 489{
473 int cpu_temp; 490 int index = to_sensor_dev_attr(devattr)->index;
491 int temp;
474 492
475 cpu_temp = i8k_get_temp(0); 493 temp = i8k_get_temp(index);
476 if (cpu_temp < 0) 494 if (temp < 0)
477 return cpu_temp; 495 return temp;
478 return sprintf(buf, "%d\n", cpu_temp * 1000); 496 return sprintf(buf, "%d\n", temp * 1000);
479} 497}
480 498
481static ssize_t i8k_hwmon_show_fan(struct device *dev, 499static ssize_t i8k_hwmon_show_fan(struct device *dev,
@@ -491,12 +509,44 @@ static ssize_t i8k_hwmon_show_fan(struct device *dev,
491 return sprintf(buf, "%d\n", fan_speed); 509 return sprintf(buf, "%d\n", fan_speed);
492} 510}
493 511
512static ssize_t i8k_hwmon_show_pwm(struct device *dev,
513 struct device_attribute *devattr,
514 char *buf)
515{
516 int index = to_sensor_dev_attr(devattr)->index;
517 int status;
518
519 status = i8k_get_fan_status(index);
520 if (status < 0)
521 return -EIO;
522 return sprintf(buf, "%d\n", clamp_val(status * 128, 0, 255));
523}
524
525static ssize_t i8k_hwmon_set_pwm(struct device *dev,
526 struct device_attribute *attr,
527 const char *buf, size_t count)
528{
529 int index = to_sensor_dev_attr(attr)->index;
530 unsigned long val;
531 int err;
532
533 err = kstrtoul(buf, 10, &val);
534 if (err)
535 return err;
536 val = clamp_val(DIV_ROUND_CLOSEST(val, 128), 0, 2);
537
538 mutex_lock(&i8k_mutex);
539 err = i8k_set_fan(index, val);
540 mutex_unlock(&i8k_mutex);
541
542 return err < 0 ? -EIO : count;
543}
544
494static ssize_t i8k_hwmon_show_label(struct device *dev, 545static ssize_t i8k_hwmon_show_label(struct device *dev,
495 struct device_attribute *devattr, 546 struct device_attribute *devattr,
496 char *buf) 547 char *buf)
497{ 548{
498 static const char *labels[4] = { 549 static const char *labels[3] = {
499 "i8k",
500 "CPU", 550 "CPU",
501 "Left Fan", 551 "Left Fan",
502 "Right Fan", 552 "Right Fan",
@@ -506,108 +556,108 @@ static ssize_t i8k_hwmon_show_label(struct device *dev,
506 return sprintf(buf, "%s\n", labels[index]); 556 return sprintf(buf, "%s\n", labels[index]);
507} 557}
508 558
509static DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL); 559static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 0);
560static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 1);
561static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2);
562static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 3);
510static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL, 563static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
511 I8K_FAN_LEFT); 564 I8K_FAN_LEFT);
565static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
566 i8k_hwmon_set_pwm, I8K_FAN_LEFT);
512static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL, 567static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
513 I8K_FAN_RIGHT); 568 I8K_FAN_RIGHT);
514static SENSOR_DEVICE_ATTR(name, S_IRUGO, i8k_hwmon_show_label, NULL, 0); 569static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
515static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1); 570 i8k_hwmon_set_pwm, I8K_FAN_RIGHT);
516static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2); 571static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 0);
517static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 3); 572static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
573static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
574
575static struct attribute *i8k_attrs[] = {
576 &sensor_dev_attr_temp1_input.dev_attr.attr, /* 0 */
577 &sensor_dev_attr_temp1_label.dev_attr.attr, /* 1 */
578 &sensor_dev_attr_temp2_input.dev_attr.attr, /* 2 */
579 &sensor_dev_attr_temp3_input.dev_attr.attr, /* 3 */
580 &sensor_dev_attr_temp4_input.dev_attr.attr, /* 4 */
581 &sensor_dev_attr_fan1_input.dev_attr.attr, /* 5 */
582 &sensor_dev_attr_pwm1.dev_attr.attr, /* 6 */
583 &sensor_dev_attr_fan1_label.dev_attr.attr, /* 7 */
584 &sensor_dev_attr_fan2_input.dev_attr.attr, /* 8 */
585 &sensor_dev_attr_pwm2.dev_attr.attr, /* 9 */
586 &sensor_dev_attr_fan2_label.dev_attr.attr, /* 10 */
587 NULL
588};
518 589
519static void i8k_hwmon_remove_files(struct device *dev) 590static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
591 int index)
520{ 592{
521 device_remove_file(dev, &dev_attr_temp1_input); 593 if ((index == 0 || index == 1) &&
522 device_remove_file(dev, &sensor_dev_attr_fan1_input.dev_attr); 594 !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
523 device_remove_file(dev, &sensor_dev_attr_fan2_input.dev_attr); 595 return 0;
524 device_remove_file(dev, &sensor_dev_attr_temp1_label.dev_attr); 596 if (index == 2 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2))
525 device_remove_file(dev, &sensor_dev_attr_fan1_label.dev_attr); 597 return 0;
526 device_remove_file(dev, &sensor_dev_attr_fan2_label.dev_attr); 598 if (index == 3 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3))
527 device_remove_file(dev, &sensor_dev_attr_name.dev_attr); 599 return 0;
600 if (index == 4 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
601 return 0;
602 if (index >= 5 && index <= 7 &&
603 !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
604 return 0;
605 if (index >= 8 && index <= 10 &&
606 !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
607 return 0;
608
609 return attr->mode;
528} 610}
529 611
612static const struct attribute_group i8k_group = {
613 .attrs = i8k_attrs,
614 .is_visible = i8k_is_visible,
615};
616__ATTRIBUTE_GROUPS(i8k);
617
530static int __init i8k_init_hwmon(void) 618static int __init i8k_init_hwmon(void)
531{ 619{
532 int err; 620 int err;
533 621
534 i8k_hwmon_dev = hwmon_device_register(NULL); 622 i8k_hwmon_flags = 0;
535 if (IS_ERR(i8k_hwmon_dev)) {
536 err = PTR_ERR(i8k_hwmon_dev);
537 i8k_hwmon_dev = NULL;
538 printk(KERN_ERR "i8k: hwmon registration failed (%d)\n", err);
539 return err;
540 }
541
542 /* Required name attribute */
543 err = device_create_file(i8k_hwmon_dev,
544 &sensor_dev_attr_name.dev_attr);
545 if (err)
546 goto exit_unregister;
547 623
548 /* CPU temperature attributes, if temperature reading is OK */ 624 /* CPU temperature attributes, if temperature reading is OK */
549 err = i8k_get_temp(0); 625 err = i8k_get_temp(0);
550 if (err < 0) { 626 if (err >= 0)
551 dev_dbg(i8k_hwmon_dev, 627 i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP1;
552 "Not creating temperature attributes (%d)\n", err); 628 /* check for additional temperature sensors */
553 } else { 629 err = i8k_get_temp(1);
554 err = device_create_file(i8k_hwmon_dev, &dev_attr_temp1_input); 630 if (err >= 0)
555 if (err) 631 i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP2;
556 goto exit_remove_files; 632 err = i8k_get_temp(2);
557 err = device_create_file(i8k_hwmon_dev, 633 if (err >= 0)
558 &sensor_dev_attr_temp1_label.dev_attr); 634 i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP3;
559 if (err) 635 err = i8k_get_temp(3);
560 goto exit_remove_files; 636 if (err >= 0)
561 } 637 i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
562 638
563 /* Left fan attributes, if left fan is present */ 639 /* Left fan attributes, if left fan is present */
564 err = i8k_get_fan_status(I8K_FAN_LEFT); 640 err = i8k_get_fan_status(I8K_FAN_LEFT);
565 if (err < 0) { 641 if (err >= 0)
566 dev_dbg(i8k_hwmon_dev, 642 i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
567 "Not creating %s fan attributes (%d)\n", "left", err);
568 } else {
569 err = device_create_file(i8k_hwmon_dev,
570 &sensor_dev_attr_fan1_input.dev_attr);
571 if (err)
572 goto exit_remove_files;
573 err = device_create_file(i8k_hwmon_dev,
574 &sensor_dev_attr_fan1_label.dev_attr);
575 if (err)
576 goto exit_remove_files;
577 }
578 643
579 /* Right fan attributes, if right fan is present */ 644 /* Right fan attributes, if right fan is present */
580 err = i8k_get_fan_status(I8K_FAN_RIGHT); 645 err = i8k_get_fan_status(I8K_FAN_RIGHT);
581 if (err < 0) { 646 if (err >= 0)
582 dev_dbg(i8k_hwmon_dev, 647 i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
583 "Not creating %s fan attributes (%d)\n", "right", err);
584 } else {
585 err = device_create_file(i8k_hwmon_dev,
586 &sensor_dev_attr_fan2_input.dev_attr);
587 if (err)
588 goto exit_remove_files;
589 err = device_create_file(i8k_hwmon_dev,
590 &sensor_dev_attr_fan2_label.dev_attr);
591 if (err)
592 goto exit_remove_files;
593 }
594 648
649 i8k_hwmon_dev = hwmon_device_register_with_groups(NULL, "i8k", NULL,
650 i8k_groups);
651 if (IS_ERR(i8k_hwmon_dev)) {
652 err = PTR_ERR(i8k_hwmon_dev);
653 i8k_hwmon_dev = NULL;
654 pr_err("hwmon registration failed (%d)\n", err);
655 return err;
656 }
595 return 0; 657 return 0;
596
597 exit_remove_files:
598 i8k_hwmon_remove_files(i8k_hwmon_dev);
599 exit_unregister:
600 hwmon_device_unregister(i8k_hwmon_dev);
601 return err;
602} 658}
603 659
604static void __exit i8k_exit_hwmon(void) 660static struct dmi_system_id i8k_dmi_table[] __initdata = {
605{
606 i8k_hwmon_remove_files(i8k_hwmon_dev);
607 hwmon_device_unregister(i8k_hwmon_dev);
608}
609
610static struct dmi_system_id __initdata i8k_dmi_table[] = {
611 { 661 {
612 .ident = "Dell Inspiron", 662 .ident = "Dell Inspiron",
613 .matches = { 663 .matches = {
@@ -671,7 +721,23 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = {
671 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), 721 DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
672 }, 722 },
673 }, 723 },
674 { } 724 {
725 .ident = "Dell Studio",
726 .matches = {
727 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
728 DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
729 },
730 .driver_data = (void *)1, /* fan multiplier override */
731 },
732 {
733 .ident = "Dell XPS M140",
734 .matches = {
735 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
736 DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
737 },
738 .driver_data = (void *)1, /* fan multiplier override */
739 },
740 { }
675}; 741};
676 742
677/* 743/*
@@ -679,8 +745,7 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = {
679 */ 745 */
680static int __init i8k_probe(void) 746static int __init i8k_probe(void)
681{ 747{
682 char buff[4]; 748 const struct dmi_system_id *id;
683 int version;
684 749
685 /* 750 /*
686 * Get DMI information 751 * Get DMI information
@@ -689,49 +754,30 @@ static int __init i8k_probe(void)
689 if (!ignore_dmi && !force) 754 if (!ignore_dmi && !force)
690 return -ENODEV; 755 return -ENODEV;
691 756
692 printk(KERN_INFO "i8k: not running on a supported Dell system.\n"); 757 pr_info("not running on a supported Dell system.\n");
693 printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n", 758 pr_info("vendor=%s, model=%s, version=%s\n",
694 i8k_get_dmi_data(DMI_SYS_VENDOR), 759 i8k_get_dmi_data(DMI_SYS_VENDOR),
695 i8k_get_dmi_data(DMI_PRODUCT_NAME), 760 i8k_get_dmi_data(DMI_PRODUCT_NAME),
696 i8k_get_dmi_data(DMI_BIOS_VERSION)); 761 i8k_get_dmi_data(DMI_BIOS_VERSION));
697 } 762 }
698 763
699 strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version)); 764 strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
765 sizeof(bios_version));
700 766
701 /* 767 /*
702 * Get SMM Dell signature 768 * Get SMM Dell signature
703 */ 769 */
704 if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) && 770 if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
705 i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) { 771 i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
706 printk(KERN_ERR "i8k: unable to get SMM Dell signature\n"); 772 pr_err("unable to get SMM Dell signature\n");
707 if (!force) 773 if (!force)
708 return -ENODEV; 774 return -ENODEV;
709 } 775 }
710 776
711 /* 777 i8k_fan_mult = fan_mult;
712 * Get SMM BIOS version. 778 id = dmi_first_match(i8k_dmi_table);
713 */ 779 if (id && fan_mult == I8K_FAN_MULT && id->driver_data)
714 version = i8k_get_bios_version(); 780 i8k_fan_mult = (unsigned long)id->driver_data;
715 if (version <= 0) {
716 printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
717 } else {
718 buff[0] = (version >> 16) & 0xff;
719 buff[1] = (version >> 8) & 0xff;
720 buff[2] = (version) & 0xff;
721 buff[3] = '\0';
722 /*
723 * If DMI BIOS version is unknown use SMM BIOS version.
724 */
725 if (!dmi_get_system_info(DMI_BIOS_VERSION))
726 strlcpy(bios_version, buff, sizeof(bios_version));
727
728 /*
729 * Check if the two versions match.
730 */
731 if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
732 printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
733 buff, bios_version);
734 }
735 781
736 return 0; 782 return 0;
737} 783}
@@ -754,10 +800,6 @@ static int __init i8k_init(void)
754 if (err) 800 if (err)
755 goto exit_remove_proc; 801 goto exit_remove_proc;
756 802
757 printk(KERN_INFO
758 "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
759 I8K_VERSION);
760
761 return 0; 803 return 0;
762 804
763 exit_remove_proc: 805 exit_remove_proc:
@@ -767,7 +809,7 @@ static int __init i8k_init(void)
767 809
768static void __exit i8k_exit(void) 810static void __exit i8k_exit(void)
769{ 811{
770 i8k_exit_hwmon(); 812 hwmon_device_unregister(i8k_hwmon_dev);
771 remove_proc_entry("i8k", NULL); 813 remove_proc_entry("i8k", NULL);
772} 814}
773 815
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 0913d79424d3..c4094c4e22c1 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -587,6 +587,8 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
587 return -ENODEV; 587 return -ENODEV;
588 switch ( cmd ) { 588 switch ( cmd ) {
589 case LPTIME: 589 case LPTIME:
590 if (arg > UINT_MAX / HZ)
591 return -EINVAL;
590 LP_TIME(minor) = arg * HZ/100; 592 LP_TIME(minor) = arg * HZ/100;
591 break; 593 break;
592 case LPCHAR: 594 case LPCHAR:
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 1fd00dc06897..76c490fa0511 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -168,7 +168,10 @@ static irqreturn_t button_handler (int irq, void *dev_id)
168static int button_read (struct file *filp, char __user *buffer, 168static int button_read (struct file *filp, char __user *buffer,
169 size_t count, loff_t *ppos) 169 size_t count, loff_t *ppos)
170{ 170{
171 interruptible_sleep_on (&button_wait_queue); 171 DEFINE_WAIT(wait);
172 prepare_to_wait(&button_wait_queue, &wait, TASK_INTERRUPTIBLE);
173 schedule();
174 finish_wait(&button_wait_queue, &wait);
172 return (copy_to_user (buffer, &button_output_buffer, bcount)) 175 return (copy_to_user (buffer, &button_output_buffer, bcount))
173 ? -EFAULT : bcount; 176 ? -EFAULT : bcount;
174} 177}
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index d5d2e4a985aa..daea84c41743 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -216,4 +216,4 @@ error:
216 ttyprintk_driver = NULL; 216 ttyprintk_driver = NULL;
217 return ret; 217 return ret;
218} 218}
219module_init(ttyprintk_init); 219device_initcall(ttyprintk_init);