Files
android/drivers/misc/mediatek/lpm/mtk_lpm_registry.c
T
threeeye bc1d038eac REVVL 6 Pro kernel bring-up: full working tree snapshot (2026-09-12)
Squashed backup commit (no shallow-clone history issues) of
xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2 branch, upstream
commit 9eece662e) plus all fixes applied to get everpal_defconfig building
clean against a modern (GCC 15.2.0) toolchain -- see the previous commit
message on the lineage-23.2 branch (also in this repo history is not
available here since this is a squashed snapshot; full incremental history
lives in the local DL380 checkout and the upstream GitHub remote).

Upstream: https://github.com/xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2)
2026-09-12 13:36:46 +00:00

89 lines
1.7 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/kernel.h>
#include <linux/cpuidle.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include "mtk_lpm_registry.h"
#include "mtk_lpm_internal.h"
#define MTK_LPM_REGISTRY_MAGIC 0xCDAC9131
struct mtk_lpm_registry_wk {
unsigned int magic;
int type;
void *priv;
blockcall cb;
struct cpumask cpus;
};
#define INIT_MTK_LPM_REG_WK(wk, _type, _cb, _priv) ({\
(wk)->magic = MTK_LPM_REGISTRY_MAGIC;\
(wk)->type = _type;\
(wk)->cb = _cb;\
(wk)->priv = _priv; })
#define IS_MTK_LPM_REG_WK(wk)\
((wk) && ((wk)->magic == MTK_LPM_REGISTRY_MAGIC))
#define IS_MTK_LPM_REG_WAKEALL(cpumask)\
(cpumask_weight(cpumask) == num_online_cpus())
static long mtk_lpm_registry_work(void *pData)
{
struct mtk_lpm_registry_wk *lpm_wk =
(struct mtk_lpm_registry_wk *)pData;
unsigned long flags;
if (!IS_MTK_LPM_REG_WK(lpm_wk))
return 0;
switch (lpm_wk->type) {
case MTK_LPM_REG_PER_CPU:
mtk_lpm_system_lock(flags);
lpm_wk->cb(smp_processor_id(), lpm_wk->priv);
mtk_lpm_system_unlock(flags);
synchronize_rcu();
break;
case MTK_LPM_REG_ALL_ONLINE:
mtk_lpm_system_lock(flags);
cpumask_set_cpu(smp_processor_id(), &lpm_wk->cpus);
if (IS_MTK_LPM_REG_WAKEALL(&lpm_wk->cpus))
lpm_wk->cb(smp_processor_id(), lpm_wk->priv);
mtk_lpm_system_unlock(flags);
synchronize_rcu();
break;
default:
break;
}
return 0;
}
int mtk_lpm_do_work(int type, blockcall call, void *priv)
{
int cpu;
struct mtk_lpm_registry_wk lpm_wk;
INIT_MTK_LPM_REG_WK(&lpm_wk, type, call, priv);
cpuidle_pause_and_lock();
cpumask_clear(&lpm_wk.cpus);
for_each_online_cpu(cpu) {
work_on_cpu(cpu, mtk_lpm_registry_work, &lpm_wk);
}
cpuidle_resume_and_unlock();
return 0;
}