The logic used for power_supply_is_system_supplied() counts all power
supplies and:
* If no power supplies found assumes AC
* If non-battery power supplies found uses online to determine AC/DC.
- If any are onlined, assumes AC
- Othewise DC.
This logic makes sense for desktop systems that don't export an ACPI
battery, but it fails once you include a dGPU that provides a UCSI
power supply on a desktop system without any other power supplies.
The dGPU by default doesn't have anything plugged in so it's 'offline'.
This makes power_supply_is_system_supplied() return 0 with a count of
1 meaning all drivers that use this get a wrong judgement.
To fix this case adjust the logic to also examine the scope of the
power supply. If the power supply is deemed a device power supply,
then don't count it.
Cc: Evan Quan <Evan.Quan@amd.com>
Suggested-by: Lijo Lazar <Lijo.Lazar@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
---
drivers/power/supply/power_supply_core.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
index ab986dbace16..d57f420ba8c3 100644
--- a/drivers/power/supply/power_supply_core.c
+++ b/drivers/power/supply/power_supply_core.c
@@ -348,6 +348,10 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
struct power_supply *psy = dev_get_drvdata(dev);
unsigned int *count = data;
+ if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret))
+ if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
+ return 0;
+
(*count)++;
if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY)
if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE,
@@ -366,8 +370,8 @@ int power_supply_is_system_supplied(void)
__power_supply_is_system_supplied);
/*
- * If no power class device was found at all, most probably we are
- * running on a desktop system, so assume we are on mains power.
+ * If no system scope power class device was found at all, most probably we
+ * are running on a desktop system, so assume we are on mains power.
*/
if (count == 0)
return 1;
--
2.34.1
Hi, On Tue, May 16, 2023 at 01:25:40PM -0500, Mario Limonciello wrote: > The logic used for power_supply_is_system_supplied() counts all power > supplies and: > * If no power supplies found assumes AC > * If non-battery power supplies found uses online to determine AC/DC. > - If any are onlined, assumes AC > - Othewise DC. > > This logic makes sense for desktop systems that don't export an ACPI > battery, but it fails once you include a dGPU that provides a UCSI > power supply on a desktop system without any other power supplies. > > The dGPU by default doesn't have anything plugged in so it's 'offline'. > This makes power_supply_is_system_supplied() return 0 with a count of > 1 meaning all drivers that use this get a wrong judgement. > > To fix this case adjust the logic to also examine the scope of the > power supply. If the power supply is deemed a device power supply, > then don't count it. > > Cc: Evan Quan <Evan.Quan@amd.com> > Suggested-by: Lijo Lazar <Lijo.Lazar@amd.com> > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > --- Good find; the current logic should also break with a desktop PC once a POWER_SUPPLY_SCOPE_DEVICE battery device is attached (e.g. a HID device), because it increases the counter. I suppose I can just apply this to my fixes branch since there is no compile time dependency to the second patch? -- Sebastian > drivers/power/supply/power_supply_core.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c > index ab986dbace16..d57f420ba8c3 100644 > --- a/drivers/power/supply/power_supply_core.c > +++ b/drivers/power/supply/power_supply_core.c > @@ -348,6 +348,10 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data) > struct power_supply *psy = dev_get_drvdata(dev); > unsigned int *count = data; > > + if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) > + if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) > + return 0; > + > (*count)++; > if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) > if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, > @@ -366,8 +370,8 @@ int power_supply_is_system_supplied(void) > __power_supply_is_system_supplied); > > /* > - * If no power class device was found at all, most probably we are > - * running on a desktop system, so assume we are on mains power. > + * If no system scope power class device was found at all, most probably we > + * are running on a desktop system, so assume we are on mains power. > */ > if (count == 0) > return 1; > -- > 2.34.1 >
On 5/16/2023 3:41 PM, Sebastian Reichel wrote: > Hi, > > On Tue, May 16, 2023 at 01:25:40PM -0500, Mario Limonciello wrote: >> The logic used for power_supply_is_system_supplied() counts all power >> supplies and: >> * If no power supplies found assumes AC >> * If non-battery power supplies found uses online to determine AC/DC. >> - If any are onlined, assumes AC >> - Othewise DC. >> >> This logic makes sense for desktop systems that don't export an ACPI >> battery, but it fails once you include a dGPU that provides a UCSI >> power supply on a desktop system without any other power supplies. >> >> The dGPU by default doesn't have anything plugged in so it's 'offline'. >> This makes power_supply_is_system_supplied() return 0 with a count of >> 1 meaning all drivers that use this get a wrong judgement. >> >> To fix this case adjust the logic to also examine the scope of the >> power supply. If the power supply is deemed a device power supply, >> then don't count it. >> >> Cc: Evan Quan <Evan.Quan@amd.com> >> Suggested-by: Lijo Lazar <Lijo.Lazar@amd.com> >> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> >> --- > Good find; the current logic should also break with a desktop PC > once a POWER_SUPPLY_SCOPE_DEVICE battery device is attached (e.g. > a HID device), because it increases the counter. Yup! > I suppose I can just apply this to my fixes branch since there is > no compile time dependency to the second patch? Yes, that's correct. I don't see a problem with the other patch going through another tree. > -- Sebastian > >> drivers/power/supply/power_supply_core.c | 8 ++++++-- >> 1 file changed, 6 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c >> index ab986dbace16..d57f420ba8c3 100644 >> --- a/drivers/power/supply/power_supply_core.c >> +++ b/drivers/power/supply/power_supply_core.c >> @@ -348,6 +348,10 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data) >> struct power_supply *psy = dev_get_drvdata(dev); >> unsigned int *count = data; >> >> + if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) >> + if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) >> + return 0; >> + >> (*count)++; >> if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) >> if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, >> @@ -366,8 +370,8 @@ int power_supply_is_system_supplied(void) >> __power_supply_is_system_supplied); >> >> /* >> - * If no power class device was found at all, most probably we are >> - * running on a desktop system, so assume we are on mains power. >> + * If no system scope power class device was found at all, most probably we >> + * are running on a desktop system, so assume we are on mains power. >> */ >> if (count == 0) >> return 1; >> -- >> 2.34.1 >>
Hi, On Tue, May 16, 2023 at 03:44:17PM -0500, Limonciello, Mario wrote: > On 5/16/2023 3:41 PM, Sebastian Reichel wrote: > > Hi, > > > > On Tue, May 16, 2023 at 01:25:40PM -0500, Mario Limonciello wrote: > > > The logic used for power_supply_is_system_supplied() counts all power > > > supplies and: > > > * If no power supplies found assumes AC > > > * If non-battery power supplies found uses online to determine AC/DC. > > > - If any are onlined, assumes AC > > > - Othewise DC. > > > > > > This logic makes sense for desktop systems that don't export an ACPI > > > battery, but it fails once you include a dGPU that provides a UCSI > > > power supply on a desktop system without any other power supplies. > > > > > > The dGPU by default doesn't have anything plugged in so it's 'offline'. > > > This makes power_supply_is_system_supplied() return 0 with a count of > > > 1 meaning all drivers that use this get a wrong judgement. > > > > > > To fix this case adjust the logic to also examine the scope of the > > > power supply. If the power supply is deemed a device power supply, > > > then don't count it. > > > > > > Cc: Evan Quan <Evan.Quan@amd.com> > > > Suggested-by: Lijo Lazar <Lijo.Lazar@amd.com> > > > Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> > > > --- > > Good find; the current logic should also break with a desktop PC > > once a POWER_SUPPLY_SCOPE_DEVICE battery device is attached (e.g. > > a HID device), because it increases the counter. > > Yup! > > > I suppose I can just apply this to my fixes branch since there is > > no compile time dependency to the second patch? > > Yes, that's correct. I don't see a problem with the other patch going > through another tree. Ok, I modified the commit message to also mention the HID issue and applied it to power-supply's fixes branch. Thanks, -- Sebastian > > > -- Sebastian > > > > > drivers/power/supply/power_supply_core.c | 8 ++++++-- > > > 1 file changed, 6 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c > > > index ab986dbace16..d57f420ba8c3 100644 > > > --- a/drivers/power/supply/power_supply_core.c > > > +++ b/drivers/power/supply/power_supply_core.c > > > @@ -348,6 +348,10 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data) > > > struct power_supply *psy = dev_get_drvdata(dev); > > > unsigned int *count = data; > > > + if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) > > > + if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) > > > + return 0; > > > + > > > (*count)++; > > > if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) > > > if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, > > > @@ -366,8 +370,8 @@ int power_supply_is_system_supplied(void) > > > __power_supply_is_system_supplied); > > > /* > > > - * If no power class device was found at all, most probably we are > > > - * running on a desktop system, so assume we are on mains power. > > > + * If no system scope power class device was found at all, most probably we > > > + * are running on a desktop system, so assume we are on mains power. > > > */ > > > if (count == 0) > > > return 1; > > > -- > > > 2.34.1 > > >
© 2016 - 2026 Red Hat, Inc.