diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2012-08-16 19:39:43 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-16 09:51:02 -0700 |
commit | c216fdeb2e7371554c56ba457c374cce9c77f91a (patch) | |
tree | 9d88b3170a5470844e61ac90a30fd923d50df14b /drivers/misc/mei/wd.c | |
parent | 248ffdf7c95726a8dae76e25fdb037899c5b77fa (diff) |
mei: wd: decouple and revamp watchdog state machine
Before ME watchdog was exported through standard watchdog interface
it was closed and started together with the mei device.
The major issue is that closing ME watchdog disabled also MEI device,
to fix this the watchdog state machine has to be independent from MEI
state machine.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/wd.c')
-rw-r--r-- | drivers/misc/mei/wd.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 755a58305a7..0824166a730 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -67,6 +67,7 @@ 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 = MEI_WD_DEFAULT_TIMEOUT; + dev->wd_state = MEI_WD_IDLE; /* find ME WD client */ mei_me_cl_update_filext(dev, &dev->wd_cl, @@ -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_STOP_MSG_SIZE); - dev->stop = true; + + 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; } @@ -239,7 +237,7 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev) return -ENODEV; mutex_lock(&dev->device_lock); - mei_wd_stop(dev, false); + mei_wd_stop(dev); mutex_unlock(&dev->device_lock); return 0; @@ -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) { |