info structure).
* status: this routine checks the status of the watchdog timer device. The
status of the device is reported with watchdog WDIOF_* status flags/bits.
+ WDIOF_MAGICCLOSE and WDIOF_KEEPALIVEPING are reported by the watchdog core;
+ it is not necessary to report those bits from the driver. Also, if no status
+ function is provided by the driver, the watchdog core reports the status bits
+ provided in the bootstatus variable of struct watchdog_device.
* set_timeout: this routine checks and changes the timeout of the watchdog
timer device. It returns 0 on success, -EINVAL for "parameter out of range"
and -EIO for "could not write value to the watchdog". On success this
unsigned long status; /* Internal status bits */
#define _WDOG_DEV_OPEN 0 /* Opened ? */
#define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */
+#define _WDOG_KEEPALIVE 2 /* Did we receive a keepalive ? */
};
/* the dev_t structure to store the dynamically allocated watchdog devices */
if (!watchdog_active(wdd) && !watchdog_hw_running(wdd))
return 0;
+ set_bit(_WDOG_KEEPALIVE, &wd_data->status);
+
wd_data->last_keepalive = jiffies;
return __watchdog_ping(wdd);
}
if (watchdog_active(wdd))
return 0;
+ set_bit(_WDOG_KEEPALIVE, &wd_data->status);
+
started_at = jiffies;
if (watchdog_hw_running(wdd) && wdd->ops->ping)
err = wdd->ops->ping(wdd);
static unsigned int watchdog_get_status(struct watchdog_device *wdd)
{
- if (!wdd->ops->status)
- return 0;
+ struct watchdog_core_data *wd_data = wdd->wd_data;
+ unsigned int status;
- return wdd->ops->status(wdd);
+ if (wdd->ops->status)
+ status = wdd->ops->status(wdd);
+ else
+ status = wdd->bootstatus & (WDIOF_CARDRESET |
+ WDIOF_OVERHEAT |
+ WDIOF_FANFAULT |
+ WDIOF_EXTERN1 |
+ WDIOF_EXTERN2 |
+ WDIOF_POWERUNDER |
+ WDIOF_POWEROVER);
+
+ if (test_bit(_WDOG_ALLOW_RELEASE, &wd_data->status))
+ status |= WDIOF_MAGICCLOSE;
+
+ if (test_and_clear_bit(_WDOG_KEEPALIVE, &wd_data->status))
+ status |= WDIOF_KEEPALIVEPING;
+
+ return status;
}
/*
status = watchdog_get_status(wdd);
mutex_unlock(&wd_data->lock);
- return sprintf(buf, "%u\n", status);
+ return sprintf(buf, "0x%x\n", status);
}
static DEVICE_ATTR_RO(status);
struct watchdog_device *wdd = dev_get_drvdata(dev);
umode_t mode = attr->mode;
- if (attr == &dev_attr_status.attr && !wdd->ops->status)
- mode = 0;
- else if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
+ if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft)
mode = 0;
return mode;