aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/init.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/init.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/init.c')
-rw-r--r--drivers/misc/mei/init.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 87c077bae5d8..c47fa273879e 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -129,14 +129,19 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
129 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", 129 dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
130 mei_dev_state_str(dev->dev_state)); 130 mei_dev_state_str(dev->dev_state));
131 131
132 /* we're already in reset, cancel the init timer
133 * if the reset was called due the hbm protocol error
134 * we need to call it before hw start
135 * so the hbm watchdog won't kick in
136 */
137 mei_hbm_idle(dev);
138
132 ret = mei_hw_reset(dev, interrupts_enabled); 139 ret = mei_hw_reset(dev, interrupts_enabled);
133 if (ret) { 140 if (ret) {
134 dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n"); 141 dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
135 interrupts_enabled = false; 142 interrupts_enabled = false;
136 dev->dev_state = MEI_DEV_DISABLED;
137 } 143 }
138 144
139 dev->hbm_state = MEI_HBM_IDLE;
140 145
141 if (dev->dev_state != MEI_DEV_INITIALIZING && 146 if (dev->dev_state != MEI_DEV_INITIALIZING &&
142 dev->dev_state != MEI_DEV_POWER_UP) { 147 dev->dev_state != MEI_DEV_POWER_UP) {
@@ -160,8 +165,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
160 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); 165 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
161 } 166 }
162 167
163 /* we're already in reset, cancel the init timer */
164 dev->init_clients_timer = 0;
165 168
166 dev->me_clients_num = 0; 169 dev->me_clients_num = 0;
167 dev->rd_msg_hdr = 0; 170 dev->rd_msg_hdr = 0;
@@ -169,6 +172,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
169 172
170 if (!interrupts_enabled) { 173 if (!interrupts_enabled) {
171 dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n"); 174 dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n");
175 dev->dev_state = MEI_DEV_DISABLED;
172 return; 176 return;
173 } 177 }
174 178