aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83793.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/hwmon/w83793.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/hwmon/w83793.c')
-rw-r--r--drivers/hwmon/w83793.c544
1 files changed, 501 insertions, 43 deletions
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 47dd398f7258..612807d97155 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -3,6 +3,10 @@
3 Copyright (C) 2006 Winbond Electronics Corp. 3 Copyright (C) 2006 Winbond Electronics Corp.
4 Yuan Mu 4 Yuan Mu
5 Rudolf Marek <r.marek@assembler.cz> 5 Rudolf Marek <r.marek@assembler.cz>
6 Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG.
7 Watchdog driver part
8 (Based partially on fschmd driver,
9 Copyright 2007-2008 by Hans de Goede)
6 10
7 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
@@ -35,13 +39,22 @@
35#include <linux/hwmon-sysfs.h> 39#include <linux/hwmon-sysfs.h>
36#include <linux/err.h> 40#include <linux/err.h>
37#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/fs.h>
43#include <linux/watchdog.h>
44#include <linux/miscdevice.h>
45#include <linux/uaccess.h>
46#include <linux/kref.h>
47#include <linux/notifier.h>
48#include <linux/reboot.h>
49
50/* Default values */
51#define WATCHDOG_TIMEOUT 2 /* 2 minute default timeout */
38 52
39/* Addresses to scan */ 53/* Addresses to scan */
40static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, 54static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
41 I2C_CLIENT_END }; 55 I2C_CLIENT_END };
42 56
43/* Insmod parameters */ 57/* Insmod parameters */
44I2C_CLIENT_INSMOD_1(w83793);
45 58
46static unsigned short force_subclients[4]; 59static unsigned short force_subclients[4];
47module_param_array(force_subclients, short, NULL, 0); 60module_param_array(force_subclients, short, NULL, 0);
@@ -52,6 +65,18 @@ static int reset;
52module_param(reset, bool, 0); 65module_param(reset, bool, 0);
53MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); 66MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
54 67
68static int timeout = WATCHDOG_TIMEOUT; /* default timeout in minutes */
69module_param(timeout, int, 0);
70MODULE_PARM_DESC(timeout,
71 "Watchdog timeout in minutes. 2<= timeout <=255 (default="
72 __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
73
74static int nowayout = WATCHDOG_NOWAYOUT;
75module_param(nowayout, int, 0);
76MODULE_PARM_DESC(nowayout,
77 "Watchdog cannot be stopped once started (default="
78 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
79
55/* 80/*
56 Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved 81 Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
57 as ID, Bank Select registers 82 as ID, Bank Select registers
@@ -73,6 +98,11 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
73#define W83793_REG_VID_LATCHB 0x08 98#define W83793_REG_VID_LATCHB 0x08
74#define W83793_REG_VID_CTRL 0x59 99#define W83793_REG_VID_CTRL 0x59
75 100
101#define W83793_REG_WDT_LOCK 0x01
102#define W83793_REG_WDT_ENABLE 0x02
103#define W83793_REG_WDT_STATUS 0x03
104#define W83793_REG_WDT_TIMEOUT 0x04
105
76static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f }; 106static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
77 107
78#define TEMP_READ 0 108#define TEMP_READ 0
@@ -224,13 +254,42 @@ struct w83793_data {
224 u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */ 254 u8 tolerance[3]; /* Temp tolerance(Smart Fan I/II) */
225 u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */ 255 u8 sf2_pwm[6][7]; /* Smart FanII: Fan duty cycle */
226 u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */ 256 u8 sf2_temp[6][7]; /* Smart FanII: Temp level point */
257
258 /* watchdog */
259 struct i2c_client *client;
260 struct mutex watchdog_lock;
261 struct list_head list; /* member of the watchdog_data_list */
262 struct kref kref;
263 struct miscdevice watchdog_miscdev;
264 unsigned long watchdog_is_open;
265 char watchdog_expect_close;
266 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
267 unsigned int watchdog_caused_reboot;
268 int watchdog_timeout; /* watchdog timeout in minutes */
227}; 269};
228 270
271/* Somewhat ugly :( global data pointer list with all devices, so that
272 we can find our device data as when using misc_register. There is no
273 other method to get to one's device data from the open file-op and
274 for usage in the reboot notifier callback. */
275static LIST_HEAD(watchdog_data_list);
276
277/* Note this lock not only protect list access, but also data.kref access */
278static DEFINE_MUTEX(watchdog_data_mutex);
279
280/* Release our data struct when we're detached from the i2c client *and* all
281 references to our watchdog device are released */
282static void w83793_release_resources(struct kref *ref)
283{
284 struct w83793_data *data = container_of(ref, struct w83793_data, kref);
285 kfree(data);
286}
287
229static u8 w83793_read_value(struct i2c_client *client, u16 reg); 288static u8 w83793_read_value(struct i2c_client *client, u16 reg);
230static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value); 289static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
231static int w83793_probe(struct i2c_client *client, 290static int w83793_probe(struct i2c_client *client,
232 const struct i2c_device_id *id); 291 const struct i2c_device_id *id);
233static int w83793_detect(struct i2c_client *client, int kind, 292static int w83793_detect(struct i2c_client *client,
234 struct i2c_board_info *info); 293 struct i2c_board_info *info);
235static int w83793_remove(struct i2c_client *client); 294static int w83793_remove(struct i2c_client *client);
236static void w83793_init_client(struct i2c_client *client); 295static void w83793_init_client(struct i2c_client *client);
@@ -238,7 +297,7 @@ static void w83793_update_nonvolatile(struct device *dev);
238static struct w83793_data *w83793_update_device(struct device *dev); 297static struct w83793_data *w83793_update_device(struct device *dev);
239 298
240static const struct i2c_device_id w83793_id[] = { 299static const struct i2c_device_id w83793_id[] = {
241 { "w83793", w83793 }, 300 { "w83793", 0 },
242 { } 301 { }
243}; 302};
244MODULE_DEVICE_TABLE(i2c, w83793_id); 303MODULE_DEVICE_TABLE(i2c, w83793_id);
@@ -252,7 +311,7 @@ static struct i2c_driver w83793_driver = {
252 .remove = w83793_remove, 311 .remove = w83793_remove,
253 .id_table = w83793_id, 312 .id_table = w83793_id,
254 .detect = w83793_detect, 313 .detect = w83793_detect,
255 .address_data = &addr_data, 314 .address_list = normal_i2c,
256}; 315};
257 316
258static ssize_t 317static ssize_t
@@ -1064,14 +1123,349 @@ static void w83793_init_client(struct i2c_client *client)
1064 /* Start monitoring */ 1123 /* Start monitoring */
1065 w83793_write_value(client, W83793_REG_CONFIG, 1124 w83793_write_value(client, W83793_REG_CONFIG,
1066 w83793_read_value(client, W83793_REG_CONFIG) | 0x01); 1125 w83793_read_value(client, W83793_REG_CONFIG) | 0x01);
1126}
1127
1128/*
1129 * Watchdog routines
1130 */
1131
1132static int watchdog_set_timeout(struct w83793_data *data, int timeout)
1133{
1134 int ret, mtimeout;
1135
1136 mtimeout = DIV_ROUND_UP(timeout, 60);
1137
1138 if (mtimeout > 255)
1139 return -EINVAL;
1067 1140
1141 mutex_lock(&data->watchdog_lock);
1142 if (!data->client) {
1143 ret = -ENODEV;
1144 goto leave;
1145 }
1146
1147 data->watchdog_timeout = mtimeout;
1148
1149 /* Set Timeout value (in Minutes) */
1150 w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
1151 data->watchdog_timeout);
1152
1153 ret = mtimeout * 60;
1154
1155leave:
1156 mutex_unlock(&data->watchdog_lock);
1157 return ret;
1158}
1159
1160static int watchdog_get_timeout(struct w83793_data *data)
1161{
1162 int timeout;
1163
1164 mutex_lock(&data->watchdog_lock);
1165 timeout = data->watchdog_timeout * 60;
1166 mutex_unlock(&data->watchdog_lock);
1167
1168 return timeout;
1169}
1170
1171static int watchdog_trigger(struct w83793_data *data)
1172{
1173 int ret = 0;
1174
1175 mutex_lock(&data->watchdog_lock);
1176 if (!data->client) {
1177 ret = -ENODEV;
1178 goto leave;
1179 }
1180
1181 /* Set Timeout value (in Minutes) */
1182 w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
1183 data->watchdog_timeout);
1184
1185leave:
1186 mutex_unlock(&data->watchdog_lock);
1187 return ret;
1188}
1189
1190static int watchdog_enable(struct w83793_data *data)
1191{
1192 int ret = 0;
1193
1194 mutex_lock(&data->watchdog_lock);
1195 if (!data->client) {
1196 ret = -ENODEV;
1197 goto leave;
1198 }
1199
1200 /* Set initial timeout */
1201 w83793_write_value(data->client, W83793_REG_WDT_TIMEOUT,
1202 data->watchdog_timeout);
1203
1204 /* Enable Soft Watchdog */
1205 w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0x55);
1206
1207leave:
1208 mutex_unlock(&data->watchdog_lock);
1209 return ret;
1210}
1211
1212static int watchdog_disable(struct w83793_data *data)
1213{
1214 int ret = 0;
1215
1216 mutex_lock(&data->watchdog_lock);
1217 if (!data->client) {
1218 ret = -ENODEV;
1219 goto leave;
1220 }
1221
1222 /* Disable Soft Watchdog */
1223 w83793_write_value(data->client, W83793_REG_WDT_LOCK, 0xAA);
1224
1225leave:
1226 mutex_unlock(&data->watchdog_lock);
1227 return ret;
1228}
1229
1230static int watchdog_open(struct inode *inode, struct file *filp)
1231{
1232 struct w83793_data *pos, *data = NULL;
1233 int watchdog_is_open;
1234
1235 /* We get called from drivers/char/misc.c with misc_mtx hold, and we
1236 call misc_register() from w83793_probe() with watchdog_data_mutex
1237 hold, as misc_register() takes the misc_mtx lock, this is a possible
1238 deadlock, so we use mutex_trylock here. */
1239 if (!mutex_trylock(&watchdog_data_mutex))
1240 return -ERESTARTSYS;
1241 list_for_each_entry(pos, &watchdog_data_list, list) {
1242 if (pos->watchdog_miscdev.minor == iminor(inode)) {
1243 data = pos;
1244 break;
1245 }
1246 }
1247
1248 /* Check, if device is already open */
1249 watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
1250
1251 /* Increase data reference counter (if not already done).
1252 Note we can never not have found data, so we don't check for this */
1253 if (!watchdog_is_open)
1254 kref_get(&data->kref);
1255
1256 mutex_unlock(&watchdog_data_mutex);
1257
1258 /* Check, if device is already open and possibly issue error */
1259 if (watchdog_is_open)
1260 return -EBUSY;
1261
1262 /* Enable Soft Watchdog */
1263 watchdog_enable(data);
1264
1265 /* Store pointer to data into filp's private data */
1266 filp->private_data = data;
1267
1268 return nonseekable_open(inode, filp);
1269}
1270
1271static int watchdog_close(struct inode *inode, struct file *filp)
1272{
1273 struct w83793_data *data = filp->private_data;
1274
1275 if (data->watchdog_expect_close) {
1276 watchdog_disable(data);
1277 data->watchdog_expect_close = 0;
1278 } else {
1279 watchdog_trigger(data);
1280 dev_crit(&data->client->dev,
1281 "unexpected close, not stopping watchdog!\n");
1282 }
1283
1284 clear_bit(0, &data->watchdog_is_open);
1285
1286 /* Decrease data reference counter */
1287 mutex_lock(&watchdog_data_mutex);
1288 kref_put(&data->kref, w83793_release_resources);
1289 mutex_unlock(&watchdog_data_mutex);
1290
1291 return 0;
1068} 1292}
1069 1293
1294static ssize_t watchdog_write(struct file *filp, const char __user *buf,
1295 size_t count, loff_t *offset)
1296{
1297 ssize_t ret;
1298 struct w83793_data *data = filp->private_data;
1299
1300 if (count) {
1301 if (!nowayout) {
1302 size_t i;
1303
1304 /* Clear it in case it was set with a previous write */
1305 data->watchdog_expect_close = 0;
1306
1307 for (i = 0; i != count; i++) {
1308 char c;
1309 if (get_user(c, buf + i))
1310 return -EFAULT;
1311 if (c == 'V')
1312 data->watchdog_expect_close = 1;
1313 }
1314 }
1315 ret = watchdog_trigger(data);
1316 if (ret < 0)
1317 return ret;
1318 }
1319 return count;
1320}
1321
1322static int watchdog_ioctl(struct inode *inode, struct file *filp,
1323 unsigned int cmd, unsigned long arg)
1324{
1325 static struct watchdog_info ident = {
1326 .options = WDIOF_KEEPALIVEPING |
1327 WDIOF_SETTIMEOUT |
1328 WDIOF_CARDRESET,
1329 .identity = "w83793 watchdog"
1330 };
1331
1332 int val, ret = 0;
1333 struct w83793_data *data = filp->private_data;
1334
1335 switch (cmd) {
1336 case WDIOC_GETSUPPORT:
1337 if (!nowayout)
1338 ident.options |= WDIOF_MAGICCLOSE;
1339 if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
1340 ret = -EFAULT;
1341 break;
1342
1343 case WDIOC_GETSTATUS:
1344 val = data->watchdog_caused_reboot ? WDIOF_CARDRESET : 0;
1345 ret = put_user(val, (int __user *)arg);
1346 break;
1347
1348 case WDIOC_GETBOOTSTATUS:
1349 ret = put_user(0, (int __user *)arg);
1350 break;
1351
1352 case WDIOC_KEEPALIVE:
1353 ret = watchdog_trigger(data);
1354 break;
1355
1356 case WDIOC_GETTIMEOUT:
1357 val = watchdog_get_timeout(data);
1358 ret = put_user(val, (int __user *)arg);
1359 break;
1360
1361 case WDIOC_SETTIMEOUT:
1362 if (get_user(val, (int __user *)arg)) {
1363 ret = -EFAULT;
1364 break;
1365 }
1366 ret = watchdog_set_timeout(data, val);
1367 if (ret > 0)
1368 ret = put_user(ret, (int __user *)arg);
1369 break;
1370
1371 case WDIOC_SETOPTIONS:
1372 if (get_user(val, (int __user *)arg)) {
1373 ret = -EFAULT;
1374 break;
1375 }
1376
1377 if (val & WDIOS_DISABLECARD)
1378 ret = watchdog_disable(data);
1379 else if (val & WDIOS_ENABLECARD)
1380 ret = watchdog_enable(data);
1381 else
1382 ret = -EINVAL;
1383
1384 break;
1385 default:
1386 ret = -ENOTTY;
1387 }
1388
1389 return ret;
1390}
1391
1392static const struct file_operations watchdog_fops = {
1393 .owner = THIS_MODULE,
1394 .llseek = no_llseek,
1395 .open = watchdog_open,
1396 .release = watchdog_close,
1397 .write = watchdog_write,
1398 .ioctl = watchdog_ioctl,
1399};
1400
1401/*
1402 * Notifier for system down
1403 */
1404
1405static int watchdog_notify_sys(struct notifier_block *this, unsigned long code,
1406 void *unused)
1407{
1408 struct w83793_data *data = NULL;
1409
1410 if (code == SYS_DOWN || code == SYS_HALT) {
1411
1412 /* Disable each registered watchdog */
1413 mutex_lock(&watchdog_data_mutex);
1414 list_for_each_entry(data, &watchdog_data_list, list) {
1415 if (data->watchdog_miscdev.minor)
1416 watchdog_disable(data);
1417 }
1418 mutex_unlock(&watchdog_data_mutex);
1419 }
1420
1421 return NOTIFY_DONE;
1422}
1423
1424/*
1425 * The WDT needs to learn about soft shutdowns in order to
1426 * turn the timebomb registers off.
1427 */
1428
1429static struct notifier_block watchdog_notifier = {
1430 .notifier_call = watchdog_notify_sys,
1431};
1432
1433/*
1434 * Init / remove routines
1435 */
1436
1070static int w83793_remove(struct i2c_client *client) 1437static int w83793_remove(struct i2c_client *client)
1071{ 1438{
1072 struct w83793_data *data = i2c_get_clientdata(client); 1439 struct w83793_data *data = i2c_get_clientdata(client);
1073 struct device *dev = &client->dev; 1440 struct device *dev = &client->dev;
1074 int i; 1441 int i, tmp;
1442
1443 /* Unregister the watchdog (if registered) */
1444 if (data->watchdog_miscdev.minor) {
1445 misc_deregister(&data->watchdog_miscdev);
1446
1447 if (data->watchdog_is_open) {
1448 dev_warn(&client->dev,
1449 "i2c client detached with watchdog open! "
1450 "Stopping watchdog.\n");
1451 watchdog_disable(data);
1452 }
1453
1454 mutex_lock(&watchdog_data_mutex);
1455 list_del(&data->list);
1456 mutex_unlock(&watchdog_data_mutex);
1457
1458 /* Tell the watchdog code the client is gone */
1459 mutex_lock(&data->watchdog_lock);
1460 data->client = NULL;
1461 mutex_unlock(&data->watchdog_lock);
1462 }
1463
1464 /* Reset Configuration Register to Disable Watch Dog Registers */
1465 tmp = w83793_read_value(client, W83793_REG_CONFIG);
1466 w83793_write_value(client, W83793_REG_CONFIG, tmp & ~0x04);
1467
1468 unregister_reboot_notifier(&watchdog_notifier);
1075 1469
1076 hwmon_device_unregister(data->hwmon_dev); 1470 hwmon_device_unregister(data->hwmon_dev);
1077 1471
@@ -1100,7 +1494,10 @@ static int w83793_remove(struct i2c_client *client)
1100 if (data->lm75[1] != NULL) 1494 if (data->lm75[1] != NULL)
1101 i2c_unregister_device(data->lm75[1]); 1495 i2c_unregister_device(data->lm75[1]);
1102 1496
1103 kfree(data); 1497 /* Decrease data reference counter */
1498 mutex_lock(&watchdog_data_mutex);
1499 kref_put(&data->kref, w83793_release_resources);
1500 mutex_unlock(&watchdog_data_mutex);
1104 1501
1105 return 0; 1502 return 0;
1106} 1503}
@@ -1161,10 +1558,10 @@ ERROR_SC_0:
1161} 1558}
1162 1559
1163/* Return 0 if detection is successful, -ENODEV otherwise */ 1560/* Return 0 if detection is successful, -ENODEV otherwise */
1164static int w83793_detect(struct i2c_client *client, int kind, 1561static int w83793_detect(struct i2c_client *client,
1165 struct i2c_board_info *info) 1562 struct i2c_board_info *info)
1166{ 1563{
1167 u8 tmp, bank; 1564 u8 tmp, bank, chip_id;
1168 struct i2c_adapter *adapter = client->adapter; 1565 struct i2c_adapter *adapter = client->adapter;
1169 unsigned short address = client->addr; 1566 unsigned short address = client->addr;
1170 1567
@@ -1174,44 +1571,27 @@ static int w83793_detect(struct i2c_client *client, int kind,
1174 1571
1175 bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); 1572 bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
1176 1573
1177 if (kind < 0) { 1574 tmp = bank & 0x80 ? 0x5c : 0xa3;
1178 tmp = bank & 0x80 ? 0x5c : 0xa3; 1575 /* Check Winbond vendor ID */
1179 /* Check Winbond vendor ID */ 1576 if (tmp != i2c_smbus_read_byte_data(client, W83793_REG_VENDORID)) {
1180 if (tmp != i2c_smbus_read_byte_data(client, 1577 pr_debug("w83793: Detection failed at check vendor id\n");
1181 W83793_REG_VENDORID)) { 1578 return -ENODEV;
1182 pr_debug("w83793: Detection failed at check "
1183 "vendor id\n");
1184 return -ENODEV;
1185 }
1186
1187 /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
1188 should match */
1189 if ((bank & 0x07) == 0
1190 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
1191 (address << 1)) {
1192 pr_debug("w83793: Detection failed at check "
1193 "i2c addr\n");
1194 return -ENODEV;
1195 }
1196
1197 } 1579 }
1198 1580
1199 /* We have either had a force parameter, or we have already detected the 1581 /* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
1200 Winbond. Determine the chip type now */ 1582 should match */
1201 1583 if ((bank & 0x07) == 0
1202 if (kind <= 0) { 1584 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
1203 if (0x7b == i2c_smbus_read_byte_data(client, 1585 (address << 1)) {
1204 W83793_REG_CHIPID)) { 1586 pr_debug("w83793: Detection failed at check i2c addr\n");
1205 kind = w83793; 1587 return -ENODEV;
1206 } else {
1207 if (kind == 0)
1208 dev_warn(&adapter->dev, "w83793: Ignoring "
1209 "'force' parameter for unknown chip "
1210 "at address 0x%02x\n", address);
1211 return -ENODEV;
1212 }
1213 } 1588 }
1214 1589
1590 /* Determine the chip type now */
1591 chip_id = i2c_smbus_read_byte_data(client, W83793_REG_CHIPID);
1592 if (chip_id != 0x7b)
1593 return -ENODEV;
1594
1215 strlcpy(info->type, "w83793", I2C_NAME_SIZE); 1595 strlcpy(info->type, "w83793", I2C_NAME_SIZE);
1216 1596
1217 return 0; 1597 return 0;
@@ -1221,6 +1601,7 @@ static int w83793_probe(struct i2c_client *client,
1221 const struct i2c_device_id *id) 1601 const struct i2c_device_id *id)
1222{ 1602{
1223 struct device *dev = &client->dev; 1603 struct device *dev = &client->dev;
1604 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
1224 struct w83793_data *data; 1605 struct w83793_data *data;
1225 int i, tmp, val, err; 1606 int i, tmp, val, err;
1226 int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; 1607 int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
@@ -1236,6 +1617,14 @@ static int w83793_probe(struct i2c_client *client,
1236 i2c_set_clientdata(client, data); 1617 i2c_set_clientdata(client, data);
1237 data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL); 1618 data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
1238 mutex_init(&data->update_lock); 1619 mutex_init(&data->update_lock);
1620 mutex_init(&data->watchdog_lock);
1621 INIT_LIST_HEAD(&data->list);
1622 kref_init(&data->kref);
1623
1624 /* Store client pointer in our data struct for watchdog usage
1625 (where the client is found through a data ptr instead of the
1626 otherway around) */
1627 data->client = client;
1239 1628
1240 err = w83793_detect_subclients(client); 1629 err = w83793_detect_subclients(client);
1241 if (err) 1630 if (err)
@@ -1398,8 +1787,77 @@ static int w83793_probe(struct i2c_client *client,
1398 goto exit_remove; 1787 goto exit_remove;
1399 } 1788 }
1400 1789
1790 /* Watchdog initialization */
1791
1792 /* Register boot notifier */
1793 err = register_reboot_notifier(&watchdog_notifier);
1794 if (err != 0) {
1795 dev_err(&client->dev,
1796 "cannot register reboot notifier (err=%d)\n", err);
1797 goto exit_devunreg;
1798 }
1799
1800 /* Enable Watchdog registers.
1801 Set Configuration Register to Enable Watch Dog Registers
1802 (Bit 2) = XXXX, X1XX. */
1803 tmp = w83793_read_value(client, W83793_REG_CONFIG);
1804 w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04);
1805
1806 /* Set the default watchdog timeout */
1807 data->watchdog_timeout = timeout;
1808
1809 /* Check, if last reboot was caused by watchdog */
1810 data->watchdog_caused_reboot =
1811 w83793_read_value(data->client, W83793_REG_WDT_STATUS) & 0x01;
1812
1813 /* Disable Soft Watchdog during initialiation */
1814 watchdog_disable(data);
1815
1816 /* We take the data_mutex lock early so that watchdog_open() cannot
1817 run when misc_register() has completed, but we've not yet added
1818 our data to the watchdog_data_list (and set the default timeout) */
1819 mutex_lock(&watchdog_data_mutex);
1820 for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
1821 /* Register our watchdog part */
1822 snprintf(data->watchdog_name, sizeof(data->watchdog_name),
1823 "watchdog%c", (i == 0) ? '\0' : ('0' + i));
1824 data->watchdog_miscdev.name = data->watchdog_name;
1825 data->watchdog_miscdev.fops = &watchdog_fops;
1826 data->watchdog_miscdev.minor = watchdog_minors[i];
1827
1828 err = misc_register(&data->watchdog_miscdev);
1829 if (err == -EBUSY)
1830 continue;
1831 if (err) {
1832 data->watchdog_miscdev.minor = 0;
1833 dev_err(&client->dev,
1834 "Registering watchdog chardev: %d\n", err);
1835 break;
1836 }
1837
1838 list_add(&data->list, &watchdog_data_list);
1839
1840 dev_info(&client->dev,
1841 "Registered watchdog chardev major 10, minor: %d\n",
1842 watchdog_minors[i]);
1843 break;
1844 }
1845 if (i == ARRAY_SIZE(watchdog_minors)) {
1846 data->watchdog_miscdev.minor = 0;
1847 dev_warn(&client->dev, "Couldn't register watchdog chardev "
1848 "(due to no free minor)\n");
1849 }
1850
1851 mutex_unlock(&watchdog_data_mutex);
1852
1401 return 0; 1853 return 0;
1402 1854
1855 /* Unregister hwmon device */
1856
1857exit_devunreg:
1858
1859 hwmon_device_unregister(data->hwmon_dev);
1860
1403 /* Unregister sysfs hooks */ 1861 /* Unregister sysfs hooks */
1404 1862
1405exit_remove: 1863exit_remove:
@@ -1646,7 +2104,7 @@ static void __exit sensors_w83793_exit(void)
1646 i2c_del_driver(&w83793_driver); 2104 i2c_del_driver(&w83793_driver);
1647} 2105}
1648 2106
1649MODULE_AUTHOR("Yuan Mu"); 2107MODULE_AUTHOR("Yuan Mu, Sven Anders");
1650MODULE_DESCRIPTION("w83793 driver"); 2108MODULE_DESCRIPTION("w83793 driver");
1651MODULE_LICENSE("GPL"); 2109MODULE_LICENSE("GPL");
1652 2110