summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/intel-agp.c3
-rw-r--r--drivers/char/agp/intel-agp.h8
-rw-r--r--drivers/char/agp/intel-gtt.c10
-rw-r--r--drivers/char/agp/uninorth-agp.c2
-rw-r--r--drivers/char/i8k.c166
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c2
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
};