diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 14:29:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 14:29:17 -0400 |
commit | 4858704da75ba84ce21e6d4b3b974e8b8594c9f2 (patch) | |
tree | 153f92e4ac0d5c90890ee1b14458ea56e22f984e /drivers/macintosh | |
parent | 86ade88e15b0852fa437e816037ecb266ae990ad (diff) | |
parent | 036533e232922ec6667817de9b037d0b1ebd062e (diff) |
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
therm_windtunnel: Convert to a new-style i2c driver
therm_adt746x: Convert to a new-style i2c driver
windfarm: Convert to new-style i2c drivers
therm_pm72: Convert to a new-style i2c driver
i2c-viapro: Add new PCI device ID for VX855
i2c/chips: Move max6875 to drivers/misc/eeprom
i2c: Do not give adapters a default parent
i2c: Do not probe for TV chips on Voodoo3 adapters
i2c: Retry automatically on arbitration loss
i2c: Remove void casts
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/therm_adt746x.c | 84 | ||||
-rw-r--r-- | drivers/macintosh/therm_pm72.c | 95 | ||||
-rw-r--r-- | drivers/macintosh/therm_windtunnel.c | 126 | ||||
-rw-r--r-- | drivers/macintosh/windfarm_lm75_sensor.c | 129 | ||||
-rw-r--r-- | drivers/macintosh/windfarm_max6690_sensor.c | 103 | ||||
-rw-r--r-- | drivers/macintosh/windfarm_smu_sat.c | 109 |
6 files changed, 346 insertions, 300 deletions
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 0ddf9044948a..fde377c60cca 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -72,7 +72,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations " | |||
72 | "(default 0)"); | 72 | "(default 0)"); |
73 | 73 | ||
74 | struct thermostat { | 74 | struct thermostat { |
75 | struct i2c_client clt; | 75 | struct i2c_client *clt; |
76 | u8 temps[3]; | 76 | u8 temps[3]; |
77 | u8 cached_temp[3]; | 77 | u8 cached_temp[3]; |
78 | u8 initial_limits[3]; | 78 | u8 initial_limits[3]; |
@@ -87,9 +87,6 @@ static struct of_device * of_dev; | |||
87 | static struct thermostat* thermostat; | 87 | static struct thermostat* thermostat; |
88 | static struct task_struct *thread_therm = NULL; | 88 | static struct task_struct *thread_therm = NULL; |
89 | 89 | ||
90 | static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | ||
91 | int busno); | ||
92 | |||
93 | static void write_both_fan_speed(struct thermostat *th, int speed); | 90 | static void write_both_fan_speed(struct thermostat *th, int speed); |
94 | static void write_fan_speed(struct thermostat *th, int speed, int fan); | 91 | static void write_fan_speed(struct thermostat *th, int speed, int fan); |
95 | 92 | ||
@@ -101,7 +98,7 @@ write_reg(struct thermostat* th, int reg, u8 data) | |||
101 | 98 | ||
102 | tmp[0] = reg; | 99 | tmp[0] = reg; |
103 | tmp[1] = data; | 100 | tmp[1] = data; |
104 | rc = i2c_master_send(&th->clt, (const char *)tmp, 2); | 101 | rc = i2c_master_send(th->clt, (const char *)tmp, 2); |
105 | if (rc < 0) | 102 | if (rc < 0) |
106 | return rc; | 103 | return rc; |
107 | if (rc != 2) | 104 | if (rc != 2) |
@@ -116,12 +113,12 @@ read_reg(struct thermostat* th, int reg) | |||
116 | int rc; | 113 | int rc; |
117 | 114 | ||
118 | reg_addr = (u8)reg; | 115 | reg_addr = (u8)reg; |
119 | rc = i2c_master_send(&th->clt, ®_addr, 1); | 116 | rc = i2c_master_send(th->clt, ®_addr, 1); |
120 | if (rc < 0) | 117 | if (rc < 0) |
121 | return rc; | 118 | return rc; |
122 | if (rc != 1) | 119 | if (rc != 1) |
123 | return -ENODEV; | 120 | return -ENODEV; |
124 | rc = i2c_master_recv(&th->clt, (char *)&data, 1); | 121 | rc = i2c_master_recv(th->clt, (char *)&data, 1); |
125 | if (rc < 0) | 122 | if (rc < 0) |
126 | return rc; | 123 | return rc; |
127 | return data; | 124 | return data; |
@@ -131,26 +128,36 @@ static int | |||
131 | attach_thermostat(struct i2c_adapter *adapter) | 128 | attach_thermostat(struct i2c_adapter *adapter) |
132 | { | 129 | { |
133 | unsigned long bus_no; | 130 | unsigned long bus_no; |
131 | struct i2c_board_info info; | ||
132 | struct i2c_client *client; | ||
134 | 133 | ||
135 | if (strncmp(adapter->name, "uni-n", 5)) | 134 | if (strncmp(adapter->name, "uni-n", 5)) |
136 | return -ENODEV; | 135 | return -ENODEV; |
137 | bus_no = simple_strtoul(adapter->name + 6, NULL, 10); | 136 | bus_no = simple_strtoul(adapter->name + 6, NULL, 10); |
138 | if (bus_no != therm_bus) | 137 | if (bus_no != therm_bus) |
139 | return -ENODEV; | 138 | return -ENODEV; |
140 | return attach_one_thermostat(adapter, therm_address, bus_no); | 139 | |
140 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
141 | strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE); | ||
142 | info.addr = therm_address; | ||
143 | client = i2c_new_device(adapter, &info); | ||
144 | if (!client) | ||
145 | return -ENODEV; | ||
146 | |||
147 | /* | ||
148 | * Let i2c-core delete that device on driver removal. | ||
149 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
150 | */ | ||
151 | list_add_tail(&client->detected, &client->driver->clients); | ||
152 | return 0; | ||
141 | } | 153 | } |
142 | 154 | ||
143 | static int | 155 | static int |
144 | detach_thermostat(struct i2c_adapter *adapter) | 156 | remove_thermostat(struct i2c_client *client) |
145 | { | 157 | { |
146 | struct thermostat* th; | 158 | struct thermostat *th = i2c_get_clientdata(client); |
147 | int i; | 159 | int i; |
148 | 160 | ||
149 | if (thermostat == NULL) | ||
150 | return 0; | ||
151 | |||
152 | th = thermostat; | ||
153 | |||
154 | if (thread_therm != NULL) { | 161 | if (thread_therm != NULL) { |
155 | kthread_stop(thread_therm); | 162 | kthread_stop(thread_therm); |
156 | } | 163 | } |
@@ -166,8 +173,6 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
166 | 173 | ||
167 | write_both_fan_speed(th, -1); | 174 | write_both_fan_speed(th, -1); |
168 | 175 | ||
169 | i2c_detach_client(&th->clt); | ||
170 | |||
171 | thermostat = NULL; | 176 | thermostat = NULL; |
172 | 177 | ||
173 | kfree(th); | 178 | kfree(th); |
@@ -175,14 +180,6 @@ detach_thermostat(struct i2c_adapter *adapter) | |||
175 | return 0; | 180 | return 0; |
176 | } | 181 | } |
177 | 182 | ||
178 | static struct i2c_driver thermostat_driver = { | ||
179 | .driver = { | ||
180 | .name = "therm_adt746x", | ||
181 | }, | ||
182 | .attach_adapter = attach_thermostat, | ||
183 | .detach_adapter = detach_thermostat, | ||
184 | }; | ||
185 | |||
186 | static int read_fan_speed(struct thermostat *th, u8 addr) | 183 | static int read_fan_speed(struct thermostat *th, u8 addr) |
187 | { | 184 | { |
188 | u8 tmp[2]; | 185 | u8 tmp[2]; |
@@ -371,8 +368,8 @@ static void set_limit(struct thermostat *th, int i) | |||
371 | th->limits[i] = default_limits_local[i] + limit_adjust; | 368 | th->limits[i] = default_limits_local[i] + limit_adjust; |
372 | } | 369 | } |
373 | 370 | ||
374 | static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | 371 | static int probe_thermostat(struct i2c_client *client, |
375 | int busno) | 372 | const struct i2c_device_id *id) |
376 | { | 373 | { |
377 | struct thermostat* th; | 374 | struct thermostat* th; |
378 | int rc; | 375 | int rc; |
@@ -385,16 +382,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
385 | if (!th) | 382 | if (!th) |
386 | return -ENOMEM; | 383 | return -ENOMEM; |
387 | 384 | ||
388 | th->clt.addr = addr; | 385 | i2c_set_clientdata(client, th); |
389 | th->clt.adapter = adapter; | 386 | th->clt = client; |
390 | th->clt.driver = &thermostat_driver; | ||
391 | strcpy(th->clt.name, "thermostat"); | ||
392 | 387 | ||
393 | rc = read_reg(th, 0); | 388 | rc = read_reg(th, 0); |
394 | if (rc < 0) { | 389 | if (rc < 0) { |
395 | printk(KERN_ERR "adt746x: Thermostat failed to read config " | 390 | dev_err(&client->dev, "Thermostat failed to read config!\n"); |
396 | "from bus %d !\n", | ||
397 | busno); | ||
398 | kfree(th); | 391 | kfree(th); |
399 | return -ENODEV; | 392 | return -ENODEV; |
400 | } | 393 | } |
@@ -423,14 +416,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
423 | 416 | ||
424 | thermostat = th; | 417 | thermostat = th; |
425 | 418 | ||
426 | if (i2c_attach_client(&th->clt)) { | ||
427 | printk(KERN_INFO "adt746x: Thermostat failed to attach " | ||
428 | "client !\n"); | ||
429 | thermostat = NULL; | ||
430 | kfree(th); | ||
431 | return -ENODEV; | ||
432 | } | ||
433 | |||
434 | /* be sure to really write fan speed the first time */ | 419 | /* be sure to really write fan speed the first time */ |
435 | th->last_speed[0] = -2; | 420 | th->last_speed[0] = -2; |
436 | th->last_speed[1] = -2; | 421 | th->last_speed[1] = -2; |
@@ -456,6 +441,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, | |||
456 | return 0; | 441 | return 0; |
457 | } | 442 | } |
458 | 443 | ||
444 | static const struct i2c_device_id therm_adt746x_id[] = { | ||
445 | { "therm_adt746x", 0 }, | ||
446 | { } | ||
447 | }; | ||
448 | |||
449 | static struct i2c_driver thermostat_driver = { | ||
450 | .driver = { | ||
451 | .name = "therm_adt746x", | ||
452 | }, | ||
453 | .attach_adapter = attach_thermostat, | ||
454 | .probe = probe_thermostat, | ||
455 | .remove = remove_thermostat, | ||
456 | .id_table = therm_adt746x_id, | ||
457 | }; | ||
458 | |||
459 | /* | 459 | /* |
460 | * Now, unfortunately, sysfs doesn't give us a nice void * we could | 460 | * Now, unfortunately, sysfs doesn't give us a nice void * we could |
461 | * pass around to the attribute functions, so we don't really have | 461 | * pass around to the attribute functions, so we don't really have |
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 817607e2af6a..a028598af2d3 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -287,22 +287,6 @@ struct fcu_fan_table fcu_fans[] = { | |||
287 | }; | 287 | }; |
288 | 288 | ||
289 | /* | 289 | /* |
290 | * i2c_driver structure to attach to the host i2c controller | ||
291 | */ | ||
292 | |||
293 | static int therm_pm72_attach(struct i2c_adapter *adapter); | ||
294 | static int therm_pm72_detach(struct i2c_adapter *adapter); | ||
295 | |||
296 | static struct i2c_driver therm_pm72_driver = | ||
297 | { | ||
298 | .driver = { | ||
299 | .name = "therm_pm72", | ||
300 | }, | ||
301 | .attach_adapter = therm_pm72_attach, | ||
302 | .detach_adapter = therm_pm72_detach, | ||
303 | }; | ||
304 | |||
305 | /* | ||
306 | * Utility function to create an i2c_client structure and | 290 | * Utility function to create an i2c_client structure and |
307 | * attach it to one of u3 adapters | 291 | * attach it to one of u3 adapters |
308 | */ | 292 | */ |
@@ -310,6 +294,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) | |||
310 | { | 294 | { |
311 | struct i2c_client *clt; | 295 | struct i2c_client *clt; |
312 | struct i2c_adapter *adap; | 296 | struct i2c_adapter *adap; |
297 | struct i2c_board_info info; | ||
313 | 298 | ||
314 | if (id & 0x200) | 299 | if (id & 0x200) |
315 | adap = k2; | 300 | adap = k2; |
@@ -320,31 +305,21 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) | |||
320 | if (adap == NULL) | 305 | if (adap == NULL) |
321 | return NULL; | 306 | return NULL; |
322 | 307 | ||
323 | clt = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 308 | memset(&info, 0, sizeof(struct i2c_board_info)); |
324 | if (clt == NULL) | 309 | info.addr = (id >> 1) & 0x7f; |
325 | return NULL; | 310 | strlcpy(info.type, "therm_pm72", I2C_NAME_SIZE); |
326 | 311 | clt = i2c_new_device(adap, &info); | |
327 | clt->addr = (id >> 1) & 0x7f; | 312 | if (!clt) { |
328 | clt->adapter = adap; | ||
329 | clt->driver = &therm_pm72_driver; | ||
330 | strncpy(clt->name, name, I2C_NAME_SIZE-1); | ||
331 | |||
332 | if (i2c_attach_client(clt)) { | ||
333 | printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id); | 313 | printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id); |
334 | kfree(clt); | ||
335 | return NULL; | 314 | return NULL; |
336 | } | 315 | } |
337 | return clt; | ||
338 | } | ||
339 | 316 | ||
340 | /* | 317 | /* |
341 | * Utility function to get rid of the i2c_client structure | 318 | * Let i2c-core delete that device on driver removal. |
342 | * (will also detach from the adapter hopepfully) | 319 | * This is safe because i2c-core holds the core_lock mutex for us. |
343 | */ | 320 | */ |
344 | static void detach_i2c_chip(struct i2c_client *clt) | 321 | list_add_tail(&clt->detected, &clt->driver->clients); |
345 | { | 322 | return clt; |
346 | i2c_detach_client(clt); | ||
347 | kfree(clt); | ||
348 | } | 323 | } |
349 | 324 | ||
350 | /* | 325 | /* |
@@ -1203,8 +1178,6 @@ static int init_cpu_state(struct cpu_pid_state *state, int index) | |||
1203 | 1178 | ||
1204 | return 0; | 1179 | return 0; |
1205 | fail: | 1180 | fail: |
1206 | if (state->monitor) | ||
1207 | detach_i2c_chip(state->monitor); | ||
1208 | state->monitor = NULL; | 1181 | state->monitor = NULL; |
1209 | 1182 | ||
1210 | return -ENODEV; | 1183 | return -ENODEV; |
@@ -1232,7 +1205,6 @@ static void dispose_cpu_state(struct cpu_pid_state *state) | |||
1232 | device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); | 1205 | device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); |
1233 | } | 1206 | } |
1234 | 1207 | ||
1235 | detach_i2c_chip(state->monitor); | ||
1236 | state->monitor = NULL; | 1208 | state->monitor = NULL; |
1237 | } | 1209 | } |
1238 | 1210 | ||
@@ -1407,7 +1379,6 @@ static void dispose_backside_state(struct backside_pid_state *state) | |||
1407 | device_remove_file(&of_dev->dev, &dev_attr_backside_temperature); | 1379 | device_remove_file(&of_dev->dev, &dev_attr_backside_temperature); |
1408 | device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm); | 1380 | device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm); |
1409 | 1381 | ||
1410 | detach_i2c_chip(state->monitor); | ||
1411 | state->monitor = NULL; | 1382 | state->monitor = NULL; |
1412 | } | 1383 | } |
1413 | 1384 | ||
@@ -1532,7 +1503,6 @@ static void dispose_drives_state(struct drives_pid_state *state) | |||
1532 | device_remove_file(&of_dev->dev, &dev_attr_drives_temperature); | 1503 | device_remove_file(&of_dev->dev, &dev_attr_drives_temperature); |
1533 | device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm); | 1504 | device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm); |
1534 | 1505 | ||
1535 | detach_i2c_chip(state->monitor); | ||
1536 | state->monitor = NULL; | 1506 | state->monitor = NULL; |
1537 | } | 1507 | } |
1538 | 1508 | ||
@@ -1654,7 +1624,6 @@ static void dispose_dimms_state(struct dimm_pid_state *state) | |||
1654 | 1624 | ||
1655 | device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature); | 1625 | device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature); |
1656 | 1626 | ||
1657 | detach_i2c_chip(state->monitor); | ||
1658 | state->monitor = NULL; | 1627 | state->monitor = NULL; |
1659 | } | 1628 | } |
1660 | 1629 | ||
@@ -1779,7 +1748,6 @@ static void dispose_slots_state(struct slots_pid_state *state) | |||
1779 | device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); | 1748 | device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); |
1780 | device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); | 1749 | device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); |
1781 | 1750 | ||
1782 | detach_i2c_chip(state->monitor); | ||
1783 | state->monitor = NULL; | 1751 | state->monitor = NULL; |
1784 | } | 1752 | } |
1785 | 1753 | ||
@@ -2008,8 +1976,6 @@ static int attach_fcu(void) | |||
2008 | */ | 1976 | */ |
2009 | static void detach_fcu(void) | 1977 | static void detach_fcu(void) |
2010 | { | 1978 | { |
2011 | if (fcu) | ||
2012 | detach_i2c_chip(fcu); | ||
2013 | fcu = NULL; | 1979 | fcu = NULL; |
2014 | } | 1980 | } |
2015 | 1981 | ||
@@ -2060,12 +2026,21 @@ static int therm_pm72_attach(struct i2c_adapter *adapter) | |||
2060 | return 0; | 2026 | return 0; |
2061 | } | 2027 | } |
2062 | 2028 | ||
2029 | static int therm_pm72_probe(struct i2c_client *client, | ||
2030 | const struct i2c_device_id *id) | ||
2031 | { | ||
2032 | /* Always succeed, the real work was done in therm_pm72_attach() */ | ||
2033 | return 0; | ||
2034 | } | ||
2035 | |||
2063 | /* | 2036 | /* |
2064 | * Called on every adapter when the driver or the i2c controller | 2037 | * Called when any of the devices which participates into thermal management |
2065 | * is going away. | 2038 | * is going away. |
2066 | */ | 2039 | */ |
2067 | static int therm_pm72_detach(struct i2c_adapter *adapter) | 2040 | static int therm_pm72_remove(struct i2c_client *client) |
2068 | { | 2041 | { |
2042 | struct i2c_adapter *adapter = client->adapter; | ||
2043 | |||
2069 | mutex_lock(&driver_lock); | 2044 | mutex_lock(&driver_lock); |
2070 | 2045 | ||
2071 | if (state != state_detached) | 2046 | if (state != state_detached) |
@@ -2096,6 +2071,30 @@ static int therm_pm72_detach(struct i2c_adapter *adapter) | |||
2096 | return 0; | 2071 | return 0; |
2097 | } | 2072 | } |
2098 | 2073 | ||
2074 | /* | ||
2075 | * i2c_driver structure to attach to the host i2c controller | ||
2076 | */ | ||
2077 | |||
2078 | static const struct i2c_device_id therm_pm72_id[] = { | ||
2079 | /* | ||
2080 | * Fake device name, thermal management is done by several | ||
2081 | * chips but we don't need to differentiate between them at | ||
2082 | * this point. | ||
2083 | */ | ||
2084 | { "therm_pm72", 0 }, | ||
2085 | { } | ||
2086 | }; | ||
2087 | |||
2088 | static struct i2c_driver therm_pm72_driver = { | ||
2089 | .driver = { | ||
2090 | .name = "therm_pm72", | ||
2091 | }, | ||
2092 | .attach_adapter = therm_pm72_attach, | ||
2093 | .probe = therm_pm72_probe, | ||
2094 | .remove = therm_pm72_remove, | ||
2095 | .id_table = therm_pm72_id, | ||
2096 | }; | ||
2097 | |||
2099 | static int fan_check_loc_match(const char *loc, int fan) | 2098 | static int fan_check_loc_match(const char *loc, int fan) |
2100 | { | 2099 | { |
2101 | char tmp[64]; | 2100 | char tmp[64]; |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 3da0a02efd76..40023313a760 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -48,16 +48,6 @@ | |||
48 | 48 | ||
49 | #define LOG_TEMP 0 /* continously log temperature */ | 49 | #define LOG_TEMP 0 /* continously log temperature */ |
50 | 50 | ||
51 | static int do_probe( struct i2c_adapter *adapter, int addr, int kind); | ||
52 | |||
53 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ | ||
54 | static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, | ||
55 | 0x4c, 0x4d, 0x4e, 0x4f, | ||
56 | 0x2c, 0x2d, 0x2e, 0x2f, | ||
57 | I2C_CLIENT_END }; | ||
58 | |||
59 | I2C_CLIENT_INSMOD; | ||
60 | |||
61 | static struct { | 51 | static struct { |
62 | volatile int running; | 52 | volatile int running; |
63 | struct task_struct *poll_task; | 53 | struct task_struct *poll_task; |
@@ -315,53 +305,54 @@ static int control_loop(void *dummy) | |||
315 | static int | 305 | static int |
316 | do_attach( struct i2c_adapter *adapter ) | 306 | do_attach( struct i2c_adapter *adapter ) |
317 | { | 307 | { |
318 | int ret = 0; | 308 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ |
309 | static const unsigned short scan_ds1775[] = { | ||
310 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, | ||
311 | I2C_CLIENT_END | ||
312 | }; | ||
313 | static const unsigned short scan_adm1030[] = { | ||
314 | 0x2c, 0x2d, 0x2e, 0x2f, | ||
315 | I2C_CLIENT_END | ||
316 | }; | ||
319 | 317 | ||
320 | if( strncmp(adapter->name, "uni-n", 5) ) | 318 | if( strncmp(adapter->name, "uni-n", 5) ) |
321 | return 0; | 319 | return 0; |
322 | 320 | ||
323 | if( !x.running ) { | 321 | if( !x.running ) { |
324 | ret = i2c_probe( adapter, &addr_data, &do_probe ); | 322 | struct i2c_board_info info; |
323 | |||
324 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
325 | strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); | ||
326 | i2c_new_probed_device(adapter, &info, scan_ds1775); | ||
327 | |||
328 | strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); | ||
329 | i2c_new_probed_device(adapter, &info, scan_adm1030); | ||
330 | |||
325 | if( x.thermostat && x.fan ) { | 331 | if( x.thermostat && x.fan ) { |
326 | x.running = 1; | 332 | x.running = 1; |
327 | x.poll_task = kthread_run(control_loop, NULL, "g4fand"); | 333 | x.poll_task = kthread_run(control_loop, NULL, "g4fand"); |
328 | } | 334 | } |
329 | } | 335 | } |
330 | return ret; | 336 | return 0; |
331 | } | 337 | } |
332 | 338 | ||
333 | static int | 339 | static int |
334 | do_detach( struct i2c_client *client ) | 340 | do_remove(struct i2c_client *client) |
335 | { | 341 | { |
336 | int err; | 342 | if (x.running) { |
337 | 343 | x.running = 0; | |
338 | if( (err=i2c_detach_client(client)) ) | 344 | kthread_stop(x.poll_task); |
339 | printk(KERN_ERR "failed to detach thermostat client\n"); | 345 | x.poll_task = NULL; |
340 | else { | ||
341 | if( x.running ) { | ||
342 | x.running = 0; | ||
343 | kthread_stop(x.poll_task); | ||
344 | x.poll_task = NULL; | ||
345 | } | ||
346 | if( client == x.thermostat ) | ||
347 | x.thermostat = NULL; | ||
348 | else if( client == x.fan ) | ||
349 | x.fan = NULL; | ||
350 | else { | ||
351 | printk(KERN_ERR "g4fan: bad client\n"); | ||
352 | } | ||
353 | kfree( client ); | ||
354 | } | 346 | } |
355 | return err; | 347 | if (client == x.thermostat) |
356 | } | 348 | x.thermostat = NULL; |
349 | else if (client == x.fan) | ||
350 | x.fan = NULL; | ||
351 | else | ||
352 | printk(KERN_ERR "g4fan: bad client\n"); | ||
357 | 353 | ||
358 | static struct i2c_driver g4fan_driver = { | 354 | return 0; |
359 | .driver = { | 355 | } |
360 | .name = "therm_windtunnel", | ||
361 | }, | ||
362 | .attach_adapter = do_attach, | ||
363 | .detach_client = do_detach, | ||
364 | }; | ||
365 | 356 | ||
366 | static int | 357 | static int |
367 | attach_fan( struct i2c_client *cl ) | 358 | attach_fan( struct i2c_client *cl ) |
@@ -374,13 +365,8 @@ attach_fan( struct i2c_client *cl ) | |||
374 | goto out; | 365 | goto out; |
375 | printk("ADM1030 fan controller [@%02x]\n", cl->addr ); | 366 | printk("ADM1030 fan controller [@%02x]\n", cl->addr ); |
376 | 367 | ||
377 | strlcpy( cl->name, "ADM1030 fan controller", sizeof(cl->name) ); | 368 | x.fan = cl; |
378 | |||
379 | if( !i2c_attach_client(cl) ) | ||
380 | x.fan = cl; | ||
381 | out: | 369 | out: |
382 | if( cl != x.fan ) | ||
383 | kfree( cl ); | ||
384 | return 0; | 370 | return 0; |
385 | } | 371 | } |
386 | 372 | ||
@@ -412,39 +398,47 @@ attach_thermostat( struct i2c_client *cl ) | |||
412 | x.temp = temp; | 398 | x.temp = temp; |
413 | x.overheat_temp = os_temp; | 399 | x.overheat_temp = os_temp; |
414 | x.overheat_hyst = hyst_temp; | 400 | x.overheat_hyst = hyst_temp; |
415 | 401 | x.thermostat = cl; | |
416 | strlcpy( cl->name, "DS1775 thermostat", sizeof(cl->name) ); | ||
417 | |||
418 | if( !i2c_attach_client(cl) ) | ||
419 | x.thermostat = cl; | ||
420 | out: | 402 | out: |
421 | if( cl != x.thermostat ) | ||
422 | kfree( cl ); | ||
423 | return 0; | 403 | return 0; |
424 | } | 404 | } |
425 | 405 | ||
406 | enum chip { ds1775, adm1030 }; | ||
407 | |||
408 | static const struct i2c_device_id therm_windtunnel_id[] = { | ||
409 | { "therm_ds1775", ds1775 }, | ||
410 | { "therm_adm1030", adm1030 }, | ||
411 | { } | ||
412 | }; | ||
413 | |||
426 | static int | 414 | static int |
427 | do_probe( struct i2c_adapter *adapter, int addr, int kind ) | 415 | do_probe(struct i2c_client *cl, const struct i2c_device_id *id) |
428 | { | 416 | { |
429 | struct i2c_client *cl; | 417 | struct i2c_adapter *adapter = cl->adapter; |
430 | 418 | ||
431 | if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA | 419 | if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA |
432 | | I2C_FUNC_SMBUS_WRITE_BYTE) ) | 420 | | I2C_FUNC_SMBUS_WRITE_BYTE) ) |
433 | return 0; | 421 | return 0; |
434 | 422 | ||
435 | if( !(cl=kzalloc(sizeof(*cl), GFP_KERNEL)) ) | 423 | switch (id->driver_data) { |
436 | return -ENOMEM; | 424 | case adm1030: |
437 | |||
438 | cl->addr = addr; | ||
439 | cl->adapter = adapter; | ||
440 | cl->driver = &g4fan_driver; | ||
441 | cl->flags = 0; | ||
442 | |||
443 | if( addr < 0x48 ) | ||
444 | return attach_fan( cl ); | 425 | return attach_fan( cl ); |
445 | return attach_thermostat( cl ); | 426 | case ds1775: |
427 | return attach_thermostat(cl); | ||
428 | } | ||
429 | return 0; | ||
446 | } | 430 | } |
447 | 431 | ||
432 | static struct i2c_driver g4fan_driver = { | ||
433 | .driver = { | ||
434 | .name = "therm_windtunnel", | ||
435 | }, | ||
436 | .attach_adapter = do_attach, | ||
437 | .probe = do_probe, | ||
438 | .remove = do_remove, | ||
439 | .id_table = therm_windtunnel_id, | ||
440 | }; | ||
441 | |||
448 | 442 | ||
449 | /************************************************************************/ | 443 | /************************************************************************/ |
450 | /* initialization / cleanup */ | 444 | /* initialization / cleanup */ |
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index b92b959fe16e..529886c7a826 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c | |||
@@ -37,34 +37,22 @@ | |||
37 | struct wf_lm75_sensor { | 37 | struct wf_lm75_sensor { |
38 | int ds1775 : 1; | 38 | int ds1775 : 1; |
39 | int inited : 1; | 39 | int inited : 1; |
40 | struct i2c_client i2c; | 40 | struct i2c_client *i2c; |
41 | struct wf_sensor sens; | 41 | struct wf_sensor sens; |
42 | }; | 42 | }; |
43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) | 43 | #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) |
44 | #define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c) | ||
45 | |||
46 | static int wf_lm75_attach(struct i2c_adapter *adapter); | ||
47 | static int wf_lm75_detach(struct i2c_client *client); | ||
48 | |||
49 | static struct i2c_driver wf_lm75_driver = { | ||
50 | .driver = { | ||
51 | .name = "wf_lm75", | ||
52 | }, | ||
53 | .attach_adapter = wf_lm75_attach, | ||
54 | .detach_client = wf_lm75_detach, | ||
55 | }; | ||
56 | 44 | ||
57 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | 45 | static int wf_lm75_get(struct wf_sensor *sr, s32 *value) |
58 | { | 46 | { |
59 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 47 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
60 | s32 data; | 48 | s32 data; |
61 | 49 | ||
62 | if (lm->i2c.adapter == NULL) | 50 | if (lm->i2c == NULL) |
63 | return -ENODEV; | 51 | return -ENODEV; |
64 | 52 | ||
65 | /* Init chip if necessary */ | 53 | /* Init chip if necessary */ |
66 | if (!lm->inited) { | 54 | if (!lm->inited) { |
67 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1); | 55 | u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1); |
68 | 56 | ||
69 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", | 57 | DBG("wf_lm75: Initializing %s, cfg was: %02x\n", |
70 | sr->name, cfg); | 58 | sr->name, cfg); |
@@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | |||
73 | * the firmware for now | 61 | * the firmware for now |
74 | */ | 62 | */ |
75 | cfg_new = cfg & ~0x01; | 63 | cfg_new = cfg & ~0x01; |
76 | i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new); | 64 | i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new); |
77 | lm->inited = 1; | 65 | lm->inited = 1; |
78 | 66 | ||
79 | /* If we just powered it up, let's wait 200 ms */ | 67 | /* If we just powered it up, let's wait 200 ms */ |
@@ -81,7 +69,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) | |||
81 | } | 69 | } |
82 | 70 | ||
83 | /* Read temperature register */ | 71 | /* Read temperature register */ |
84 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0)); | 72 | data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0)); |
85 | data <<= 8; | 73 | data <<= 8; |
86 | *value = data; | 74 | *value = data; |
87 | 75 | ||
@@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr) | |||
92 | { | 80 | { |
93 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); | 81 | struct wf_lm75_sensor *lm = wf_to_lm75(sr); |
94 | 82 | ||
95 | /* check if client is registered and detach from i2c */ | ||
96 | if (lm->i2c.adapter) { | ||
97 | i2c_detach_client(&lm->i2c); | ||
98 | lm->i2c.adapter = NULL; | ||
99 | } | ||
100 | |||
101 | kfree(lm); | 83 | kfree(lm); |
102 | } | 84 | } |
103 | 85 | ||
@@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = { | |||
107 | .owner = THIS_MODULE, | 89 | .owner = THIS_MODULE, |
108 | }; | 90 | }; |
109 | 91 | ||
110 | static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, | 92 | static int wf_lm75_probe(struct i2c_client *client, |
111 | u8 addr, int ds1775, | 93 | const struct i2c_device_id *id) |
112 | const char *loc) | ||
113 | { | 94 | { |
114 | struct wf_lm75_sensor *lm; | 95 | struct wf_lm75_sensor *lm; |
115 | int rc; | 96 | int rc; |
116 | 97 | ||
117 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | ||
118 | ds1775 ? "ds1775" : "lm75", addr); | ||
119 | |||
120 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); | 98 | lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); |
121 | if (lm == NULL) | 99 | if (lm == NULL) |
122 | return NULL; | 100 | return -ENODEV; |
101 | |||
102 | lm->inited = 0; | ||
103 | lm->ds1775 = id->driver_data; | ||
104 | lm->i2c = client; | ||
105 | lm->sens.name = client->dev.platform_data; | ||
106 | lm->sens.ops = &wf_lm75_ops; | ||
107 | i2c_set_clientdata(client, lm); | ||
108 | |||
109 | rc = wf_register_sensor(&lm->sens); | ||
110 | if (rc) { | ||
111 | i2c_set_clientdata(client, NULL); | ||
112 | kfree(lm); | ||
113 | } | ||
114 | |||
115 | return rc; | ||
116 | } | ||
117 | |||
118 | static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, | ||
119 | u8 addr, int ds1775, | ||
120 | const char *loc) | ||
121 | { | ||
122 | struct i2c_board_info info; | ||
123 | struct i2c_client *client; | ||
124 | char *name; | ||
125 | |||
126 | DBG("wf_lm75: creating %s device at address 0x%02x\n", | ||
127 | ds1775 ? "ds1775" : "lm75", addr); | ||
123 | 128 | ||
124 | /* Usual rant about sensor names not beeing very consistent in | 129 | /* Usual rant about sensor names not beeing very consistent in |
125 | * the device-tree, oh well ... | 130 | * the device-tree, oh well ... |
126 | * Add more entries below as you deal with more setups | 131 | * Add more entries below as you deal with more setups |
127 | */ | 132 | */ |
128 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) | 133 | if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) |
129 | lm->sens.name = "hd-temp"; | 134 | name = "hd-temp"; |
130 | else if (!strcmp(loc, "Incoming Air Temp")) | 135 | else if (!strcmp(loc, "Incoming Air Temp")) |
131 | lm->sens.name = "incoming-air-temp"; | 136 | name = "incoming-air-temp"; |
132 | else if (!strcmp(loc, "ODD Temp")) | 137 | else if (!strcmp(loc, "ODD Temp")) |
133 | lm->sens.name = "optical-drive-temp"; | 138 | name = "optical-drive-temp"; |
134 | else if (!strcmp(loc, "HD Temp")) | 139 | else if (!strcmp(loc, "HD Temp")) |
135 | lm->sens.name = "hard-drive-temp"; | 140 | name = "hard-drive-temp"; |
136 | else | 141 | else |
137 | goto fail; | 142 | goto fail; |
138 | 143 | ||
139 | lm->inited = 0; | 144 | memset(&info, 0, sizeof(struct i2c_board_info)); |
140 | lm->sens.ops = &wf_lm75_ops; | 145 | info.addr = (addr >> 1) & 0x7f; |
141 | lm->ds1775 = ds1775; | 146 | info.platform_data = name; |
142 | lm->i2c.addr = (addr >> 1) & 0x7f; | 147 | strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE); |
143 | lm->i2c.adapter = adapter; | ||
144 | lm->i2c.driver = &wf_lm75_driver; | ||
145 | strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1); | ||
146 | |||
147 | rc = i2c_attach_client(&lm->i2c); | ||
148 | if (rc) { | ||
149 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c," | ||
150 | " err %d\n", ds1775 ? "ds1775" : "lm75", | ||
151 | lm->i2c.name, rc); | ||
152 | goto fail; | ||
153 | } | ||
154 | 148 | ||
155 | if (wf_register_sensor(&lm->sens)) { | 149 | client = i2c_new_device(adapter, &info); |
156 | i2c_detach_client(&lm->i2c); | 150 | if (client == NULL) { |
151 | printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n", | ||
152 | ds1775 ? "ds1775" : "lm75", name); | ||
157 | goto fail; | 153 | goto fail; |
158 | } | 154 | } |
159 | 155 | ||
160 | return lm; | 156 | /* |
157 | * Let i2c-core delete that device on driver removal. | ||
158 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
159 | */ | ||
160 | list_add_tail(&client->detected, &client->driver->clients); | ||
161 | return client; | ||
161 | fail: | 162 | fail: |
162 | kfree(lm); | ||
163 | return NULL; | 163 | return NULL; |
164 | } | 164 | } |
165 | 165 | ||
@@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | static int wf_lm75_detach(struct i2c_client *client) | 205 | static int wf_lm75_remove(struct i2c_client *client) |
206 | { | 206 | { |
207 | struct wf_lm75_sensor *lm = i2c_to_lm75(client); | 207 | struct wf_lm75_sensor *lm = i2c_get_clientdata(client); |
208 | 208 | ||
209 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); | 209 | DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); |
210 | 210 | ||
211 | /* Mark client detached */ | 211 | /* Mark client detached */ |
212 | lm->i2c.adapter = NULL; | 212 | lm->i2c = NULL; |
213 | 213 | ||
214 | /* release sensor */ | 214 | /* release sensor */ |
215 | wf_unregister_sensor(&lm->sens); | 215 | wf_unregister_sensor(&lm->sens); |
216 | 216 | ||
217 | i2c_set_clientdata(client, NULL); | ||
217 | return 0; | 218 | return 0; |
218 | } | 219 | } |
219 | 220 | ||
221 | static const struct i2c_device_id wf_lm75_id[] = { | ||
222 | { "wf_lm75", 0 }, | ||
223 | { "wf_ds1775", 1 }, | ||
224 | { } | ||
225 | }; | ||
226 | |||
227 | static struct i2c_driver wf_lm75_driver = { | ||
228 | .driver = { | ||
229 | .name = "wf_lm75", | ||
230 | }, | ||
231 | .attach_adapter = wf_lm75_attach, | ||
232 | .probe = wf_lm75_probe, | ||
233 | .remove = wf_lm75_remove, | ||
234 | .id_table = wf_lm75_id, | ||
235 | }; | ||
236 | |||
220 | static int __init wf_lm75_sensor_init(void) | 237 | static int __init wf_lm75_sensor_init(void) |
221 | { | 238 | { |
222 | /* Don't register on old machines that use therm_pm72 for now */ | 239 | /* Don't register on old machines that use therm_pm72 for now */ |
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index e207a90d6b27..e2a55ecda2b2 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c | |||
@@ -26,34 +26,22 @@ | |||
26 | #define MAX6690_EXTERNAL_TEMP 1 | 26 | #define MAX6690_EXTERNAL_TEMP 1 |
27 | 27 | ||
28 | struct wf_6690_sensor { | 28 | struct wf_6690_sensor { |
29 | struct i2c_client i2c; | 29 | struct i2c_client *i2c; |
30 | struct wf_sensor sens; | 30 | struct wf_sensor sens; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) | 33 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) |
34 | #define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) | ||
35 | |||
36 | static int wf_max6690_attach(struct i2c_adapter *adapter); | ||
37 | static int wf_max6690_detach(struct i2c_client *client); | ||
38 | |||
39 | static struct i2c_driver wf_max6690_driver = { | ||
40 | .driver = { | ||
41 | .name = "wf_max6690", | ||
42 | }, | ||
43 | .attach_adapter = wf_max6690_attach, | ||
44 | .detach_client = wf_max6690_detach, | ||
45 | }; | ||
46 | 34 | ||
47 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) | 35 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) |
48 | { | 36 | { |
49 | struct wf_6690_sensor *max = wf_to_6690(sr); | 37 | struct wf_6690_sensor *max = wf_to_6690(sr); |
50 | s32 data; | 38 | s32 data; |
51 | 39 | ||
52 | if (max->i2c.adapter == NULL) | 40 | if (max->i2c == NULL) |
53 | return -ENODEV; | 41 | return -ENODEV; |
54 | 42 | ||
55 | /* chip gets initialized by firmware */ | 43 | /* chip gets initialized by firmware */ |
56 | data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); | 44 | data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP); |
57 | if (data < 0) | 45 | if (data < 0) |
58 | return data; | 46 | return data; |
59 | *value = data << 16; | 47 | *value = data << 16; |
@@ -64,10 +52,6 @@ static void wf_max6690_release(struct wf_sensor *sr) | |||
64 | { | 52 | { |
65 | struct wf_6690_sensor *max = wf_to_6690(sr); | 53 | struct wf_6690_sensor *max = wf_to_6690(sr); |
66 | 54 | ||
67 | if (max->i2c.adapter) { | ||
68 | i2c_detach_client(&max->i2c); | ||
69 | max->i2c.adapter = NULL; | ||
70 | } | ||
71 | kfree(max); | 55 | kfree(max); |
72 | } | 56 | } |
73 | 57 | ||
@@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = { | |||
77 | .owner = THIS_MODULE, | 61 | .owner = THIS_MODULE, |
78 | }; | 62 | }; |
79 | 63 | ||
80 | static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr, | 64 | static int wf_max6690_probe(struct i2c_client *client, |
81 | const char *loc) | 65 | const struct i2c_device_id *id) |
82 | { | 66 | { |
83 | struct wf_6690_sensor *max; | 67 | struct wf_6690_sensor *max; |
84 | char *name; | 68 | int rc; |
85 | 69 | ||
86 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); | 70 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); |
87 | if (max == NULL) { | 71 | if (max == NULL) { |
88 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " | 72 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: " |
89 | "no memory\n", loc); | 73 | "no memory\n"); |
90 | return; | 74 | return -ENOMEM; |
75 | } | ||
76 | |||
77 | max->i2c = client; | ||
78 | max->sens.name = client->dev.platform_data; | ||
79 | max->sens.ops = &wf_max6690_ops; | ||
80 | i2c_set_clientdata(client, max); | ||
81 | |||
82 | rc = wf_register_sensor(&max->sens); | ||
83 | if (rc) { | ||
84 | i2c_set_clientdata(client, NULL); | ||
85 | kfree(max); | ||
91 | } | 86 | } |
92 | 87 | ||
88 | return rc; | ||
89 | } | ||
90 | |||
91 | static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, | ||
92 | u8 addr, const char *loc) | ||
93 | { | ||
94 | struct i2c_board_info info; | ||
95 | struct i2c_client *client; | ||
96 | char *name; | ||
97 | |||
93 | if (!strcmp(loc, "BACKSIDE")) | 98 | if (!strcmp(loc, "BACKSIDE")) |
94 | name = "backside-temp"; | 99 | name = "backside-temp"; |
95 | else if (!strcmp(loc, "NB Ambient")) | 100 | else if (!strcmp(loc, "NB Ambient")) |
@@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr, | |||
99 | else | 104 | else |
100 | goto fail; | 105 | goto fail; |
101 | 106 | ||
102 | max->sens.ops = &wf_max6690_ops; | 107 | memset(&info, 0, sizeof(struct i2c_board_info)); |
103 | max->sens.name = name; | 108 | info.addr = addr >> 1; |
104 | max->i2c.addr = addr >> 1; | 109 | info.platform_data = name; |
105 | max->i2c.adapter = adapter; | 110 | strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE); |
106 | max->i2c.driver = &wf_max6690_driver; | ||
107 | strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); | ||
108 | 111 | ||
109 | if (i2c_attach_client(&max->i2c)) { | 112 | client = i2c_new_device(adapter, &info); |
113 | if (client == NULL) { | ||
110 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); | 114 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); |
111 | goto fail; | 115 | goto fail; |
112 | } | 116 | } |
113 | 117 | ||
114 | if (wf_register_sensor(&max->sens)) { | 118 | /* |
115 | i2c_detach_client(&max->i2c); | 119 | * Let i2c-core delete that device on driver removal. |
116 | goto fail; | 120 | * This is safe because i2c-core holds the core_lock mutex for us. |
117 | } | 121 | */ |
118 | 122 | list_add_tail(&client->detected, &client->driver->clients); | |
119 | return; | 123 | return client; |
120 | 124 | ||
121 | fail: | 125 | fail: |
122 | kfree(max); | 126 | return NULL; |
123 | } | 127 | } |
124 | 128 | ||
125 | static int wf_max6690_attach(struct i2c_adapter *adapter) | 129 | static int wf_max6690_attach(struct i2c_adapter *adapter) |
@@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter) | |||
154 | return 0; | 158 | return 0; |
155 | } | 159 | } |
156 | 160 | ||
157 | static int wf_max6690_detach(struct i2c_client *client) | 161 | static int wf_max6690_remove(struct i2c_client *client) |
158 | { | 162 | { |
159 | struct wf_6690_sensor *max = i2c_to_6690(client); | 163 | struct wf_6690_sensor *max = i2c_get_clientdata(client); |
160 | 164 | ||
161 | max->i2c.adapter = NULL; | 165 | max->i2c = NULL; |
162 | wf_unregister_sensor(&max->sens); | 166 | wf_unregister_sensor(&max->sens); |
163 | 167 | ||
164 | return 0; | 168 | return 0; |
165 | } | 169 | } |
166 | 170 | ||
171 | static const struct i2c_device_id wf_max6690_id[] = { | ||
172 | { "wf_max6690", 0 }, | ||
173 | { } | ||
174 | }; | ||
175 | |||
176 | static struct i2c_driver wf_max6690_driver = { | ||
177 | .driver = { | ||
178 | .name = "wf_max6690", | ||
179 | }, | ||
180 | .attach_adapter = wf_max6690_attach, | ||
181 | .probe = wf_max6690_probe, | ||
182 | .remove = wf_max6690_remove, | ||
183 | .id_table = wf_max6690_id, | ||
184 | }; | ||
185 | |||
167 | static int __init wf_max6690_sensor_init(void) | 186 | static int __init wf_max6690_sensor_init(void) |
168 | { | 187 | { |
169 | /* Don't register on old machines that use therm_pm72 for now */ | 188 | /* Don't register on old machines that use therm_pm72 for now */ |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 7847e981ac33..5da729e58f99 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
@@ -39,7 +39,7 @@ struct wf_sat { | |||
39 | struct mutex mutex; | 39 | struct mutex mutex; |
40 | unsigned long last_read; /* jiffies when cache last updated */ | 40 | unsigned long last_read; /* jiffies when cache last updated */ |
41 | u8 cache[16]; | 41 | u8 cache[16]; |
42 | struct i2c_client i2c; | 42 | struct i2c_client *i2c; |
43 | struct device_node *node; | 43 | struct device_node *node; |
44 | }; | 44 | }; |
45 | 45 | ||
@@ -54,18 +54,6 @@ struct wf_sat_sensor { | |||
54 | }; | 54 | }; |
55 | 55 | ||
56 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) | 56 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) |
57 | #define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) | ||
58 | |||
59 | static int wf_sat_attach(struct i2c_adapter *adapter); | ||
60 | static int wf_sat_detach(struct i2c_client *client); | ||
61 | |||
62 | static struct i2c_driver wf_sat_driver = { | ||
63 | .driver = { | ||
64 | .name = "wf_smu_sat", | ||
65 | }, | ||
66 | .attach_adapter = wf_sat_attach, | ||
67 | .detach_client = wf_sat_detach, | ||
68 | }; | ||
69 | 57 | ||
70 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | 58 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, |
71 | unsigned int *size) | 59 | unsigned int *size) |
@@ -81,13 +69,13 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | |||
81 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) | 69 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) |
82 | return NULL; | 70 | return NULL; |
83 | 71 | ||
84 | err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); | 72 | err = i2c_smbus_write_word_data(sat->i2c, 8, id << 8); |
85 | if (err) { | 73 | if (err) { |
86 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); | 74 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); |
87 | return NULL; | 75 | return NULL; |
88 | } | 76 | } |
89 | 77 | ||
90 | err = i2c_smbus_read_word_data(&sat->i2c, 9); | 78 | err = i2c_smbus_read_word_data(sat->i2c, 9); |
91 | if (err < 0) { | 79 | if (err < 0) { |
92 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); | 80 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); |
93 | return NULL; | 81 | return NULL; |
@@ -105,7 +93,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | |||
105 | return NULL; | 93 | return NULL; |
106 | 94 | ||
107 | for (i = 0; i < len; i += 4) { | 95 | for (i = 0; i < len; i += 4) { |
108 | err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data); | 96 | err = i2c_smbus_read_i2c_block_data(sat->i2c, 0xa, 4, data); |
109 | if (err < 0) { | 97 | if (err < 0) { |
110 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", | 98 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", |
111 | err); | 99 | err); |
@@ -138,7 +126,7 @@ static int wf_sat_read_cache(struct wf_sat *sat) | |||
138 | { | 126 | { |
139 | int err; | 127 | int err; |
140 | 128 | ||
141 | err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache); | 129 | err = i2c_smbus_read_i2c_block_data(sat->i2c, 0x3f, 16, sat->cache); |
142 | if (err < 0) | 130 | if (err < 0) |
143 | return err; | 131 | return err; |
144 | sat->last_read = jiffies; | 132 | sat->last_read = jiffies; |
@@ -161,7 +149,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value) | |||
161 | int i, err; | 149 | int i, err; |
162 | s32 val; | 150 | s32 val; |
163 | 151 | ||
164 | if (sat->i2c.adapter == NULL) | 152 | if (sat->i2c == NULL) |
165 | return -ENODEV; | 153 | return -ENODEV; |
166 | 154 | ||
167 | mutex_lock(&sat->mutex); | 155 | mutex_lock(&sat->mutex); |
@@ -193,10 +181,6 @@ static void wf_sat_release(struct wf_sensor *sr) | |||
193 | struct wf_sat *sat = sens->sat; | 181 | struct wf_sat *sat = sens->sat; |
194 | 182 | ||
195 | if (atomic_dec_and_test(&sat->refcnt)) { | 183 | if (atomic_dec_and_test(&sat->refcnt)) { |
196 | if (sat->i2c.adapter) { | ||
197 | i2c_detach_client(&sat->i2c); | ||
198 | sat->i2c.adapter = NULL; | ||
199 | } | ||
200 | if (sat->nr >= 0) | 184 | if (sat->nr >= 0) |
201 | sats[sat->nr] = NULL; | 185 | sats[sat->nr] = NULL; |
202 | kfree(sat); | 186 | kfree(sat); |
@@ -212,38 +196,58 @@ static struct wf_sensor_ops wf_sat_ops = { | |||
212 | 196 | ||
213 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | 197 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) |
214 | { | 198 | { |
199 | struct i2c_board_info info; | ||
200 | struct i2c_client *client; | ||
201 | const u32 *reg; | ||
202 | u8 addr; | ||
203 | |||
204 | reg = of_get_property(dev, "reg", NULL); | ||
205 | if (reg == NULL) | ||
206 | return; | ||
207 | addr = *reg; | ||
208 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
209 | |||
210 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
211 | info.addr = (addr >> 1) & 0x7f; | ||
212 | info.platform_data = dev; | ||
213 | strlcpy(info.type, "wf_sat", I2C_NAME_SIZE); | ||
214 | |||
215 | client = i2c_new_device(adapter, &info); | ||
216 | if (client == NULL) { | ||
217 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * Let i2c-core delete that device on driver removal. | ||
223 | * This is safe because i2c-core holds the core_lock mutex for us. | ||
224 | */ | ||
225 | list_add_tail(&client->detected, &client->driver->clients); | ||
226 | } | ||
227 | |||
228 | static int wf_sat_probe(struct i2c_client *client, | ||
229 | const struct i2c_device_id *id) | ||
230 | { | ||
231 | struct device_node *dev = client->dev.platform_data; | ||
215 | struct wf_sat *sat; | 232 | struct wf_sat *sat; |
216 | struct wf_sat_sensor *sens; | 233 | struct wf_sat_sensor *sens; |
217 | const u32 *reg; | 234 | const u32 *reg; |
218 | const char *loc, *type; | 235 | const char *loc, *type; |
219 | u8 addr, chip, core; | 236 | u8 chip, core; |
220 | struct device_node *child; | 237 | struct device_node *child; |
221 | int shift, cpu, index; | 238 | int shift, cpu, index; |
222 | char *name; | 239 | char *name; |
223 | int vsens[2], isens[2]; | 240 | int vsens[2], isens[2]; |
224 | 241 | ||
225 | reg = of_get_property(dev, "reg", NULL); | ||
226 | if (reg == NULL) | ||
227 | return; | ||
228 | addr = *reg; | ||
229 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
230 | |||
231 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); | 242 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); |
232 | if (sat == NULL) | 243 | if (sat == NULL) |
233 | return; | 244 | return -ENOMEM; |
234 | sat->nr = -1; | 245 | sat->nr = -1; |
235 | sat->node = of_node_get(dev); | 246 | sat->node = of_node_get(dev); |
236 | atomic_set(&sat->refcnt, 0); | 247 | atomic_set(&sat->refcnt, 0); |
237 | mutex_init(&sat->mutex); | 248 | mutex_init(&sat->mutex); |
238 | sat->i2c.addr = (addr >> 1) & 0x7f; | 249 | sat->i2c = client; |
239 | sat->i2c.adapter = adapter; | 250 | i2c_set_clientdata(client, sat); |
240 | sat->i2c.driver = &wf_sat_driver; | ||
241 | strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); | ||
242 | |||
243 | if (i2c_attach_client(&sat->i2c)) { | ||
244 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
245 | goto fail; | ||
246 | } | ||
247 | 251 | ||
248 | vsens[0] = vsens[1] = -1; | 252 | vsens[0] = vsens[1] = -1; |
249 | isens[0] = isens[1] = -1; | 253 | isens[0] = isens[1] = -1; |
@@ -344,10 +348,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | |||
344 | if (sat->nr >= 0) | 348 | if (sat->nr >= 0) |
345 | sats[sat->nr] = sat; | 349 | sats[sat->nr] = sat; |
346 | 350 | ||
347 | return; | 351 | return 0; |
348 | |||
349 | fail: | ||
350 | kfree(sat); | ||
351 | } | 352 | } |
352 | 353 | ||
353 | static int wf_sat_attach(struct i2c_adapter *adapter) | 354 | static int wf_sat_attach(struct i2c_adapter *adapter) |
@@ -366,16 +367,32 @@ static int wf_sat_attach(struct i2c_adapter *adapter) | |||
366 | return 0; | 367 | return 0; |
367 | } | 368 | } |
368 | 369 | ||
369 | static int wf_sat_detach(struct i2c_client *client) | 370 | static int wf_sat_remove(struct i2c_client *client) |
370 | { | 371 | { |
371 | struct wf_sat *sat = i2c_to_sat(client); | 372 | struct wf_sat *sat = i2c_get_clientdata(client); |
372 | 373 | ||
373 | /* XXX TODO */ | 374 | /* XXX TODO */ |
374 | 375 | ||
375 | sat->i2c.adapter = NULL; | 376 | sat->i2c = NULL; |
377 | i2c_set_clientdata(client, NULL); | ||
376 | return 0; | 378 | return 0; |
377 | } | 379 | } |
378 | 380 | ||
381 | static const struct i2c_device_id wf_sat_id[] = { | ||
382 | { "wf_sat", 0 }, | ||
383 | { } | ||
384 | }; | ||
385 | |||
386 | static struct i2c_driver wf_sat_driver = { | ||
387 | .driver = { | ||
388 | .name = "wf_smu_sat", | ||
389 | }, | ||
390 | .attach_adapter = wf_sat_attach, | ||
391 | .probe = wf_sat_probe, | ||
392 | .remove = wf_sat_remove, | ||
393 | .id_table = wf_sat_id, | ||
394 | }; | ||
395 | |||
379 | static int __init sat_sensors_init(void) | 396 | static int __init sat_sensors_init(void) |
380 | { | 397 | { |
381 | return i2c_add_driver(&wf_sat_driver); | 398 | return i2c_add_driver(&wf_sat_driver); |