mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Armin Wolf <W_Armin@gmx.de>
To: "Pali Rohár" <pali@kernel.org>, "Andres Salomon" <dilinger@queued.net>
Cc: linux-kernel@vger.kernel.org,
	platform-driver-x86@vger.kernel.org,
	"Matthew Garrett" <mjg59@srcf.ucam.org>,
	"Sebastian Reichel" <sre@kernel.org>,
	"Hans de Goede" <hdegoede@redhat.com>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	linux-pm@vger.kernel.org, Dell.Client.Kernel@dell.com
Subject: Re: [PATCH v2 1/2] platform/x86:dell-laptop: Add knobs to change battery charge settings
Date: Fri, 26 Jul 2024 01:48:50 +0200	[thread overview]
Message-ID: <45c7c4c3-2f99-4ca0-9c85-a96a03ccfae8@gmx.de> (raw)
In-Reply-To: <20240725221511.mqb4tlam2r7yheoi@pali>

Am 26.07.24 um 00:15 schrieb Pali Rohár:

> On Thursday 25 July 2024 16:24:57 Andres Salomon wrote:
>> On Thu, 25 Jul 2024 01:01:58 +0200
>> Pali Rohár <pali@kernel.org> wrote:
>>
>>> On Wednesday 24 July 2024 18:23:18 Andres Salomon wrote:
>>>> On Wed, 24 Jul 2024 22:45:23 +0200
>>>> Pali Rohár <pali@kernel.org> wrote:
>>>>
>>>>> On Wednesday 24 July 2024 22:34:03 Pali Rohár wrote:
>>>>>> Hello, the driver change looks good. I have just few minor comments for
>>>>>> this change below.
>>>>>>
>>>>>> Anyway, if there is somebody on the list with Dell laptop with 2 or 3
>>>>>> batteries, see below, it would be nice to check how such laptop would
>>>>>> behave with this patch. It does not seem that patch should cause
>>>>>> regression but always it is better to do testing if it is possible.
>>>>>>
>>>>>> On Tuesday 23 July 2024 22:05:02 Andres Salomon wrote:
>>>> [...]
>>>>> And because CLASS_TOKEN_WRITE is being repeated, what about defining
>>>>> something like this?
>>>>>
>>>>>      static inline int dell_set_token_value(struct calling_interface_buffer *buffer, u16 class, u16 tokenid, u32 value)
>>>>>      {
>>>>>          dell_send_request_for_tokenid(buffer, class, CLASS_TOKEN_WRITE, tokenid, value);
>>>>>      }
>>>>>
>>>>> Just an idea. Do you think that it could be useful in second patch?
>>>>>
>>>> Let me implement the other changes first and then take a look.
>>> Ok.
>>>
>> For the helper function, I noticed that all of the CLASS_TOKEN_WRITEs
>> also have SELECT_TOKEN_STD except for one (dell_send_intensity). So I
>> think it makes sense to have the helper function also do that as well.
>> Eg,
>>
>> static inline int dell_set_std_token_value(struct calling_interface_buffer *buffer, u16 tokenid, u32 value)
>> {
>> 	dell_send_request_for_tokenid(buffer, SELECT_TOKEN_STD, CLASS_TOKEN_WRITE, tokenid, value);
>> }
>>
>> I agree with your renaming to dell_send_request_for_tokenid, btw.
>>
>>
>>>>>>> +static int dell_battery_read(const int type)
>>>>>>> +{
>>>>>>> +	struct calling_interface_buffer buffer;
>>>>>>> +	int err;
>>>>>>> +
>>>>>>> +	err = dell_send_request_by_token_loc(&buffer, CLASS_TOKEN_READ,
>>>>>>> +			SELECT_TOKEN_STD, type, 0);
>>>>>>> +	if (err)
>>>>>>> +		return err;
>>>>>>> +
>>>>>>> +	return buffer.output[1];
>>>>>> buffer.output[1] is of type u32. So theoretically it can contain value
>>>>>> above 2^31. For safety it would be better to check if the output[1]
>>>>>> value fits into INT_MAX and if not then return something like -ERANGE
>>>>>> (or some other better errno code).
>>
>> I ended up returning -EIO here, with the logic that if we're getting
>> some nonsense value from SMBIOS, it could either be junk in the stored
>> values or communication corruption.
>>
>> Likewise, I used -EIO for the checks in charge_control_start_threshold_show
>> and charge_control_end_threshold_show when SMBIOS returns values > 100%.
>>
>>
>>
>>>>
>>>>>>
>>>>>>> +	if (end < 0)
>>>>>>> +		end = CHARGE_END_MAX;
>>>>>>> +	if ((end - start) < CHARGE_MIN_DIFF)
>>>>>> nit: I'm not sure what is the correct coding style for kernel drivers
>>>>>> but I thought that parenthesis around (end - start) are not being
>>>>>> written.
>>>>>>
>> I think it makes the comparison much easier to read. I'd prefer to
>> keep it, unless the coding style specifically forbids it.
> As I said I'm really not sure. So if nobody would complain then you can
> let it as is.
>
> You can use ./scripts/checkpatch.pl application which is in git tree,
> which does basic checks for code style. It cannot prove if something is
> really correct but it can prove if something is incorrect.
>
>>
>>
>>>>>>> +
>>>>>>> +static u32 __init battery_get_supported_modes(void)
>>>>>>> +{
>>>>>>> +	u32 modes = 0;
>>>>>>> +	int i;
>>>>>>> +
>>>>>>> +	for (i = 0; i < ARRAY_SIZE(battery_modes); i++) {
>>>>>>> +		if (dell_smbios_find_token(battery_modes[i].token))
>>>>>>> +			modes |= BIT(i);
>>>>>>> +	}
>>>>>>> +
>>>>>>> +	return modes;
>>>>>>> +}
>>>>>>> +
>>>>>>> +static void __init dell_battery_init(struct device *dev)
>>>>>>> +{
>>>>>>> +	battery_supported_modes = battery_get_supported_modes();
>>>>>>> +
>>>>>>> +	if (battery_supported_modes != 0)
>>>>>>> +		battery_hook_register(&dell_battery_hook);
>>>>>> Anyway, how is this battery_hook_register() suppose to work on systems
>>>>>> with multiple batteries? The provided API is only for the primary
>>>>>> battery, but on older Dell laptop it was possible to connect up to
>>>>>> 3 batteries. Would not this case some issues?
>>>> This interface is _only_ for controlling charging of the primary battery.
>>>> In theory, it should hopefully ignore any other batteries, which would
>>>> need to have their settings changed in the BIOS or with a special tool or
>>>> whatever.
>>> That is OK. But where it is specified that the hook is being registered
>>> only for the primary battery? Because from the usage it looks like that
>>> the hook is applied either for all batteries present in the system or
>>> for some one arbitrary chosen battery.
>>>
>>>> However, I'm basing that assumption on the SMBIOS interface. These tokens
>>>> are marked "Primary Battery". There are separate tokens marked "Battery
>>>> Slice", which from my understanding was an older type of battery that
>>>  From SMBIOS perspective it is clear, each battery seems to have its own
>>> tokens.
>>>
>>> The issue here is: how to tell kernel that the particular
>>> dell_battery_hook has to be bound with the primary battery?
>>>
>> So from userspace, we've got the expectation that multiple batteries
>> would show up as /sys/class/power_supply/BAT0, /sys/class/power_supply/BAT1,
>> and so on.
> Yes, I hope so.
>
>> The current BAT0 entry shows things like 'capacity' even without this
>> patch, and we're just piggybacking off of that to add charge_type and
>> other entries. So there shouldn't be any confusion there, agreed?
> I have not looked at the battery_hook_register() code yet (seems that I
> would have to properly read it and understand it). But does it mean that
> battery_hook_register() is adding hook just for "BAT0"?
>
> What I mean: cannot that hook be registered to "BAT1" too? Because if
> yes then we should prevent it. Otherwise this hook which is for "Dell
> Primary Battery" could be registered also for secondary battery "BAT1".
> (I hope that now it is more clear what I mean).

Hi,

the battery hook is being registered to all ACPI batteries present on a given system,
so you need to do some manual filtering when .add_battery() is called.

As a side note: i suspect that "newer" Dell machines use a different interface for controlling
battery charging, since the Dell Power Manager software on my machine seems to provide some
additional features not found in this token-based interface.

Unfortunately i am not sure if reverse-engineering the Dell software is legal, does the kernel
community have some helping guides in this area? If it is legal, then i would happily volunteer
to do the reverse-engineering.

Otherwise maybe someone at Dell can provide some clarifications if a different interface for controlling
battery charging exists and how to use it?

Thanks,
Armin Wolf

>> In the kernel, we're registering the acpi_battery_hook as "Dell Primary
>> Battery Extension". The functions set up by that acpi_battery_hook are
>> the only ones using battery_support_modes. We could make it more explicit
>> by:
>> 1) renaming it to primary_battery_modes, along with
>> dell_primary_battery_{init,exit} and/or
>> 2) allocating the mode mask and strings dynamically, and storing that
>> inside of the dev kobject.
>>
>> However, #2 seems overly complicated for what we're doing. In the
>> circumstances that we want to add support for secondary batteries,
>> we're going to need to query separate tokens, add another
>> acpi_battery_hook, and also add a second mask. Whether that's a global
>> variable or kept inside pdev seems like more of a style issue than
>> anything else.
>>
>> #1 is easy enough to change, if you think that's necessary.
> I think that "Dell Primary Battery Extension" is OK. All SMBIOS code is
> currently primary-battery only.
>
> The only my point is to prevent this &dell_battery_hook to be registered
> for non-primary battery.
>

  reply	other threads:[~2024-07-25 23:49 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-24  2:05 Andres Salomon
2024-07-24  2:07 ` [PATCH v2 2/2] platform/x86:dell-laptop: remove duplicate code w/ battery function Andres Salomon
2024-07-24 20:50   ` Pali Rohár
2024-07-24 20:34 ` [PATCH v2 1/2] platform/x86:dell-laptop: Add knobs to change battery charge settings Pali Rohár
2024-07-24 20:45   ` Pali Rohár
2024-07-24 22:23     ` Andres Salomon
2024-07-24 23:01       ` Pali Rohár
2024-07-25 20:24         ` Andres Salomon
2024-07-25 22:15           ` Pali Rohár
2024-07-25 23:48             ` Armin Wolf [this message]
2024-07-26  0:04               ` Pali Rohár
2024-07-26  4:25                 ` Andres Salomon
2024-07-26 18:42                   ` Armin Wolf
2024-07-26 18:46                     ` Armin Wolf
2024-08-07 21:28                       ` Andres Salomon
2024-08-07 21:44                         ` Pali Rohár
2024-08-07 22:05                           ` Andres Salomon
2024-08-07 23:51                             ` Sebastian Reichel
2024-08-11  5:28                 ` Armin Wolf
2024-08-12 13:54 ` Hans de Goede

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=45c7c4c3-2f99-4ca0-9c85-a96a03ccfae8@gmx.de \
    --to=w_armin@gmx.de \
    --cc=Dell.Client.Kernel@dell.com \
    --cc=dilinger@queued.net \
    --cc=hdegoede@redhat.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    --cc=pali@kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=sre@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®