<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/drivers/acpi/battery.c, branch v4.13-rc5</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle</title>
<updated>2017-06-14T22:55:44+00:00</updated>
<author>
<name>Rafael J. Wysocki</name>
<email>rafael.j.wysocki@intel.com</email>
</author>
<published>2017-06-12T20:56:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=33e4f80ee69b5168badf37edbfed796eb48434b9'/>
<id>33e4f80ee69b5168badf37edbfed796eb48434b9</id>
<content type='text'>
The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ
during suspend-to-idle transitions and, consequently, any events
signaled through it wake up the system from that state.  However,
on some systems some of the events signaled via the ACPI SCI while
suspended to idle should not cause the system to wake up.  In fact,
quite often they should just be discarded.

Arguably, systems should not resume entirely on such events, but in
order to decide which events really should cause the system to resume
and which are spurious, it is necessary to resume up to the point
when ACPI SCIs are actually handled and processed, which is after
executing dpm_resume_noirq() in the system resume path.

For this reasons, add a loop around freeze_enter() in which the
platforms can process events signaled via multiplexed IRQ lines
like the ACPI SCI and add suspend-to-idle hooks that can be
used for this purpose to struct platform_freeze_ops.

In the ACPI case, the -&gt;wake hook is used for checking if the SCI
has triggered while suspended and deferring the interrupt-induced
system wakeup until the events signaled through it are actually
processed sufficiently to decide whether or not the system should
resume.  In turn, the -&gt;sync hook allows all of the relevant event
queues to be flushed so as to prevent events from being missed due
to race conditions.

In addition to that, some ACPI code processing wakeup events needs
to be modified to use the "hard" version of wakeup triggers, so that
it will cause a system resume to happen on device-induced wakeup
events even if the "soft" mechanism to prevent the system from
suspending is not enabled.  However, to preserve the existing
behavior with respect to suspend-to-RAM, this only is done in
the suspend-to-idle case and only if an SCI has occurred while
suspended.

Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ
during suspend-to-idle transitions and, consequently, any events
signaled through it wake up the system from that state.  However,
on some systems some of the events signaled via the ACPI SCI while
suspended to idle should not cause the system to wake up.  In fact,
quite often they should just be discarded.

Arguably, systems should not resume entirely on such events, but in
order to decide which events really should cause the system to resume
and which are spurious, it is necessary to resume up to the point
when ACPI SCIs are actually handled and processed, which is after
executing dpm_resume_noirq() in the system resume path.

For this reasons, add a loop around freeze_enter() in which the
platforms can process events signaled via multiplexed IRQ lines
like the ACPI SCI and add suspend-to-idle hooks that can be
used for this purpose to struct platform_freeze_ops.

In the ACPI case, the -&gt;wake hook is used for checking if the SCI
has triggered while suspended and deferring the interrupt-induced
system wakeup until the events signaled through it are actually
processed sufficiently to decide whether or not the system should
resume.  In turn, the -&gt;sync hook allows all of the relevant event
queues to be flushed so as to prevent events from being missed due
to race conditions.

In addition to that, some ACPI code processing wakeup events needs
to be modified to use the "hard" version of wakeup triggers, so that
it will cause a system resume to happen on device-induced wakeup
events even if the "soft" mechanism to prevent the system from
suspending is not enabled.  However, to preserve the existing
behavior with respect to suspend-to-RAM, this only is done in
the suspend-to-idle case and only if an SCI has occurred while
suspended.

Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branches 'intel_pstate' and 'pm-sleep'</title>
<updated>2017-06-08T23:25:16+00:00</updated>
<author>
<name>Rafael J. Wysocki</name>
<email>rafael.j.wysocki@intel.com</email>
</author>
<published>2017-06-08T23:25:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=fbd78afe34d9cc3a86aff7cc214d9f06e815e63e'/>
<id>fbd78afe34d9cc3a86aff7cc214d9f06e815e63e</id>
<content type='text'>
* intel_pstate:
  cpufreq: intel_pstate: Avoid division by 0 in min_perf_pct_min()

* pm-sleep:
  Revert "ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle"
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* intel_pstate:
  cpufreq: intel_pstate: Avoid division by 0 in min_perf_pct_min()

* pm-sleep:
  Revert "ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle"
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle"</title>
<updated>2017-06-06T22:57:37+00:00</updated>
<author>
<name>Rafael J. Wysocki</name>
<email>rafael.j.wysocki@intel.com</email>
</author>
<published>2017-06-06T22:57:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=f3b7eaae1b35eb8077610eb7c7db042c9b0645e1'/>
<id>f3b7eaae1b35eb8077610eb7c7db042c9b0645e1</id>
<content type='text'>
Revert commit eed4d47efe95 (ACPI / sleep: Ignore spurious SCI wakeups
from suspend-to-idle) as it turned out to be premature and triggered
a number of different issues on various systems.

That includes, but is not limited to, premature suspend-to-RAM aborts
on Dell XPS 13 (9343) reported by Dominik.

The issue the commit in question attempted to address is real and
will need to be taken care of going forward, but evidently more work
is needed for this purpose.

Reported-by: Dominik Brodowski &lt;linux@dominikbrodowski.net&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Revert commit eed4d47efe95 (ACPI / sleep: Ignore spurious SCI wakeups
from suspend-to-idle) as it turned out to be premature and triggered
a number of different issues on various systems.

That includes, but is not limited to, premature suspend-to-RAM aborts
on Dell XPS 13 (9343) reported by Dominik.

The issue the commit in question attempted to address is real and
will need to be taken care of going forward, but evidently more work
is needed for this purpose.

Reported-by: Dominik Brodowski &lt;linux@dominikbrodowski.net&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branches 'pm-domains', 'pm-cpuidle', 'pm-sleep' and 'powercap'</title>
<updated>2017-05-09T21:21:46+00:00</updated>
<author>
<name>Rafael J. Wysocki</name>
<email>rafael.j.wysocki@intel.com</email>
</author>
<published>2017-05-09T21:21:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=80449d89d4d6d0af4d6d310597e0f4a3fe0c08a9'/>
<id>80449d89d4d6d0af4d6d310597e0f4a3fe0c08a9</id>
<content type='text'>
* pm-domains:
  PM / Domains: Add DT file to MAINTAINERS
  PM / Domains: Fix DT example

* pm-cpuidle:
  x86/intel_idle: add Gemini Lake support
  cpuidle: check dev before usage in cpuidle_use_deepest_state()

* pm-sleep:
  ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle
  PM / wakeup: Integrate mechanism to abort transitions in progress

* powercap:
  powercap: intel_rapl: Add support for Gemini Lake
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* pm-domains:
  PM / Domains: Add DT file to MAINTAINERS
  PM / Domains: Fix DT example

* pm-cpuidle:
  x86/intel_idle: add Gemini Lake support
  cpuidle: check dev before usage in cpuidle_use_deepest_state()

* pm-sleep:
  ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle
  PM / wakeup: Integrate mechanism to abort transitions in progress

* powercap:
  powercap: intel_rapl: Add support for Gemini Lake
</pre>
</div>
</content>
</entry>
<entry>
<title>ACPI / sleep: Ignore spurious SCI wakeups from suspend-to-idle</title>
<updated>2017-05-05T20:54:28+00:00</updated>
<author>
<name>Rafael J. Wysocki</name>
<email>rafael.j.wysocki@intel.com</email>
</author>
<published>2017-04-26T21:23:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=eed4d47efe9508b855b09754cf6de4325d8a2f0d'/>
<id>eed4d47efe9508b855b09754cf6de4325d8a2f0d</id>
<content type='text'>
The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ
during suspend-to-idle transitions and, consequently, any events
signaled through it wake up the system from that state.  However,
on some systems some of the events signaled via the ACPI SCI while
suspended to idle should not cause the system to wake up.  In fact,
quite often they should just be discarded.

Arguably, systems should not resume entirely on such events, but in
order to decide which events really should cause the system to resume
and which are spurious, it is necessary to resume up to the point
when ACPI SCIs are actually handled and processed, which is after
executing dpm_resume_noirq() in the system resume path.

For this reasons, add a loop around freeze_enter() in which the
platforms can process events signaled via multiplexed IRQ lines
like the ACPI SCI and add suspend-to-idle hooks that can be
used for this purpose to struct platform_freeze_ops.

In the ACPI case, the -&gt;wake hook is used for checking if the SCI
has triggered while suspended and deferring the interrupt-induced
system wakeup until the events signaled through it are actually
processed sufficiently to decide whether or not the system should
resume.  In turn, the -&gt;sync hook allows all of the relevant event
queues to be flushed so as to prevent events from being missed due
to race conditions.

In addition to that, some ACPI code processing wakeup events needs
to be modified to use the "hard" version of wakeup triggers, so that
it will cause a system resume to happen on device-induced wakeup
events even if the "soft" mechanism to prevent the system from
suspending is not enabled (that also helps to catch device-induced
wakeup events occurring during suspend transitions in progress).

Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The ACPI SCI (System Control Interrupt) is set up as a wakeup IRQ
during suspend-to-idle transitions and, consequently, any events
signaled through it wake up the system from that state.  However,
on some systems some of the events signaled via the ACPI SCI while
suspended to idle should not cause the system to wake up.  In fact,
quite often they should just be discarded.

Arguably, systems should not resume entirely on such events, but in
order to decide which events really should cause the system to resume
and which are spurious, it is necessary to resume up to the point
when ACPI SCIs are actually handled and processed, which is after
executing dpm_resume_noirq() in the system resume path.

For this reasons, add a loop around freeze_enter() in which the
platforms can process events signaled via multiplexed IRQ lines
like the ACPI SCI and add suspend-to-idle hooks that can be
used for this purpose to struct platform_freeze_ops.

In the ACPI case, the -&gt;wake hook is used for checking if the SCI
has triggered while suspended and deferring the interrupt-induced
system wakeup until the events signaled through it are actually
processed sufficiently to decide whether or not the system should
resume.  In turn, the -&gt;sync hook allows all of the relevant event
queues to be flushed so as to prevent events from being missed due
to race conditions.

In addition to that, some ACPI code processing wakeup events needs
to be modified to use the "hard" version of wakeup triggers, so that
it will cause a system resume to happen on device-induced wakeup
events even if the "soft" mechanism to prevent the system from
suspending is not enabled (that also helps to catch device-induced
wakeup events occurring during suspend transitions in progress).

Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ACPI / battery: Add a blacklist with PMIC ACPI HIDs with a native battery driver</title>
<updated>2017-04-19T20:53:35+00:00</updated>
<author>
<name>Hans de Goede</name>
<email>hdegoede@redhat.com</email>
</author>
<published>2017-04-19T12:02:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=dccfae6d4f4c2cfa1fdc3bf55755fcad02184b99'/>
<id>dccfae6d4f4c2cfa1fdc3bf55755fcad02184b99</id>
<content type='text'>
On some systems we have a native PMIC driver which provides battery
monitoring, while the ACPI battery driver is broken on these systems
due to bad DSDTs or because we do not support the proprietary and
undocumented ACPI opregions these ACPI battery devices rely on
(e.g. BMOP opregion).

This leads to there being 2 battery power_supply-s registed like this:

~$ acpi
Battery 0: Charging, 84%, 00:49:39 until charged
Battery 1: Unknown, 0%, rate information unavailable

Even if the ACPI battery where to function fine (which on systems
where we have a native PMIC driver it often doesn't) we still do not
want to export the same battery to userspace twice.

This commit adds a blacklist with PMIC ACPI HIDs for which we've a
native battery driver and makes the ACPI battery driver not register
itself when a PMIC on this list is present.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=194811
Signed-off-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
On some systems we have a native PMIC driver which provides battery
monitoring, while the ACPI battery driver is broken on these systems
due to bad DSDTs or because we do not support the proprietary and
undocumented ACPI opregions these ACPI battery devices rely on
(e.g. BMOP opregion).

This leads to there being 2 battery power_supply-s registed like this:

~$ acpi
Battery 0: Charging, 84%, 00:49:39 until charged
Battery 1: Unknown, 0%, rate information unavailable

Even if the ACPI battery where to function fine (which on systems
where we have a native PMIC driver it often doesn't) we still do not
want to export the same battery to userspace twice.

This commit adds a blacklist with PMIC ACPI HIDs for which we've a
native battery driver and makes the ACPI battery driver not register
itself when a PMIC on this list is present.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=194811
Signed-off-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ACPI / battery: Fix acpi_battery_exit on acpi_battery_init_async errors</title>
<updated>2017-04-19T20:53:35+00:00</updated>
<author>
<name>Hans de Goede</name>
<email>hdegoede@redhat.com</email>
</author>
<published>2017-04-19T12:02:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=bc39fbcf9c782970263bdc5b428e4a755db16efb'/>
<id>bc39fbcf9c782970263bdc5b428e4a755db16efb</id>
<content type='text'>
The acpi_lock_battery_dir() / acpi_bus_register_driver() calls in
acpi_battery_init_async() may fail.

Check that they succeeded before undoing them.

Signed-off-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The acpi_lock_battery_dir() / acpi_bus_register_driver() calls in
acpi_battery_init_async() may fail.

Check that they succeeded before undoing them.

Signed-off-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Replace &lt;asm/uaccess.h&gt; with &lt;linux/uaccess.h&gt; globally</title>
<updated>2016-12-24T19:46:01+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2016-12-24T19:46:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=7c0f6ba682b9c7632072ffbedf8d328c8f3c42ba'/>
<id>7c0f6ba682b9c7632072ffbedf8d328c8f3c42ba</id>
<content type='text'>
This was entirely automated, using the script by Al:

  PATT='^[[:blank:]]*#[[:blank:]]*include[[:blank:]]*&lt;asm/uaccess.h&gt;'
  sed -i -e "s!$PATT!#include &lt;linux/uaccess.h&gt;!" \
        $(git grep -l "$PATT"|grep -v ^include/linux/uaccess.h)

to do the replacement at the end of the merge window.

Requested-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This was entirely automated, using the script by Al:

  PATT='^[[:blank:]]*#[[:blank:]]*include[[:blank:]]*&lt;asm/uaccess.h&gt;'
  sed -i -e "s!$PATT!#include &lt;linux/uaccess.h&gt;!" \
        $(git grep -l "$PATT"|grep -v ^include/linux/uaccess.h)

to do the replacement at the end of the merge window.

Requested-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ACPI / battery: If _BIX fails, retry with _BIF</title>
<updated>2016-11-16T22:09:45+00:00</updated>
<author>
<name>Dave Lambley</name>
<email>linux@davel.me.uk</email>
</author>
<published>2016-11-04T01:05:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=2d09af4a88d99a8dd0429263451b7b88e6d92738'/>
<id>2d09af4a88d99a8dd0429263451b7b88e6d92738</id>
<content type='text'>
The Lenovo Yoga 300 laptop's firmware advertises that it provides the _BIX
the method to retrieve battery information. Unfortunately (some versions
of?) the implementation return with an error.

[   21.712228] ACPI Exception: AE_AML_PACKAGE_LIMIT, Index (0x000000010) is beyond end of object (length 0xD) (20160422/exoparg2-427)
[   21.712244] ACPI Error: Method parse/execution failed [\_SB.PCI0.LPCB.H_EC.BAT1._BIX] (Node ffff95f8ff0b20f0), AE_AML_PACKAGE_LIMIT (20160422/psparse-542)

The _BIF method does succeed and returns convincing data. We detect _BIX
failing and automatically retry with _BIF.

Signed-off-by: Dave Lambley &lt;linux@davel.me.uk&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The Lenovo Yoga 300 laptop's firmware advertises that it provides the _BIX
the method to retrieve battery information. Unfortunately (some versions
of?) the implementation return with an error.

[   21.712228] ACPI Exception: AE_AML_PACKAGE_LIMIT, Index (0x000000010) is beyond end of object (length 0xD) (20160422/exoparg2-427)
[   21.712244] ACPI Error: Method parse/execution failed [\_SB.PCI0.LPCB.H_EC.BAT1._BIX] (Node ffff95f8ff0b20f0), AE_AML_PACKAGE_LIMIT (20160422/psparse-542)

The _BIF method does succeed and returns convincing data. We detect _BIX
failing and automatically retry with _BIF.

Signed-off-by: Dave Lambley &lt;linux@davel.me.uk&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ACPI / battery: Add sysfs representation after checking _BST</title>
<updated>2016-08-30T22:35:16+00:00</updated>
<author>
<name>Carlos Garnacho</name>
<email>carlosg@gnome.org</email>
</author>
<published>2016-08-10T15:24:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=12c78ca2ab5e64b636ce085fb08f7685654a5f22'/>
<id>12c78ca2ab5e64b636ce085fb08f7685654a5f22</id>
<content type='text'>
Thus move sysfs_add_battery() after acpi_battery_get_state(), which doesn't
require the power_supply. Prevents possible hanged tasks if
acpi_battery_get_state() fails consistently (and takes a long time in doing
so) when called inside acpi_battery_add().

In this situation the battery module first calls sysfs_add_battery(),
which creates a power_supply, which spawns an async
power_supply_deferred_register_work() task, which shall try to hold the
parent battery device mutex (being already held) so this register work
is set up after device initialization. If initialization takes long enough
the thread will be eventually run and try to hold the mutex before
acpi_battery_add() had the chance to finish.

Eventually the 5 retries in acpi_battery_update_retry() fail, the error
state is propagated, and results in sysfs_remove_battery() being called
within the error handling paths of acpi_battery_add(), and the power_supply
tear down too.

This triggers a cancel_delayed_work_sync() of the deferred_register_work
task, which ends up in schedule(). The end result is that the deferred
task is blocked trying to acquire the parent device mutex, which is not
released because the thread doing initialization (and failure handling)
went to sleep awaiting for the deferred task to be cancelled.

The hanged tasks look like this:

INFO: task kworker/u8:0:6 blocked for more than 120 seconds.
 ...
Call Trace:
 [&lt;ffffffff815daec5&gt;] schedule+0x35/0x80
 [&lt;ffffffff815dda3c&gt;] schedule_timeout+0x1ec/0x250
 [&lt;ffffffff810a0572&gt;] ? check_preempt_curr+0x52/0x90
 [&lt;ffffffff810a05c9&gt;] ? ttwu_do_wakeup+0x19/0xe0
 [&lt;ffffffff815db915&gt;] wait_for_common+0xc5/0x190
 [&lt;ffffffff810a1500&gt;] ? wake_up_q+0x70/0x70
 [&lt;ffffffff815db9fd&gt;] wait_for_completion+0x1d/0x20
 [&lt;ffffffff8108ffb1&gt;] flush_work+0x111/0x1c0
 [&lt;ffffffff8108dfe0&gt;] ? flush_workqueue_prep_pwqs+0x1a0/0x1a0
 [&lt;ffffffff810909af&gt;] __cancel_work_timer+0x9f/0x1d0
 [&lt;ffffffff81090b13&gt;] cancel_delayed_work_sync+0x13/0x20
 [&lt;ffffffff8147ac67&gt;] power_supply_unregister+0x37/0xc0
 [&lt;ffffffffa058b03d&gt;] sysfs_remove_battery+0x3d/0x52 [battery]
 [&lt;ffffffffa058bf3a&gt;] acpi_battery_add+0x112/0x181 [battery]
 [&lt;ffffffff81366db6&gt;] acpi_device_probe+0x54/0x19b
 [&lt;ffffffff81427e9c&gt;] driver_probe_device+0x22c/0x440
 [&lt;ffffffff81428181&gt;] __driver_attach+0xd1/0xf0
 [&lt;ffffffff814280b0&gt;] ? driver_probe_device+0x440/0x440
 [&lt;ffffffff8142591c&gt;] bus_for_each_dev+0x6c/0xc0
 [&lt;ffffffff8142758e&gt;] driver_attach+0x1e/0x20
 [&lt;ffffffff81426fc3&gt;] bus_add_driver+0x1c3/0x280
 [&lt;ffffffff81428b00&gt;] driver_register+0x60/0xe0
 [&lt;ffffffff81366c80&gt;] acpi_bus_register_driver+0x3b/0x43
 [&lt;ffffffffa0591040&gt;] acpi_battery_init_async+0x1c/0x1e [battery]
 [&lt;ffffffff81099268&gt;] async_run_entry_fn+0x48/0x150
 [&lt;ffffffff81090d09&gt;] process_one_work+0x1e9/0x440
 [&lt;ffffffff81090fab&gt;] worker_thread+0x4b/0x4f0
 [&lt;ffffffff81090f60&gt;] ? process_one_work+0x440/0x440
 [&lt;ffffffff81096b58&gt;] kthread+0xd8/0xf0
 [&lt;ffffffff815de97f&gt;] ret_from_fork+0x1f/0x40
 [&lt;ffffffff81096a80&gt;] ? kthread_worker_fn+0x180/0x180

INFO: task kworker/u8:4:282 blocked for more than 120 seconds.
 ...
Call Trace:
 [&lt;ffffffff810ad745&gt;] ? put_prev_entity+0x35/0x8b0
 [&lt;ffffffff815daec5&gt;] schedule+0x35/0x80
 [&lt;ffffffff815db14e&gt;] schedule_preempt_disabled+0xe/0x10
 [&lt;ffffffff815dc533&gt;] __mutex_lock_slowpath+0xb3/0x120
 [&lt;ffffffff815dc5bf&gt;] mutex_lock+0x1f/0x30
 [&lt;ffffffff8147a59b&gt;] power_supply_deferred_register_work+0x2b/0x50
 [&lt;ffffffff81090d09&gt;] process_one_work+0x1e9/0x440
 [&lt;ffffffff81090fab&gt;] worker_thread+0x4b/0x4f0
 [&lt;ffffffff81090f60&gt;] ? process_one_work+0x440/0x440
 [&lt;ffffffff81090f60&gt;] ? process_one_work+0x440/0x440
 [&lt;ffffffff81096b58&gt;] kthread+0xd8/0xf0
 [&lt;ffffffff815de97f&gt;] ret_from_fork+0x1f/0x40
 [&lt;ffffffff81096a80&gt;] ? kthread_worker_fn+0x180/0x180

Making sysfs_add_battery() the last operation here means that the
power_supply won't be created yet when the acpi_add_battery() failure
handling happens, the deferred task won't even spawn, and
sysfs_remove_battery will just skip over the NULL battery-&gt;bat.

Signed-off-by: Carlos Garnacho &lt;carlosg@gnome.org&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Thus move sysfs_add_battery() after acpi_battery_get_state(), which doesn't
require the power_supply. Prevents possible hanged tasks if
acpi_battery_get_state() fails consistently (and takes a long time in doing
so) when called inside acpi_battery_add().

In this situation the battery module first calls sysfs_add_battery(),
which creates a power_supply, which spawns an async
power_supply_deferred_register_work() task, which shall try to hold the
parent battery device mutex (being already held) so this register work
is set up after device initialization. If initialization takes long enough
the thread will be eventually run and try to hold the mutex before
acpi_battery_add() had the chance to finish.

Eventually the 5 retries in acpi_battery_update_retry() fail, the error
state is propagated, and results in sysfs_remove_battery() being called
within the error handling paths of acpi_battery_add(), and the power_supply
tear down too.

This triggers a cancel_delayed_work_sync() of the deferred_register_work
task, which ends up in schedule(). The end result is that the deferred
task is blocked trying to acquire the parent device mutex, which is not
released because the thread doing initialization (and failure handling)
went to sleep awaiting for the deferred task to be cancelled.

The hanged tasks look like this:

INFO: task kworker/u8:0:6 blocked for more than 120 seconds.
 ...
Call Trace:
 [&lt;ffffffff815daec5&gt;] schedule+0x35/0x80
 [&lt;ffffffff815dda3c&gt;] schedule_timeout+0x1ec/0x250
 [&lt;ffffffff810a0572&gt;] ? check_preempt_curr+0x52/0x90
 [&lt;ffffffff810a05c9&gt;] ? ttwu_do_wakeup+0x19/0xe0
 [&lt;ffffffff815db915&gt;] wait_for_common+0xc5/0x190
 [&lt;ffffffff810a1500&gt;] ? wake_up_q+0x70/0x70
 [&lt;ffffffff815db9fd&gt;] wait_for_completion+0x1d/0x20
 [&lt;ffffffff8108ffb1&gt;] flush_work+0x111/0x1c0
 [&lt;ffffffff8108dfe0&gt;] ? flush_workqueue_prep_pwqs+0x1a0/0x1a0
 [&lt;ffffffff810909af&gt;] __cancel_work_timer+0x9f/0x1d0
 [&lt;ffffffff81090b13&gt;] cancel_delayed_work_sync+0x13/0x20
 [&lt;ffffffff8147ac67&gt;] power_supply_unregister+0x37/0xc0
 [&lt;ffffffffa058b03d&gt;] sysfs_remove_battery+0x3d/0x52 [battery]
 [&lt;ffffffffa058bf3a&gt;] acpi_battery_add+0x112/0x181 [battery]
 [&lt;ffffffff81366db6&gt;] acpi_device_probe+0x54/0x19b
 [&lt;ffffffff81427e9c&gt;] driver_probe_device+0x22c/0x440
 [&lt;ffffffff81428181&gt;] __driver_attach+0xd1/0xf0
 [&lt;ffffffff814280b0&gt;] ? driver_probe_device+0x440/0x440
 [&lt;ffffffff8142591c&gt;] bus_for_each_dev+0x6c/0xc0
 [&lt;ffffffff8142758e&gt;] driver_attach+0x1e/0x20
 [&lt;ffffffff81426fc3&gt;] bus_add_driver+0x1c3/0x280
 [&lt;ffffffff81428b00&gt;] driver_register+0x60/0xe0
 [&lt;ffffffff81366c80&gt;] acpi_bus_register_driver+0x3b/0x43
 [&lt;ffffffffa0591040&gt;] acpi_battery_init_async+0x1c/0x1e [battery]
 [&lt;ffffffff81099268&gt;] async_run_entry_fn+0x48/0x150
 [&lt;ffffffff81090d09&gt;] process_one_work+0x1e9/0x440
 [&lt;ffffffff81090fab&gt;] worker_thread+0x4b/0x4f0
 [&lt;ffffffff81090f60&gt;] ? process_one_work+0x440/0x440
 [&lt;ffffffff81096b58&gt;] kthread+0xd8/0xf0
 [&lt;ffffffff815de97f&gt;] ret_from_fork+0x1f/0x40
 [&lt;ffffffff81096a80&gt;] ? kthread_worker_fn+0x180/0x180

INFO: task kworker/u8:4:282 blocked for more than 120 seconds.
 ...
Call Trace:
 [&lt;ffffffff810ad745&gt;] ? put_prev_entity+0x35/0x8b0
 [&lt;ffffffff815daec5&gt;] schedule+0x35/0x80
 [&lt;ffffffff815db14e&gt;] schedule_preempt_disabled+0xe/0x10
 [&lt;ffffffff815dc533&gt;] __mutex_lock_slowpath+0xb3/0x120
 [&lt;ffffffff815dc5bf&gt;] mutex_lock+0x1f/0x30
 [&lt;ffffffff8147a59b&gt;] power_supply_deferred_register_work+0x2b/0x50
 [&lt;ffffffff81090d09&gt;] process_one_work+0x1e9/0x440
 [&lt;ffffffff81090fab&gt;] worker_thread+0x4b/0x4f0
 [&lt;ffffffff81090f60&gt;] ? process_one_work+0x440/0x440
 [&lt;ffffffff81090f60&gt;] ? process_one_work+0x440/0x440
 [&lt;ffffffff81096b58&gt;] kthread+0xd8/0xf0
 [&lt;ffffffff815de97f&gt;] ret_from_fork+0x1f/0x40
 [&lt;ffffffff81096a80&gt;] ? kthread_worker_fn+0x180/0x180

Making sysfs_add_battery() the last operation here means that the
power_supply won't be created yet when the acpi_add_battery() failure
handling happens, the deferred task won't even spawn, and
sysfs_remove_battery will just skip over the NULL battery-&gt;bat.

Signed-off-by: Carlos Garnacho &lt;carlosg@gnome.org&gt;
Signed-off-by: Rafael J. Wysocki &lt;rafael.j.wysocki@intel.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
