summaryrefslogtreecommitdiffstats
path: root/drivers/staging/mei/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/mei/interrupt.c')
-rw-r--r--drivers/staging/mei/interrupt.c85
1 files changed, 54 insertions, 31 deletions
diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c
index 9cb186bf1874..882d106d54e5 100644
--- a/drivers/staging/mei/interrupt.c
+++ b/drivers/staging/mei/interrupt.c
@@ -396,6 +396,18 @@ static void mei_client_connect_response(struct mei_device *dev,
dev->wd_due_counter = (dev->wd_timeout) ? 1 : 0;
dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
+
+ /* Registering watchdog interface device once we got connection
+ to the WD Client
+ */
+ if (watchdog_register_device(&amt_wd_dev)) {
+ printk(KERN_ERR "mei: unable to register watchdog device.\n");
+ dev->wd_interface_reg = false;
+ } else {
+ dev_dbg(&dev->pdev->dev, "successfully register watchdog interface.\n");
+ dev->wd_interface_reg = true;
+ }
+
mei_host_init_iamthif(dev);
return;
}
@@ -641,6 +653,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
struct hbm_host_enum_response *enum_res;
struct hbm_client_disconnect_request *disconnect_req;
struct hbm_host_stop_request *host_stop_req;
+ int res;
unsigned char *buffer;
@@ -734,7 +747,38 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
MEI_CLIENT_PROPERTIES_MESSAGE) {
dev->me_client_index++;
dev->me_client_presentation_num++;
- mei_host_client_properties(dev);
+
+ /** Send Client Propeties request **/
+ res = mei_host_client_properties(dev);
+ if (res < 0) {
+ dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed");
+ return;
+ } else if (!res) {
+ /*
+ * No more clients to send to.
+ * Clear Map for indicating now ME clients
+ * with associated host client
+ */
+ bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
+ dev->open_handle_count = 0;
+
+ /*
+ * Reserving the first three client IDs
+ * Client Id 0 - Reserved for MEI Bus Message communications
+ * Client Id 1 - Reserved for Watchdog
+ * Client ID 2 - Reserved for AMTHI
+ */
+ bitmap_set(dev->host_clients_map, 0, 3);
+ dev->mei_state = MEI_ENABLED;
+
+ /* if wd initialization fails, initialization the AMTHI client,
+ * otherwise the AMTHI client will be initialized after the WD client connect response
+ * will be received
+ */
+ if (mei_wd_host_init(dev))
+ mei_host_init_iamthif(dev);
+ }
+
} else {
dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message");
mei_reset(dev, 1);
@@ -1381,7 +1425,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
*
* NOTE: This function is called by timer interrupt work
*/
-void mei_wd_timer(struct work_struct *work)
+void mei_timer(struct work_struct *work)
{
unsigned long timeout;
struct mei_cl *cl_pos = NULL;
@@ -1391,7 +1435,7 @@ void mei_wd_timer(struct work_struct *work)
struct mei_cl_cb *cb_next = NULL;
struct mei_device *dev = container_of(work,
- struct mei_device, wd_work.work);
+ struct mei_device, timer_work.work);
mutex_lock(&dev->device_lock);
@@ -1418,33 +1462,6 @@ void mei_wd_timer(struct work_struct *work)
}
}
- if (dev->wd_cl.state != MEI_FILE_CONNECTED)
- goto out;
-
- /* Watchdog */
- if (dev->wd_due_counter && !dev->wd_bypass) {
- if (--dev->wd_due_counter == 0) {
- if (dev->mei_host_buffer_is_empty &&
- mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
- dev->mei_host_buffer_is_empty = false;
- dev_dbg(&dev->pdev->dev, "send watchdog.\n");
-
- if (mei_wd_send(dev))
- dev_dbg(&dev->pdev->dev, "wd send failed.\n");
- else
- if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
- goto out;
-
- if (dev->wd_timeout)
- dev->wd_due_counter = 2;
- else
- dev->wd_due_counter = 0;
-
- } else
- dev->wd_pending = true;
-
- }
- }
if (dev->iamthif_stall_timer) {
if (--dev->iamthif_stall_timer == 0) {
dev_dbg(&dev->pdev->dev, "reseting because of hang to amthi.\n");
@@ -1510,7 +1527,7 @@ void mei_wd_timer(struct work_struct *work)
}
}
out:
- schedule_delayed_work(&dev->wd_work, 2 * HZ);
+ schedule_delayed_work(&dev->timer_work, 2 * HZ);
mutex_unlock(&dev->device_lock);
}
@@ -1540,6 +1557,12 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
mutex_lock(&dev->device_lock);
mei_io_list_init(&complete_list);
dev->host_hw_state = mei_hcsr_read(dev);
+
+ /* Ack the interrupt here
+ * In case of MSI we don't go throuhg the quick handler */
+ if (pci_dev_msi_enabled(dev->pdev))
+ mei_reg_write(dev, H_CSR, dev->host_hw_state);
+
dev->me_hw_state = mei_mecsr_read(dev);
/* check if ME wants a reset */