Message ID | 20241109044151.29804-21-mario.limonciello@amd.com |
---|---|
State | New |
Headers | show |
Series | Add support for binding ACPI platform profile to multiple drivers | expand |
Am 09.11.24 um 05:41 schrieb Mario Limonciello: > Multiple drivers may attempt to register platform profile handlers, > but only one may be registered and the behavior is non-deterministic > for which one wins. It's mostly controlled by probing order. > > This can be problematic if one driver changes CPU settings and another > driver notifies the EC for changing fan curves. > > Modify the ACPI platform profile handler to let multiple drivers > register platform profile handlers and abstract this detail from userspace. > > To avoid undefined behaviors only offer profiles that are commonly > advertised across multiple handlers. > > If any problems occur when changing profiles for any driver, then the > drivers that were already changed remain changed and the legacy sysfs > handler will report 'custom'. 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: Armin Wolf <W_Armin@gmx.de> > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > --- > v6: > * rebase > v5: > * reword commit message > --- > drivers/acpi/platform_profile.c | 12 +----------- > 1 file changed, 1 insertion(+), 11 deletions(-) > > diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c > index 7ad473982ab11..0a8b86b44e161 100644 > --- a/drivers/acpi/platform_profile.c > +++ b/drivers/acpi/platform_profile.c > @@ -10,7 +10,6 @@ > #include <linux/platform_profile.h> > #include <linux/sysfs.h> > > -static struct platform_profile_handler *cur_profile; > static DEFINE_MUTEX(profile_lock); > > static const char * const profile_names[] = { > @@ -415,8 +414,7 @@ static const struct attribute_group platform_profile_group = { > > void platform_profile_notify(struct platform_profile_handler *pprof) > { > - if (!cur_profile) > - return; > + guard(mutex)(&profile_lock); > _notify_class_profile(NULL, pprof); > sysfs_notify(acpi_kobj, NULL, "platform_profile"); > } > @@ -480,9 +478,6 @@ int platform_profile_register(struct platform_profile_handler *pprof) > } > > guard(mutex)(&profile_lock); > - /* We can only have one active profile */ > - if (cur_profile) > - return -EEXIST; > > /* create class interface for individual handler */ > pprof->minor = ida_alloc(&platform_profile_ida, GFP_KERNEL); > @@ -498,8 +493,6 @@ int platform_profile_register(struct platform_profile_handler *pprof) > > sysfs_notify(acpi_kobj, NULL, "platform_profile"); > > - cur_profile = pprof; > - > err = sysfs_update_group(acpi_kobj, &platform_profile_group); > if (err) > goto cleanup_cur; > @@ -507,7 +500,6 @@ int platform_profile_register(struct platform_profile_handler *pprof) > return 0; > > cleanup_cur: > - cur_profile = NULL; > device_unregister(pprof->class_dev); > > cleanup_ida: > @@ -528,8 +520,6 @@ int platform_profile_remove(struct platform_profile_handler *pprof) > > sysfs_notify(acpi_kobj, NULL, "platform_profile"); > > - cur_profile = NULL; > - > sysfs_update_group(acpi_kobj, &platform_profile_group); > > return 0;
diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c index 7ad473982ab11..0a8b86b44e161 100644 --- a/drivers/acpi/platform_profile.c +++ b/drivers/acpi/platform_profile.c @@ -10,7 +10,6 @@ #include <linux/platform_profile.h> #include <linux/sysfs.h> -static struct platform_profile_handler *cur_profile; static DEFINE_MUTEX(profile_lock); static const char * const profile_names[] = { @@ -415,8 +414,7 @@ static const struct attribute_group platform_profile_group = { void platform_profile_notify(struct platform_profile_handler *pprof) { - if (!cur_profile) - return; + guard(mutex)(&profile_lock); _notify_class_profile(NULL, pprof); sysfs_notify(acpi_kobj, NULL, "platform_profile"); } @@ -480,9 +478,6 @@ int platform_profile_register(struct platform_profile_handler *pprof) } guard(mutex)(&profile_lock); - /* We can only have one active profile */ - if (cur_profile) - return -EEXIST; /* create class interface for individual handler */ pprof->minor = ida_alloc(&platform_profile_ida, GFP_KERNEL); @@ -498,8 +493,6 @@ int platform_profile_register(struct platform_profile_handler *pprof) sysfs_notify(acpi_kobj, NULL, "platform_profile"); - cur_profile = pprof; - err = sysfs_update_group(acpi_kobj, &platform_profile_group); if (err) goto cleanup_cur; @@ -507,7 +500,6 @@ int platform_profile_register(struct platform_profile_handler *pprof) return 0; cleanup_cur: - cur_profile = NULL; device_unregister(pprof->class_dev); cleanup_ida: @@ -528,8 +520,6 @@ int platform_profile_remove(struct platform_profile_handler *pprof) sysfs_notify(acpi_kobj, NULL, "platform_profile"); - cur_profile = NULL; - sysfs_update_group(acpi_kobj, &platform_profile_group); return 0;