Skip to content

Commit a914b6f

Browse files
andip71mrslezak
authored andcommitted
boeffla_wl_blocker: add generic wakelock blocker driver v1.0.0 - v1.1.0
1 parent 4e59054 commit a914b6f

7 files changed

Lines changed: 348 additions & 11 deletions

File tree

kernel_platform/common/arch/arm64/configs/gki_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ CONFIG_CMDLINE_EXTEND=y
7272
CONFIG_HIBERNATION=y
7373
CONFIG_PM_WAKELOCKS=y
7474
CONFIG_PM_WAKELOCKS_LIMIT=0
75+
CONFIG_BOEFFLA_WL_BLOCKER=y
7576
# CONFIG_PM_WAKELOCKS_GC is not set
7677
CONFIG_ENERGY_MODEL=y
7778
CONFIG_CPU_IDLE=y

kernel_platform/common/drivers/base/power/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ obj-$(CONFIG_PM_TRACE_RTC) += trace.o
55
obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o
66
obj-$(CONFIG_HAVE_CLK) += clock_ops.o
77
obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
8+
obj-$(CONFIG_BOEFFLA_WL_BLOCKER) += boeffla_wl_blocker.o
89

910
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
/*
2+
* Author: andip71, 01.09.2017
3+
*
4+
* Version 1.1.0
5+
*
6+
* This software is licensed under the terms of the GNU General Public
7+
* License version 2, as published by the Free Software Foundation, and
8+
* may be copied, distributed, and modified under those terms.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
*/
16+
17+
/*
18+
* Change log:
19+
*
20+
* 1.1.0 (01.09.2017)
21+
* - By default, the following wakelocks are blocked in an own list
22+
* qcom_rx_wakelock, wlan, wlan_wow_wl, wlan_extscan_wl, NETLINK
23+
*
24+
* 1.0.1 (29.08.2017)
25+
* - Add killing wakelock when currently active
26+
*
27+
* 1.0.0 (28.08.2017)
28+
* - Initial version
29+
*
30+
*/
31+
32+
#include <linux/module.h>
33+
#include <linux/kobject.h>
34+
#include <linux/sysfs.h>
35+
#include <linux/device.h>
36+
#include <linux/miscdevice.h>
37+
#include <linux/printk.h>
38+
#include "boeffla_wl_blocker.h"
39+
40+
41+
/*****************************************/
42+
// Variables
43+
/*****************************************/
44+
45+
char list_wl[LENGTH_LIST_WL] = {0};
46+
char list_wl_default[LENGTH_LIST_WL_DEFAULT] = {0};
47+
48+
extern char list_wl_search[LENGTH_LIST_WL_SEARCH];
49+
extern bool wl_blocker_active;
50+
extern bool wl_blocker_debug;
51+
52+
53+
/*****************************************/
54+
// internal functions
55+
/*****************************************/
56+
57+
static void build_search_string(char *list1, char *list2)
58+
{
59+
// store wakelock list and search string (with semicolons added at start and end)
60+
sprintf(list_wl_search, ";%s;%s;", list1, list2);
61+
62+
// set flag if wakelock blocker should be active (for performance reasons)
63+
if (strlen(list_wl_search) > 5)
64+
wl_blocker_active = true;
65+
else
66+
wl_blocker_active = false;
67+
}
68+
69+
70+
/*****************************************/
71+
// sysfs interface functions
72+
/*****************************************/
73+
74+
// show list of user configured wakelocks
75+
static ssize_t wakelock_blocker_show(struct device *dev, struct device_attribute *attr,
76+
char *buf)
77+
{
78+
// return list of wakelocks to be blocked
79+
return sprintf(buf, "%s\n", list_wl);
80+
}
81+
82+
83+
// store list of user configured wakelocks
84+
static ssize_t wakelock_blocker_store(struct device * dev, struct device_attribute *attr,
85+
const char * buf, size_t n)
86+
{
87+
int len = n;
88+
89+
// check if string is too long to be stored
90+
if (len > LENGTH_LIST_WL)
91+
return -EINVAL;
92+
93+
// store user configured wakelock list and rebuild search string
94+
sscanf(buf, "%s", list_wl);
95+
build_search_string(list_wl_default, list_wl);
96+
97+
return n;
98+
}
99+
100+
101+
// show list of default, predefined wakelocks
102+
static ssize_t wakelock_blocker_default_show(struct device *dev, struct device_attribute *attr,
103+
char *buf)
104+
{
105+
// return list of wakelocks to be blocked
106+
return sprintf(buf, "%s\n", list_wl_default);
107+
}
108+
109+
110+
// store list of default, predefined wakelocks
111+
static ssize_t wakelock_blocker_default_store(struct device * dev, struct device_attribute *attr,
112+
const char * buf, size_t n)
113+
{
114+
int len = n;
115+
116+
// check if string is too long to be stored
117+
if (len > LENGTH_LIST_WL_DEFAULT)
118+
return -EINVAL;
119+
120+
// store default, predefined wakelock list and rebuild search string
121+
sscanf(buf, "%s", list_wl_default);
122+
build_search_string(list_wl_default, list_wl);
123+
124+
return n;
125+
}
126+
127+
128+
// show debug information of driver internals
129+
static ssize_t debug_show(struct device *dev, struct device_attribute *attr, char *buf)
130+
{
131+
// return current debug status
132+
return sprintf(buf, "Debug status: %d\n\nUser list: %s\nDefault list: %s\nSearch list: %s\nActive: %d\n",
133+
wl_blocker_debug, list_wl, list_wl_default, list_wl_search, wl_blocker_active);
134+
}
135+
136+
137+
// store debug mode on/off (1/0)
138+
static ssize_t debug_store(struct device *dev, struct device_attribute *attr,
139+
const char *buf, size_t count)
140+
{
141+
unsigned int ret = -EINVAL;
142+
unsigned int val;
143+
144+
// check data and store if valid
145+
ret = sscanf(buf, "%d", &val);
146+
147+
if (ret != 1)
148+
return -EINVAL;
149+
150+
if (val == 1)
151+
wl_blocker_debug = true;
152+
else
153+
wl_blocker_debug = false;
154+
155+
return count;
156+
}
157+
158+
159+
static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
160+
{
161+
// return version information
162+
return sprintf(buf, "%s\n", BOEFFLA_WL_BLOCKER_VERSION);
163+
}
164+
165+
166+
167+
/*****************************************/
168+
// Initialize sysfs objects
169+
/*****************************************/
170+
171+
// define objects
172+
static DEVICE_ATTR(wakelock_blocker, 0644, wakelock_blocker_show, wakelock_blocker_store);
173+
static DEVICE_ATTR(wakelock_blocker_default, 0644, wakelock_blocker_default_show, wakelock_blocker_default_store);
174+
static DEVICE_ATTR(debug, 0664, debug_show, debug_store);
175+
static DEVICE_ATTR(version, 0664, version_show, NULL);
176+
177+
// define attributes
178+
static struct attribute *boeffla_wl_blocker_attributes[] = {
179+
&dev_attr_wakelock_blocker.attr,
180+
&dev_attr_wakelock_blocker_default.attr,
181+
&dev_attr_debug.attr,
182+
&dev_attr_version.attr,
183+
NULL
184+
};
185+
186+
// define attribute group
187+
static struct attribute_group boeffla_wl_blocker_control_group = {
188+
.attrs = boeffla_wl_blocker_attributes,
189+
};
190+
191+
// define control device
192+
static struct miscdevice boeffla_wl_blocker_control_device = {
193+
.minor = MISC_DYNAMIC_MINOR,
194+
.name = "boeffla_wakelock_blocker",
195+
};
196+
197+
198+
/*****************************************/
199+
// Driver init and exit functions
200+
/*****************************************/
201+
202+
static int boeffla_wl_blocker_init(void)
203+
{
204+
// register boeffla wakelock blocker control device
205+
misc_register(&boeffla_wl_blocker_control_device);
206+
if (sysfs_create_group(&boeffla_wl_blocker_control_device.this_device->kobj,
207+
&boeffla_wl_blocker_control_group) < 0) {
208+
printk("Boeffla WL blocker: failed to create sys fs object.\n");
209+
return 0;
210+
}
211+
212+
// initialize default list
213+
sprintf(list_wl_default, "%s", LIST_WL_DEFAULT);
214+
build_search_string(list_wl_default, list_wl);
215+
216+
// Print debug info
217+
printk("Boeffla WL blocker: driver version %s started\n", BOEFFLA_WL_BLOCKER_VERSION);
218+
219+
return 0;
220+
}
221+
222+
223+
static void boeffla_wl_blocker_exit(void)
224+
{
225+
// remove boeffla wakelock blocker control device
226+
sysfs_remove_group(&boeffla_wl_blocker_control_device.this_device->kobj,
227+
&boeffla_wl_blocker_control_group);
228+
229+
// Print debug info
230+
printk("Boeffla WL blocker: driver stopped\n");
231+
}
232+
233+
234+
/* define driver entry points */
235+
module_init(boeffla_wl_blocker_init);
236+
module_exit(boeffla_wl_blocker_exit);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Author: andip71, 01.09.2017
3+
*
4+
* Version 1.1.0
5+
*
6+
* This software is licensed under the terms of the GNU General Public
7+
* License version 2, as published by the Free Software Foundation, and
8+
* may be copied, distributed, and modified under those terms.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
*/
16+
17+
#define BOEFFLA_WL_BLOCKER_VERSION "1.1.0"
18+
19+
#define LIST_WL_DEFAULT "qcom_rx_wakelock;smp2p-sleepstate;wlan;wlan_pno_wl;hal_bluetooth_lock;898000.qcom,qup_uart;grip_wake_lock"
20+
21+
#define LENGTH_LIST_WL 255
22+
#define LENGTH_LIST_WL_DEFAULT 100
23+
#define LENGTH_LIST_WL_SEARCH LENGTH_LIST_WL + LENGTH_LIST_WL_DEFAULT + 5

kernel_platform/common/drivers/base/power/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,10 @@ static void dpm_noirq_resume_devices(pm_message_t state)
696696
struct device *dev;
697697
ktime_t starttime = ktime_get();
698698

699+
#ifdef CONFIG_BOEFFLA_WL_BLOCKER
700+
pm_print_active_wakeup_sources();
701+
#endif
702+
699703
trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, true);
700704
mutex_lock(&dpm_list_mtx);
701705
pm_transition = state;

0 commit comments

Comments
 (0)