summaryrefslogtreecommitdiff
path: root/drivers/macintosh/therm_windtunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh/therm_windtunnel.c')
-rw-r--r--drivers/macintosh/therm_windtunnel.c99
1 files changed, 65 insertions, 34 deletions
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 68dcbcb4fc5b..0b2e08a1bee0 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -36,9 +36,10 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kthread.h>
+#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
-#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/sections.h>
@@ -300,9 +301,11 @@ static int control_loop(void *dummy)
/* i2c probing and setup */
/************************************************************************/
-static int
-do_attach( struct i2c_adapter *adapter )
+static void do_attach(struct i2c_adapter *adapter)
{
+ struct i2c_board_info info = { };
+ struct device_node *np;
+
/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
static const unsigned short scan_ds1775[] = {
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
@@ -313,28 +316,29 @@ do_attach( struct i2c_adapter *adapter )
I2C_CLIENT_END
};
- if( strncmp(adapter->name, "uni-n", 5) )
- return 0;
-
- if( !x.running ) {
- struct i2c_board_info info;
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE);
- i2c_new_probed_device(adapter, &info, scan_ds1775, NULL);
+ if (x.running || strncmp(adapter->name, "uni-n", 5))
+ return;
- strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE);
- i2c_new_probed_device(adapter, &info, scan_adm1030, NULL);
+ of_node_get(adapter->dev.of_node);
+ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775");
+ if (np) {
+ of_node_put(np);
+ } else {
+ strscpy(info.type, "MAC,ds1775", I2C_NAME_SIZE);
+ i2c_new_scanned_device(adapter, &info, scan_ds1775, NULL);
+ }
- if( x.thermostat && x.fan ) {
- x.running = 1;
- x.poll_task = kthread_run(control_loop, NULL, "g4fand");
- }
+ of_node_get(adapter->dev.of_node);
+ np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030");
+ if (np) {
+ of_node_put(np);
+ } else {
+ strscpy(info.type, "MAC,adm1030", I2C_NAME_SIZE);
+ i2c_new_scanned_device(adapter, &info, scan_adm1030, NULL);
}
- return 0;
}
-static int
+static void
do_remove(struct i2c_client *client)
{
if (x.running) {
@@ -348,8 +352,6 @@ do_remove(struct i2c_client *client)
x.fan = NULL;
else
printk(KERN_ERR "g4fan: bad client\n");
-
- return 0;
}
static int
@@ -404,16 +406,18 @@ out:
enum chip { ds1775, adm1030 };
static const struct i2c_device_id therm_windtunnel_id[] = {
- { "therm_ds1775", ds1775 },
- { "therm_adm1030", adm1030 },
+ { "MAC,ds1775", ds1775 },
+ { "MAC,adm1030", adm1030 },
{ }
};
MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id);
static int
-do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+do_probe(struct i2c_client *cl)
{
+ const struct i2c_device_id *id = i2c_client_get_device_id(cl);
struct i2c_adapter *adapter = cl->adapter;
+ int ret = 0;
if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA
| I2C_FUNC_SMBUS_WRITE_BYTE) )
@@ -421,18 +425,25 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
switch (id->driver_data) {
case adm1030:
- return attach_fan( cl );
+ ret = attach_fan(cl);
+ break;
case ds1775:
- return attach_thermostat(cl);
+ ret = attach_thermostat(cl);
+ break;
}
- return 0;
+
+ if (!x.running && x.thermostat && x.fan) {
+ x.running = 1;
+ x.poll_task = kthread_run(control_loop, NULL, "g4fand");
+ }
+
+ return ret;
}
static struct i2c_driver g4fan_driver = {
.driver = {
.name = "therm_windtunnel",
},
- .attach_adapter = do_attach,
.probe = do_probe,
.remove = do_remove,
.id_table = therm_windtunnel_id,
@@ -445,14 +456,34 @@ static struct i2c_driver g4fan_driver = {
static int therm_of_probe(struct platform_device *dev)
{
- return i2c_add_driver( &g4fan_driver );
+ struct i2c_adapter *adap;
+ int ret, i = 0;
+
+ adap = i2c_get_adapter(0);
+ if (!adap)
+ return -EPROBE_DEFER;
+
+ ret = i2c_add_driver(&g4fan_driver);
+ if (ret) {
+ i2c_put_adapter(adap);
+ return ret;
+ }
+
+ /* We assume Macs have consecutive I2C bus numbers starting at 0 */
+ while (adap) {
+ do_attach(adap);
+ if (x.running)
+ return 0;
+ i2c_put_adapter(adap);
+ adap = i2c_get_adapter(++i);
+ }
+
+ return -ENODEV;
}
-static int
-therm_of_remove( struct platform_device *dev )
+static void therm_of_remove(struct platform_device *dev)
{
i2c_del_driver( &g4fan_driver );
- return 0;
}
static const struct of_device_id therm_of_match[] = {{
@@ -518,7 +549,7 @@ g4fan_exit( void )
platform_driver_unregister( &therm_of_driver );
if( x.of_dev )
- of_device_unregister( x.of_dev );
+ of_platform_device_destroy(&x.of_dev->dev, NULL);
}
module_init(g4fan_init);