From: LABBE Corentin <clabbe@baylibre.com>
To: Guenter Roeck <linux@roeck-us.net>
Cc: jdelvare@suse.com, linux-hwmon@vger.kernel.org,
linux-kernel@vger.kernel.org, Zhang Rui <rui.zhang@intel.com>
Subject: Re: [PATCH v3 2/2] hwmon: acpi_power_meter: convert to hwmon_device_register_with_info
Date: Sat, 21 May 2022 21:16:26 +0200 [thread overview]
Message-ID: <Yok6iuNUGerryFkO@Red> (raw)
In-Reply-To: <b038aa19-9cba-d16a-15c5-e02fc749ab96@roeck-us.net>
Le Sat, May 21, 2022 at 06:52:15AM -0700, Guenter Roeck a écrit :
> On 5/16/22 05:21, Guenter Roeck wrote:
> > On 5/15/22 23:21, LABBE Corentin wrote:
> >> Le Sun, May 15, 2022 at 05:29:54PM -0700, Guenter Roeck a écrit :
> >>> On 5/15/22 12:36, LABBE Corentin wrote:
> >>>> Le Wed, May 11, 2022 at 07:10:29PM -0700, Guenter Roeck a écrit :
> >>>>> Corentin,
> >>>>>
> >>>>> On 5/8/22 23:30, Corentin Labbe wrote:
> >>>>>> Booting lead to a hwmon_device_register() is deprecated. Please convert the driver to use hwmon_device_register_with_info().
> >>>>>> So let's convert the driver to use hwmon_device_register_with_info().
> >>>>>>
> >>>>>> Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
> >>>>>> ---
> >>>>> [ ... ]
> >>>>>
> >>>>>> @@ -836,20 +740,20 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
> >>>>>> if (res)
> >>>>>> break;
> >>>>>> - remove_attrs(resource);
> >>>>>> + remove_domain_devices(resource);
> >>>>>> setup_attrs(resource);
> >>>>>
> >>>>> Zhang Rui found an interesting problem with this code:
> >>>>> It needs a call to sysfs_update_groups(hwmon_dev->groups)
> >>>>> to update sysfs attribute visibility, probably between
> >>>>> remove_domain_devices() and setup_attrs().
> >>>>>
> >>>>>> break;
> >>>>>> case METER_NOTIFY_TRIP:
> >>>>>> - sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
> >>>>>> + hwmon_notify_event(&device->dev, hwmon_power, hwmon_power_average, 0);
> >>>>>
> >>>>> ... which makes realize: The notification device should be the hwmon device.
> >>>>> That would be resource->hwmon_dev, not the acpi device.
> >>>>>
> >>>>
> >>>> Hello
> >>>>
> >>>> Since my hardware lacks capabilities testing this, I have emulated it on qemu:
> >>>> https://github.com/montjoie/qemu/commit/320f2ddacb954ab308ef699f66fca6313f75bc2b
> >>>>
> >>>> I have added a custom ACPI _DBX method for triggering some ACPI state change. (like config change, like enabling CAP).
> >>>>
> >>>> For testing config change I have tried lot of way:
> >>>> res = read_capabilities(resource);
> >>>> @@ -742,18 +758,22 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
> >>>> remove_domain_devices(resource);
> >>>> setup_attrs(resource);
> >>>> + res = sysfs_update_groups(&resource->hwmon_dev->kobj, acpi_power_groups);
> >>>> + res = sysfs_update_groups(&resource->acpi_dev->dev.kobj, acpi_power_groups);
> >>>> + res = hwmon_notify_event(resource->hwmon_dev, hwmon_power, hwmon_power_cap, 0);
> >>>> + res = hwmon_notify_event(resource->hwmon_dev, hwmon_power, hwmon_power_average, 0);
> >>>
> >>> Did you add a debug log here ?
> >>
> >> Yes I added debug log to check what is called.
> >>
> >>>
> >>> acpi_power_groups would be the wrong parameter for sysfs_update_groups().
> >>> It would have to be resource->hwmon_dev->groups.
> >>>
> >>
> >> Even with that, no call to is_visible:
> >> @@ -742,18 +758,22 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
> >> remove_domain_devices(resource);
> >> setup_attrs(resource);
> >> + res = sysfs_update_groups(&resource->hwmon_dev->kobj, resource->hwmon_dev->groups);
> >> + res = sysfs_update_groups(&resource->acpi_dev->dev.kobj, resource->hwmon_dev->groups);
> >> + res = hwmon_notify_event(resource->hwmon_dev, hwmon_power, hwmon_power_cap, 0);
> >> + res = hwmon_notify_event(resource->hwmon_dev, hwmon_power, hwmon_power_average, 0);
> >> break;
> >>
> >> I checked drivers/hwmon/hwmon.c is seems that is_visible is only called by gen_attr/gen_attrs which is only called by __hwmon_create_attrs and then by registers functions.
> >> So perhaps it explain why it is never called.
> >
> > Ah yes, you are correct. Sorry, it has been too long ago that I wrote that code.
> > Effectively that means we'll have to rework the hwmon core to generate attributes
> > anyway and leave it up to the driver core to call the is_visible function.
> >
>
> Attached is an outline of what would be needed in the hwmon core.
> Completely untested. I wonder if it may be easier to always
> create all attributes and have them return -ENODATA if not
> supported.
>
With your patch, the notify config change lead to new attributes to be displayed.
Your patch just needs:
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -315,7 +315,7 @@ static void hwmon_thermal_notify(struct device *dev, int index)
}
#else
-static int hwmon_thermal_register_sensors(struct device *dev)
+static int hwmon_thermal_register_sensors(struct device *dev, bool update)
{
return 0;
}
Tested with:
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -40,7 +40,7 @@
#define METER_NOTIFY_INTERVAL 0x84
static int cap_in_hardware;
-static bool force_cap_on;
+static bool force_cap_on = 1;
static int can_cap_in_hardware(void)
{
@@ -337,6 +337,16 @@ static ssize_t power1_is_battery_show(struct device *dev,
{
struct acpi_power_meter_resource *resource = dev_get_drvdata(dev);
int val;
+ unsigned long long data;
+ acpi_status status;
+
+ status = acpi_evaluate_integer(resource->acpi_dev->handle, "_DBX",
+ NULL, &data);
+ if (ACPI_FAILURE(status)) {
+ acpi_evaluation_failure_warn(resource->acpi_dev->handle, "_DBX",
+ status);
+ }
+ pr_info("DBX give %llu\n", data);
if (resource->caps.flags & POWER_METER_IS_BATTERY)
val = 1;
@@ -570,6 +580,8 @@ static umode_t acpi_power_is_visible(const void *data,
{
const struct acpi_power_meter_resource *resource = data;
+ pr_info("%s\n", __func__);
+
switch (attr) {
case hwmon_power_average_min:
case hwmon_power_average_max:
@@ -741,7 +753,7 @@ static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
remove_domain_devices(resource);
setup_attrs(resource);
- res = sysfs_update_groups(&resource->acpi_dev->dev.kobj, resource->hwmon_dev->groups);
+ res = hwmon_update_groups(resource->hwmon_dev);
break;
case METER_NOTIFY_TRIP:
On a microvm qemu with my ACPI power meter emulation:
/ # ls /sys/class/hwmon/hwmon0/
device power1_average power1_is_battery subsystem
name power1_average_interval power1_model_number uevent
power power1_interval_max power1_oem_info
power1_accuracy power1_interval_min power1_serial_number
/ # cat /sys/class/hwmon/hwmon0/
device/ power1_average_interval power1_oem_info
name power1_interval_max power1_serial_number
power/ power1_interval_min subsystem/
power1_accuracy power1_is_battery uevent
power1_average power1_model_number
/ # cat /sys/class/hwmon/hwmon0/power1_is_battery
[ 14.969697] power_meter ACPI000D:00: Found ACPI power meter.
[ 14.970114] acpi_power_is_visible
[ 14.970133] acpi_power_is_visible
[ 14.970141] acpi_power_is_visible
[ 14.970147] acpi_power_is_visible
[ 14.970153] acpi_power_is_visible
[ 14.970158] acpi_power_is_visible
[ 14.970164] acpi_power_is_visible
[ 14.970169] acpi_power_is_visible
[ 14.970187] acpi_power_is_visible
[ 14.970193] acpi_power_is_visible
[ 14.970202] acpi_power_is_visible
[ 14.970346] DBX give 40
[ 14.975185] power_meter ACPI000D:00: Capping in progress.
0
cat: /sys/class/hwmon/hwmon0/power1_is_battery: No such device
/ # ls /sys/class/hwmon/hwmon0/
device power1_average_min power1_is_battery
name power1_cap power1_model_number
power power1_cap_hyst power1_oem_info
power1_accuracy power1_cap_max power1_serial_number
power1_average power1_cap_min subsystem
power1_average_interval power1_interval_max uevent
power1_average_max power1_interval_min
Thanks
next prev parent reply other threads:[~2022-05-21 19:16 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-09 6:30 [PATCH v3 0/2] hwmon: acpi_power_meter: convert to new hwmon API Corentin Labbe
2022-05-09 6:30 ` [PATCH v3 1/2] hwmon: acpi_power_meter: fix style issue Corentin Labbe
2022-05-10 2:39 ` Guenter Roeck
2022-05-09 6:30 ` [PATCH v3 2/2] hwmon: acpi_power_meter: convert to hwmon_device_register_with_info Corentin Labbe
2022-05-10 3:05 ` Guenter Roeck
2022-05-12 2:10 ` Guenter Roeck
2022-05-13 8:02 ` LABBE Corentin
2022-05-13 11:33 ` Zhang Rui
2022-05-13 13:03 ` Guenter Roeck
2022-05-15 19:36 ` LABBE Corentin
2022-05-16 0:29 ` Guenter Roeck
2022-05-16 6:21 ` LABBE Corentin
2022-05-16 12:21 ` Guenter Roeck
2022-05-21 13:52 ` Guenter Roeck
2022-05-21 19:16 ` LABBE Corentin [this message]
2022-06-30 14:49 ` LABBE Corentin
2022-06-30 15:13 ` Guenter Roeck
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Yok6iuNUGerryFkO@Red \
--to=clabbe@baylibre.com \
--cc=jdelvare@suse.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=rui.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.