aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-03-10 07:56:08 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-15 14:18:07 -0400
commit7cb035d9e619a8d20f5d3b9791f8cb5160d19e70 (patch)
treee4dd1bb6addf4dc4e49370cbcfb5a1cdabe49174 /drivers/misc/mei
parent3d374d09f16f64ab4d71704cbe621514d36cd0b1 (diff)
mei: add mei_stop function to stop mei device
mei_stop calls mei_reset with disabling the interrupts. It will have the same effect as the open code it replaces in the mei_remove. The reset sequence on remove is required for the Lynx Point LP devices to clean the reset state. mei_stop is called from mei_pci_suspend and mei_remove functions Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/init.c18
-rw-r--r--drivers/misc/mei/mei_dev.h1
-rw-r--r--drivers/misc/mei/pci-me.c52
3 files changed, 26 insertions, 45 deletions
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 6ec530168afb..356179991a2e 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -183,6 +183,24 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
183 mei_cl_all_write_clear(dev); 183 mei_cl_all_write_clear(dev);
184} 184}
185 185
186void mei_stop(struct mei_device *dev)
187{
188 dev_dbg(&dev->pdev->dev, "stopping the device.\n");
189
190 mutex_lock(&dev->device_lock);
191
192 cancel_delayed_work(&dev->timer_work);
193
194 mei_wd_stop(dev);
195
196 dev->dev_state = MEI_DEV_POWER_DOWN;
197 mei_reset(dev, 0);
198
199 mutex_unlock(&dev->device_lock);
200
201 flush_scheduled_work();
202}
203
186 204
187 205
188 206
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index cb80166161f0..97873812e33b 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -381,6 +381,7 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
381void mei_device_init(struct mei_device *dev); 381void mei_device_init(struct mei_device *dev);
382void mei_reset(struct mei_device *dev, int interrupts); 382void mei_reset(struct mei_device *dev, int interrupts);
383int mei_hw_init(struct mei_device *dev); 383int mei_hw_init(struct mei_device *dev);
384void mei_stop(struct mei_device *dev);
384 385
385/* 386/*
386 * MEI interrupt functions prototype 387 * MEI interrupt functions prototype
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index b40ec0601ab0..b8b5c9c3ad03 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -247,44 +247,14 @@ static void mei_remove(struct pci_dev *pdev)
247 247
248 hw = to_me_hw(dev); 248 hw = to_me_hw(dev);
249 249
250 mutex_lock(&dev->device_lock);
251
252 cancel_delayed_work(&dev->timer_work);
253 250
254 mei_wd_stop(dev); 251 dev_err(&pdev->dev, "stop\n");
252 mei_stop(dev);
255 253
256 mei_pdev = NULL; 254 mei_pdev = NULL;
257 255
258 if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
259 dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
260 mei_cl_disconnect(&dev->iamthif_cl);
261 }
262 if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
263 dev->wd_cl.state = MEI_FILE_DISCONNECTING;
264 mei_cl_disconnect(&dev->wd_cl);
265 }
266
267 /* Unregistering watchdog device */
268 mei_watchdog_unregister(dev); 256 mei_watchdog_unregister(dev);
269 257
270 /* remove entry if already in list */
271 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
272
273 if (dev->open_handle_count > 0)
274 dev->open_handle_count--;
275 mei_cl_unlink(&dev->wd_cl);
276
277 if (dev->open_handle_count > 0)
278 dev->open_handle_count--;
279 mei_cl_unlink(&dev->iamthif_cl);
280
281 dev->iamthif_current_cb = NULL;
282 dev->me_clients_num = 0;
283
284 mutex_unlock(&dev->device_lock);
285
286 flush_scheduled_work();
287
288 /* disable interrupts */ 258 /* disable interrupts */
289 mei_disable_interrupts(dev); 259 mei_disable_interrupts(dev);
290 260
@@ -308,28 +278,20 @@ static int mei_pci_suspend(struct device *device)
308{ 278{
309 struct pci_dev *pdev = to_pci_dev(device); 279 struct pci_dev *pdev = to_pci_dev(device);
310 struct mei_device *dev = pci_get_drvdata(pdev); 280 struct mei_device *dev = pci_get_drvdata(pdev);
311 int err;
312 281
313 if (!dev) 282 if (!dev)
314 return -ENODEV; 283 return -ENODEV;
315 mutex_lock(&dev->device_lock);
316 284
317 cancel_delayed_work(&dev->timer_work); 285 dev_err(&pdev->dev, "suspend\n");
318 286
319 /* Stop watchdog if exists */ 287 mei_stop(dev);
320 err = mei_wd_stop(dev); 288
321 /* Set new mei state */ 289 mei_disable_interrupts(dev);
322 if (dev->dev_state == MEI_DEV_ENABLED ||
323 dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
324 dev->dev_state = MEI_DEV_POWER_DOWN;
325 mei_reset(dev, 0);
326 }
327 mutex_unlock(&dev->device_lock);
328 290
329 free_irq(pdev->irq, dev); 291 free_irq(pdev->irq, dev);
330 pci_disable_msi(pdev); 292 pci_disable_msi(pdev);
331 293
332 return err; 294 return 0;
333} 295}
334 296
335static int mei_pci_resume(struct device *device) 297static int mei_pci_resume(struct device *device)