
* use test_and_set_bit and __clear_bit to access twl4030 i2c bus only once at same time * do not reset watchdog too often (max every 2 seconds) --- board/nokia/rx51/rx51.c | 25 +++++++++++++++++++++++-- include/configs/nokia_rx51.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c index 96e65d6..a90e4dd 100644 --- a/board/nokia/rx51/rx51.c +++ b/board/nokia/rx51/rx51.c @@ -36,6 +36,7 @@ #include <i2c.h> #include <video_fb.h> #include <asm/io.h> +#include <asm/bitops.h> #include <asm/arch/mux.h> #include <asm/arch/sys_proto.h> #include <asm/omap_gpio.h> @@ -192,6 +193,23 @@ int rx51_kp_init(void) return ret; }
+static unsigned long int twl_wd_start = 0; +static volatile unsigned long int twl_chip_lock; + +void hw_watchdog_reset(void) +{ + + if ( get_timer(twl_wd_start) < 2 * CONFIG_SYS_HZ ) + return; + + if ( test_and_set_bit(0, &twl_chip_lock) ) + return; + twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 31, TWL4030_PM_RECEIVER_WATCHDOG_CFG); + __clear_bit(0, &twl_chip_lock); + + twl_wd_start = get_timer(0); +} + char rx51_kp_fill(u8 k, u8 mods) { if (mods & 2) { /* fn */ @@ -217,6 +235,9 @@ int rx51_kp_tstc(void) u8 intr; u8 mods;
+ if ( test_and_set_bit(0, &twl_chip_lock) ) + return 0; + /* twl4030 remembers up to 2 events */ for (i = 0; i < 2; i++) {
@@ -249,6 +270,7 @@ int rx51_kp_tstc(void) } } } + __clear_bit(0, &twl_chip_lock); return (KEYBUF_SIZE + keybuf_tail - keybuf_head)%KEYBUF_SIZE; }
@@ -256,7 +278,6 @@ int rx51_kp_getc(void) { keybuf_head %= KEYBUF_SIZE; while (!rx51_kp_tstc()) - ; + udelay(10000); return keybuf[keybuf_head++]; } - diff --git a/include/configs/nokia_rx51.h b/include/configs/nokia_rx51.h index 6da56f5..6d93146 100644 --- a/include/configs/nokia_rx51.h +++ b/include/configs/nokia_rx51.h @@ -144,6 +144,7 @@ #define CONFIG_SYS_I2C_BUS 0 #define CONFIG_SYS_I2C_BUS_SELECT 1 #define CONFIG_DRIVER_OMAP34XX_I2C 1 +#define CONFIG_HW_WATCHDOG
/* * TWL4030