Skip to content

Commit

Permalink
ACPI: platform_profile: Only show profiles common for all handlers
Browse files Browse the repository at this point in the history
If multiple platform profile handlers have been registered, don't allow
switching to profiles unique to only one handler.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Tested-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Tested-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20241206031918.1537-16-mario.limonciello@amd.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
  • Loading branch information
Mario Limonciello authored and Ilpo Järvinen committed Dec 10, 2024
1 parent e5fe5dd commit 06ec243
Showing 1 changed file with 44 additions and 10 deletions.
54 changes: 44 additions & 10 deletions drivers/acpi/platform_profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,22 +198,56 @@ static const struct class platform_profile_class = {
.dev_groups = profile_groups,
};

/**
* _aggregate_choices - Aggregate the available profile choices
* @dev: The device
* @data: The available profile choices
*
* Return: 0 on success, -errno on failure
*/
static int _aggregate_choices(struct device *dev, void *data)
{
struct platform_profile_handler *handler;
unsigned long *aggregate = data;

lockdep_assert_held(&profile_lock);
handler = dev_get_drvdata(dev);
if (test_bit(PLATFORM_PROFILE_LAST, aggregate))
bitmap_copy(aggregate, handler->choices, PLATFORM_PROFILE_LAST);
else
bitmap_and(aggregate, handler->choices, aggregate, PLATFORM_PROFILE_LAST);

return 0;
}

/**
* platform_profile_choices_show - Show the available profile choices for legacy sysfs interface
* @dev: The device
* @attr: The attribute
* @buf: The buffer to write to
*
* Return: The number of bytes written
*/
static ssize_t platform_profile_choices_show(struct device *dev,
struct device_attribute *attr,
char *buf)
struct device_attribute *attr,
char *buf)
{
int len = 0;
int i;
unsigned long aggregate[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
int err;

set_bit(PLATFORM_PROFILE_LAST, aggregate);
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
if (!cur_profile)
return -ENODEV;
for_each_set_bit(i, cur_profile->choices, PLATFORM_PROFILE_LAST)
len += sysfs_emit_at(buf, len, len ? " %s": "%s", profile_names[i]);
err = class_for_each_device(&platform_profile_class, NULL,
aggregate, _aggregate_choices);
if (err)
return err;
}
len += sysfs_emit_at(buf, len, "\n");

return len;
/* no profile handler registered any more */
if (bitmap_empty(aggregate, PLATFORM_PROFILE_LAST))
return -EINVAL;

return _commmon_choices_show(aggregate, buf);
}

static ssize_t platform_profile_show(struct device *dev,
Expand Down

0 comments on commit 06ec243

Please sign in to comment.