kernel-brax3-ubuntu-touch/drivers/thermal/mediatek/md_cooling_debugfs.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

294 lines
6.3 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020 MediaTek Inc.
*/
#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include "md_cooling.h"
#define MD_COOLING_DEBUGFS_ENTRY_RO(name) \
static int md_cooling_##name##_open(struct inode *i, struct file *file) \
{ \
return single_open(file, md_cooling_##name##_show, i->i_private); \
} \
\
static const struct file_operations md_cooling_##name##_fops = { \
.owner = THIS_MODULE, \
.open = md_cooling_##name##_open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
}
#define MD_COOLING_DEBUGFS_ENTRY_RW(name) \
static int md_cooling_##name##_open(struct inode *i, struct file *file) \
{ \
return single_open(file, md_cooling_##name##_show, i->i_private); \
} \
\
static const struct file_operations md_cooling_##name##_fops = { \
.owner = THIS_MODULE, \
.open = md_cooling_##name##_open, \
.read = seq_read, \
.write = md_cooling_##name##_write, \
.llseek = seq_lseek, \
.release = single_release, \
}
static struct dentry *mdc_debug_dir;
static int ca_ctrl;
static int pa_ctrl;
static int duty_ctrl;
static int md_cooling_status_show(struct seq_file *m, void *unused)
{
struct md_cooling_device *md_cdev;
int i, j;
unsigned int pa_num = get_pa_num();
seq_printf(m, "PA num = %d\n", pa_num);
seq_printf(m, "MD status = %d\n", get_md_cooling_status());
for (i = 0; i < NR_MD_COOLING_TYPE; i++) {
for (j = 0; j < pa_num; j++) {
md_cdev = get_md_cdev((enum md_cooling_type)i, j);
if (!md_cdev)
continue;
seq_printf(m, "\n[%s, %d]\n", md_cdev->name,
md_cdev->pa_id);
seq_printf(m, "target/max = %ld/%ld\n",
md_cdev->target_state, md_cdev->max_state);
if (md_cdev->type == MD_COOLING_TYPE_TX_PWR)
seq_printf(m, "throttle tx_pwr = %d/%d/%d\n",
md_cdev->throttle_tx_power[0],
md_cdev->throttle_tx_power[1],
md_cdev->throttle_tx_power[2]);
}
}
return 0;
}
MD_COOLING_DEBUGFS_ENTRY_RO(status);
static int md_cooling_duty_ctrl_show(struct seq_file *m, void *unused)
{
seq_printf(m, "duty ctrl is %s\n", duty_ctrl ? "ON" : "OFF");
return 0;
}
static ssize_t md_cooling_duty_ctrl_write(struct file *flip,
const char *ubuf, size_t cnt, loff_t *data)
{
int ret = cnt, msg, no_ims, active, suspend, enable;
char *buf;
if (cnt > 32)
return -ENOMEM;
buf = kmalloc(cnt + 1, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
if (copy_from_user(buf, ubuf, cnt)) {
ret = -EFAULT;
goto err;
}
buf[cnt] = '\0';
if ((sscanf(buf, "%d %d %d", &no_ims, &active, &suspend) != 3)) {
ret = -EINVAL;
goto err;
}
if (get_md_cooling_status() != MD_LV_THROTTLE_DISABLED) {
ret = -EBUSY;
goto err;
}
if (no_ims) {
/* set active/suspend=1/255 for no IMS case */
msg = duty_ctrl_to_tmc_msg(1, 255, 0);
enable = 1;
} else if (active >= 1 && active <= 255
&& suspend >= 1 && suspend <= 255) {
msg = duty_ctrl_to_tmc_msg(active, suspend, 1);
enable = 1;
} else {
msg = TMC_THROTTLE_DISABLE_MSG;
enable = 0;
}
if (send_throttle_msg(msg)) {
ret = -EBUSY;
goto err;
}
duty_ctrl = enable;
err:
kfree(buf);
return ret;
}
MD_COOLING_DEBUGFS_ENTRY_RW(duty_ctrl);
static int md_cooling_ca_ctrl_show(struct seq_file *m, void *unused)
{
seq_printf(m, "CA ctrl is %s\n", ca_ctrl ? "ON" : "OFF");
return 0;
}
static ssize_t md_cooling_ca_ctrl_write(struct file *flip,
const char *ubuf, size_t cnt, loff_t *data)
{
int val;
if (kstrtoint_from_user(ubuf, cnt, 0, &val))
return -EFAULT;
if (get_md_cooling_status() != MD_LV_THROTTLE_DISABLED)
return -EBUSY;
if (send_throttle_msg(ca_ctrl_to_tmc_msg(val)))
return -EBUSY;
ca_ctrl = val;
return cnt;
}
MD_COOLING_DEBUGFS_ENTRY_RW(ca_ctrl);
static int md_cooling_pa_ctrl_show(struct seq_file *m, void *unused)
{
seq_printf(m, "PA ctrl is %s\n", pa_ctrl ? "ON" : "OFF");
return 0;
}
static ssize_t md_cooling_pa_ctrl_write(struct file *flip,
const char *ubuf, size_t cnt, loff_t *data)
{
int val;
if (kstrtoint_from_user(ubuf, cnt, 0, &val))
return -EFAULT;
if (get_md_cooling_status() != MD_LV_THROTTLE_DISABLED)
return -EBUSY;
if (send_throttle_msg(pa_ctrl_to_tmc_msg(val)))
return -EBUSY;
pa_ctrl = val;
return cnt;
}
MD_COOLING_DEBUGFS_ENTRY_RW(pa_ctrl);
static int md_cooling_update_tx_pwr_show(struct seq_file *m, void *unused)
{
struct md_cooling_device *md_cdev;
int i;
for (i = 0; i < get_pa_num(); i++) {
md_cdev = get_md_cdev(MD_COOLING_TYPE_TX_PWR, i);
if (!md_cdev)
continue;
seq_printf(m, "PA%d throttle tx_pwr = %d/%d/%d\n",
i,
md_cdev->throttle_tx_power[0],
md_cdev->throttle_tx_power[1],
md_cdev->throttle_tx_power[2]);
}
return 0;
}
static ssize_t md_cooling_update_tx_pwr_write(struct file *flip,
const char *ubuf, size_t cnt, loff_t *data)
{
int ret = cnt, id, tx_pwr_lv1, tx_pwr_lv2, tx_pwr_lv3;
unsigned int tx_pwr[MAX_NUM_TX_PWR_STATE];
char *buf;
if (cnt > 32)
return -ENOMEM;
buf = kmalloc(cnt + 1, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
if (copy_from_user(buf, ubuf, cnt)) {
ret = -EFAULT;
goto err;
}
buf[cnt] = '\0';
if ((sscanf(buf, "%d %d %d %d", &id, &tx_pwr_lv1,
&tx_pwr_lv2, &tx_pwr_lv3) != (MAX_NUM_TX_PWR_STATE + 1))) {
ret = -EINVAL;
goto err;
}
if (id >= get_pa_num()) {
pr_err("Invalid PA id(%d)\n", id);
ret = -EINVAL;
goto err;
}
tx_pwr[0] = tx_pwr_lv1;
tx_pwr[1] = tx_pwr_lv2;
tx_pwr[2] = tx_pwr_lv3;
update_throttle_power(id, tx_pwr);
err:
kfree(buf);
return ret;
}
MD_COOLING_DEBUGFS_ENTRY_RW(update_tx_pwr);
int md_cooling_debugfs_init(void)
{
mdc_debug_dir = debugfs_create_dir("md_cooling", NULL);
if (!mdc_debug_dir) {
pr_err("failed to create mdc_debug_dir\n");
goto failed;
}
if (!debugfs_create_file("status", 0440,
mdc_debug_dir, NULL, &md_cooling_status_fops))
goto failed;
if (!debugfs_create_file("duty_ctrl", 0640,
mdc_debug_dir, NULL, &md_cooling_duty_ctrl_fops))
goto failed;
if (!debugfs_create_file("ca_ctrl", 0640,
mdc_debug_dir, NULL, &md_cooling_ca_ctrl_fops))
goto failed;
if (!debugfs_create_file("pa_ctrl", 0640,
mdc_debug_dir, NULL, &md_cooling_pa_ctrl_fops))
goto failed;
if (!debugfs_create_file("update_tx_pwr", 0640,
mdc_debug_dir, NULL, &md_cooling_update_tx_pwr_fops))
goto failed;
return 0;
failed:
return -ENODEV;
}
void md_cooling_debugfs_exit(void)
{
debugfs_remove_recursive(mdc_debug_dir);
}