diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2013-03-10 07:56:08 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-15 14:18:07 -0400 |
commit | 7cb035d9e619a8d20f5d3b9791f8cb5160d19e70 (patch) | |
tree | e4dd1bb6addf4dc4e49370cbcfb5a1cdabe49174 /drivers/misc/mei | |
parent | 3d374d09f16f64ab4d71704cbe621514d36cd0b1 (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.c | 18 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 1 | ||||
-rw-r--r-- | drivers/misc/mei/pci-me.c | 52 |
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 | ||
186 | void 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) | |||
381 | void mei_device_init(struct mei_device *dev); | 381 | void mei_device_init(struct mei_device *dev); |
382 | void mei_reset(struct mei_device *dev, int interrupts); | 382 | void mei_reset(struct mei_device *dev, int interrupts); |
383 | int mei_hw_init(struct mei_device *dev); | 383 | int mei_hw_init(struct mei_device *dev); |
384 | void 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 | ||
335 | static int mei_pci_resume(struct device *device) | 297 | static int mei_pci_resume(struct device *device) |