ANDROID: cpufreq: add vendor hook in cpufreq_offline

Add vendor hook in cpufreq_offline to block uevent pathway before
cpufreq cooling unregister to prevent NETLINK broadcast waking up during
suspend.

The change is because android hardware health service will register
epoll with EPOLLWAKEUP flag [1].  Afterwards, when suspend starts,
NETLINK will hold the wakelock because the EPOLLWAKEUP flag registered
from health service.

One more key factor is the CAP_BLOCK_SUSPEND capability of health
service [2] that may affect suspend flow as well.

Currently only the patch [3] is available but not accepted in upstream.

[1] https://android.googlesource.com/platform/hardware/interfaces/+/master/health/utils/libhealthloop/HealthLoop.cpp#69
[2] https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1461242
[3] https://patchwork.kernel.org/project/linux-pm/list/?series=658300&state=%2A&archive=both

Bug: 260537724
Change-Id: Ifea4bff2d8fdc3b7e60e7f1cb7ec29a8d3c8771a
Signed-off-by: Jia-Wei Chang <jia-wei.chang@mediatek.com>
This commit is contained in:
Jia-Wei Chang
2022-12-14 13:42:00 +08:00
parent b5b2dbf1a2
commit cb0ff59972
5 changed files with 23 additions and 0 deletions

View File

@@ -164,6 +164,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_table_limits);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpufreq_resolve_freq);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpufreq_fast_switch);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpufreq_target);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpufreq_offline);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_skip_swapcache_flags);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_gfp_zone_flags);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_readahead_gfp_mask);

View File

@@ -1629,6 +1629,7 @@ static int cpufreq_offline(unsigned int cpu)
}
if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
trace_android_vh_cpufreq_offline(&policy->cdev->device, true);
cpufreq_cooling_unregister(policy->cdev);
trace_android_vh_thermal_unregister(policy);
policy->cdev = NULL;

View File

@@ -13,6 +13,8 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <trace/hooks/cpufreq.h>
#define LUT_MAX_ENTRIES 32U
#define LUT_FREQ GENMASK(11, 0)
@@ -249,6 +251,11 @@ static void mtk_cpufreq_register_em(struct cpufreq_policy *policy)
&em_cb, policy->cpus, true);
}
static void mtk_cpufreq_suppress(void *data, struct device *dev, int val)
{
dev_set_uevent_suppress(dev, val);
}
static struct cpufreq_driver cpufreq_mtk_hw_driver = {
.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
@@ -280,6 +287,8 @@ static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
if (ret)
dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n");
ret = register_trace_android_vh_cpufreq_offline(mtk_cpufreq_suppress, NULL);
return ret;
}

View File

@@ -15,6 +15,8 @@
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/thermal.h>
#include <linux/device.h>
#include <trace/hooks/cpufreq.h>
#define MIN_VOLT_SHIFT (100000)
#define MAX_VOLT_SHIFT (200000)
@@ -462,6 +464,11 @@ static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
return 0;
}
static void mtk_cpufreq_suppress(void *data, struct device *dev, int val)
{
dev_set_uevent_suppress(dev, val);
}
static struct cpufreq_driver mtk_cpufreq_driver = {
.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
@@ -509,6 +516,8 @@ static int mtk_cpufreq_probe(struct platform_device *pdev)
goto release_dvfs_info_list;
}
ret = register_trace_android_vh_cpufreq_offline(mtk_cpufreq_suppress, NULL);
return 0;
release_dvfs_info_list:

View File

@@ -47,6 +47,9 @@ DECLARE_HOOK(android_vh_cpufreq_target,
unsigned int old_target_freq),
TP_ARGS(policy, target_freq, old_target_freq));
DECLARE_HOOK(android_vh_cpufreq_offline,
TP_PROTO(struct device *dev, int val),
TP_ARGS(dev, val));
#endif /* _TRACE_HOOK_CPUFREQ_H */
/* This part must be outside protection */
#include <trace/define_trace.h>