Re: [PATCH 1/2] hp-wmi: Modernize hp_wmi_perform_query() to use the modern API
Armin Wolf <[email protected]> Thu, 30 Jul 2026 18:36:30 +0200
| Newsgroups | org.kernel.vger.platform-driver-x86 |
|---|---|
| Message-ID | <[email protected]> |
Am 22.07.26 um 00:20 schrieb yahia: > From: yahia ahmed <[email protected]> > > hp_wmi_perform_query() currently uses the deprecated GUID-based WMI > interface wmi_evaluate_method(). > > Migrate hp-wmi to the modern bus-based WMI API by registering a > struct wmi_driver and replacing wmi_evaluate_method() calls with > wmidev_evaluate_method(). Hi, using the WMI device as a global variable is not a good idea, especially w= ithout locking. I suggest that you instead perform much of the setup done in hp_wmi_init()= inside the WMI driver probe() callback and replace the usage of global variables with= a state container: https://docs.kernel.org/driver-api/driver-model/design-patterns.html Doing so requires that you first move the WMI event handling into a proper= WMI event driver, see https://docs.kernel.org/wmi/driver-development-guide.html (sections "W= MI event drivers" and "Handling multiple WMI devices at once") for details. You can use the = uniwill-wmi driver as an inspiration regarding WMI event handling coupled with notifier block= s. Thanks, Armin Wolf > Suggested-by: Ilpo J=C3=A4rvinen <[email protected]> > Signed-off-by: yahia ahmed <[email protected]> > --- > drivers/platform/x86/hp/hp-wmi.c | 49 ++++++++++++++++++++++++++++---- > 1 file changed, 44 insertions(+), 5 deletions(-) > > diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/= hp-wmi.c > index 8ba286ed8721..5845b169df39 100644 > --- a/drivers/platform/x86/hp/hp-wmi.c > +++ b/drivers/platform/x86/hp/hp-wmi.c > @@ -14,6 +14,7 @@ > #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > =20 > #include <linux/acpi.h> > +#include <linux/wmi.h> > #include <linux/cleanup.h> > #include <linux/compiler_attributes.h> > #include <linux/dmi.h> > @@ -506,6 +507,14 @@ struct hp_wmi_hwmon_priv { > struct delayed_work keep_alive_dwork; > }; > =20 > +struct wmi_device *hp_wmi_wdev; > + > +static const struct wmi_device_id hp_wmi_guid_table[] =3D { > + { .guid_string =3D HPWMI_BIOS_GUID }, > + {} > +}; > +MODULE_DEVICE_TABLE(wmi, hp_wmi_guid_table); > + > struct victus_s_fan_table_header { > u8 num_fans; > u8 unknown; > @@ -606,7 +615,7 @@ static int hp_wmi_perform_query(int query, enum hp_w= mi_command command, > args->datasize =3D insize; > memcpy(args->data, buffer, flex_array_size(args, data, insize)); > =20 > - ret =3D wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output); > + ret =3D wmidev_evaluate_method(hp_wmi_wdev, 0, mid, &input, &output); > if (ret) > goto out_free; > =20 > @@ -2717,14 +2726,40 @@ static void __init setup_active_thermal_profile_= params(void) > } > } > =20 > +static int hp_wmi_probe(struct wmi_device *wdev, const void *context) > +{ > + hp_wmi_wdev =3D wdev; > + return 0; > +} > + > +static void hp_wmi_remove(struct wmi_device *wdev) > +{ > + hp_wmi_wdev =3D NULL; > +} > + > +static struct wmi_driver hp_wmi_wdev_driver =3D { > + .driver =3D { > + .name =3D "hp-wmi-wdev", > + }, > + .id_table =3D hp_wmi_guid_table, > + .probe =3D hp_wmi_probe, > + .remove =3D hp_wmi_remove, > +}; > + > + > static int __init hp_wmi_init(void) > { > int event_capable =3D wmi_has_guid(HPWMI_EVENT_GUID); > int bios_capable =3D wmi_has_guid(HPWMI_BIOS_GUID); > int err, tmp =3D 0; > + err =3D wmi_driver_register(&hp_wmi_wdev_driver); > + if (err) > + return err; > =20 > - if (!bios_capable && !event_capable) > - return -ENODEV; > + if (!bios_capable && !event_capable) { > + err =3D -ENODEV; > + goto err_unregister_wmi; > + } > =20 > if (hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, HPWMI_READ, &tmp, > sizeof(tmp), sizeof(tmp)) =3D=3D HPWMI_RET_INVALID_PARAMETERS) > @@ -2733,7 +2768,7 @@ static int __init hp_wmi_init(void) > if (event_capable) { > err =3D hp_wmi_input_setup(); > if (err) > - return err; > + goto err_unregister_wmi; > } > =20 > if (bios_capable) { > @@ -2771,7 +2806,8 @@ static int __init hp_wmi_init(void) > err_destroy_input: > if (event_capable) > hp_wmi_input_destroy(); > - > +err_unregister_wmi: > + wmi_driver_unregister(&hp_wmi_wmi_driver); > return err; > } > module_init(hp_wmi_init); > @@ -2794,5 +2830,8 @@ static void __exit hp_wmi_exit(void) > platform_device_unregister(hp_wmi_platform_dev); > platform_driver_unregister(&hp_wmi_driver); > } > + > + if (hp_wmi_wdev) > + wmi_driver_unregister(&hp_wmi_wdev_driver); > } > module_exit(hp_wmi_exit);