mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
Power: Add /proc/wakeup_sources for Battery Tracer
Because /sys/kernel/debug will not be mounted on user build release, it's hard to debug power issues due to the lack of wakeup_sources system file node which is used by Battery Tracer. Add /proc/wakeup_sources for Battery Tracer to use Change-Id: I5b6774a25cda4d6344fbe266e8effb53f478edd7 Reviewed-on: https://gerrit.mot.com/2361839 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Jianqi Yang <yangj@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
1c3022555b
commit
31ad034f3e
4 changed files with 173 additions and 0 deletions
9
drivers/power/wakeup_sources/Android.mk
Normal file
9
drivers/power/wakeup_sources/Android.mk
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
DLKM_DIR := motorola/kernel/modules
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := wakeup_sources.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
KBUILD_OPTIONS_GKI += GKI_OBJ_MODULE_DIR=gki
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
6
drivers/power/wakeup_sources/Kbuild
Normal file
6
drivers/power/wakeup_sources/Kbuild
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include
|
||||
|
||||
obj-m += wakeup_sources.o
|
||||
|
||||
14
drivers/power/wakeup_sources/Makefile
Normal file
14
drivers/power/wakeup_sources/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
all: modules
|
||||
|
||||
modules:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(M) modules_install
|
||||
|
||||
%:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(M) $@ $(KBUILD_OPTIONS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers
|
||||
rm -rf .tmp_versions
|
||||
144
drivers/power/wakeup_sources/wakeup_sources.c
Normal file
144
drivers/power/wakeup_sources/wakeup_sources.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/pm_wakeup.h>
|
||||
|
||||
/*
|
||||
* /proc/wakeup_sources
|
||||
*/
|
||||
|
||||
struct proc_dir_entry *g_proc_wakeup_sources;
|
||||
int g_lock_wakeup_sources;
|
||||
|
||||
/**
|
||||
* print_wakeup_source_stats - Print wakeup source statistics information.
|
||||
* @m: seq_file to print the statistics into.
|
||||
* @ws: Wakeup source object to print the statistics for.
|
||||
*/
|
||||
static int print_wakeup_source_stats(struct seq_file *m,
|
||||
struct wakeup_source *ws)
|
||||
{
|
||||
unsigned long flags;
|
||||
ktime_t total_time;
|
||||
ktime_t max_time;
|
||||
unsigned long active_count;
|
||||
ktime_t active_time;
|
||||
ktime_t prevent_sleep_time;
|
||||
|
||||
spin_lock_irqsave(&ws->lock, flags);
|
||||
|
||||
total_time = ws->total_time;
|
||||
max_time = ws->max_time;
|
||||
prevent_sleep_time = ws->prevent_sleep_time;
|
||||
active_count = ws->active_count;
|
||||
if (ws->active) {
|
||||
ktime_t now = ktime_get();
|
||||
|
||||
active_time = ktime_sub(now, ws->last_time);
|
||||
total_time = ktime_add(total_time, active_time);
|
||||
if (active_time > max_time)
|
||||
max_time = active_time;
|
||||
|
||||
if (ws->autosleep_enabled)
|
||||
prevent_sleep_time = ktime_add(prevent_sleep_time,
|
||||
ktime_sub(now, ws->start_prevent_time));
|
||||
} else {
|
||||
active_time = 0;
|
||||
}
|
||||
|
||||
seq_printf(m, "%-12s\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%lld\t\t%lld\t\t%lld\t\t%lld\t\t%lld\n",
|
||||
ws->name, active_count, ws->event_count,
|
||||
ws->wakeup_count, ws->expire_count,
|
||||
ktime_to_ms(active_time), ktime_to_ms(total_time),
|
||||
ktime_to_ms(max_time), ktime_to_ms(ws->last_time),
|
||||
ktime_to_ms(prevent_sleep_time));
|
||||
|
||||
spin_unlock_irqrestore(&ws->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *wakeup_sources_stats_seq_start(struct seq_file *m,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct wakeup_source *ws;
|
||||
loff_t n = *pos;
|
||||
|
||||
if (n == 0) {
|
||||
seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t"
|
||||
"expire_count\tactive_since\ttotal_time\tmax_time\t"
|
||||
"last_change\tprevent_suspend_time\n");
|
||||
}
|
||||
|
||||
g_lock_wakeup_sources = wakeup_sources_read_lock();
|
||||
for_each_wakeup_source(ws) {
|
||||
if (n-- <= 0)
|
||||
return ws;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *wakeup_sources_stats_seq_next(struct seq_file *m,
|
||||
void *v, loff_t *pos)
|
||||
{
|
||||
struct wakeup_source *ws = v;
|
||||
struct wakeup_source *next_ws = NULL;
|
||||
|
||||
++(*pos);
|
||||
next_ws = wakeup_sources_walk_next(ws);
|
||||
|
||||
return next_ws;
|
||||
}
|
||||
|
||||
static void wakeup_sources_stats_seq_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
wakeup_sources_read_unlock(g_lock_wakeup_sources);
|
||||
}
|
||||
|
||||
/**
|
||||
* wakeup_sources_stats_seq_show - Print wakeup sources statistics information.
|
||||
* @m: seq_file to print the statistics into.
|
||||
* @v: wakeup_source of each iteration
|
||||
*/
|
||||
static int wakeup_sources_stats_seq_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct wakeup_source *ws = v;
|
||||
|
||||
print_wakeup_source_stats(m, ws);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations wakeup_sources_stats_seq_ops = {
|
||||
.start = wakeup_sources_stats_seq_start,
|
||||
.next = wakeup_sources_stats_seq_next,
|
||||
.stop = wakeup_sources_stats_seq_stop,
|
||||
.show = wakeup_sources_stats_seq_show,
|
||||
};
|
||||
|
||||
static int __init proc_wakeup_sources_init(void)
|
||||
{
|
||||
pr_debug("%s(), %d\n", __func__, __LINE__);
|
||||
g_proc_wakeup_sources = proc_create_seq("wakeup_sources",
|
||||
S_IRUGO, NULL, &wakeup_sources_stats_seq_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit proc_wakeup_sources_exit(void)
|
||||
{
|
||||
pr_debug("%s(), %d\n", __func__, __LINE__);
|
||||
proc_remove(g_proc_wakeup_sources);
|
||||
}
|
||||
|
||||
module_init(proc_wakeup_sources_init);
|
||||
module_exit(proc_wakeup_sources_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
Loading…
Reference in a new issue