android_kernel_google_msm/kernel/power
Iliyan Malchev 7e87a4dc87 PM: wakeup_reason: correctly deduce wakeup interrupts
The wakeup_reason driver works by having a callback log_wakeup_reason(), be
called by the resume path once for each wakeup interrupt, with the irq number
as argument.  It then saves this interrupt in an array, and reports it when
requested (via /sys/kernel/wakeup_reasons/last_resume_reason) and also prints
the information out in kmsg.

This approach works, but it has the deficiency that often the reported wakeup
interrupt, while correct, is not the interrupt truly responsible for the
wakeup.  The reason for this is due to chained interrupt controllers (whether
in hardware or simulated in software).  It could be, for example, that the
power button is wired to a GPIO handled by a single interrupt for all GPIOs,
which interrupt then determines the GPIO and maps this to a software interrupt.
Whether this is done in software, or by chaining interrupt controllers, the end
result is that the wakeup reason will show not the interrupt associated with
the power button, but the base-GPIO interrupt instead.

This patch reworks the wakeup_sources driver such that it reports those final
interrupts we are interested in, and not the intermediate (and not the base)
ones.  It does so as follows:

-- The assumption is that generic_handle_irq() is called to dispatch all
   interrupts; due to this, chained interrupts result in recursive calls of
   generic_handle_irq().
-- We reconstruct the chains of interrupts that originate with the base wakeup
   interrupt and terminate with the interrupt we are interested in by tracing
   the calls to generic_handle_irq()
-- The tracing works by maitaining a per-cpu counter that is incremented with
   each call to generic_handle_irq(); that counter is reported to the
   wakeup_sources driver by a pair of functions, called
   log_possible_wakeup_reason_start() and log_possible_wakeup_reason_complete().
   The former is called before generic_handle_irq() handles the interrupt
   (thereby potentially calling itself recusively) and the latter afterward.
-- The two functions mentioned above are complemented by log_base_wake_reason()
   (renamed from log_wakeup_reason()), which is used to report the base wakeup
   interrupts to the wakeup_reason driver.
-- The three functions work together to build a set of trees, one per base
   wakeup reason, the leaves of which correspond to the interrupts we are
   interesed in; these trees can be arbitratily complex, though in reality they
   most often are a single node, or a chain of two nodes.  The complexity
   supports arbitrarily involved interrupt dispatch.
-- On resume, we build the tree; once the tree is completed, we walk it
   recursively, and print out to kmesg the (more useful) list of wakeup
   sources; simiarly, we walk the tree and print the leaves when
   /sys/kernel/wakeup_reasons/last_resume_reason is read.

Signed-off-by: Iliyan Malchev <malchev@google.com>
Change-Id: If8acb2951b61d2c6bcf4d011fe04d7f91057d139
2017-10-15 17:05:07 +03:00
..
autosleep.c PM / Sleep: Add "prevent autosleep time" statistics to wakeup sources 2017-10-15 15:46:55 +03:00
block_io.c
console.c
consoleearlysuspend.c consoleearlysuspend: Fix for 2.6.32 2013-02-20 01:32:22 -08:00
earlysuspend.c PM / Sleep: Clean up remnants of workqueue-based sync 2017-10-15 15:46:58 +03:00
fbearlysuspend.c framebuffer: add a pollable sysfs entry for display status 2013-02-20 01:32:14 -08:00
hibernate.c
Kconfig PM / Sleep: User space wakeup sources garbage collector Kconfig option 2017-10-15 15:46:57 +03:00
main.c PM / Sleep: Fix a mistake in a conditional in autosleep_store() 2017-10-15 15:46:58 +03:00
Makefile PM / Sleep: Add user space interface for manipulating wakeup sources, v3 2017-10-15 15:46:55 +03:00
power.h PM / Sleep: Add user space interface for manipulating wakeup sources, v3 2017-10-15 15:46:55 +03:00
poweroff.c
process.c power: log the last suspend abort reason. 2017-10-15 16:23:56 +03:00
qos.c
snapshot.c
suspend.c power: log the last suspend abort reason. 2017-10-15 16:23:56 +03:00
suspend_test.c
suspend_time.c
swap.c PM / Hibernate: fix the number of pages used for hibernate/thaw buffering 2012-04-24 23:53:28 +02:00
user.c
userwakelock.c PM: Add user-space wake lock api. 2013-02-20 01:32:11 -08:00
wakelock.c PM / Sleep: User space wakeup sources garbage collector Kconfig option 2017-10-15 15:46:57 +03:00
wakeup_reason.c PM: wakeup_reason: correctly deduce wakeup interrupts 2017-10-15 17:05:07 +03:00