aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/interrupt.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-01-08 13:19:22 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-08 18:25:41 -0500
commit66ae460b13c31a176b41550259683c841a62af3e (patch)
treee923cdf7f4cc857bed6a5c74a5ca4c674034a37e /drivers/misc/mei/interrupt.c
parent544f94601409653f07ae6e22d4a39e3a90dceead (diff)
mei: use hbm idle state to prevent spurious resets
When reset is caused by hbm protocol mismatch or timeout we might end up in an endless reset loop and hbm protocol will never sync Cc: <stable@vger.kernel.org> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/interrupt.c')
-rw-r--r--drivers/misc/mei/interrupt.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index bbb61bec863b..206dbe99bedd 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -537,7 +537,6 @@ EXPORT_SYMBOL_GPL(mei_irq_write_handler);
537 * 537 *
538 * @work: pointer to the work_struct structure 538 * @work: pointer to the work_struct structure
539 * 539 *
540 * NOTE: This function is called by timer interrupt work
541 */ 540 */
542void mei_timer(struct work_struct *work) 541void mei_timer(struct work_struct *work)
543{ 542{
@@ -552,18 +551,24 @@ void mei_timer(struct work_struct *work)
552 551
553 552
554 mutex_lock(&dev->device_lock); 553 mutex_lock(&dev->device_lock);
555 if (dev->dev_state != MEI_DEV_ENABLED) { 554
556 if (dev->dev_state == MEI_DEV_INIT_CLIENTS) { 555 /* Catch interrupt stalls during HBM init handshake */
557 if (dev->init_clients_timer) { 556 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
558 if (--dev->init_clients_timer == 0) { 557 dev->hbm_state != MEI_HBM_IDLE) {
559 dev_err(&dev->pdev->dev, "reset: init clients timeout hbm_state = %d.\n", 558
560 dev->hbm_state); 559 if (dev->init_clients_timer) {
561 mei_reset(dev, 1); 560 if (--dev->init_clients_timer == 0) {
562 } 561 dev_err(&dev->pdev->dev, "timer: init clients timeout hbm_state = %d.\n",
562 dev->hbm_state);
563 mei_reset(dev, 1);
564 goto out;
563 } 565 }
564 } 566 }
565 goto out;
566 } 567 }
568
569 if (dev->dev_state != MEI_DEV_ENABLED)
570 goto out;
571
567 /*** connect/disconnect timeouts ***/ 572 /*** connect/disconnect timeouts ***/
568 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { 573 list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
569 if (cl_pos->timer_count) { 574 if (cl_pos->timer_count) {