diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 12:09:59 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-01 12:09:59 -0700 |
commit | 3aebd34b1200a902a8662da8845824a02f00772e (patch) | |
tree | 13eac224dc1ac40be53bccc90f27bebf2e619c26 /drivers/misc/mei/wd.c | |
parent | 2c0c86d5b67ee04e8b71a2ea2a3af6d224611cfc (diff) | |
parent | 5dc2db05f2f690d71d95979b14cca50ab8e49f40 (diff) |
Merge tag 'char-misc-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver merge from Greg Kroah-Hartman:
"Here is the "big" char/misc driver tree update for the 3.7-rc1 merge
window.
Nothing major, just a number of driver updates and fixes, all of which
have been in the linux-next releases for a while now either in my
tree, or in Andrew's (the lis3l driver changes came from his tree last
week).
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
* tag 'char-misc-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (52 commits)
drivers/misc/lis3lv02d/lis3lv02d_i2c.c: add lis3lv02d device tree init
drivers/misc/lis3lv02d/lis3lv02d_spi.c: add lis3lv02d device tree init
drivers/misc/lis3lv02d: remove lis3lv02d driver DT init
drivers/misc/lis3lv02d/lis3lv02d_spi.c: add DT matching table passthru code
drivers/misc/lis3lv02d: add generic DT matching code
lis3lv02d: fix some comments specific to lis331dlh driver
MISC: hpilo, remove pci_disable_device
pcmcia: synclink_cs: fix potential tty NULL dereference
drivers/char/mmtimer.c: Remove useless kfree
drivers/char: removes unnecessary semicolon
char/misc: remove CONFIG_EXPERIMENTAL dependencies
mei: don't print buffer as a string
mei: struct mei_message_data doesn't have to be packed
mei: add error messages for open count errors
misc: use module_spi_driver
tifm: use module_pci_driver
misc/at25, dt: Improve at25 SPI eeprom device tree bindings.
mei: add lynx point pci device ids
mei: fix max number of open handles
mei: rename struct pci_dev *mei_device to mei_pdev
...
Diffstat (limited to 'drivers/misc/mei/wd.c')
-rw-r--r-- | drivers/misc/mei/wd.c | 91 |
1 files changed, 48 insertions, 43 deletions
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 5133fd77b91..d96c537f046 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; } |