@@ -99,6 +99,8 @@ static ssize_t platform_profile_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct platform_profile_handler *handler;
+ unsigned long choices;
int err, i;
/* Scan for a matching profile */
@@ -107,16 +109,29 @@ static ssize_t platform_profile_store(struct device *dev,
return -EINVAL;
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
- if (!cur_profile)
+ if (!platform_profile_is_registered())
return -ENODEV;
- /* Check that platform supports this profile choice */
- if (!test_bit(i, cur_profile->choices))
+ /* Check that all handlers support this profile choice */
+ choices = platform_profile_get_choices();
+ if (!test_bit(i, &choices))
return -EOPNOTSUPP;
- err = cur_profile->profile_set(cur_profile, i);
- if (err)
+ list_for_each_entry(handler, &platform_profile_handler_list, list) {
+ err = handler->profile_set(handler, i);
+ if (err) {
+ pr_err("Failed to set profile for handler %s\n", handler->name);
+ break;
+ }
+ }
+ if (err) {
+ list_for_each_entry_continue_reverse(handler, &platform_profile_handler_list, list) {
+ if (handler->profile_set(handler, PLATFORM_PROFILE_BALANCED))
+ pr_err("Failed to revert profile for handler %s\n",
+ handler->name);
+ }
return err;
+ }
}
sysfs_notify(acpi_kobj, NULL, "platform_profile");