mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [char-misc-next 0/7] mei: csc: support controller with separate PCI device
@ 2026-02-01  9:43 Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 1/7] mei: me: use PCI_DEVICE_DATA macro Alexander Usyskin
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: Menachem Adin, Alexander Usyskin, linux-kernel

Intel PCI driver for chassis controller embedded in Intel graphics
devices.

An MEI device here called CSC can be embedded in discrete
Intel graphics devices having separate PCI device, to support a range
of chassis tasks such as graphics card firmware update and security
tasks.

First five patches are cleanups and preparations.
Then the new component added and additional fix for power management
for this new component only.

Alexander Usyskin (7):
  mei: me: use PCI_DEVICE_DATA macro
  mei: fix idle print specifiers
  mei: me: move trace into firmware status read
  mei: trace: print return value of pci_cfg_read
  mei: convert PCI error to common errno
  mei: csc: support controller with separate PCI device
  mei: csc: wake device while reading firmware status

 drivers/misc/mei/Kconfig      |  11 ++
 drivers/misc/mei/Makefile     |   3 +
 drivers/misc/mei/bus-fixup.c  |   6 +-
 drivers/misc/mei/gsc-me.c     |   3 +-
 drivers/misc/mei/hw-me-regs.h | 165 ++++++++++-----------
 drivers/misc/mei/hw-me.c      |  53 +++++--
 drivers/misc/mei/hw-me.h      |  10 +-
 drivers/misc/mei/hw-txe.c     |   4 +-
 drivers/misc/mei/init.c       |   4 +-
 drivers/misc/mei/main.c       |  18 ++-
 drivers/misc/mei/mei-trace.h  |  10 +-
 drivers/misc/mei/mei_dev.h    |   5 +
 drivers/misc/mei/pci-csc.c    | 261 ++++++++++++++++++++++++++++++++++
 drivers/misc/mei/pci-me.c     | 216 ++++++++++++++--------------
 14 files changed, 546 insertions(+), 223 deletions(-)
 create mode 100644 drivers/misc/mei/pci-csc.c

-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 1/7] mei: me: use PCI_DEVICE_DATA macro
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 2/7] mei: fix idle print specifiers Alexander Usyskin
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Andy Shevchenko

Drop old local MEI_PCI_DEVICE macro and use common
PCI_DEVICE_DATA instead.
Update defines to adhere to current naming convention.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/bus-fixup.c  |   6 +-
 drivers/misc/mei/hw-me-regs.h | 162 +++++++++++++-------------
 drivers/misc/mei/hw-me.h      |   6 -
 drivers/misc/mei/pci-me.c     | 208 +++++++++++++++++-----------------
 4 files changed, 188 insertions(+), 194 deletions(-)

diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
index e6a1d3534663..bea7a47d216e 100644
--- a/drivers/misc/mei/bus-fixup.c
+++ b/drivers/misc/mei/bus-fixup.c
@@ -303,9 +303,9 @@ static void mei_wd(struct mei_cl_device *cldev)
 {
 	struct pci_dev *pdev = to_pci_dev(cldev->dev.parent);
 
-	if (pdev->device == MEI_DEV_ID_WPT_LP ||
-	    pdev->device == MEI_DEV_ID_SPT ||
-	    pdev->device == MEI_DEV_ID_SPT_H)
+	if (pdev->device == PCI_DEVICE_ID_INTEL_MEI_WPT_LP ||
+	    pdev->device == PCI_DEVICE_ID_INTEL_MEI_SPT ||
+	    pdev->device == PCI_DEVICE_ID_INTEL_MEI_SPT_H)
 		cldev->me_cl->props.protocol_version = 0x2;
 
 	cldev->do_match = 1;
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index fa30899a5fa2..840e1fd2714c 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -9,120 +9,120 @@
 /*
  * MEI device IDs
  */
-#define MEI_DEV_ID_82946GZ    0x2974  /* 82946GZ/GL */
-#define MEI_DEV_ID_82G35      0x2984  /* 82G35 Express */
-#define MEI_DEV_ID_82Q965     0x2994  /* 82Q963/Q965 */
-#define MEI_DEV_ID_82G965     0x29A4  /* 82P965/G965 */
+#define PCI_DEVICE_ID_INTEL_MEI_82946GZ    0x2974  /* 82946GZ/GL */
+#define PCI_DEVICE_ID_INTEL_MEI_82G35      0x2984  /* 82G35 Express */
+#define PCI_DEVICE_ID_INTEL_MEI_82Q965     0x2994  /* 82Q963/Q965 */
+#define PCI_DEVICE_ID_INTEL_MEI_82G965     0x29A4  /* 82P965/G965 */
 
-#define MEI_DEV_ID_82GM965    0x2A04  /* Mobile PM965/GM965 */
-#define MEI_DEV_ID_82GME965   0x2A14  /* Mobile GME965/GLE960 */
+#define PCI_DEVICE_ID_INTEL_MEI_82GM965    0x2A04  /* Mobile PM965/GM965 */
+#define PCI_DEVICE_ID_INTEL_MEI_82GME965   0x2A14  /* Mobile GME965/GLE960 */
 
-#define MEI_DEV_ID_ICH9_82Q35 0x29B4  /* 82Q35 Express */
-#define MEI_DEV_ID_ICH9_82G33 0x29C4  /* 82G33/G31/P35/P31 Express */
-#define MEI_DEV_ID_ICH9_82Q33 0x29D4  /* 82Q33 Express */
-#define MEI_DEV_ID_ICH9_82X38 0x29E4  /* 82X38/X48 Express */
-#define MEI_DEV_ID_ICH9_3200  0x29F4  /* 3200/3210 Server */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_82Q35 0x29B4  /* 82Q35 Express */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_82G33 0x29C4  /* 82G33/G31/P35/P31 Express */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_82Q33 0x29D4  /* 82Q33 Express */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_82X38 0x29E4  /* 82X38/X48 Express */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_3200  0x29F4  /* 3200/3210 Server */
 
-#define MEI_DEV_ID_ICH9_6     0x28B4  /* Bearlake */
-#define MEI_DEV_ID_ICH9_7     0x28C4  /* Bearlake */
-#define MEI_DEV_ID_ICH9_8     0x28D4  /* Bearlake */
-#define MEI_DEV_ID_ICH9_9     0x28E4  /* Bearlake */
-#define MEI_DEV_ID_ICH9_10    0x28F4  /* Bearlake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_6     0x28B4  /* Bearlake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_7     0x28C4  /* Bearlake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_8     0x28D4  /* Bearlake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_9     0x28E4  /* Bearlake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9_10    0x28F4  /* Bearlake */
 
-#define MEI_DEV_ID_ICH9M_1    0x2A44  /* Cantiga */
-#define MEI_DEV_ID_ICH9M_2    0x2A54  /* Cantiga */
-#define MEI_DEV_ID_ICH9M_3    0x2A64  /* Cantiga */
-#define MEI_DEV_ID_ICH9M_4    0x2A74  /* Cantiga */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9M_1    0x2A44  /* Cantiga */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9M_2    0x2A54  /* Cantiga */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9M_3    0x2A64  /* Cantiga */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH9M_4    0x2A74  /* Cantiga */
 
-#define MEI_DEV_ID_ICH10_1    0x2E04  /* Eaglelake */
-#define MEI_DEV_ID_ICH10_2    0x2E14  /* Eaglelake */
-#define MEI_DEV_ID_ICH10_3    0x2E24  /* Eaglelake */
-#define MEI_DEV_ID_ICH10_4    0x2E34  /* Eaglelake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH10_1    0x2E04  /* Eaglelake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH10_2    0x2E14  /* Eaglelake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH10_3    0x2E24  /* Eaglelake */
+#define PCI_DEVICE_ID_INTEL_MEI_ICH10_4    0x2E34  /* Eaglelake */
 
-#define MEI_DEV_ID_IBXPK_1    0x3B64  /* Calpella */
-#define MEI_DEV_ID_IBXPK_2    0x3B65  /* Calpella */
+#define PCI_DEVICE_ID_INTEL_MEI_IBXPK_1    0x3B64  /* Calpella */
+#define PCI_DEVICE_ID_INTEL_MEI_IBXPK_2    0x3B65  /* Calpella */
 
-#define MEI_DEV_ID_CPT_1      0x1C3A  /* Couger Point */
-#define MEI_DEV_ID_PBG_1      0x1D3A  /* C600/X79 Patsburg */
+#define PCI_DEVICE_ID_INTEL_MEI_CPT_1      0x1C3A  /* Couger Point */
+#define PCI_DEVICE_ID_INTEL_MEI_PBG_1      0x1D3A  /* C600/X79 Patsburg */
 
-#define MEI_DEV_ID_PPT_1      0x1E3A  /* Panther Point */
-#define MEI_DEV_ID_PPT_2      0x1CBA  /* Panther Point */
-#define MEI_DEV_ID_PPT_3      0x1DBA  /* Panther Point */
+#define PCI_DEVICE_ID_INTEL_MEI_PPT_1      0x1E3A  /* Panther Point */
+#define PCI_DEVICE_ID_INTEL_MEI_PPT_2      0x1CBA  /* Panther Point */
+#define PCI_DEVICE_ID_INTEL_MEI_PPT_3      0x1DBA  /* Panther Point */
 
-#define MEI_DEV_ID_LPT_H      0x8C3A  /* Lynx Point H */
-#define MEI_DEV_ID_LPT_W      0x8D3A  /* Lynx Point - Wellsburg */
-#define MEI_DEV_ID_LPT_LP     0x9C3A  /* Lynx Point LP */
-#define MEI_DEV_ID_LPT_HR     0x8CBA  /* Lynx Point H Refresh */
+#define PCI_DEVICE_ID_INTEL_MEI_LPT_H      0x8C3A  /* Lynx Point H */
+#define PCI_DEVICE_ID_INTEL_MEI_LPT_W      0x8D3A  /* Lynx Point - Wellsburg */
+#define PCI_DEVICE_ID_INTEL_MEI_LPT_LP     0x9C3A  /* Lynx Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_LPT_HR     0x8CBA  /* Lynx Point H Refresh */
 
-#define MEI_DEV_ID_WPT_LP     0x9CBA  /* Wildcat Point LP */
-#define MEI_DEV_ID_WPT_LP_2   0x9CBB  /* Wildcat Point LP 2 */
+#define PCI_DEVICE_ID_INTEL_MEI_WPT_LP     0x9CBA  /* Wildcat Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_WPT_LP_2   0x9CBB  /* Wildcat Point LP 2 */
 
-#define MEI_DEV_ID_SPT        0x9D3A  /* Sunrise Point */
-#define MEI_DEV_ID_SPT_2      0x9D3B  /* Sunrise Point 2 */
-#define MEI_DEV_ID_SPT_3      0x9D3E  /* Sunrise Point 3 (iToutch) */
-#define MEI_DEV_ID_SPT_H      0xA13A  /* Sunrise Point H */
-#define MEI_DEV_ID_SPT_H_2    0xA13B  /* Sunrise Point H 2 */
+#define PCI_DEVICE_ID_INTEL_MEI_SPT        0x9D3A  /* Sunrise Point */
+#define PCI_DEVICE_ID_INTEL_MEI_SPT_2      0x9D3B  /* Sunrise Point 2 */
+#define PCI_DEVICE_ID_INTEL_MEI_SPT_3      0x9D3E  /* Sunrise Point 3 (iToutch) */
+#define PCI_DEVICE_ID_INTEL_MEI_SPT_H      0xA13A  /* Sunrise Point H */
+#define PCI_DEVICE_ID_INTEL_MEI_SPT_H_2    0xA13B  /* Sunrise Point H 2 */
 
-#define MEI_DEV_ID_LBG        0xA1BA  /* Lewisburg (SPT) */
+#define PCI_DEVICE_ID_INTEL_MEI_LBG        0xA1BA  /* Lewisburg (SPT) */
 
-#define MEI_DEV_ID_BXT_M      0x1A9A  /* Broxton M */
-#define MEI_DEV_ID_APL_I      0x5A9A  /* Apollo Lake I */
+#define PCI_DEVICE_ID_INTEL_MEI_BXT_M      0x1A9A  /* Broxton M */
+#define PCI_DEVICE_ID_INTEL_MEI_APL_I      0x5A9A  /* Apollo Lake I */
 
-#define MEI_DEV_ID_DNV_IE     0x19E5  /* Denverton IE */
+#define PCI_DEVICE_ID_INTEL_MEI_DNV_IE     0x19E5  /* Denverton IE */
 
-#define MEI_DEV_ID_GLK        0x319A  /* Gemini Lake */
+#define PCI_DEVICE_ID_INTEL_MEI_GLK        0x319A  /* Gemini Lake */
 
-#define MEI_DEV_ID_KBP        0xA2BA  /* Kaby Point */
-#define MEI_DEV_ID_KBP_2      0xA2BB  /* Kaby Point 2 */
-#define MEI_DEV_ID_KBP_3      0xA2BE  /* Kaby Point 3 (iTouch) */
+#define PCI_DEVICE_ID_INTEL_MEI_KBP        0xA2BA  /* Kaby Point */
+#define PCI_DEVICE_ID_INTEL_MEI_KBP_2      0xA2BB  /* Kaby Point 2 */
+#define PCI_DEVICE_ID_INTEL_MEI_KBP_3      0xA2BE  /* Kaby Point 3 (iTouch) */
 
-#define MEI_DEV_ID_CNP_LP     0x9DE0  /* Cannon Point LP */
-#define MEI_DEV_ID_CNP_LP_3   0x9DE4  /* Cannon Point LP 3 (iTouch) */
-#define MEI_DEV_ID_CNP_H      0xA360  /* Cannon Point H */
-#define MEI_DEV_ID_CNP_H_3    0xA364  /* Cannon Point H 3 (iTouch) */
+#define PCI_DEVICE_ID_INTEL_MEI_CNP_LP     0x9DE0  /* Cannon Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_CNP_LP_3   0x9DE4  /* Cannon Point LP 3 (iTouch) */
+#define PCI_DEVICE_ID_INTEL_MEI_CNP_H      0xA360  /* Cannon Point H */
+#define PCI_DEVICE_ID_INTEL_MEI_CNP_H_3    0xA364  /* Cannon Point H 3 (iTouch) */
 
-#define MEI_DEV_ID_CMP_LP     0x02e0  /* Comet Point LP */
-#define MEI_DEV_ID_CMP_LP_3   0x02e4  /* Comet Point LP 3 (iTouch) */
+#define PCI_DEVICE_ID_INTEL_MEI_CMP_LP     0x02e0  /* Comet Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_CMP_LP_3   0x02e4  /* Comet Point LP 3 (iTouch) */
 
-#define MEI_DEV_ID_CMP_V      0xA3BA  /* Comet Point Lake V */
+#define PCI_DEVICE_ID_INTEL_MEI_CMP_V      0xA3BA  /* Comet Point Lake V */
 
-#define MEI_DEV_ID_CMP_H      0x06e0  /* Comet Lake H */
-#define MEI_DEV_ID_CMP_H_3    0x06e4  /* Comet Lake H 3 (iTouch) */
+#define PCI_DEVICE_ID_INTEL_MEI_CMP_H      0x06e0  /* Comet Lake H */
+#define PCI_DEVICE_ID_INTEL_MEI_CMP_H_3    0x06e4  /* Comet Lake H 3 (iTouch) */
 
-#define MEI_DEV_ID_CDF        0x18D3  /* Cedar Fork */
+#define PCI_DEVICE_ID_INTEL_MEI_CDF        0x18D3  /* Cedar Fork */
 
-#define MEI_DEV_ID_ICP_LP     0x34E0  /* Ice Lake Point LP */
-#define MEI_DEV_ID_ICP_N      0x38E0  /* Ice Lake Point N */
+#define PCI_DEVICE_ID_INTEL_MEI_ICP_LP     0x34E0  /* Ice Lake Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_ICP_N      0x38E0  /* Ice Lake Point N */
 
-#define MEI_DEV_ID_JSP_N      0x4DE0  /* Jasper Lake Point N */
+#define PCI_DEVICE_ID_INTEL_MEI_JSP_N      0x4DE0  /* Jasper Lake Point N */
 
-#define MEI_DEV_ID_TGP_LP     0xA0E0  /* Tiger Lake Point LP */
-#define MEI_DEV_ID_TGP_H      0x43E0  /* Tiger Lake Point H */
+#define PCI_DEVICE_ID_INTEL_MEI_TGP_LP     0xA0E0  /* Tiger Lake Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_TGP_H      0x43E0  /* Tiger Lake Point H */
 
-#define MEI_DEV_ID_MCC        0x4B70  /* Mule Creek Canyon (EHL) */
-#define MEI_DEV_ID_MCC_4      0x4B75  /* Mule Creek Canyon 4 (EHL) */
+#define PCI_DEVICE_ID_INTEL_MEI_MCC        0x4B70  /* Mule Creek Canyon (EHL) */
+#define PCI_DEVICE_ID_INTEL_MEI_MCC_4      0x4B75  /* Mule Creek Canyon 4 (EHL) */
 
-#define MEI_DEV_ID_EBG        0x1BE0  /* Emmitsburg WS */
+#define PCI_DEVICE_ID_INTEL_MEI_EBG        0x1BE0  /* Emmitsburg WS */
 
-#define MEI_DEV_ID_ADP_S      0x7AE8  /* Alder Lake Point S */
-#define MEI_DEV_ID_ADP_LP     0x7A60  /* Alder Lake Point LP */
-#define MEI_DEV_ID_ADP_P      0x51E0  /* Alder Lake Point P */
-#define MEI_DEV_ID_ADP_N      0x54E0  /* Alder Lake Point N */
+#define PCI_DEVICE_ID_INTEL_MEI_ADP_S      0x7AE8  /* Alder Lake Point S */
+#define PCI_DEVICE_ID_INTEL_MEI_ADP_LP     0x7A60  /* Alder Lake Point LP */
+#define PCI_DEVICE_ID_INTEL_MEI_ADP_P      0x51E0  /* Alder Lake Point P */
+#define PCI_DEVICE_ID_INTEL_MEI_ADP_N      0x54E0  /* Alder Lake Point N */
 
-#define MEI_DEV_ID_RPL_S      0x7A68  /* Raptor Lake Point S */
+#define PCI_DEVICE_ID_INTEL_MEI_RPL_S      0x7A68  /* Raptor Lake Point S */
 
-#define MEI_DEV_ID_MTL_M      0x7E70  /* Meteor Lake Point M */
-#define MEI_DEV_ID_ARL_S      0x7F68  /* Arrow Lake Point S */
-#define MEI_DEV_ID_ARL_H      0x7770  /* Arrow Lake Point H */
+#define PCI_DEVICE_ID_INTEL_MEI_MTL_M      0x7E70  /* Meteor Lake Point M */
+#define PCI_DEVICE_ID_INTEL_MEI_ARL_S      0x7F68  /* Arrow Lake Point S */
+#define PCI_DEVICE_ID_INTEL_MEI_ARL_H      0x7770  /* Arrow Lake Point H */
 
-#define MEI_DEV_ID_LNL_M      0xA870  /* Lunar Lake Point M */
+#define PCI_DEVICE_ID_INTEL_MEI_LNL_M      0xA870  /* Lunar Lake Point M */
 
-#define MEI_DEV_ID_PTL_H      0xE370  /* Panther Lake H */
-#define MEI_DEV_ID_PTL_P      0xE470  /* Panther Lake P */
+#define PCI_DEVICE_ID_INTEL_MEI_PTL_H      0xE370  /* Panther Lake H */
+#define PCI_DEVICE_ID_INTEL_MEI_PTL_P      0xE470  /* Panther Lake P */
 
-#define MEI_DEV_ID_WCL_P      0x4D70  /* Wildcat Lake P */
+#define PCI_DEVICE_ID_INTEL_MEI_WCL_P      0x4D70  /* Wildcat Lake P */
 
-#define MEI_DEV_ID_NVL_S      0x6E68  /* Nova Lake Point S */
+#define PCI_DEVICE_ID_INTEL_MEI_NVL_S      0x6E68  /* Nova Lake Point S */
 
 /*
  * MEI HW Section
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 204b92af6c47..843ec2497b52 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -33,12 +33,6 @@ struct mei_cfg {
 	u32 hw_trc_supported:1;
 };
 
-
-#define MEI_PCI_DEVICE(dev, cfg) \
-	.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
-	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \
-	.driver_data = (kernel_ulong_t)(cfg),
-
 #define MEI_ME_RPM_TIMEOUT    500 /* ms */
 
 /**
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 2a6e569558b9..fe5d5aee074c 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -26,110 +26,110 @@
 
 /* mei_pci_tbl - PCI Device ID Table */
 static const struct pci_device_id mei_me_pci_tbl[] = {
-	{MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_82G35, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_82Q965, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_82G965, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_82GM965, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_82GME965, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q35, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82G33, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q33, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82X38, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_3200, MEI_ME_ICH_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_6, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_7, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_8, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_9, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_10, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_1, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_2, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_3, MEI_ME_ICH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_4, MEI_ME_ICH_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_1, MEI_ME_ICH10_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_2, MEI_ME_ICH10_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, MEI_ME_ICH10_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, MEI_ME_ICH10_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH6_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH6_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, MEI_ME_PCH_CPT_PBG_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, MEI_ME_PCH_CPT_PBG_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH7_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH7_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH7_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_4_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_4_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_4_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_3, MEI_ME_PCH8_ITOUCH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_4_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_4_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH12_SPS_4_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_DNV_IE, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_GLK, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP_3, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP, MEI_ME_PCH12_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_LP_3, MEI_ME_PCH8_ITOUCH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_SPS_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_3, MEI_ME_PCH12_SPS_ITOUCH_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_ITOUCH_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_V, MEI_ME_PCH12_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H, MEI_ME_PCH12_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_TGP_H, MEI_ME_PCH15_SPS_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_JSP_N, MEI_ME_PCH15_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_CDF, MEI_ME_PCH8_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_EBG, MEI_ME_PCH15_SPS_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_S, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_LP, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_SPS_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)},
-	{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_WCL_P, MEI_ME_PCH15_CFG)},
-
-	{MEI_PCI_DEVICE(MEI_DEV_ID_NVL_S, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_82946GZ, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_82G35, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_82Q965, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_82G965, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_82GM965, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_82GME965, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_82Q35, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_82G33, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_82Q33, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_82X38, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_3200, MEI_ME_ICH_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_6, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_7, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_8, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_9, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9_10, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9M_1, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9M_2, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9M_3, MEI_ME_ICH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH9M_4, MEI_ME_ICH_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH10_1, MEI_ME_ICH10_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH10_2, MEI_ME_ICH10_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH10_3, MEI_ME_ICH10_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICH10_4, MEI_ME_ICH10_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_IBXPK_1, MEI_ME_PCH6_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_IBXPK_2, MEI_ME_PCH6_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CPT_1, MEI_ME_PCH_CPT_PBG_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_PBG_1, MEI_ME_PCH_CPT_PBG_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_PPT_1, MEI_ME_PCH7_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_PPT_2, MEI_ME_PCH7_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_PPT_3, MEI_ME_PCH7_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_LPT_H, MEI_ME_PCH8_SPS_4_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_LPT_W, MEI_ME_PCH8_SPS_4_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_LPT_LP, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_LPT_HR, MEI_ME_PCH8_SPS_4_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_WPT_LP, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_WPT_LP_2, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_SPT, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_SPT_2, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_SPT_3, MEI_ME_PCH8_ITOUCH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_SPT_H, MEI_ME_PCH8_SPS_4_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_SPT_H_2, MEI_ME_PCH8_SPS_4_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_LBG, MEI_ME_PCH12_SPS_4_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_BXT_M, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_APL_I, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_DNV_IE, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_GLK, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_KBP, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_KBP_2, MEI_ME_PCH8_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_KBP_3, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_CNP_LP, MEI_ME_PCH12_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CNP_LP_3, MEI_ME_PCH8_ITOUCH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CNP_H, MEI_ME_PCH12_SPS_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CNP_H_3, MEI_ME_PCH12_SPS_ITOUCH_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_CMP_LP, MEI_ME_PCH12_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CMP_LP_3, MEI_ME_PCH8_ITOUCH_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CMP_V, MEI_ME_PCH12_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CMP_H, MEI_ME_PCH12_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_CMP_H_3, MEI_ME_PCH8_ITOUCH_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_ICP_LP, MEI_ME_PCH12_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ICP_N, MEI_ME_PCH12_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_TGP_LP, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_TGP_H, MEI_ME_PCH15_SPS_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_JSP_N, MEI_ME_PCH15_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_MCC, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_MCC_4, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_CDF, MEI_ME_PCH8_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_EBG, MEI_ME_PCH15_SPS_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_ADP_S, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ADP_LP, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ADP_P, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ADP_N, MEI_ME_PCH15_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_RPL_S, MEI_ME_PCH15_SPS_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_MTL_M, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ARL_S, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_ARL_H, MEI_ME_PCH15_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_LNL_M, MEI_ME_PCH15_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_PTL_H, MEI_ME_PCH15_CFG)},
+	{PCI_DEVICE_DATA(INTEL, MEI_PTL_P, MEI_ME_PCH15_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_WCL_P, MEI_ME_PCH15_CFG)},
+
+	{PCI_DEVICE_DATA(INTEL, MEI_NVL_S, MEI_ME_PCH15_CFG)},
 
 	/* required last entry */
 	{0, }
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 2/7] mei: fix idle print specifiers
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 1/7] mei: me: use PCI_DEVICE_DATA macro Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 3/7] mei: me: move trace into firmware status read Alexander Usyskin
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Andy Shevchenko

%01d is equal to %d, simplify the format.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index b789c4d9c709..f54991b40fc7 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -348,7 +348,7 @@ bool mei_write_is_idle(struct mei_device *dev)
 		list_empty(&dev->write_list)   &&
 		list_empty(&dev->write_waiting_list));
 
-	dev_dbg(&dev->dev, "write pg: is idle[%d] state=%s ctrl=%01d write=%01d wwait=%01d\n",
+	dev_dbg(&dev->dev, "write pg: is idle[%d] state=%s ctrl=%d write=%d wwait=%d\n",
 		idle,
 		mei_dev_state_str(dev->dev_state),
 		list_empty(&dev->ctrl_wr_list),
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 3/7] mei: me: move trace into firmware status read
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 1/7] mei: me: use PCI_DEVICE_DATA macro Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 2/7] mei: fix idle print specifiers Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 4/7] mei: trace: print return value of pci_cfg_read Alexander Usyskin
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Mika Westerberg

Move register trace near it actual read in the firmware status callback
and make it adhere to the actual read type.

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/gsc-me.c |  3 ++-
 drivers/misc/mei/hw-me.c  | 11 +++--------
 drivers/misc/mei/hw-me.h  |  2 +-
 drivers/misc/mei/pci-me.c |  8 ++++++--
 4 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index 93cba090ea08..73d5beeb9c34 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -23,11 +23,12 @@
 
 #define MEI_GSC_RPM_TIMEOUT 500
 
-static int mei_gsc_read_hfs(const struct mei_device *dev, int where, u32 *val)
+static int mei_gsc_read_hfs(const struct mei_device *dev, int where, const char *name, u32 *val)
 {
 	struct mei_me_hw *hw = to_me_hw(dev);
 
 	*val = ioread32(hw->mem_addr + where + 0xC00);
+	trace_mei_reg_read(&dev->dev, name, where, *val);
 
 	return 0;
 }
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index d4612c659784..c0d4a02d9cae 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -215,11 +215,8 @@ static int mei_me_fw_status(struct mei_device *dev,
 
 	fw_status->count = fw_src->count;
 	for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) {
-		ret = hw->read_fws(dev, fw_src->status[i],
+		ret = hw->read_fws(dev, fw_src->status[i], "PCI_CFG_HFS_X",
 				   &fw_status->status[i]);
-		trace_mei_pci_cfg_read(&dev->dev, "PCI_CFG_HFS_X",
-				       fw_src->status[i],
-				       fw_status->status[i]);
 		if (ret)
 			return ret;
 	}
@@ -250,8 +247,7 @@ static int mei_me_hw_config(struct mei_device *dev)
 	hw->hbuf_depth = (hcsr & H_CBD) >> 24;
 
 	reg = 0;
-	hw->read_fws(dev, PCI_CFG_HFS_1, &reg);
-	trace_mei_pci_cfg_read(&dev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg);
+	hw->read_fws(dev, PCI_CFG_HFS_1, "PCI_CFG_HFS_1", &reg);
 	hw->d0i3_supported =
 		((reg & PCI_CFG_HFS_1_D0I3_MSK) == PCI_CFG_HFS_1_D0I3_MSK);
 
@@ -446,8 +442,7 @@ static void mei_gsc_pxp_check(struct mei_device *dev)
 	if (!kind_is_gsc(dev) && !kind_is_gscfi(dev))
 		return;
 
-	hw->read_fws(dev, PCI_CFG_HFS_5, &fwsts5);
-	trace_mei_pci_cfg_read(&dev->dev, "PCI_CFG_HFS_5", PCI_CFG_HFS_5, fwsts5);
+	hw->read_fws(dev, PCI_CFG_HFS_5, "PCI_CFG_HFS_5", &fwsts5);
 
 	if ((fwsts5 & GSC_CFG_HFS_5_BOOT_TYPE_MSK) == GSC_CFG_HFS_5_BOOT_TYPE_PXP) {
 		if (dev->gsc_reset_to_pxp == MEI_DEV_RESET_TO_PXP_DEFAULT)
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 843ec2497b52..9df5899d2602 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -56,7 +56,7 @@ struct mei_me_hw {
 	enum mei_pg_state pg_state;
 	bool d0i3_supported;
 	u8 hbuf_depth;
-	int (*read_fws)(const struct mei_device *dev, int where, u32 *val);
+	int (*read_fws)(const struct mei_device *dev, int where, const char *name, u32 *val);
 	/* polling */
 	struct task_struct *polling_thread;
 	wait_queue_head_t wait_active;
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index fe5d5aee074c..b4c9526857bb 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -23,6 +23,7 @@
 #include "client.h"
 #include "hw-me-regs.h"
 #include "hw-me.h"
+#include "mei-trace.h"
 
 /* mei_pci_tbl - PCI Device ID Table */
 static const struct pci_device_id mei_me_pci_tbl[] = {
@@ -145,11 +146,14 @@ static inline void mei_me_set_pm_domain(struct mei_device *dev) {}
 static inline void mei_me_unset_pm_domain(struct mei_device *dev) {}
 #endif /* CONFIG_PM */
 
-static int mei_me_read_fws(const struct mei_device *dev, int where, u32 *val)
+static int mei_me_read_fws(const struct mei_device *dev, int where, const char *name, u32 *val)
 {
 	struct pci_dev *pdev = to_pci_dev(dev->parent);
+	int ret;
 
-	return pci_read_config_dword(pdev, where, val);
+	ret = pci_read_config_dword(pdev, where, val);
+	trace_mei_pci_cfg_read(&dev->dev, name, where, *val);
+	return ret;
 }
 
 /**
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 4/7] mei: trace: print return value of pci_cfg_read
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
                   ` (2 preceding siblings ...)
  2026-02-01  9:43 ` [char-misc-next 3/7] mei: me: move trace into firmware status read Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 5/7] mei: convert PCI error to common errno Alexander Usyskin
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Andy Shevchenko

Extend debug capabilities.
Add return value print in the trace_mei_pci_cfg_read().

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/hw-me.c     | 15 +++++++++------
 drivers/misc/mei/hw-txe.c    |  2 +-
 drivers/misc/mei/mei-trace.h | 10 ++++++----
 drivers/misc/mei/pci-me.c    |  2 +-
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index c0d4a02d9cae..72a7cfb2989f 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1505,10 +1505,11 @@ static bool mei_me_fw_type_nm(const struct pci_dev *pdev)
 {
 	u32 reg;
 	unsigned int devfn;
+	int ret;
 
 	devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
-	pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_2, &reg);
-	trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_2", PCI_CFG_HFS_2, reg);
+	ret = pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_2, &reg);
+	trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_2", PCI_CFG_HFS_2, reg, ret);
 	/* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
 	return (reg & 0x600) == 0x200;
 }
@@ -1531,10 +1532,11 @@ static bool mei_me_fw_type_sps_4(const struct pci_dev *pdev)
 {
 	u32 reg;
 	unsigned int devfn;
+	int ret;
 
 	devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
-	pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_1, &reg);
-	trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg);
+	ret = pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_1, &reg);
+	trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg, ret);
 	return (reg & PCI_CFG_HFS_1_OPMODE_MSK) == PCI_CFG_HFS_1_OPMODE_SPS;
 }
 
@@ -1556,10 +1558,11 @@ static bool mei_me_fw_type_sps_ign(const struct pci_dev *pdev)
 	u32 reg;
 	u32 fw_type;
 	unsigned int devfn;
+	int ret;
 
 	devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
-	pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_3, &reg);
-	trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_3", PCI_CFG_HFS_3, reg);
+	ret = pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_3, &reg);
+	trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_3", PCI_CFG_HFS_3, reg, ret);
 	fw_type = (reg & PCI_CFG_HFS_3_FW_SKU_MSK);
 
 	dev_dbg(&pdev->dev, "fw type is %d\n", fw_type);
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index e4688c391027..008cb1ede56c 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -651,7 +651,7 @@ static int mei_txe_fw_status(struct mei_device *dev,
 					    &fw_status->status[i]);
 		trace_mei_pci_cfg_read(&dev->dev, "PCI_CFG_HSF_X",
 				       fw_src->status[i],
-				       fw_status->status[i]);
+				       fw_status->status[i], ret);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/misc/mei/mei-trace.h b/drivers/misc/mei/mei-trace.h
index 24fa321d88bd..fa5224e5353a 100644
--- a/drivers/misc/mei/mei-trace.h
+++ b/drivers/misc/mei/mei-trace.h
@@ -55,22 +55,24 @@ TRACE_EVENT(mei_reg_write,
 );
 
 TRACE_EVENT(mei_pci_cfg_read,
-	TP_PROTO(const struct device *dev, const char *reg, u32 offs, u32 val),
-	TP_ARGS(dev, reg, offs, val),
+	TP_PROTO(const struct device *dev, const char *reg, u32 offs, u32 val, int ret),
+	TP_ARGS(dev, reg, offs, val, ret),
 	TP_STRUCT__entry(
 		__string(dev, dev_name(dev))
 		__string(reg, reg)
 		__field(u32, offs)
 		__field(u32, val)
+		__field(int, ret)
 	),
 	TP_fast_assign(
 		__assign_str(dev);
 		__assign_str(reg);
 		__entry->offs = offs;
 		__entry->val = val;
+		__entry->ret = ret;
 	),
-	TP_printk("[%s] pci cfg read %s:[%#x] = %#x",
-		  __get_str(dev), __get_str(reg), __entry->offs, __entry->val)
+	TP_printk("[%s] pci cfg read %s:[%#x] = %#x, ret = %d",
+		  __get_str(dev), __get_str(reg), __entry->offs, __entry->val, __entry->ret)
 );
 
 #endif /* _MEI_TRACE_H_ */
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index b4c9526857bb..a75773cc8fb7 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -152,7 +152,7 @@ static int mei_me_read_fws(const struct mei_device *dev, int where, const char *
 	int ret;
 
 	ret = pci_read_config_dword(pdev, where, val);
-	trace_mei_pci_cfg_read(&dev->dev, name, where, *val);
+	trace_mei_pci_cfg_read(&dev->dev, name, where, *val, ret);
 	return ret;
 }
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 5/7] mei: convert PCI error to common errno
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
                   ` (3 preceding siblings ...)
  2026-02-01  9:43 ` [char-misc-next 4/7] mei: trace: print return value of pci_cfg_read Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 6/7] mei: csc: support controller with separate PCI device Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 7/7] mei: csc: wake device while reading firmware status Alexander Usyskin
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Mika Westerberg

Ensure that callers receive only < 0 return value on error.
Convert PCI error returned by pci_read_config_dword()
to common errno before returning from function.

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/hw-txe.c | 2 +-
 drivers/misc/mei/pci-me.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index 008cb1ede56c..a83de653c603 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -653,7 +653,7 @@ static int mei_txe_fw_status(struct mei_device *dev,
 				       fw_src->status[i],
 				       fw_status->status[i], ret);
 		if (ret)
-			return ret;
+			return pcibios_err_to_errno(ret);
 	}
 
 	return 0;
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index a75773cc8fb7..8d16bfa6027c 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -153,7 +153,7 @@ static int mei_me_read_fws(const struct mei_device *dev, int where, const char *
 
 	ret = pci_read_config_dword(pdev, where, val);
 	trace_mei_pci_cfg_read(&dev->dev, name, where, *val, ret);
-	return ret;
+	return pcibios_err_to_errno(ret);
 }
 
 /**
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 6/7] mei: csc: support controller with separate PCI device
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
                   ` (4 preceding siblings ...)
  2026-02-01  9:43 ` [char-misc-next 5/7] mei: convert PCI error to common errno Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  2026-02-01  9:43 ` [char-misc-next 7/7] mei: csc: wake device while reading firmware status Alexander Usyskin
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Mika Westerberg

Intel PCI driver for chassis controller embedded in Intel graphics
devices.

An MEI device here called CSC can be embedded in discrete
Intel graphics devices having separate PCI device, to support a range
of chassis tasks such as graphics card firmware update and security tasks.

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/Kconfig      |  11 ++
 drivers/misc/mei/Makefile     |   3 +
 drivers/misc/mei/hw-me-regs.h |   3 +
 drivers/misc/mei/hw-me.c      |  27 ++++
 drivers/misc/mei/hw-me.h      |   2 +
 drivers/misc/mei/init.c       |   4 +-
 drivers/misc/mei/mei_dev.h    |   3 +
 drivers/misc/mei/pci-csc.c    | 259 ++++++++++++++++++++++++++++++++++
 8 files changed, 311 insertions(+), 1 deletion(-)
 create mode 100644 drivers/misc/mei/pci-csc.c

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index 5902dd1ee44b..8d192c3a1d59 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -58,6 +58,17 @@ config INTEL_MEI_GSC
 	  tasks such as graphics card firmware update and security
 	  tasks.
 
+config INTEL_MEI_CSC
+	tristate "Intel MEI CSC embedded device"
+	depends on INTEL_MEI_ME
+	help
+	  Intel PCI driver for the chassis controller embedded in Intel graphics devices.
+
+	  An MEI device here called CSC can be embedded in discrete
+	  Intel graphics devices, to support a range of chassis
+	  tasks such as graphics card firmware update and security
+	  tasks.
+
 config INTEL_MEI_VSC_HW
 	tristate "Intel visual sensing controller device transport driver"
 	depends on ACPI && SPI
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index a203ed766b33..9a6aa335921e 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -21,6 +21,9 @@ mei-me-objs += hw-me.o
 obj-$(CONFIG_INTEL_MEI_GSC) += mei-gsc.o
 mei-gsc-objs := gsc-me.o
 
+obj-$(CONFIG_INTEL_MEI_CSC) += mei-csc.o
+mei-csc-objs := pci-csc.o
+
 obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o
 mei-txe-objs := pci-txe.o
 mei-txe-objs += hw-txe.o
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index 840e1fd2714c..9b1675f98404 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -124,6 +124,8 @@
 
 #define PCI_DEVICE_ID_INTEL_MEI_NVL_S      0x6E68  /* Nova Lake Point S */
 
+#define PCI_DEVICE_ID_INTEL_MEI_CRI        0x6766  /* Crescent Island */
+
 /*
  * MEI HW Section
  */
@@ -134,6 +136,7 @@
 #  define PCI_CFG_HFS_1_OPMODE_MSK 0xf0000 /* OP MODE Mask: SPS <= 4.0 */
 #  define PCI_CFG_HFS_1_OPMODE_SPS 0xf0000 /* SPS SKU : SPS <= 4.0 */
 #define PCI_CFG_HFS_2         0x48
+#  define PCI_CFG_HFS_2_D3_BLOCK              BIT(7)
 #  define PCI_CFG_HFS_2_PM_CMOFF_TO_CMX_ERROR 0x1000000 /* CMoff->CMx wake after an error */
 #  define PCI_CFG_HFS_2_PM_CM_RESET_ERROR     0x5000000 /* CME reset due to exception */
 #  define PCI_CFG_HFS_2_PM_EVENT_MASK         0xf000000
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 72a7cfb2989f..3412a7b5b0e8 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -224,6 +224,15 @@ static int mei_me_fw_status(struct mei_device *dev,
 	return 0;
 }
 
+static bool mei_csc_pg_blocked(struct mei_device *dev)
+{
+	struct mei_me_hw *hw = to_me_hw(dev);
+	u32 reg = 0;
+
+	hw->read_fws(dev, PCI_CFG_HFS_2, "PCI_CFG_HFS_2", &reg);
+	return (reg & PCI_CFG_HFS_2_D3_BLOCK) == PCI_CFG_HFS_2_D3_BLOCK;
+}
+
 /**
  * mei_me_hw_config - configure hw dependent settings
  *
@@ -1206,6 +1215,7 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
 				return ret;
 		} else {
 			hw->pg_state = MEI_PG_OFF;
+			dev->pg_blocked = mei_csc_pg_blocked(dev);
 		}
 	}
 
@@ -1294,6 +1304,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
 {
 	struct mei_device *dev = (struct mei_device *) dev_id;
 	struct list_head cmpl_list;
+	bool pg_blocked;
 	s32 slots;
 	u32 hcsr;
 	int rets = 0;
@@ -1351,6 +1362,14 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
 		}
 		goto end;
 	}
+
+	pg_blocked = mei_csc_pg_blocked(dev);
+	if (pg_blocked && !dev->pg_blocked) /* PG block requested */
+		pm_request_resume(&dev->dev);
+	else if (!pg_blocked && dev->pg_blocked) /* PG block lifted */
+		pm_request_autosuspend(&dev->dev);
+	dev->pg_blocked = pg_blocked;
+
 	/* check slots available for reading */
 	slots = mei_count_full_read_slots(dev);
 	while (slots > 0) {
@@ -1726,6 +1745,13 @@ static const struct mei_cfg mei_me_gscfi_cfg = {
 	MEI_CFG_FW_VER_SUPP,
 };
 
+/* Chassis System Controller Firmware Interface */
+static const struct mei_cfg mei_me_csc_cfg = {
+	MEI_CFG_TYPE_GSCFI,
+	MEI_CFG_PCH8_HFS,
+	MEI_CFG_FW_VER_SUPP,
+};
+
 /*
  * mei_cfg_list - A list of platform platform specific configurations.
  * Note: has to be synchronized with  enum mei_cfg_idx.
@@ -1748,6 +1774,7 @@ static const struct mei_cfg *const mei_cfg_list[] = {
 	[MEI_ME_PCH15_SPS_CFG] = &mei_me_pch15_sps_cfg,
 	[MEI_ME_GSC_CFG] = &mei_me_gsc_cfg,
 	[MEI_ME_GSCFI_CFG] = &mei_me_gscfi_cfg,
+	[MEI_ME_CSC_CFG] = &mei_me_csc_cfg,
 };
 
 const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx)
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 9df5899d2602..8da8662a9d61 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -104,6 +104,7 @@ static inline bool mei_me_hw_use_polling(const struct mei_me_hw *hw)
  *                         SPS firmware exclusion.
  * @MEI_ME_GSC_CFG:        Graphics System Controller
  * @MEI_ME_GSCFI_CFG:      Graphics System Controller Firmware Interface
+ * @MEI_ME_CSC_CFG:        Chassis System Controller Firmware Interface
  * @MEI_ME_NUM_CFG:        Upper Sentinel.
  */
 enum mei_cfg_idx {
@@ -124,6 +125,7 @@ enum mei_cfg_idx {
 	MEI_ME_PCH15_SPS_CFG,
 	MEI_ME_GSC_CFG,
 	MEI_ME_GSCFI_CFG,
+	MEI_ME_CSC_CFG,
 	MEI_ME_NUM_CFG,
 };
 
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index f54991b40fc7..766f119f7ed0 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -344,13 +344,15 @@ EXPORT_SYMBOL_GPL(mei_stop);
 bool mei_write_is_idle(struct mei_device *dev)
 {
 	bool idle = (dev->dev_state == MEI_DEV_ENABLED &&
+		!dev->pg_blocked &&
 		list_empty(&dev->ctrl_wr_list) &&
 		list_empty(&dev->write_list)   &&
 		list_empty(&dev->write_waiting_list));
 
-	dev_dbg(&dev->dev, "write pg: is idle[%d] state=%s ctrl=%d write=%d wwait=%d\n",
+	dev_dbg(&dev->dev, "write pg: is idle[%d] state=%s blocked=%d ctrl=%d write=%d wwait=%d\n",
 		idle,
 		mei_dev_state_str(dev->dev_state),
+		dev->pg_blocked,
 		list_empty(&dev->ctrl_wr_list),
 		list_empty(&dev->write_list),
 		list_empty(&dev->write_waiting_list));
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 0bf8d552c3ea..1796c6793a94 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -490,6 +490,7 @@ struct mei_dev_timeouts {
  * @timer_work  : MEI timer delayed work (timeouts)
  *
  * @recvd_hw_ready : hw ready message received flag
+ * @pg_blocked  : low power mode is not allowed
  *
  * @wait_hw_ready : wait queue for receive HW ready message form FW
  * @wait_pg     : wait queue for receive PG message from FW
@@ -575,6 +576,8 @@ struct mei_device {
 	struct delayed_work timer_work;
 
 	bool recvd_hw_ready;
+	bool pg_blocked;
+
 	/*
 	 * waiting queue for receive message from FW
 	 */
diff --git a/drivers/misc/mei/pci-csc.c b/drivers/misc/mei/pci-csc.c
new file mode 100644
index 000000000000..15e170b1e0b6
--- /dev/null
+++ b/drivers/misc/mei/pci-csc.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025-2026, Intel Corporation. All rights reserved.
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * for CSC platforms.
+ */
+
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include "client.h"
+#include "hw-me-regs.h"
+#include "hw-me.h"
+#include "mei_dev.h"
+#include "mei-trace.h"
+
+#define MEI_CSC_HECI2_OFFSET 0x1000
+
+static int mei_csc_read_fws(const struct mei_device *mdev, int where, const char *name, u32 *val)
+{
+	struct mei_me_hw *hw = to_me_hw(mdev);
+
+	*val = ioread32(hw->mem_addr + where + 0xC00);
+	trace_mei_reg_read(&mdev->dev, name, where, *val);
+	return 0;
+}
+
+static int mei_csc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	struct device *dev = &pdev->dev;
+	const struct mei_cfg *cfg;
+	char __iomem *registers;
+	struct mei_device *mdev;
+	struct mei_me_hw *hw;
+	int err;
+
+	cfg = mei_me_get_cfg(ent->driver_data);
+	if (!cfg)
+		return -ENODEV;
+
+	err = pcim_enable_device(pdev);
+	if (err)
+		return dev_err_probe(dev, err, "Failed to enable PCI device.\n");
+
+	pci_set_master(pdev);
+
+	registers = pcim_iomap_region(pdev, 0, KBUILD_MODNAME);
+	if (IS_ERR(registers))
+		return dev_err_probe(dev, PTR_ERR(registers), "Failed to get PCI region.\n");
+
+	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+	if (err)
+		return dev_err_probe(dev, err, "No usable DMA configuration.\n");
+
+	/* allocates and initializes the mei dev structure */
+	mdev = mei_me_dev_init(dev, cfg, false);
+	if (!mdev)
+		return -ENOMEM;
+
+	hw = to_me_hw(mdev);
+
+	/*
+	 * Both HECI1 and HECI2 are on this device, but only HECI2 is supported.
+	 */
+	hw->mem_addr = registers + MEI_CSC_HECI2_OFFSET;
+	hw->read_fws = mei_csc_read_fws;
+
+	/*
+	 * mei_register() assumes ownership of mdev.
+	 * No need to release it explicitly in error path.
+	 */
+	err = mei_register(mdev, dev);
+	if (err)
+		return err;
+
+	pci_set_drvdata(pdev, mdev);
+
+	err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_INTX | PCI_IRQ_MSI);
+	if (err < 0) {
+		dev_err_probe(dev, err, "Failed to allocate IRQ.\n");
+		goto err_mei_unreg;
+	}
+
+	hw->irq = pci_irq_vector(pdev, 0);
+
+	/* request and enable interrupt */
+	err = request_threaded_irq(hw->irq,
+				   mei_me_irq_quick_handler, mei_me_irq_thread_handler,
+				   IRQF_SHARED | IRQF_ONESHOT, KBUILD_MODNAME, mdev);
+	if (err)
+		goto err_free_irq_vectors;
+
+	/*
+	 * Continue to char device setup in spite of firmware handshake failure.
+	 * In order to provide access to the firmware status registers to the user
+	 * space via sysfs. The firmware status registers required to understand
+	 * firmware error state and possible recovery flow.
+	 */
+	if (mei_start(mdev))
+		dev_warn(dev, "Failed to initialize HECI hardware.\n");
+
+	pm_runtime_set_autosuspend_delay(dev, MEI_ME_RPM_TIMEOUT);
+	pm_runtime_use_autosuspend(dev);
+
+	/*
+	 * MEI requires to resume from runtime suspend mode
+	 * in order to perform link reset flow upon system suspend.
+	 */
+	dev_pm_set_driver_flags(dev, DPM_FLAG_NO_DIRECT_COMPLETE);
+
+	pm_runtime_allow(dev);
+	pm_runtime_put_noidle(dev);
+
+	return 0;
+
+err_free_irq_vectors:
+	pci_free_irq_vectors(pdev);
+err_mei_unreg:
+	mei_deregister(mdev);
+	return err;
+}
+
+static void mei_csc_shutdown(struct pci_dev *pdev)
+{
+	struct mei_device *mdev = pci_get_drvdata(pdev);
+	struct mei_me_hw *hw = to_me_hw(mdev);
+
+	pm_runtime_get_noresume(&pdev->dev);
+
+	mei_stop(mdev);
+
+	mei_disable_interrupts(mdev);
+	free_irq(hw->irq, mdev);
+	pci_free_irq_vectors(pdev);
+}
+
+static void mei_csc_remove(struct pci_dev *pdev)
+{
+	struct mei_device *mdev = pci_get_drvdata(pdev);
+
+	mei_csc_shutdown(pdev);
+
+	mei_deregister(mdev);
+}
+
+static int mei_csc_pci_prepare(struct device *dev)
+{
+	pm_runtime_resume(dev);
+	return 0;
+}
+
+static int mei_csc_pci_suspend(struct device *dev)
+{
+	struct mei_device *mdev = dev_get_drvdata(dev);
+
+	mei_stop(mdev);
+
+	mei_disable_interrupts(mdev);
+
+	return 0;
+}
+
+static int mei_csc_pci_resume(struct device *dev)
+{
+	struct mei_device *mdev = dev_get_drvdata(dev);
+	int err;
+
+	err = mei_restart(mdev);
+	if (err)
+		return err;
+
+	/* Start timer if stopped in suspend */
+	schedule_delayed_work(&mdev->timer_work, HZ);
+
+	return 0;
+}
+
+static void mei_csc_pci_complete(struct device *dev)
+{
+	pm_runtime_suspend(dev);
+}
+
+static int mei_csc_pm_runtime_idle(struct device *dev)
+{
+	struct mei_device *mdev = dev_get_drvdata(dev);
+
+	return mei_write_is_idle(mdev) ? 0 : -EBUSY;
+}
+
+static int mei_csc_pm_runtime_suspend(struct device *dev)
+{
+	struct mei_device *mdev = dev_get_drvdata(dev);
+	struct mei_me_hw *hw = to_me_hw(mdev);
+
+	guard(mutex)(&mdev->device_lock);
+
+	if (!mei_write_is_idle(mdev))
+		return -EAGAIN;
+
+	hw->pg_state = MEI_PG_ON;
+	return 0;
+}
+
+static int mei_csc_pm_runtime_resume(struct device *dev)
+{
+	struct mei_device *mdev = dev_get_drvdata(dev);
+	struct mei_me_hw *hw = to_me_hw(mdev);
+	irqreturn_t irq_ret;
+
+	scoped_guard(mutex, &mdev->device_lock)
+		hw->pg_state = MEI_PG_OFF;
+
+	/* Process all queues that wait for resume */
+	irq_ret = mei_me_irq_thread_handler(1, mdev);
+	if (irq_ret != IRQ_HANDLED)
+		dev_err(dev, "thread handler fail %d\n", irq_ret);
+
+	return 0;
+}
+
+static const struct dev_pm_ops mei_csc_pm_ops = {
+	.prepare = pm_sleep_ptr(mei_csc_pci_prepare),
+	.complete = pm_sleep_ptr(mei_csc_pci_complete),
+	SYSTEM_SLEEP_PM_OPS(mei_csc_pci_suspend, mei_csc_pci_resume)
+	RUNTIME_PM_OPS(mei_csc_pm_runtime_suspend,
+		       mei_csc_pm_runtime_resume, mei_csc_pm_runtime_idle)
+};
+
+static const struct pci_device_id mei_csc_pci_tbl[] = {
+	{ PCI_DEVICE_DATA(INTEL, MEI_CRI, MEI_ME_CSC_CFG) },
+	{}
+};
+MODULE_DEVICE_TABLE(pci, mei_csc_pci_tbl);
+
+static struct pci_driver mei_csc_driver = {
+	.name = KBUILD_MODNAME,
+	.id_table = mei_csc_pci_tbl,
+	.probe = mei_csc_probe,
+	.remove = mei_csc_remove,
+	.shutdown = mei_csc_shutdown,
+	.driver = {
+		.pm = &mei_csc_pm_ops,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	}
+};
+module_pci_driver(mei_csc_driver);
+
+MODULE_DESCRIPTION("Intel(R) Management Engine Interface for discrete graphics (CSC)");
+MODULE_LICENSE("GPL");
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [char-misc-next 7/7] mei: csc: wake device while reading firmware status
  2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
                   ` (5 preceding siblings ...)
  2026-02-01  9:43 ` [char-misc-next 6/7] mei: csc: support controller with separate PCI device Alexander Usyskin
@ 2026-02-01  9:43 ` Alexander Usyskin
  6 siblings, 0 replies; 8+ messages in thread
From: Alexander Usyskin @ 2026-02-01  9:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Menachem Adin, Alexander Usyskin, linux-kernel, Mika Westerberg

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: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/misc/mei/main.c    | 18 ++++++++++++++----
 drivers/misc/mei/mei_dev.h |  2 ++
 drivers/misc/mei/pci-csc.c |  2 ++
 3 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 6f26d5160788..54f70f513482 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -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;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 1796c6793a94..d8634a726990 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -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
diff --git a/drivers/misc/mei/pci-csc.c b/drivers/misc/mei/pci-csc.c
index 15e170b1e0b6..70792bf9b3c0 100644
--- a/drivers/misc/mei/pci-csc.c
+++ b/drivers/misc/mei/pci-csc.c
@@ -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);
 
 	/*
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-02-01 10:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-01  9:43 [char-misc-next 0/7] mei: csc: support controller with separate PCI device Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 1/7] mei: me: use PCI_DEVICE_DATA macro Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 2/7] mei: fix idle print specifiers Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 3/7] mei: me: move trace into firmware status read Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 4/7] mei: trace: print return value of pci_cfg_read Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 5/7] mei: convert PCI error to common errno Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 6/7] mei: csc: support controller with separate PCI device Alexander Usyskin
2026-02-01  9:43 ` [char-misc-next 7/7] mei: csc: wake device while reading firmware status Alexander Usyskin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®