diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2020-07-27 21:58:41 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-07-27 21:58:41 +0200 |
commit | 8b0bf1ee077715ceb0535fbda799038ea62baef8 (patch) | |
tree | 2ef39a48cc78e4b2ec9d37643d4f7c6c320f0341 /drivers/watchdog | |
parent | 67f0e7aedefcb06b38ef50ddd32b0a280bbb10e8 (diff) | |
parent | a66ffa8dab14b82f9f9edddb03d6358b861ff5c0 (diff) | |
download | barebox-8b0bf1ee077715ceb0535fbda799038ea62baef8.tar.gz barebox-8b0bf1ee077715ceb0535fbda799038ea62baef8.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/f71808e_wdt.c | 59 | ||||
-rw-r--r-- | drivers/watchdog/rave-sp-wdt.c | 5 |
2 files changed, 41 insertions, 23 deletions
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 6f2d30ec77..925c2f809d 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -11,7 +11,6 @@ #include <init.h> #include <asm/io.h> -#include <linux/bitops.h> #include <driver.h> #include <watchdog.h> #include <printk.h> @@ -114,30 +113,50 @@ static inline void superio_exit(u16 base) outb(SIO_LOCK_KEY, base); } +static inline u8 f71808e_wdt_conf_in(struct f71808e_wdt *wd) +{ + return superio_inb(wd->sioaddr, F71808FG_REG_WDT_CONF); +} + +static inline void f71808e_wdt_conf_out(struct f71808e_wdt *wd, u8 wdt_conf) +{ + /* + * Writing 1 to WDTMOUT_STS clears it. Writing 0 keeps the old state. + * We want the latter, so the OS driver can check it later on. + */ + wdt_conf &= ~BIT(F71808FG_FLAG_WDTMOUT_STS); + superio_outb(wd->sioaddr, F71808FG_REG_WDT_CONF, wdt_conf); +} + static void f71808e_wdt_keepalive(struct f71808e_wdt *wd) { + u8 wdt_conf; + superio_enter(wd->sioaddr); superio_select(wd->sioaddr, SIO_F71808FG_LD_WDT); + wdt_conf = f71808e_wdt_conf_in(wd); + if (wd->minutes_mode) /* select minutes for timer units */ - superio_set_bit(wd->sioaddr, F71808FG_REG_WDT_CONF, - F71808FG_FLAG_WD_UNIT); + wdt_conf |= BIT(F71808FG_FLAG_WD_UNIT); else /* select seconds for timer units */ - superio_clear_bit(wd->sioaddr, F71808FG_REG_WDT_CONF, - F71808FG_FLAG_WD_UNIT); + wdt_conf &= ~BIT(F71808FG_FLAG_WD_UNIT); + + f71808e_wdt_conf_out(wd, wdt_conf); /* Set timer value */ - superio_outb(wd->sioaddr, F71808FG_REG_WD_TIME, - wd->timer_val); + superio_outb(wd->sioaddr, F71808FG_REG_WD_TIME, wd->timer_val); superio_exit(wd->sioaddr); } static void f71808e_wdt_start(struct f71808e_wdt *wd) { + u8 wdt_conf; + /* Make sure we don't die as soon as the watchdog is enabled below */ f71808e_wdt_keepalive(wd); @@ -158,36 +177,38 @@ static void f71808e_wdt_start(struct f71808e_wdt *wd) superio_set_bit(wd->sioaddr, F71808FG_REG_WDO_CONF, F71808FG_FLAG_WDOUT_EN); - superio_set_bit(wd->sioaddr, F71808FG_REG_WDT_CONF, - F71808FG_FLAG_WD_EN); + wdt_conf = f71808e_wdt_conf_in(wd); + wdt_conf |= BIT(F71808FG_FLAG_WD_EN); + f71808e_wdt_conf_out(wd, wdt_conf); if (wd->pulse_width > 0) { /* Select "pulse" output mode with given duration */ - u8 wdt_conf = superio_inb(wd->sioaddr, F71808FG_REG_WDT_CONF); - /* Set WD_PSWIDTH bits (1:0) */ wdt_conf = (wdt_conf & 0xfc) | (wd->pulse_width & 0x03); /* Set WD_PULSE to "pulse" mode */ wdt_conf |= BIT(F71808FG_FLAG_WD_PULSE); - superio_outb(wd->sioaddr, F71808FG_REG_WDT_CONF, wdt_conf); } else { /* Select "level" output mode */ - superio_clear_bit(wd->sioaddr, F71808FG_REG_WDT_CONF, - F71808FG_FLAG_WD_PULSE); + wdt_conf &= ~BIT(F71808FG_FLAG_WD_PULSE); } + f71808e_wdt_conf_out(wd, wdt_conf); + superio_exit(wd->sioaddr); } static void f71808e_wdt_stop(struct f71808e_wdt *wd) { + u8 wdt_conf; + superio_enter(wd->sioaddr); superio_select(wd->sioaddr, SIO_F71808FG_LD_WDT); - superio_clear_bit(wd->sioaddr, F71808FG_REG_WDT_CONF, - F71808FG_FLAG_WD_EN); + wdt_conf = f71808e_wdt_conf_in(wd); + wdt_conf &= ~BIT(F71808FG_FLAG_WD_EN); + f71808e_wdt_conf_out(wd, wdt_conf); superio_exit(wd->sioaddr); } @@ -222,14 +243,14 @@ static int f71808e_wdt_init(struct f71808e_wdt *wd, struct device_d *dev) { struct watchdog *wdd = &wd->wdd; const char * const *names = pulse_width_names; - unsigned long wdt_conf; + u8 wdt_conf; int ret; superio_enter(wd->sioaddr); superio_select(wd->sioaddr, SIO_F71808FG_LD_WDT); - wdt_conf = superio_inb(wd->sioaddr, F71808FG_REG_WDT_CONF); + wdt_conf = f71808e_wdt_conf_in(wd); superio_exit(wd->sioaddr); @@ -262,7 +283,7 @@ static int f71808e_wdt_init(struct f71808e_wdt *wd, struct device_d *dev) } - if (test_bit(F71808FG_FLAG_WD_EN, &wdt_conf)) + if (wdt_conf & BIT(F71808FG_FLAG_WD_EN)) wdd->running = WDOG_HW_RUNNING; else wdd->running = WDOG_HW_NOT_RUNNING; diff --git a/drivers/watchdog/rave-sp-wdt.c b/drivers/watchdog/rave-sp-wdt.c index dc673ee35f..cad63e22f9 100644 --- a/drivers/watchdog/rave-sp-wdt.c +++ b/drivers/watchdog/rave-sp-wdt.c @@ -299,10 +299,7 @@ static int rave_sp_wdt_add_params(struct rave_sp_wdt *sp_wd) rave_sp_wdt_set_boot_source, rave_sp_wdt_get_boot_source, &sp_wd->boot_source, "%u", sp_wd); - if (IS_ERR(p)) - return PTR_ERR(p); - - return 0; + return PTR_ERR_OR_ZERO(p); } static int rave_sp_wdt_probe(struct device_d *dev) |