aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/smsc47b397.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/smsc47b397.c')
-rw-r--r--drivers/hwmon/smsc47b397.c74
1 files changed, 31 insertions, 43 deletions
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index fdeeb3ab6f2f..7fe71576dea4 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -31,23 +31,14 @@
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/jiffies.h> 32#include <linux/jiffies.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/i2c-sensor.h> 34#include <linux/i2c-isa.h>
35#include <linux/hwmon.h>
36#include <linux/err.h>
35#include <linux/init.h> 37#include <linux/init.h>
36#include <asm/io.h> 38#include <asm/io.h>
37 39
38static unsigned short normal_i2c[] = { I2C_CLIENT_END };
39/* Address is autodetected, there is no default value */ 40/* Address is autodetected, there is no default value */
40static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; 41static unsigned short address;
41static struct i2c_force_data forces[] = {{NULL}};
42
43enum chips { any_chip, smsc47b397 };
44static struct i2c_address_data addr_data = {
45 .normal_i2c = normal_i2c,
46 .normal_isa = normal_isa,
47 .probe = normal_i2c, /* cheat */
48 .ignore = normal_i2c, /* cheat */
49 .forces = forces,
50};
51 42
52/* Super-I/0 registers and commands */ 43/* Super-I/0 registers and commands */
53 44
@@ -100,6 +91,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
100 91
101struct smsc47b397_data { 92struct smsc47b397_data {
102 struct i2c_client client; 93 struct i2c_client client;
94 struct class_device *class_dev;
103 struct semaphore lock; 95 struct semaphore lock;
104 96
105 struct semaphore update_lock; 97 struct semaphore update_lock;
@@ -215,52 +207,40 @@ sysfs_fan(4);
215#define device_create_file_fan(client, num) \ 207#define device_create_file_fan(client, num) \
216 device_create_file(&client->dev, &dev_attr_fan##num##_input) 208 device_create_file(&client->dev, &dev_attr_fan##num##_input)
217 209
218static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind);
219
220static int smsc47b397_attach_adapter(struct i2c_adapter *adapter)
221{
222 if (!(adapter->class & I2C_CLASS_HWMON))
223 return 0;
224 return i2c_detect(adapter, &addr_data, smsc47b397_detect);
225}
226
227static int smsc47b397_detach_client(struct i2c_client *client) 210static int smsc47b397_detach_client(struct i2c_client *client)
228{ 211{
212 struct smsc47b397_data *data = i2c_get_clientdata(client);
229 int err; 213 int err;
230 214
231 if ((err = i2c_detach_client(client))) { 215 hwmon_device_unregister(data->class_dev);
232 dev_err(&client->dev, "Client deregistration failed, " 216
233 "client not detached.\n"); 217 if ((err = i2c_detach_client(client)))
234 return err; 218 return err;
235 }
236 219
237 release_region(client->addr, SMSC_EXTENT); 220 release_region(client->addr, SMSC_EXTENT);
238 kfree(i2c_get_clientdata(client)); 221 kfree(data);
239 222
240 return 0; 223 return 0;
241} 224}
242 225
226static int smsc47b397_detect(struct i2c_adapter *adapter);
227
243static struct i2c_driver smsc47b397_driver = { 228static struct i2c_driver smsc47b397_driver = {
244 .owner = THIS_MODULE, 229 .owner = THIS_MODULE,
245 .name = "smsc47b397", 230 .name = "smsc47b397",
246 .id = I2C_DRIVERID_SMSC47B397, 231 .attach_adapter = smsc47b397_detect,
247 .flags = I2C_DF_NOTIFY,
248 .attach_adapter = smsc47b397_attach_adapter,
249 .detach_client = smsc47b397_detach_client, 232 .detach_client = smsc47b397_detach_client,
250}; 233};
251 234
252static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) 235static int smsc47b397_detect(struct i2c_adapter *adapter)
253{ 236{
254 struct i2c_client *new_client; 237 struct i2c_client *new_client;
255 struct smsc47b397_data *data; 238 struct smsc47b397_data *data;
256 int err = 0; 239 int err = 0;
257 240
258 if (!i2c_is_isa_adapter(adapter)) { 241 if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) {
259 return 0; 242 dev_err(&adapter->dev, "Region 0x%x already in use!\n",
260 } 243 address);
261
262 if (!request_region(addr, SMSC_EXTENT, smsc47b397_driver.name)) {
263 dev_err(&adapter->dev, "Region 0x%x already in use!\n", addr);
264 return -EBUSY; 244 return -EBUSY;
265 } 245 }
266 246
@@ -272,7 +252,7 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
272 252
273 new_client = &data->client; 253 new_client = &data->client;
274 i2c_set_clientdata(new_client, data); 254 i2c_set_clientdata(new_client, data);
275 new_client->addr = addr; 255 new_client->addr = address;
276 init_MUTEX(&data->lock); 256 init_MUTEX(&data->lock);
277 new_client->adapter = adapter; 257 new_client->adapter = adapter;
278 new_client->driver = &smsc47b397_driver; 258 new_client->driver = &smsc47b397_driver;
@@ -285,6 +265,12 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
285 if ((err = i2c_attach_client(new_client))) 265 if ((err = i2c_attach_client(new_client)))
286 goto error_free; 266 goto error_free;
287 267
268 data->class_dev = hwmon_device_register(&new_client->dev);
269 if (IS_ERR(data->class_dev)) {
270 err = PTR_ERR(data->class_dev);
271 goto error_detach;
272 }
273
288 device_create_file_temp(new_client, 1); 274 device_create_file_temp(new_client, 1);
289 device_create_file_temp(new_client, 2); 275 device_create_file_temp(new_client, 2);
290 device_create_file_temp(new_client, 3); 276 device_create_file_temp(new_client, 3);
@@ -297,14 +283,16 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
297 283
298 return 0; 284 return 0;
299 285
286error_detach:
287 i2c_detach_client(new_client);
300error_free: 288error_free:
301 kfree(data); 289 kfree(data);
302error_release: 290error_release:
303 release_region(addr, SMSC_EXTENT); 291 release_region(address, SMSC_EXTENT);
304 return err; 292 return err;
305} 293}
306 294
307static int __init smsc47b397_find(unsigned int *addr) 295static int __init smsc47b397_find(unsigned short *addr)
308{ 296{
309 u8 id, rev; 297 u8 id, rev;
310 298
@@ -333,15 +321,15 @@ static int __init smsc47b397_init(void)
333{ 321{
334 int ret; 322 int ret;
335 323
336 if ((ret = smsc47b397_find(normal_isa))) 324 if ((ret = smsc47b397_find(&address)))
337 return ret; 325 return ret;
338 326
339 return i2c_add_driver(&smsc47b397_driver); 327 return i2c_isa_add_driver(&smsc47b397_driver);
340} 328}
341 329
342static void __exit smsc47b397_exit(void) 330static void __exit smsc47b397_exit(void)
343{ 331{
344 i2c_del_driver(&smsc47b397_driver); 332 i2c_isa_del_driver(&smsc47b397_driver);
345} 333}
346 334
347MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); 335MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");