diff options
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;  }  |