aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-26 19:09:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-26 19:09:30 -0400
commit8c876be81a1f2f0ab33ffb2b00871e65c7a658b3 (patch)
tree60426265759ab14b00c94a791520f140062bb57c /drivers/misc/mei
parent02dbd0ff5448d4da0c6e9d59c897f3e31a16d51a (diff)
parent347e0899b1c75d907f01ac883ca38d37fe9bfa42 (diff)
Merge branch 'char-misc-linus' into char-misc-next
This picks up the MEI fixes that we need in this branch now. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/hw-me.c29
-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
4 files changed, 46 insertions, 54 deletions
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 11a2a6538c0b..7c2b14d714b9 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -152,6 +152,20 @@ static void mei_me_intr_disable(struct mei_device *dev)
152} 152}
153 153
154/** 154/**
155 * mei_me_hw_reset_release - release device from the reset
156 *
157 * @dev: the device structure
158 */
159static void mei_me_hw_reset_release(struct mei_device *dev)
160{
161 struct mei_me_hw *hw = to_me_hw(dev);
162 u32 hcsr = mei_hcsr_read(hw);
163
164 hcsr |= H_IG;
165 hcsr &= ~H_RST;
166 mei_hcsr_set(hw, hcsr);
167}
168/**
155 * mei_me_hw_reset - resets fw via mei csr register. 169 * mei_me_hw_reset - resets fw via mei csr register.
156 * 170 *
157 * @dev: the device structure 171 * @dev: the device structure
@@ -169,18 +183,14 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
169 if (intr_enable) 183 if (intr_enable)
170 hcsr |= H_IE; 184 hcsr |= H_IE;
171 else 185 else
172 hcsr &= ~H_IE; 186 hcsr |= ~H_IE;
173
174 mei_hcsr_set(hw, hcsr);
175
176 hcsr = mei_hcsr_read(hw) | H_IG;
177 hcsr &= ~H_RST;
178 187
179 mei_hcsr_set(hw, hcsr); 188 mei_hcsr_set(hw, hcsr);
180 189
181 hcsr = mei_hcsr_read(hw); 190 if (dev->dev_state == MEI_DEV_POWER_DOWN)
191 mei_me_hw_reset_release(dev);
182 192
183 dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr); 193 dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw));
184} 194}
185 195
186/** 196/**
@@ -492,7 +502,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
492 mutex_unlock(&dev->device_lock); 502 mutex_unlock(&dev->device_lock);
493 return IRQ_HANDLED; 503 return IRQ_HANDLED;
494 } else { 504 } else {
495 dev_dbg(&dev->pdev->dev, "FW not ready.\n"); 505 dev_dbg(&dev->pdev->dev, "Reset Completed.\n");
506 mei_me_hw_reset_release(dev);
496 mutex_unlock(&dev->device_lock); 507 mutex_unlock(&dev->device_lock);
497 return IRQ_HANDLED; 508 return IRQ_HANDLED;
498 } 509 }
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index fc3d97ce8300..1ab1fb1db07b 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -199,6 +199,24 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
199 mei_cl_all_write_clear(dev); 199 mei_cl_all_write_clear(dev);
200} 200}
201 201
202void mei_stop(struct mei_device *dev)
203{
204 dev_dbg(&dev->pdev->dev, "stopping the device.\n");
205
206 mutex_lock(&dev->device_lock);
207
208 cancel_delayed_work(&dev->timer_work);
209
210 mei_wd_stop(dev);
211
212 dev->dev_state = MEI_DEV_POWER_DOWN;
213 mei_reset(dev, 0);
214
215 mutex_unlock(&dev->device_lock);
216
217 flush_scheduled_work();
218}
219
202 220
203 221
204 222
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 1a4b50ca4b3b..d6fd3d6410d6 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -395,6 +395,7 @@ static inline u32 mei_data2slots(size_t length)
395void mei_device_init(struct mei_device *dev); 395void mei_device_init(struct mei_device *dev);
396void mei_reset(struct mei_device *dev, int interrupts); 396void mei_reset(struct mei_device *dev, int interrupts);
397int mei_hw_init(struct mei_device *dev); 397int mei_hw_init(struct mei_device *dev);
398void mei_stop(struct mei_device *dev);
398 399
399/* 400/*
400 * MEI interrupt functions prototype 401 * 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)