MAINTAINERS - Remove HP Fibre Channel HBA no longer in tree
[safe/jmp/linux-2.6] / drivers / macintosh / windfarm_lm75_sensor.c
index a0a41ad..b92b959 100644 (file)
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/i2c.h>
-#include <linux/i2c-dev.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/sections.h>
+#include <asm/pmac_low_i2c.h>
 
 #include "windfarm.h"
 
-#define VERSION "0.1"
+#define VERSION "0.2"
 
 #undef DEBUG
 
@@ -47,9 +47,9 @@ static int wf_lm75_attach(struct i2c_adapter *adapter);
 static int wf_lm75_detach(struct i2c_client *client);
 
 static struct i2c_driver wf_lm75_driver = {
-       .owner          = THIS_MODULE,
-       .name           = "wf_lm75",
-       .flags          = I2C_DF_NOTIFY,
+       .driver = {
+               .name   = "wf_lm75",
+       },
        .attach_adapter = wf_lm75_attach,
        .detach_client  = wf_lm75_detach,
 };
@@ -112,14 +112,14 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
                                             const char *loc)
 {
        struct wf_lm75_sensor *lm;
+       int rc;
 
        DBG("wf_lm75: creating  %s device at address 0x%02x\n",
            ds1775 ? "ds1775" : "lm75", addr);
 
-       lm = kmalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
+       lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
        if (lm == NULL)
                return NULL;
-       memset(lm, 0, sizeof(struct wf_lm75_sensor));
 
        /* Usual rant about sensor names not beeing very consistent in
         * the device-tree, oh well ...
@@ -127,6 +127,12 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
         */
        if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
                lm->sens.name = "hd-temp";
+       else if (!strcmp(loc, "Incoming Air Temp"))
+               lm->sens.name = "incoming-air-temp";
+       else if (!strcmp(loc, "ODD Temp"))
+               lm->sens.name = "optical-drive-temp";
+       else if (!strcmp(loc, "HD Temp"))
+               lm->sens.name = "hard-drive-temp";
        else
                goto fail;
 
@@ -138,9 +144,11 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
        lm->i2c.driver = &wf_lm75_driver;
        strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
 
-       if (i2c_attach_client(&lm->i2c)) {
-               printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
-                      ds1775 ? "ds1775" : "lm75", lm->i2c.name);
+       rc = i2c_attach_client(&lm->i2c);
+       if (rc) {
+               printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
+                      " err %d\n", ds1775 ? "ds1775" : "lm75",
+                      lm->i2c.name, rc);
                goto fail;
        }
 
@@ -157,69 +165,40 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
 
 static int wf_lm75_attach(struct i2c_adapter *adapter)
 {
-       u8 bus_id;
-       struct device_node *smu, *bus, *dev;
-
-       /* We currently only deal with LM75's hanging off the SMU
-        * i2c busses. If we extend that driver to other/older
-        * machines, we should split this function into SMU-i2c,
-        * keywest-i2c, PMU-i2c, ...
-        */
+       struct device_node *busnode, *dev;
+       struct pmac_i2c_bus *bus;
 
        DBG("wf_lm75: adapter %s detected\n", adapter->name);
 
-       if (strncmp(adapter->name, "smu-i2c-", 8) != 0)
-               return 0;
-       smu = of_find_node_by_type(NULL, "smu");
-       if (smu == NULL)
-               return 0;
-
-       /* Look for the bus in the device-tree */
-       bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16);
-
-       DBG("wf_lm75: bus ID is %x\n", bus_id);
-
-       /* Look for sensors subdir */
-       for (bus = NULL;
-            (bus = of_get_next_child(smu, bus)) != NULL;) {
-               u32 *reg;
-
-               if (strcmp(bus->name, "i2c"))
-                       continue;
-               reg = (u32 *)get_property(bus, "reg", NULL);
-               if (reg == NULL)
-                       continue;
-               if (bus_id == *reg)
-                       break;
-       }
-       of_node_put(smu);
-       if (bus == NULL) {
-               printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found"
-                      " in device-tree !\n", bus_id);
-               return 0;
-       }
+       bus = pmac_i2c_adapter_to_bus(adapter);
+       if (bus == NULL)
+               return -ENODEV;
+       busnode = pmac_i2c_get_bus_node(bus);
 
        DBG("wf_lm75: bus found, looking for device...\n");
 
        /* Now look for lm75(s) in there */
        for (dev = NULL;
-            (dev = of_get_next_child(bus, dev)) != NULL;) {
+            (dev = of_get_next_child(busnode, dev)) != NULL;) {
                const char *loc =
-                       get_property(dev, "hwsensor-location", NULL);
-               u32 *reg = (u32 *)get_property(dev, "reg", NULL);
-               DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg);
-               if (loc == NULL || reg == NULL)
+                       of_get_property(dev, "hwsensor-location", NULL);
+               u8 addr;
+
+               /* We must re-match the adapter in order to properly check
+                * the channel on multibus setups
+                */
+               if (!pmac_i2c_match_adapter(dev, adapter))
+                       continue;
+               addr = pmac_i2c_get_dev_addr(dev);
+               if (loc == NULL || addr == 0)
                        continue;
                /* real lm75 */
-               if (device_is_compatible(dev, "lm75"))
-                       wf_lm75_create(adapter, *reg, 0, loc);
+               if (of_device_is_compatible(dev, "lm75"))
+                       wf_lm75_create(adapter, addr, 0, loc);
                /* ds1775 (compatible, better resolution */
-               else if (device_is_compatible(dev, "ds1775"))
-                       wf_lm75_create(adapter, *reg, 1, loc);
+               else if (of_device_is_compatible(dev, "ds1775"))
+                       wf_lm75_create(adapter, addr, 1, loc);
        }
-
-       of_node_put(bus);
-
        return 0;
 }
 
@@ -240,12 +219,12 @@ static int wf_lm75_detach(struct i2c_client *client)
 
 static int __init wf_lm75_sensor_init(void)
 {
-       int rc;
-
-       rc = i2c_add_driver(&wf_lm75_driver);
-       if (rc < 0)
-               return rc;
-       return 0;
+       /* Don't register on old machines that use therm_pm72 for now */
+       if (machine_is_compatible("PowerMac7,2") ||
+           machine_is_compatible("PowerMac7,3") ||
+           machine_is_compatible("RackMac3,1"))
+               return -ENODEV;
+       return i2c_add_driver(&wf_lm75_driver);
 }
 
 static void __exit wf_lm75_sensor_exit(void)