diff options
author | Finley Xiao <finley.xiao@rock-chips.com> | 2018-07-18 09:32:08 +0800 |
---|---|---|
committer | Tao Huang <huangtao@rock-chips.com> | 2018-07-23 15:26:47 +0800 |
commit | 106471a6e4e9229976e684d8a9ecf58b1b73e141 (patch) | |
tree | 2e0beee51feb665ec762fee04c750c493e4266fd /drivers/soc | |
parent | 9d76b2eb095b678b57ed28b2324ac684c2cf48c7 (diff) |
soc: rockchip: pm_test: Add support for dvfs_table_scan
Change-Id: Ie03ed876661286d19b57029f32fe5365c0b60415
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/rockchip/pm_test.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/soc/rockchip/pm_test.c b/drivers/soc/rockchip/pm_test.c index db839d16f0ba..211bde78cc5e 100644 --- a/drivers/soc/rockchip/pm_test.c +++ b/drivers/soc/rockchip/pm_test.c @@ -29,6 +29,7 @@ #define CLK_NR_CLKS 550 static int cpu_usage_run; +static struct file *wdt_filp; static DEFINE_PER_CPU(struct work_struct, work_cpu_usage); static DEFINE_PER_CPU(struct workqueue_struct *, workqueue_cpu_usage); @@ -583,10 +584,105 @@ static ssize_t cpu_usage_store(struct kobject *kobj, return n; } +static ssize_t dvfs_table_scan_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + char *str = buf; + + str += sprintf(str, "start: start scan dvfs table\n"); + str += sprintf(str, "alive: send alive\n"); + str += sprintf(str, "stop: stop scan dvfs table\n"); + if (str != buf) + *(str - 1) = '\n'; + + return (str - buf); +} + +static int wdt_start(void) +{ + if (wdt_filp) + return 0; + + wdt_filp = filp_open("/dev/watchdog", O_WRONLY, 0); + if (IS_ERR(wdt_filp)) { + pr_err("%s: failed to open /dev/watchdog\n", __func__); + wdt_filp = NULL; + return -EINVAL; + } + + return 0; +} + +static int wdt_keepalive(void) +{ + mm_segment_t old_fs; + + if (!wdt_filp) { + pr_err("%s: /dev/watchdog filp error\n", __func__); + return -EINVAL; + } + old_fs = get_fs(); + set_fs(KERNEL_DS); + if (wdt_filp->f_op->write(wdt_filp, "\0", 1, &wdt_filp->f_pos) <= 0) + pr_err("%s: write 0 error\n", __func__); + set_fs(old_fs); + + return 0; +} + +static int wdt_stop(void) +{ + mm_segment_t old_fs; + + if (!wdt_filp) { + pr_err("%s: /dev/watchdog filp error\n", __func__); + return -EINVAL; + } + old_fs = get_fs(); + set_fs(KERNEL_DS); + if (wdt_filp->f_op->write(wdt_filp, "V", 1, &wdt_filp->f_pos) <= 0) + pr_err("%s: write V error\n", __func__); + set_fs(old_fs); + filp_close(wdt_filp, NULL); + + return 0; +} + +static ssize_t dvfs_table_scan_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + char cmd[20]; + int ret; + + ret = sscanf(buf, "%s", cmd); + if (ret != 1) + return -EINVAL; + + if (!strcmp(cmd, "start")) { + ret = wdt_start(); + if (ret) + return ret; + } else if (!strcmp(cmd, "alive")) { + ret = wdt_keepalive(); + if (ret) + return ret; + } else if (!strcmp(cmd, "stop")) { + ret = wdt_stop(); + if (ret) + return ret; + } + + return n; +} + static struct pm_attribute pm_attrs[] = { __ATTR(clk_rate, 0644, clk_rate_show, clk_rate_store), __ATTR(clk_volt, 0644, clk_volt_show, clk_volt_store), __ATTR(cpu_usage, 0644, cpu_usage_show, cpu_usage_store), + __ATTR(dvfs_table_scan, 0644, dvfs_table_scan_show, + dvfs_table_scan_store), }; static int __init pm_test_init(void) |