Commit 0a18c3bc authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: csc: wake device while reading firmware status



The CSC has firmware status registers in MMIO and they may be
unaccessible while device is suspended.
Wake device while reading firmware status via sysfs.

Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Link: https://patch.msgid.link/20260201094358.1440593-8-alexander.usyskin@intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 72fdf0bb
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Intel Management Engine Interface (Intel MEI) Linux driver
 */

#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -13,6 +14,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/pm_runtime.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/ioctl.h>
@@ -982,14 +984,22 @@ static DEVICE_ATTR_RO(trc);
static ssize_t fw_status_show(struct device *device,
		struct device_attribute *attr, char *buf)
{
	struct mei_device *dev = dev_get_drvdata(device);
	struct mei_device *mdev = dev_get_drvdata(device);
	struct mei_fw_status fw_status;
	int err, i;
	ssize_t cnt = 0;

	mutex_lock(&dev->device_lock);
	err = mei_fw_status(dev, &fw_status);
	mutex_unlock(&dev->device_lock);
	if (mdev->read_fws_need_resume) {
		err = pm_runtime_resume_and_get(mdev->parent);
		if (err) {
			dev_err(device, "read fw_status resume error = %d\n", err);
			return err;
		}
	}
	scoped_guard(mutex, &mdev->device_lock)
		err = mei_fw_status(mdev, &fw_status);
	if (mdev->read_fws_need_resume)
		pm_runtime_put_autosuspend(mdev->parent);
	if (err) {
		dev_err(device, "read fw_status error = %d\n", err);
		return err;
+2 −0
Original line number Diff line number Diff line
@@ -491,6 +491,7 @@ struct mei_dev_timeouts {
 *
 * @recvd_hw_ready : hw ready message received flag
 * @pg_blocked  : low power mode is not allowed
 * @read_fws_need_resume: the FW status handler needs HW woken from sleep
 *
 * @wait_hw_ready : wait queue for receive HW ready message form FW
 * @wait_pg     : wait queue for receive PG message from FW
@@ -577,6 +578,7 @@ struct mei_device {

	bool recvd_hw_ready;
	bool pg_blocked;
	bool read_fws_need_resume;

	/*
	 * waiting queue for receive message from FW
+2 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ static int mei_csc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	if (!mdev)
		return -ENOMEM;

	mdev->read_fws_need_resume = true;

	hw = to_me_hw(mdev);

	/*