powercap: intel_rapl_tpmi: Fix System Domain probing
authorZhang Rui <rui.zhang@intel.com>
Wed, 31 Jan 2024 11:37:11 +0000 (19:37 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 13 Feb 2024 16:31:48 +0000 (17:31 +0100)
Only domain root packages can enumerate System (Psys) domain.
Whether a package is domain root or not is described in the Bit 0 of the
Domain Info register.

Add support for Domain Info register and fix the System domain probing
accordingly.

Fixes: 9eef7f9da928 ("powercap: intel_rapl: Introduce RAPL TPMI interface driver")
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Cc: 6.5+ <stable@vger.kernel.org> # 6.5+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/powercap/intel_rapl_tpmi.c

index f1c734ac3c3498038247b01144a1cf3ccec7b815..f6b7f085977ce1c80e2716fc43ba4152486ba195 100644 (file)
@@ -131,6 +131,12 @@ static void trp_release(struct tpmi_rapl_package *trp)
        mutex_unlock(&tpmi_rapl_lock);
 }
 
+/*
+ * Bit 0 of TPMI_RAPL_REG_DOMAIN_INFO indicates if the current package is a domain
+ * root or not. Only domain root packages can enumerate System (Psys) Domain.
+ */
+#define TPMI_RAPL_DOMAIN_ROOT  BIT(0)
+
 static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
 {
        u8 tpmi_domain_version;
@@ -140,6 +146,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
        enum rapl_domain_reg_id reg_id;
        int tpmi_domain_size, tpmi_domain_flags;
        u64 tpmi_domain_header = readq(trp->base + offset);
+       u64 tpmi_domain_info;
 
        /* Domain Parent bits are ignored for now */
        tpmi_domain_version = tpmi_domain_header & 0xff;
@@ -170,6 +177,13 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset)
                domain_type = RAPL_DOMAIN_PACKAGE;
                break;
        case TPMI_RAPL_DOMAIN_SYSTEM:
+               if (!(tpmi_domain_flags & BIT(TPMI_RAPL_REG_DOMAIN_INFO))) {
+                       pr_warn(FW_BUG "System domain must support Domain Info register\n");
+                       return -ENODEV;
+               }
+               tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO);
+               if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT))
+                       return 0;
                domain_type = RAPL_DOMAIN_PLATFORM;
                break;
        case TPMI_RAPL_DOMAIN_MEMORY: