static int wdt_disable(void) { wdt_ctrl(0); return 0; }
static int wdt_ctrl(enum wdt_ctrl ctrl, enum wdt_event type, unsigned int timeout) { u16 val; int ret; struct ec_message msg = { .rlen = 0, .wlen = 0, }; u8 *fevent = &msg.u.data[0]; struct wdt_event_delay *event = (struct wdt_event_delay *)&msg.u.data[1]; switch (ctrl) { case SET_TIMEOUT: memset(event, 0xff, sizeof(*event)); msg.wlen = sizeof(*event); *fevent = 0; val = (!timeout) ? 0xffff : swab16(timeout * WDT_FREQ); switch (type) { case DELAY: event->delay = val; break; case PWRBTN: event->pwrbtn = val; break; case NMI: event->nmi = val; break; case RESET: event->reset = val; break; case WDPIN: event->wdpin = val; break; case SCI: event->sci = val; break; default: return -EINVAL; } ret = imanager_msg_write(EC_CMD_WDT_CTRL, SET_TIMEOUT, &msg); if (ret < 0) { pr_err("Failed to set timeout\n"); return ret; } break; case START: case STOP: case RST: case STOPBOOT: /* simple command, no data */ return imanager_msg_write(EC_CMD_WDT_CTRL, ctrl, NULL); default: return -EINVAL; } return timeout; } int wdt_core_start_timer(void) { return set_timer(START); } int wdt_core_stop_timer(void) { return set_timer(STOP); } int wdt_core_reset_timer(void) { return set_timer(RST); } int wdt_core_stop_boot_timer(void) { return set_timer(STOPBOOT); } inline int wdt_core_set_timeout(enum wdt_event type, u32 timeout) { return wdt_ctrl(SET_TIMEOUT, type, timeout); } int wdt_core_disable_all(void) { struct ec_message msg = { .rlen = 0, .wlen = sizeof(struct wdt_event_delay), }; struct wdt_event_delay *event = (struct wdt_event_delay *)&msg.u.data[1]; memset(event, 0xff, sizeof(*event)); return (wdt_core_stop_timer() || wdt_core_stop_boot_timer() || imanager_msg_write(EC_CMD_WDT_CTRL, SET_TIMEOUT, &msg)); } int wdt_core_init(void) { wd = imanager_get_watchdog_device(); if (!wd) return -ENODEV; return 0; }
static int wdt_ping(void) { wdt_ctrl(timeout); return 0; }