]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ACPI: CPPC: Do not prevent CPPC from working in the future
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 21 Jul 2022 17:41:10 +0000 (19:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:24:25 +0000 (14:24 +0200)
[ Upstream commit 6a6eac6568f4ec7f37f217c39d8686fd4d053db6 ]

There is a problem with the current revision checks in
is_cppc_supported() that they essentially prevent the CPPC support
from working if a new _CPC package format revision being a proper
superset of the v3 and only causing _CPC to return a package with more
entries (while retaining the types and meaning of the entries defined by
the v3) is introduced in the future and used by the platform firmware.

In that case, as long as the number of entries in the _CPC return
package is at least CPPC_V3_NUM_ENT, it should be perfectly fine to
use the v3 support code and disregard the additional package entries
added by the new package format revision.

For this reason, drop is_cppc_supported() altogether, put the revision
checks directly into acpi_cppc_processor_probe() so they are easier to
follow and rework them to take the case mentioned above into account.

Fixes: 0ba5a50084d3 ("ACPI / CPPC: Add support for CPPC v3")
Cc: 4.18+ <stable@vger.kernel.org> # 4.18+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/acpi/cppc_acpi.c
include/acpi/cppc_acpi.h

index ed1341030684541354efcb087db7b7896118938c..7cc9183c8dc8eb0bd28cb09be61707f347ab6223 100644 (file)
@@ -597,33 +597,6 @@ static int pcc_data_alloc(int pcc_ss_id)
        return 0;
 }
 
-/* Check if CPPC revision + num_ent combination is supported */
-static bool is_cppc_supported(int revision, int num_ent)
-{
-       int expected_num_ent;
-
-       switch (revision) {
-       case CPPC_V2_REV:
-               expected_num_ent = CPPC_V2_NUM_ENT;
-               break;
-       case CPPC_V3_REV:
-               expected_num_ent = CPPC_V3_NUM_ENT;
-               break;
-       default:
-               pr_debug("Firmware exports unsupported CPPC revision: %d\n",
-                       revision);
-               return false;
-       }
-
-       if (expected_num_ent != num_ent) {
-               pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n",
-                       num_ent, expected_num_ent, revision);
-               return false;
-       }
-
-       return true;
-}
-
 /*
  * An example CPC table looks like the following.
  *
@@ -723,7 +696,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
                                cpc_obj->type);
                goto out_free;
        }
-       cpc_ptr->num_entries = num_ent;
 
        /* Second entry should be revision. */
        cpc_obj = &out_obj->package.elements[1];
@@ -734,10 +706,32 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
                                cpc_obj->type);
                goto out_free;
        }
-       cpc_ptr->version = cpc_rev;
 
-       if (!is_cppc_supported(cpc_rev, num_ent))
+       if (cpc_rev < CPPC_V2_REV) {
+               pr_debug("Unsupported _CPC Revision (%d) for CPU:%d\n", cpc_rev,
+                        pr->id);
+               goto out_free;
+       }
+
+       /*
+        * Disregard _CPC if the number of entries in the return pachage is not
+        * as expected, but support future revisions being proper supersets of
+        * the v3 and only causing more entries to be returned by _CPC.
+        */
+       if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) ||
+           (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) ||
+           (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) {
+               pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n",
+                        num_ent, pr->id);
                goto out_free;
+       }
+       if (cpc_rev > CPPC_V3_REV) {
+               num_ent = CPPC_V3_NUM_ENT;
+               cpc_rev = CPPC_V3_REV;
+       }
+
+       cpc_ptr->num_entries = num_ent;
+       cpc_ptr->version = cpc_rev;
 
        /* Iterate through remaining entries in _CPC */
        for (i = 2; i < num_ent; i++) {
index bc159a9b4a7331c5b461206399753a809baef26f..6b14414b9ec125427b5f58c322d8d10f857c2169 100644 (file)
@@ -17,7 +17,7 @@
 #include <acpi/pcc.h>
 #include <acpi/processor.h>
 
-/* Support CPPCv2 and CPPCv3  */
+/* CPPCv2 and CPPCv3 support */
 #define CPPC_V2_REV    2
 #define CPPC_V3_REV    3
 #define CPPC_V2_NUM_ENT        21