Skip to content

Commit 2cedb29

Browse files
ausyskingregkh
authored andcommitted
mei: me: trigger link reset if hw ready is unexpected
Driver can receive HW not ready interrupt unexpectedly. E.g. for cards that go donwn to D3cold. Trigger link reset in this case to synchronize driver and firmware state. No need to do that sync if driver is going down or interrupt is received before driver started initial link reset sequence. Introduce UNINITIALIZED device state to allow interrupt handler to ignore interrupts before first init. Signed-off-by: Alexander Usyskin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 3ebcd34 commit 2cedb29

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

drivers/misc/mei/hw-me.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,9 +1373,20 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
13731373
/* check if we need to start the dev */
13741374
if (!mei_host_is_ready(dev)) {
13751375
if (mei_hw_is_ready(dev)) {
1376-
dev_dbg(&dev->dev, "we need to start the dev.\n");
1377-
dev->recvd_hw_ready = true;
1378-
wake_up(&dev->wait_hw_ready);
1376+
/* synchronized by dev mutex */
1377+
if (waitqueue_active(&dev->wait_hw_ready)) {
1378+
dev_dbg(&dev->dev, "we need to start the dev.\n");
1379+
dev->recvd_hw_ready = true;
1380+
wake_up(&dev->wait_hw_ready);
1381+
} else if (dev->dev_state != MEI_DEV_UNINITIALIZED &&
1382+
dev->dev_state != MEI_DEV_POWERING_DOWN &&
1383+
dev->dev_state != MEI_DEV_POWER_DOWN) {
1384+
dev_dbg(&dev->dev, "Force link reset.\n");
1385+
schedule_work(&dev->reset_work);
1386+
} else {
1387+
dev_dbg(&dev->dev, "Ignore this interrupt in state = %d\n",
1388+
dev->dev_state);
1389+
}
13791390
} else {
13801391
dev_dbg(&dev->dev, "Spurious Interrupt\n");
13811392
}

drivers/misc/mei/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ void mei_device_init(struct mei_device *dev,
399399
init_waitqueue_head(&dev->wait_hw_ready);
400400
init_waitqueue_head(&dev->wait_pg);
401401
init_waitqueue_head(&dev->wait_hbm_start);
402-
dev->dev_state = MEI_DEV_INITIALIZING;
402+
dev->dev_state = MEI_DEV_UNINITIALIZED;
403403
dev->reset_count = 0;
404404

405405
INIT_LIST_HEAD(&dev->write_list);

drivers/misc/mei/mei_dev.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ enum file_state {
5757

5858
/* MEI device states */
5959
enum mei_dev_state {
60-
MEI_DEV_INITIALIZING = 0,
60+
MEI_DEV_UNINITIALIZED = 0,
61+
MEI_DEV_INITIALIZING,
6162
MEI_DEV_INIT_CLIENTS,
6263
MEI_DEV_ENABLED,
6364
MEI_DEV_RESETTING,

0 commit comments

Comments
 (0)