aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/f71808e_wdt.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/watchdog/f71808e_wdt.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/watchdog/f71808e_wdt.c')
-rw-r--r--drivers/watchdog/f71808e_wdt.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 7e5c266cda48..d4d8d1fdccc4 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -42,18 +42,21 @@
42#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 42#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
43#define SIO_REG_DEVREV 0x22 /* Device revision */ 43#define SIO_REG_DEVREV 0x22 /* Device revision */
44#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ 44#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
45#define SIO_REG_ROM_ADDR_SEL 0x27 /* ROM address select */
46#define SIO_REG_MFUNCT1 0x29 /* Multi function select 1 */
47#define SIO_REG_MFUNCT2 0x2a /* Multi function select 2 */
48#define SIO_REG_MFUNCT3 0x2b /* Multi function select 3 */
45#define SIO_REG_ENABLE 0x30 /* Logical device enable */ 49#define SIO_REG_ENABLE 0x30 /* Logical device enable */
46#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 50#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
47 51
48#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 52#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
49#define SIO_F71808_ID 0x0901 /* Chipset ID */ 53#define SIO_F71808_ID 0x0901 /* Chipset ID */
50#define SIO_F71858_ID 0x0507 /* Chipset ID */ 54#define SIO_F71858_ID 0x0507 /* Chipset ID */
51#define SIO_F71862_ID 0x0601 /* Chipset ID */ 55#define SIO_F71862_ID 0x0601 /* Chipset ID */
56#define SIO_F71869_ID 0x0814 /* Chipset ID */
52#define SIO_F71882_ID 0x0541 /* Chipset ID */ 57#define SIO_F71882_ID 0x0541 /* Chipset ID */
53#define SIO_F71889_ID 0x0723 /* Chipset ID */ 58#define SIO_F71889_ID 0x0723 /* Chipset ID */
54 59
55#define F71882FG_REG_START 0x01
56
57#define F71808FG_REG_WDO_CONF 0xf0 60#define F71808FG_REG_WDO_CONF 0xf0
58#define F71808FG_REG_WDT_CONF 0xf5 61#define F71808FG_REG_WDT_CONF 0xf5
59#define F71808FG_REG_WD_TIME 0xf6 62#define F71808FG_REG_WD_TIME 0xf6
@@ -70,13 +73,15 @@
70#define WATCHDOG_MAX_TIMEOUT (60 * 255) 73#define WATCHDOG_MAX_TIMEOUT (60 * 255)
71#define WATCHDOG_PULSE_WIDTH 125 /* 125 ms, default pulse width for 74#define WATCHDOG_PULSE_WIDTH 125 /* 125 ms, default pulse width for
72 watchdog signal */ 75 watchdog signal */
76#define WATCHDOG_F71862FG_PIN 63 /* default watchdog reset output
77 pin number 63 */
73 78
74static unsigned short force_id; 79static unsigned short force_id;
75module_param(force_id, ushort, 0); 80module_param(force_id, ushort, 0);
76MODULE_PARM_DESC(force_id, "Override the detected device ID"); 81MODULE_PARM_DESC(force_id, "Override the detected device ID");
77 82
78static const int max_timeout = WATCHDOG_MAX_TIMEOUT; 83static const int max_timeout = WATCHDOG_MAX_TIMEOUT;
79static int timeout = 60; /* default timeout in seconds */ 84static int timeout = WATCHDOG_TIMEOUT; /* default timeout in seconds */
80module_param(timeout, int, 0); 85module_param(timeout, int, 0);
81MODULE_PARM_DESC(timeout, 86MODULE_PARM_DESC(timeout,
82 "Watchdog timeout in seconds. 1<= timeout <=" 87 "Watchdog timeout in seconds. 1<= timeout <="
@@ -89,6 +94,12 @@ MODULE_PARM_DESC(pulse_width,
89 "Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms" 94 "Watchdog signal pulse width. 0(=level), 1 ms, 25 ms, 125 ms or 5000 ms"
90 " (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")"); 95 " (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")");
91 96
97static unsigned int f71862fg_pin = WATCHDOG_F71862FG_PIN;
98module_param(f71862fg_pin, uint, 0);
99MODULE_PARM_DESC(f71862fg_pin,
100 "Watchdog f71862fg reset output pin configuration. Choose pin 56 or 63"
101 " (default=" __MODULE_STRING(WATCHDOG_F71862FG_PIN)")");
102
92static int nowayout = WATCHDOG_NOWAYOUT; 103static int nowayout = WATCHDOG_NOWAYOUT;
93module_param(nowayout, bool, 0444); 104module_param(nowayout, bool, 0444);
94MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); 105MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
@@ -98,12 +109,13 @@ module_param(start_withtimeout, uint, 0);
98MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with" 109MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with"
99 " given initial timeout. Zero (default) disables this feature."); 110 " given initial timeout. Zero (default) disables this feature.");
100 111
101enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg }; 112enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg };
102 113
103static const char *f71808e_names[] = { 114static const char *f71808e_names[] = {
104 "f71808fg", 115 "f71808fg",
105 "f71858fg", 116 "f71858fg",
106 "f71862fg", 117 "f71862fg",
118 "f71869",
107 "f71882fg", 119 "f71882fg",
108 "f71889fg", 120 "f71889fg",
109}; 121};
@@ -282,6 +294,28 @@ exit_unlock:
282 return err; 294 return err;
283} 295}
284 296
297static int f71862fg_pin_configure(unsigned short ioaddr)
298{
299 /* When ioaddr is non-zero the calling function has to take care of
300 mutex handling and superio preparation! */
301
302 if (f71862fg_pin == 63) {
303 if (ioaddr) {
304 /* SPI must be disabled first to use this pin! */
305 superio_clear_bit(ioaddr, SIO_REG_ROM_ADDR_SEL, 6);
306 superio_set_bit(ioaddr, SIO_REG_MFUNCT3, 4);
307 }
308 } else if (f71862fg_pin == 56) {
309 if (ioaddr)
310 superio_set_bit(ioaddr, SIO_REG_MFUNCT1, 1);
311 } else {
312 printk(KERN_ERR DRVNAME ": Invalid argument f71862fg_pin=%d\n",
313 f71862fg_pin);
314 return -EINVAL;
315 }
316 return 0;
317}
318
285static int watchdog_start(void) 319static int watchdog_start(void)
286{ 320{
287 /* Make sure we don't die as soon as the watchdog is enabled below */ 321 /* Make sure we don't die as soon as the watchdog is enabled below */
@@ -299,13 +333,30 @@ static int watchdog_start(void)
299 switch (watchdog.type) { 333 switch (watchdog.type) {
300 case f71808fg: 334 case f71808fg:
301 /* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */ 335 /* Set pin 21 to GPIO23/WDTRST#, then to WDTRST# */
302 superio_clear_bit(watchdog.sioaddr, 0x2a, 3); 336 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT2, 3);
303 superio_clear_bit(watchdog.sioaddr, 0x2b, 3); 337 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT3, 3);
338 break;
339
340 case f71862fg:
341 err = f71862fg_pin_configure(watchdog.sioaddr);
342 if (err)
343 goto exit_superio;
344 break;
345
346 case f71869:
347 /* GPIO14 --> WDTRST# */
348 superio_clear_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 4);
304 break; 349 break;
305 350
306 case f71882fg: 351 case f71882fg:
307 /* Set pin 56 to WDTRST# */ 352 /* Set pin 56 to WDTRST# */
308 superio_set_bit(watchdog.sioaddr, 0x29, 1); 353 superio_set_bit(watchdog.sioaddr, SIO_REG_MFUNCT1, 1);
354 break;
355
356 case f71889fg:
357 /* set pin 40 to WDTRST# */
358 superio_outb(watchdog.sioaddr, SIO_REG_MFUNCT3,
359 superio_inb(watchdog.sioaddr, SIO_REG_MFUNCT3) & 0xcf);
309 break; 360 break;
310 361
311 default: 362 default:
@@ -705,14 +756,19 @@ static int __init f71808e_find(int sioaddr)
705 case SIO_F71808_ID: 756 case SIO_F71808_ID:
706 watchdog.type = f71808fg; 757 watchdog.type = f71808fg;
707 break; 758 break;
759 case SIO_F71862_ID:
760 watchdog.type = f71862fg;
761 err = f71862fg_pin_configure(0); /* validate module parameter */
762 break;
763 case SIO_F71869_ID:
764 watchdog.type = f71869;
765 break;
708 case SIO_F71882_ID: 766 case SIO_F71882_ID:
709 watchdog.type = f71882fg; 767 watchdog.type = f71882fg;
710 break; 768 break;
711 case SIO_F71862_ID:
712 case SIO_F71889_ID: 769 case SIO_F71889_ID:
713 /* These have a watchdog, though it isn't implemented (yet). */ 770 watchdog.type = f71889fg;
714 err = -ENOSYS; 771 break;
715 goto exit;
716 case SIO_F71858_ID: 772 case SIO_F71858_ID:
717 /* Confirmed (by datasheet) not to have a watchdog. */ 773 /* Confirmed (by datasheet) not to have a watchdog. */
718 err = -ENODEV; 774 err = -ENODEV;