diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/watchdog/f71808e_wdt.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (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.c | 82 |
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 | ||
74 | static unsigned short force_id; | 79 | static unsigned short force_id; |
75 | module_param(force_id, ushort, 0); | 80 | module_param(force_id, ushort, 0); |
76 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 81 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
77 | 82 | ||
78 | static const int max_timeout = WATCHDOG_MAX_TIMEOUT; | 83 | static const int max_timeout = WATCHDOG_MAX_TIMEOUT; |
79 | static int timeout = 60; /* default timeout in seconds */ | 84 | static int timeout = WATCHDOG_TIMEOUT; /* default timeout in seconds */ |
80 | module_param(timeout, int, 0); | 85 | module_param(timeout, int, 0); |
81 | MODULE_PARM_DESC(timeout, | 86 | MODULE_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 | ||
97 | static unsigned int f71862fg_pin = WATCHDOG_F71862FG_PIN; | ||
98 | module_param(f71862fg_pin, uint, 0); | ||
99 | MODULE_PARM_DESC(f71862fg_pin, | ||
100 | "Watchdog f71862fg reset output pin configuration. Choose pin 56 or 63" | ||
101 | " (default=" __MODULE_STRING(WATCHDOG_F71862FG_PIN)")"); | ||
102 | |||
92 | static int nowayout = WATCHDOG_NOWAYOUT; | 103 | static int nowayout = WATCHDOG_NOWAYOUT; |
93 | module_param(nowayout, bool, 0444); | 104 | module_param(nowayout, bool, 0444); |
94 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | 105 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); |
@@ -98,12 +109,13 @@ module_param(start_withtimeout, uint, 0); | |||
98 | MODULE_PARM_DESC(start_withtimeout, "Start watchdog timer on module load with" | 109 | MODULE_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 | ||
101 | enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg }; | 112 | enum chips { f71808fg, f71858fg, f71862fg, f71869, f71882fg, f71889fg }; |
102 | 113 | ||
103 | static const char *f71808e_names[] = { | 114 | static 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 | ||
297 | static 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 | |||
285 | static int watchdog_start(void) | 319 | static 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; |