summaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/init.c')
-rw-r--r--drivers/misc/mei/init.c100
1 files changed, 61 insertions, 39 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 83c879b..87c077b 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -43,42 +43,6 @@ const char *mei_dev_state_str(int state)
#undef MEI_DEV_STATE
}
-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;
-
- mei_io_list_init(&dev->read_list);
- mei_io_list_init(&dev->write_list);
- 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);
-
- bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
- dev->open_handle_count = 0;
-
- /*
- * Reserving the first client ID
- * 0: Reserved for MEI Bus Message communications
- */
- bitmap_set(dev->host_clients_map, 0, 1);
-}
-EXPORT_SYMBOL_GPL(mei_device_init);
-
/**
* mei_start - initializes host and fw to start work.
*
@@ -131,10 +95,15 @@ err:
}
EXPORT_SYMBOL_GPL(mei_start);
-
+/**
+ * mei_cancel_work. Cancel mei background jobs
+ *
+ * @dev: the device structure
+ */
void mei_cancel_work(struct mei_device *dev)
{
cancel_work_sync(&dev->init_work);
+ cancel_work_sync(&dev->reset_work);
cancel_delayed_work(&dev->timer_work);
}
@@ -215,11 +184,27 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->dev_state = MEI_DEV_INIT_CLIENTS;
- mei_hbm_start_req(dev);
-
+ ret = mei_hbm_start_req(dev);
+ if (ret) {
+ dev_err(&dev->pdev->dev, "hbm_start failed disabling the device\n");
+ dev->dev_state = MEI_DEV_DISABLED;
+ return;
+ }
}
EXPORT_SYMBOL_GPL(mei_reset);
+static void mei_reset_work(struct work_struct *work)
+{
+ struct mei_device *dev =
+ container_of(work, struct mei_device, reset_work);
+
+ mutex_lock(&dev->device_lock);
+
+ mei_reset(dev, true);
+
+ mutex_unlock(&dev->device_lock);
+}
+
void mei_stop(struct mei_device *dev)
{
dev_dbg(&dev->pdev->dev, "stopping the device.\n");
@@ -243,3 +228,40 @@ EXPORT_SYMBOL_GPL(mei_stop);
+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;
+
+ mei_io_list_init(&dev->read_list);
+ mei_io_list_init(&dev->write_list);
+ 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_WORK(&dev->reset_work, mei_reset_work);
+
+ 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);
+
+ bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
+ dev->open_handle_count = 0;
+
+ /*
+ * Reserving the first client ID
+ * 0: Reserved for MEI Bus Message communications
+ */
+ bitmap_set(dev->host_clients_map, 0, 1);
+}
+EXPORT_SYMBOL_GPL(mei_device_init);
+
OpenPOWER on IntegriCloud