]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/hwmon/w83627hf.c
[PATCH] hwmon: Missing class check in two hwmon drivers
[linux-2.6-omap-h63xx.git] / drivers / hwmon / w83627hf.c
index bd87a42e068ae4d6ac0fd1763d61b3c32b1bb5d7..48270819ff992ee361f1ce670485cda061a5fb83 100644 (file)
 #include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
+#include <linux/i2c-isa.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-vid.h>
+#include <linux/err.h>
 #include <asm/io.h>
 #include "lm75.h"
 
@@ -56,12 +58,15 @@ module_param(force_i2c, byte, 0);
 MODULE_PARM_DESC(force_i2c,
                 "Initialize the i2c address of the sensors");
 
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
+/* The actual ISA address is read from Super-I/O configuration space */
+static unsigned short address;
 
 /* Insmod parameters */
-SENSORS_INSMOD_4(w83627hf, w83627thf, w83697hf, w83637hf);
+enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf };
+
+static int reset;
+module_param(reset, bool, 0);
+MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
 
 static int init = 1;
 module_param(init, bool, 0);
@@ -137,10 +142,14 @@ superio_exit(void)
 #define WINB_BASE_REG 0x60
 /* Constants specified below */
 
-/* Length of ISA address segment */
-#define WINB_EXTENT 8
+/* Alignment of the base address */
+#define WINB_ALIGNMENT         ~7
+
+/* Offset & size of I/O region we are interested in */
+#define WINB_REGION_OFFSET     5
+#define WINB_REGION_SIZE       2
 
-/* Where are the ISA address/data registers relative to the base address */
+/* Where are the sensors address/data registers relative to the base address */
 #define W83781D_ADDR_REG_OFFSET 5
 #define W83781D_DATA_REG_OFFSET 6
 
@@ -192,7 +201,6 @@ superio_exit(void)
 
 #define W83627HF_REG_PWM1 0x5A
 #define W83627HF_REG_PWM2 0x5B
-#define W83627HF_REG_PWMCLK12 0x5C
 
 #define W83627THF_REG_PWM1             0x01    /* 697HF and 637HF too */
 #define W83627THF_REG_PWM2             0x03    /* 697HF and 637HF too */
@@ -277,6 +285,7 @@ static inline u8 DIV_TO_REG(long val)
    dynamically allocated, at the same time when a new client is allocated. */
 struct w83627hf_data {
        struct i2c_client client;
+       struct class_device *class_dev;
        struct semaphore lock;
        enum chips type;
 
@@ -314,9 +323,7 @@ struct w83627hf_data {
 };
 
 
-static int w83627hf_attach_adapter(struct i2c_adapter *adapter);
-static int w83627hf_detect(struct i2c_adapter *adapter, int address,
-                         int kind);
+static int w83627hf_detect(struct i2c_adapter *adapter);
 static int w83627hf_detach_client(struct i2c_client *client);
 
 static int w83627hf_read_value(struct i2c_client *client, u16 register);
@@ -328,9 +335,7 @@ static void w83627hf_init_client(struct i2c_client *client);
 static struct i2c_driver w83627hf_driver = {
        .owner          = THIS_MODULE,
        .name           = "w83627hf",
-       .id             = I2C_DRIVERID_W83627HF,
-       .flags          = I2C_DF_NOTIFY,
-       .attach_adapter = w83627hf_attach_adapter,
+       .attach_adapter = w83627hf_detect,
        .detach_client  = w83627hf_detach_client,
 };
 
@@ -959,16 +964,7 @@ device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
 } while (0)
 
 
-/* This function is called when:
-     * w83627hf_driver is inserted (when this module is loaded), for each
-       available adapter
-     * when a new adapter is inserted (and w83627hf_driver is still present) */
-static int w83627hf_attach_adapter(struct i2c_adapter *adapter)
-{
-       return i2c_detect(adapter, &addr_data, w83627hf_detect);
-}
-
-static int w83627hf_find(int sioaddr, int *address)
+static int __init w83627hf_find(int sioaddr, unsigned short *addr)
 {
        u16 val;
 
@@ -988,36 +984,29 @@ static int w83627hf_find(int sioaddr, int *address)
        superio_select(W83627HF_LD_HWM);
        val = (superio_inb(WINB_BASE_REG) << 8) |
               superio_inb(WINB_BASE_REG + 1);
-       *address = val & ~(WINB_EXTENT - 1);
-       if (*address == 0 && force_addr == 0) {
+       *addr = val & WINB_ALIGNMENT;
+       if (*addr == 0 && force_addr == 0) {
                superio_exit();
                return -ENODEV;
        }
-       if (force_addr)
-               *address = force_addr;  /* so detect will get called */
 
        superio_exit();
        return 0;
 }
 
-int w83627hf_detect(struct i2c_adapter *adapter, int address,
-                  int kind)
+static int w83627hf_detect(struct i2c_adapter *adapter)
 {
-       int val;
+       int val, kind;
        struct i2c_client *new_client;
        struct w83627hf_data *data;
        int err = 0;
        const char *client_name = "";
 
-       if (!i2c_is_isa_adapter(adapter)) {
-               err = -ENODEV;
-               goto ERROR0;
-       }
-
        if(force_addr)
-               address = force_addr & ~(WINB_EXTENT - 1);
+               address = force_addr & WINB_ALIGNMENT;
 
-       if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
+       if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
+                           w83627hf_driver.name)) {
                err = -EBUSY;
                goto ERROR0;
        }
@@ -1102,6 +1091,12 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
        data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
 
        /* Register sysfs hooks */
+       data->class_dev = hwmon_device_register(&new_client->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               goto ERROR3;
+       }
+
        device_create_file_in(new_client, 0);
        if (kind != w83697hf)
                device_create_file_in(new_client, 1);
@@ -1152,26 +1147,28 @@ int w83627hf_detect(struct i2c_adapter *adapter, int address,
 
        return 0;
 
+      ERROR3:
+       i2c_detach_client(new_client);
       ERROR2:
        kfree(data);
       ERROR1:
-       release_region(address, WINB_EXTENT);
+       release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE);
       ERROR0:
        return err;
 }
 
 static int w83627hf_detach_client(struct i2c_client *client)
 {
+       struct w83627hf_data *data = i2c_get_clientdata(client);
        int err;
 
-       if ((err = i2c_detach_client(client))) {
-               dev_err(&client->dev,
-                      "Client deregistration failed, client not detached.\n");
+       hwmon_device_unregister(data->class_dev);
+
+       if ((err = i2c_detach_client(client)))
                return err;
-       }
 
-       release_region(client->addr, WINB_EXTENT);
-       kfree(i2c_get_clientdata(client));
+       release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE);
+       kfree(data);
 
        return 0;
 }
@@ -1282,7 +1279,6 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
        return 0;
 }
 
-/* Called when we have found a new W83781D. It should set limits, etc. */
 static void w83627hf_init_client(struct i2c_client *client)
 {
        struct w83627hf_data *data = i2c_get_clientdata(client);
@@ -1290,7 +1286,15 @@ static void w83627hf_init_client(struct i2c_client *client)
        int type = data->type;
        u8 tmp;
 
-       if(init) {
+       if (reset) {
+               /* Resetting the chip has been the default for a long time,
+                  but repeatedly caused problems (fans going to full
+                  speed...) so it is now optional. It might even go away if
+                  nobody reports it as being useful, as I see very little
+                  reason why this would be needed at all. */
+               dev_info(&client->dev, "If reset=1 solved a problem you were "
+                        "having, please report!\n");
+
                /* save this register */
                i = w83627hf_read_value(client, W83781D_REG_BEEP_CONFIG);
                /* Reset all except Watchdog values and last conversion values
@@ -1327,7 +1331,7 @@ static void w83627hf_init_client(struct i2c_client *client)
                data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
        } else {
                /* Convert VID to voltage based on default VRM */
-               data->vrm = i2c_which_vrm();
+               data->vrm = vid_which_vrm();
        }
 
        tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
@@ -1368,12 +1372,6 @@ static void w83627hf_init_client(struct i2c_client *client)
                        }
                }
 
-               if (type == w83627hf) {
-                       /* enable PWM2 control (can't hurt since PWM reg
-                          should have been reset to 0xff) */
-                       w83627hf_write_value(client, W83627HF_REG_PWMCLK12,
-                                           0x19);
-               }
                /* enable comparator mode for temp2 and temp3 so
                   alarm indication will work correctly */
                i = w83627hf_read_value(client, W83781D_REG_IRQ);
@@ -1485,20 +1483,17 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
 
 static int __init sensors_w83627hf_init(void)
 {
-       int addr;
-
-       if (w83627hf_find(0x2e, &addr)
-        && w83627hf_find(0x4e, &addr)) {
+       if (w83627hf_find(0x2e, &address)
+        && w83627hf_find(0x4e, &address)) {
                return -ENODEV;
        }
-       normal_isa[0] = addr;
 
-       return i2c_add_driver(&w83627hf_driver);
+       return i2c_isa_add_driver(&w83627hf_driver);
 }
 
 static void __exit sensors_w83627hf_exit(void)
 {
-       i2c_del_driver(&w83627hf_driver);
+       i2c_isa_del_driver(&w83627hf_driver);
 }
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "