Skip to content

Commit 9b5e045

Browse files
wentongwugregkh
authored andcommitted
mei: vsc: Don't stop/restart mei device during system suspend/resume
The dynamically created mei client device (mei csi) is used as one V4L2 sub device of the whole video pipeline, and the V4L2 connection graph is built by software node. The mei_stop() and mei_restart() will delete the old mei csi client device and create a new mei client device, which will cause the software node information saved in old mei csi device lost and the whole video pipeline will be broken. Removing mei_stop()/mei_restart() during system suspend/resume can fix the issue above and won't impact hardware actual power saving logic. Fixes: f6085a9 ("mei: vsc: Unregister interrupt handler for system suspend") Cc: [email protected] # for 6.8+ Reported-by: Hao Yao <[email protected]> Signed-off-by: Wentong Wu <[email protected]> Reviewed-by: Sakari Ailus <[email protected]> Tested-by: Jason Chen <[email protected]> Tested-by: Sakari Ailus <[email protected]> Acked-by: Tomas Winkler <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 283cb23 commit 9b5e045

File tree

1 file changed

+15
-24
lines changed

1 file changed

+15
-24
lines changed

drivers/misc/mei/platform-vsc.c

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -399,41 +399,32 @@ static void mei_vsc_remove(struct platform_device *pdev)
399399

400400
static int mei_vsc_suspend(struct device *dev)
401401
{
402-
struct mei_device *mei_dev = dev_get_drvdata(dev);
403-
struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
402+
struct mei_device *mei_dev;
403+
int ret = 0;
404404

405-
mei_stop(mei_dev);
405+
mei_dev = dev_get_drvdata(dev);
406+
if (!mei_dev)
407+
return -ENODEV;
406408

407-
mei_disable_interrupts(mei_dev);
409+
mutex_lock(&mei_dev->device_lock);
408410

409-
vsc_tp_free_irq(hw->tp);
411+
if (!mei_write_is_idle(mei_dev))
412+
ret = -EAGAIN;
410413

411-
return 0;
414+
mutex_unlock(&mei_dev->device_lock);
415+
416+
return ret;
412417
}
413418

414419
static int mei_vsc_resume(struct device *dev)
415420
{
416-
struct mei_device *mei_dev = dev_get_drvdata(dev);
417-
struct mei_vsc_hw *hw = mei_dev_to_vsc_hw(mei_dev);
418-
int ret;
419-
420-
ret = vsc_tp_request_irq(hw->tp);
421-
if (ret)
422-
return ret;
423-
424-
ret = mei_restart(mei_dev);
425-
if (ret)
426-
goto err_free;
421+
struct mei_device *mei_dev;
427422

428-
/* start timer if stopped in suspend */
429-
schedule_delayed_work(&mei_dev->timer_work, HZ);
423+
mei_dev = dev_get_drvdata(dev);
424+
if (!mei_dev)
425+
return -ENODEV;
430426

431427
return 0;
432-
433-
err_free:
434-
vsc_tp_free_irq(hw->tp);
435-
436-
return ret;
437428
}
438429

439430
static DEFINE_SIMPLE_DEV_PM_OPS(mei_vsc_pm_ops, mei_vsc_suspend, mei_vsc_resume);

0 commit comments

Comments
 (0)