diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/intel-agp.c | 3 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.h | 8 | ||||
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 10 | ||||
-rw-r--r-- | drivers/char/agp/uninorth-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/i8k.c | 166 | ||||
-rw-r--r-- | drivers/char/pcmcia/cm4000_cs.c | 2 | ||||
-rw-r--r-- | drivers/char/pcmcia/cm4040_cs.c | 2 | ||||
-rw-r--r-- | drivers/char/pcmcia/synclink_cs.c | 2 |
8 files changed, 189 insertions, 6 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b0a0dcc..b427711 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -903,6 +903,9 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB), + ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB), + ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB), + ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB), { } }; diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 5feebe2..999803c 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -225,6 +225,14 @@ #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG 0x0126 #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB 0x0150 /* Desktop */ +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT1_IG 0x0152 +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT2_IG 0x0162 +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB 0x0154 /* Mobile */ +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT1_IG 0x0156 +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG 0x0166 +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB 0x0158 /* Server */ +#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG 0x015A int intel_gmch_probe(struct pci_dev *pdev, struct agp_bridge_data *bridge); diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 0d09b53..8515101 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1420,6 +1420,16 @@ static const struct intel_gtt_driver_description { "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, "Sandybridge", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT1_IG, + "Ivybridge", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT2_IG, + "Ivybridge", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT1_IG, + "Ivybridge", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG, + "Ivybridge", &sandybridge_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG, + "Ivybridge", &sandybridge_gtt_driver }, { 0, NULL, NULL } }; diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index f845a8f..a32c492 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -80,7 +80,7 @@ static void uninorth_tlbflush(struct agp_memory *mem) ctrl | UNI_N_CFG_GART_INVAL); pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, ctrl); - if (uninorth_rev <= 0x30) { + if (!mem && uninorth_rev <= 0x30) { pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, ctrl | UNI_N_CFG_GART_2xRESET); pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index d72433f..6e40072 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -5,6 +5,9 @@ * * Copyright (C) 2001 Massimo Dal Zotto <dz@debian.org> * + * Hwmon integration: + * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org> + * * 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 * Free Software Foundation; either version 2, or (at your option) any @@ -24,6 +27,8 @@ #include <linux/dmi.h> #include <linux/capability.h> #include <linux/mutex.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -58,6 +63,7 @@ static DEFINE_MUTEX(i8k_mutex); static char bios_version[4]; +static struct device *i8k_hwmon_dev; MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); @@ -139,8 +145,8 @@ static int i8k_smm(struct smm_regs *regs) "movl %%edi,20(%%rax)\n\t" "popq %%rdx\n\t" "movl %%edx,0(%%rax)\n\t" - "lahf\n\t" - "shrl $8,%%eax\n\t" + "pushfq\n\t" + "popq %%rax\n\t" "andl $1,%%eax\n" :"=a"(rc) : "a"(regs) @@ -455,6 +461,152 @@ static int i8k_open_fs(struct inode *inode, struct file *file) return single_open(file, i8k_proc_show, NULL); } + +/* + * Hwmon interface + */ + +static ssize_t i8k_hwmon_show_temp(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + int cpu_temp; + + cpu_temp = i8k_get_temp(0); + if (cpu_temp < 0) + return cpu_temp; + return sprintf(buf, "%d\n", cpu_temp * 1000); +} + +static ssize_t i8k_hwmon_show_fan(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + int index = to_sensor_dev_attr(devattr)->index; + int fan_speed; + + fan_speed = i8k_get_fan_speed(index); + if (fan_speed < 0) + return fan_speed; + return sprintf(buf, "%d\n", fan_speed); +} + +static ssize_t i8k_hwmon_show_label(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + static const char *labels[4] = { + "i8k", + "CPU", + "Left Fan", + "Right Fan", + }; + int index = to_sensor_dev_attr(devattr)->index; + + return sprintf(buf, "%s\n", labels[index]); +} + +static DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL); +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 void i8k_hwmon_remove_files(struct device *dev) +{ + 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); +} + +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; + printk(KERN_ERR "i8k: 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; + + /* 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; + } + + /* 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; + } + + /* 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; + } + + 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 __initdata i8k_dmi_table[] = { { .ident = "Dell Inspiron", @@ -580,6 +732,7 @@ static int __init i8k_probe(void) static int __init i8k_init(void) { struct proc_dir_entry *proc_i8k; + int err; /* Are we running on an supported laptop? */ if (i8k_probe()) @@ -590,15 +743,24 @@ static int __init i8k_init(void) if (!proc_i8k) return -ENOENT; + err = i8k_init_hwmon(); + if (err) + goto exit_remove_proc; + printk(KERN_INFO "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n", I8K_VERSION); return 0; + + exit_remove_proc: + remove_proc_entry("i8k", NULL); + return err; } static void __exit i8k_exit(void) { + i8k_exit_hwmon(); remove_proc_entry("i8k", NULL); } diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 90bd016..a758486 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -1869,7 +1869,7 @@ static const struct file_operations cm4000_fops = { .llseek = no_llseek, }; -static struct pcmcia_device_id cm4000_ids[] = { +static const struct pcmcia_device_id cm4000_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002), PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39), PCMCIA_DEVICE_NULL, diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 5d8d59e..8dd48a2 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -633,7 +633,7 @@ static const struct file_operations reader_fops = { .llseek = no_llseek, }; -static struct pcmcia_device_id cm4040_ids[] = { +static const struct pcmcia_device_id cm4040_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0200), PCMCIA_DEVICE_PROD_ID12("OMNIKEY", "CardMan 4040", 0xE32CDD8C, 0x8F23318B), diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index b575411..1578139 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2758,7 +2758,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) } } -static struct pcmcia_device_id mgslpc_ids[] = { +static const struct pcmcia_device_id mgslpc_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x02c5, 0x0050), PCMCIA_DEVICE_NULL }; |