summaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/wd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/wd.c')
-rw-r--r--drivers/misc/mei/wd.c91
1 files changed, 48 insertions, 43 deletions
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 5133fd7..d96c537 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -48,8 +48,8 @@ const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89,
static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
{
dev_dbg(&dev->pdev->dev, "wd: set timeout=%d.\n", timeout);
- memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE);
- memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16));
+ memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE);
+ memcpy(dev->wd_data + MEI_WD_HDR_SIZE, &timeout, sizeof(u16));
}
/**
@@ -66,10 +66,11 @@ int mei_wd_host_init(struct mei_device *dev)
/* look for WD client and connect to it */
dev->wd_cl.state = MEI_FILE_DISCONNECTED;
- dev->wd_timeout = AMT_WD_DEFAULT_TIMEOUT;
+ dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
+ dev->wd_state = MEI_WD_IDLE;
/* find ME WD client */
- mei_find_me_client_update_filext(dev, &dev->wd_cl,
+ mei_me_cl_update_filext(dev, &dev->wd_cl,
&mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
dev_dbg(&dev->pdev->dev, "wd: check client\n");
@@ -108,10 +109,10 @@ int mei_wd_send(struct mei_device *dev)
mei_hdr->msg_complete = 1;
mei_hdr->reserved = 0;
- if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE))
- mei_hdr->length = MEI_START_WD_DATA_SIZE;
- else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE))
- mei_hdr->length = MEI_WD_PARAMS_SIZE;
+ if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE))
+ mei_hdr->length = MEI_WD_START_MSG_SIZE;
+ else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE))
+ mei_hdr->length = MEI_WD_STOP_MSG_SIZE;
else
return -EINVAL;
@@ -128,18 +129,17 @@ int mei_wd_send(struct mei_device *dev)
* -EIO when message send fails
* -EINVAL when invalid message is to be sent
*/
-int mei_wd_stop(struct mei_device *dev, bool preserve)
+int mei_wd_stop(struct mei_device *dev)
{
int ret;
- u16 wd_timeout = dev->wd_timeout;
- cancel_delayed_work(&dev->timer_work);
- if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout)
+ if (dev->wd_cl.state != MEI_FILE_CONNECTED ||
+ dev->wd_state != MEI_WD_RUNNING)
return 0;
- dev->wd_timeout = 0;
- memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE);
- dev->stop = true;
+ memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_STOP_MSG_SIZE);
+
+ dev->wd_state = MEI_WD_STOPPING;
ret = mei_flow_ctrl_creds(dev, &dev->wd_cl);
if (ret < 0)
@@ -161,13 +161,14 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
} else {
dev->wd_pending = true;
}
- dev->wd_stopped = false;
+
mutex_unlock(&dev->device_lock);
ret = wait_event_interruptible_timeout(dev->wait_stop_wd,
- dev->wd_stopped, 10 * HZ);
+ dev->wd_state == MEI_WD_IDLE,
+ msecs_to_jiffies(MEI_WD_STOP_TIMEOUT));
mutex_lock(&dev->device_lock);
- if (dev->wd_stopped) {
+ if (dev->wd_state == MEI_WD_IDLE) {
dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret);
ret = 0;
} else {
@@ -177,9 +178,6 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
"wd: stop failed to complete ret=%d.\n", ret);
}
- if (preserve)
- dev->wd_timeout = wd_timeout;
-
out:
return ret;
}
@@ -196,16 +194,16 @@ static int mei_wd_ops_start(struct watchdog_device *wd_dev)
int err = -ENODEV;
struct mei_device *dev;
- dev = pci_get_drvdata(mei_device);
+ dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
mutex_lock(&dev->device_lock);
- if (dev->mei_state != MEI_ENABLED) {
+ if (dev->dev_state != MEI_DEV_ENABLED) {
dev_dbg(&dev->pdev->dev,
- "wd: mei_state != MEI_ENABLED mei_state = %d\n",
- dev->mei_state);
+ "wd: dev_state != MEI_DEV_ENABLED dev_state = %s\n",
+ mei_dev_state_str(dev->dev_state));
goto end_unlock;
}
@@ -233,13 +231,13 @@ end_unlock:
static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
{
struct mei_device *dev;
- dev = pci_get_drvdata(mei_device);
+ dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
mutex_lock(&dev->device_lock);
- mei_wd_stop(dev, false);
+ mei_wd_stop(dev);
mutex_unlock(&dev->device_lock);
return 0;
@@ -256,8 +254,8 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
{
int ret = 0;
struct mei_device *dev;
- dev = pci_get_drvdata(mei_device);
+ dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
@@ -269,6 +267,8 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
goto end;
}
+ dev->wd_state = MEI_WD_RUNNING;
+
/* Check if we can send the ping to HW*/
if (dev->mei_host_buffer_is_empty &&
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
@@ -309,13 +309,13 @@ end:
static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout)
{
struct mei_device *dev;
- dev = pci_get_drvdata(mei_device);
+ dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
/* Check Timeout value */
- if (timeout < AMT_WD_MIN_TIMEOUT || timeout > AMT_WD_MAX_TIMEOUT)
+ if (timeout < MEI_WD_MIN_TIMEOUT || timeout > MEI_WD_MAX_TIMEOUT)
return -EINVAL;
mutex_lock(&dev->device_lock);
@@ -341,37 +341,42 @@ static const struct watchdog_ops wd_ops = {
};
static const struct watchdog_info wd_info = {
.identity = INTEL_AMT_WATCHDOG_ID,
- .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY,
+ .options = WDIOF_KEEPALIVEPING |
+ WDIOF_SETTIMEOUT |
+ WDIOF_ALARMONLY,
};
static struct watchdog_device amt_wd_dev = {
.info = &wd_info,
.ops = &wd_ops,
- .timeout = AMT_WD_DEFAULT_TIMEOUT,
- .min_timeout = AMT_WD_MIN_TIMEOUT,
- .max_timeout = AMT_WD_MAX_TIMEOUT,
+ .timeout = MEI_WD_DEFAULT_TIMEOUT,
+ .min_timeout = MEI_WD_MIN_TIMEOUT,
+ .max_timeout = MEI_WD_MAX_TIMEOUT,
};
-void mei_watchdog_register(struct mei_device *dev)
+void mei_watchdog_register(struct mei_device *dev)
{
- dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout);
-
if (watchdog_register_device(&amt_wd_dev)) {
dev_err(&dev->pdev->dev,
"wd: unable to register watchdog device.\n");
dev->wd_interface_reg = false;
- } else {
- dev_dbg(&dev->pdev->dev,
- "wd: successfully register watchdog interface.\n");
- dev->wd_interface_reg = true;
+ return;
}
+
+ dev_dbg(&dev->pdev->dev,
+ "wd: successfully register watchdog interface.\n");
+ dev->wd_interface_reg = true;
+ watchdog_set_drvdata(&amt_wd_dev, dev);
}
void mei_watchdog_unregister(struct mei_device *dev)
{
- if (dev->wd_interface_reg)
- watchdog_unregister_device(&amt_wd_dev);
+ if (!dev->wd_interface_reg)
+ return;
+
+ watchdog_set_drvdata(&amt_wd_dev, NULL);
+ watchdog_unregister_device(&amt_wd_dev);
dev->wd_interface_reg = false;
}
OpenPOWER on IntegriCloud