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;
        }