diff options
Diffstat (limited to 'drivers/misc/mei/init.c')
| -rw-r--r-- | drivers/misc/mei/init.c | 70 | 
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 356179991a2..713d89fedc4 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -14,6 +14,7 @@   *   */ +#include <linux/export.h>  #include <linux/pci.h>  #include <linux/sched.h>  #include <linux/wait.h> @@ -22,6 +23,7 @@  #include <linux/mei.h>  #include "mei_dev.h" +#include "hbm.h"  #include "client.h"  const char *mei_dev_state_str(int state) @@ -31,9 +33,8 @@ const char *mei_dev_state_str(int state)  	MEI_DEV_STATE(INITIALIZING);  	MEI_DEV_STATE(INIT_CLIENTS);  	MEI_DEV_STATE(ENABLED); -	MEI_DEV_STATE(RESETING); +	MEI_DEV_STATE(RESETTING);  	MEI_DEV_STATE(DISABLED); -	MEI_DEV_STATE(RECOVERING_FROM_RESET);  	MEI_DEV_STATE(POWER_DOWN);  	MEI_DEV_STATE(POWER_UP);  	default: @@ -46,7 +47,9 @@ void mei_device_init(struct mei_device *dev)  {  	/* setup our list array */  	INIT_LIST_HEAD(&dev->file_list); +	INIT_LIST_HEAD(&dev->device_list);  	mutex_init(&dev->device_lock); +	init_waitqueue_head(&dev->wait_hw_ready);  	init_waitqueue_head(&dev->wait_recvd_msg);  	init_waitqueue_head(&dev->wait_stop_wd);  	dev->dev_state = MEI_DEV_INITIALIZING; @@ -56,19 +59,27 @@ void mei_device_init(struct mei_device *dev)  	mei_io_list_init(&dev->write_waiting_list);  	mei_io_list_init(&dev->ctrl_wr_list);  	mei_io_list_init(&dev->ctrl_rd_list); + +	INIT_DELAYED_WORK(&dev->timer_work, mei_timer); +	INIT_WORK(&dev->init_work, mei_host_client_init); + +	INIT_LIST_HEAD(&dev->wd_cl.link); +	INIT_LIST_HEAD(&dev->iamthif_cl.link); +	mei_io_list_init(&dev->amthif_cmd_list); +	mei_io_list_init(&dev->amthif_rd_complete_list); +  } +EXPORT_SYMBOL_GPL(mei_device_init);  /** - * mei_hw_init - initializes host and fw to start work. + * mei_start - initializes host and fw to start work.   *   * @dev: the device structure   *   * returns 0 on success, <0 on failure.   */ -int mei_hw_init(struct mei_device *dev) +int mei_start(struct mei_device *dev)  { -	int ret = 0; -  	mutex_lock(&dev->device_lock);  	/* acknowledge interrupt and stop interupts */ @@ -76,29 +87,15 @@ int mei_hw_init(struct mei_device *dev)  	mei_hw_config(dev); -	dev->recvd_msg = false;  	dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");  	mei_reset(dev, 1); -	/* wait for ME to turn on ME_RDY */ -	if (!dev->recvd_msg) { -		mutex_unlock(&dev->device_lock); -		ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, -			dev->recvd_msg, -			mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); -		mutex_lock(&dev->device_lock); -	} - -	if (ret <= 0 && !dev->recvd_msg) { -		dev->dev_state = MEI_DEV_DISABLED; -		dev_dbg(&dev->pdev->dev, -			"wait_event_interruptible_timeout failed" -			"on wait for ME to turn on ME_RDY.\n"); +	if (mei_hbm_start_wait(dev)) { +		dev_err(&dev->pdev->dev, "HBM haven't started");  		goto err;  	} -  	if (!mei_host_is_ready(dev)) {  		dev_err(&dev->pdev->dev, "host is not ready.\n");  		goto err; @@ -115,7 +112,6 @@ int mei_hw_init(struct mei_device *dev)  		goto err;  	} -	dev->recvd_msg = false;  	dev_dbg(&dev->pdev->dev, "link layer has been established.\n");  	mutex_unlock(&dev->device_lock); @@ -126,6 +122,7 @@ err:  	mutex_unlock(&dev->device_lock);  	return -ENODEV;  } +EXPORT_SYMBOL_GPL(mei_start);  /**   * mei_reset - resets host and fw. @@ -137,9 +134,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)  {  	bool unexpected; -	if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) -		return; -  	unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&  			dev->dev_state != MEI_DEV_DISABLED &&  			dev->dev_state != MEI_DEV_POWER_DOWN && @@ -147,11 +141,12 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)  	mei_hw_reset(dev, interrupts_enabled); +	dev->hbm_state = MEI_HBM_IDLE;  	if (dev->dev_state != MEI_DEV_INITIALIZING) {  		if (dev->dev_state != MEI_DEV_DISABLED &&  		    dev->dev_state != MEI_DEV_POWER_DOWN) -			dev->dev_state = MEI_DEV_RESETING; +			dev->dev_state = MEI_DEV_RESETTING;  		mei_cl_all_disconnect(dev); @@ -176,12 +171,27 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)  		dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",  			 mei_dev_state_str(dev->dev_state)); +	if (!interrupts_enabled) { +		dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n"); +		return; +	} + +	mei_hw_start(dev); + +	dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); +	/* link is established * start sending messages.  */ + +	dev->dev_state = MEI_DEV_INIT_CLIENTS; + +	mei_hbm_start_req(dev); +  	/* wake up all readings so they can be interrupted */  	mei_cl_all_read_wakeup(dev);  	/* remove all waiting requests */  	mei_cl_all_write_clear(dev);  } +EXPORT_SYMBOL_GPL(mei_reset);  void mei_stop(struct mei_device *dev)  { @@ -193,14 +203,18 @@ void mei_stop(struct mei_device *dev)  	mei_wd_stop(dev); +	mei_nfc_host_exit(); +  	dev->dev_state = MEI_DEV_POWER_DOWN;  	mei_reset(dev, 0);  	mutex_unlock(&dev->device_lock);  	flush_scheduled_work(); -} +	mei_watchdog_unregister(dev); +} +EXPORT_SYMBOL_GPL(mei_stop);  | 
