ACPI: platform_profile: Check all profile handler to calculate next
authorMario Limonciello <mario.limonciello@amd.com>
Fri, 6 Dec 2024 03:19:14 +0000 (21:19 -0600)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 10 Dec 2024 17:18:14 +0000 (19:18 +0200)
As multiple platform profile handlers might not all support the same
profile, cycling to the next profile could have a different result
depending on what handler are registered.

Check what is active and supported by all handlers to decide what
to do.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20241206031918.1537-19-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/acpi/platform_profile.c

index 95aff045a1eb3c19a72c9be5176c050fc7b6927d..a1fdc56537baf37db071984c3db317ed7bcbff1a 100644 (file)
@@ -418,25 +418,37 @@ EXPORT_SYMBOL_GPL(platform_profile_notify);
 
 int platform_profile_cycle(void)
 {
-       enum platform_profile_option profile;
-       enum platform_profile_option next;
+       enum platform_profile_option next = PLATFORM_PROFILE_LAST;
+       enum platform_profile_option profile = PLATFORM_PROFILE_LAST;
+       unsigned long choices[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
        int err;
 
+       set_bit(PLATFORM_PROFILE_LAST, choices);
        scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
-               if (!cur_profile)
-                       return -ENODEV;
+               err = class_for_each_device(&platform_profile_class, NULL,
+                                           &profile, _aggregate_profiles);
+               if (err)
+                       return err;
 
-               err = cur_profile->profile_get(cur_profile, &profile);
+               if (profile == PLATFORM_PROFILE_CUSTOM ||
+                   profile == PLATFORM_PROFILE_LAST)
+                       return -EINVAL;
+
+               err = class_for_each_device(&platform_profile_class, NULL,
+                                           choices, _aggregate_choices);
                if (err)
                        return err;
 
-               next = find_next_bit_wrap(cur_profile->choices, PLATFORM_PROFILE_LAST,
+               /* never iterate into a custom if all drivers supported it */
+               clear_bit(PLATFORM_PROFILE_CUSTOM, choices);
+
+               next = find_next_bit_wrap(choices,
+                                         PLATFORM_PROFILE_LAST,
                                          profile + 1);
 
-               if (WARN_ON(next == PLATFORM_PROFILE_LAST))
-                       return -EINVAL;
+               err = class_for_each_device(&platform_profile_class, NULL, &next,
+                                           _store_and_notify);
 
-               err = cur_profile->profile_set(cur_profile, next);
                if (err)
                        return err;
        }