From 6cf77e44c2e9a1685f3f3573c1b801f16872a00c Mon Sep 17 00:00:00 2001 From: chenxing Date: Wed, 7 Aug 2013 14:55:16 +0800 Subject: [PATCH] rk: pm_tests: add rk2918 FT command board support as a watchdog for dvfs table scan --- arch/arm/plat-rk/rk_pm_tests/Kconfig | 5 + arch/arm/plat-rk/rk_pm_tests/Makefile | 1 + .../arm/plat-rk/rk_pm_tests/dvfs_table_scan.c | 157 ++++++++++++++++++ .../arm/plat-rk/rk_pm_tests/dvfs_table_scan.h | 8 + arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c | 6 +- 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.c create mode 100644 arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.h diff --git a/arch/arm/plat-rk/rk_pm_tests/Kconfig b/arch/arm/plat-rk/rk_pm_tests/Kconfig index 177d3e3581e7..77e7e19851c8 100755 --- a/arch/arm/plat-rk/rk_pm_tests/Kconfig +++ b/arch/arm/plat-rk/rk_pm_tests/Kconfig @@ -43,6 +43,11 @@ config PM_TEST_CLK_AUTO_VOLT help Use to auto scale regulator's voltage by step +config PM_TEST_DVFS_TABLE_SCAN + bool "dvfs table scan" + help + Use to scan dvfs table + config PM_TEST_DELAYLINE bool "Get delayline value" help diff --git a/arch/arm/plat-rk/rk_pm_tests/Makefile b/arch/arm/plat-rk/rk_pm_tests/Makefile index 63a59474b910..bd12a872fa35 100755 --- a/arch/arm/plat-rk/rk_pm_tests/Makefile +++ b/arch/arm/plat-rk/rk_pm_tests/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_PM_TEST_CPU_USAGE) += cpu_usage.o obj-$(CONFIG_PM_TEST_SUSPEND_DBG) += rk_suspend_test.o obj-$(CONFIG_PM_TEST_CLK_AUTO_VOLT) += clk_auto_volt.o obj-$(CONFIG_PM_TEST_DELAYLINE) += delayline.o +obj-$(CONFIG_PM_TEST_DVFS_TABLE_SCAN) += dvfs_table_scan.o obj-$(CONFIG_PM_TEST_FT) += ft/ diff --git a/arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.c b/arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.c new file mode 100644 index 000000000000..2361d0a8b385 --- /dev/null +++ b/arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "rk_pm_tests.h" +#include "maxfreq.h" +#include "rk_pm_tests.h" +#include "dvfs_table_scan.h" +/***************************************************************************/ +#if defined(CONFIG_ARCH_RK3026) +#define TTYS3_FILE_PATH "/dev/ttyS1" +#else +#define TTYS3_FILE_PATH "/dev/ttyS3" +#endif +struct workqueue_struct *workqueue_dvfs_table_scan; +struct work_struct work_dvfs_table_scan; +struct timer_list dvfs_table_scan_timer; +#define DVFS_TABLE_T_MSEC 1000 +struct file *file = NULL; +mm_segment_t old_fs; +loff_t offset = 0; +static int dvfs_table_scan_run = 0; +static int file_read(char *file_path, char *buf) +{ + PM_DBG("read %s\n", file_path); + + file->f_op->read(file, (char *)buf, 32, &offset); + + return 0; +} + +static int file_write(char *file_path, char *buf) +{ + PM_DBG("write %s %s size = %d\n", file_path, buf, strlen(buf)); + + file->f_op->write(file, (char *)buf, strlen(buf), &offset); + + return 0; +} +static void dvfs_table_scan_timer_handler(unsigned long data) +{ + //PM_DBG("enter %s\n", __func__); + char sendbuf[20]; + //static int sendcnt = 0; + memset(sendbuf, 0, sizeof(sendbuf)); + if (dvfs_table_scan_run == 0) { + PM_DBG("%s: STOP\n", __func__); + return ; + } + //sprintf(sendbuf, "alive%d", sendcnt++); + sprintf(sendbuf, "alive"); + PM_DBG("Sending alive signal...... %s\n", sendbuf); + file_write(TTYS3_FILE_PATH, sendbuf); + + mod_timer(&dvfs_table_scan_timer, jiffies + msecs_to_jiffies(DVFS_TABLE_T_MSEC)); +} +static void handler_dvfs_table_scan(struct work_struct *work) +{ + char buf[100]; + int ret = 0; + while (dvfs_table_scan_run) { + memset(buf, 0, sizeof(buf)); + ret = file_read(TTYS3_FILE_PATH, buf); + //if (ret < 0) + // PM_ERR("read error %d\n", ret); + if (strlen(buf) != 0) + PM_DBG("%s: get %s|len=%d\n", __func__, buf, strlen(buf)); + //mdelay(100); + } +} + +static void uart_init(void) +{ + file = filp_open(TTYS3_FILE_PATH, O_RDWR | O_NOCTTY, 0); + //file = filp_open(TTYS3_FILE_PATH, O_RDWR, 0); + if (IS_ERR(file)) { + PM_ERR("%s error open file %s\n", __func__, TTYS3_FILE_PATH); + return ; + } + old_fs = get_fs(); + set_fs(KERNEL_DS); +} +static void uart_deinit(void) +{ + set_fs(old_fs); + filp_close(file, NULL); +} +ssize_t dvfs_table_scan_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + char *str = buf; + str += sprintf(str, "start: \tstart scan dvfs table, send alive every 1s\n" + "stop: \tstop send alive signal\n"); + if (str != buf) + *(str - 1) = '\n'; + return (str - buf); + +} +ssize_t dvfs_table_scan_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + char cmd[20]; + + sscanf(buf, "%s", cmd); + PM_DBG("%s: get command <%s>\n", __func__, cmd); + if (0 == strncmp(cmd, "start", strlen("start"))) { + uart_init(); + dvfs_table_scan_run = 1; + file_write(TTYS3_FILE_PATH, "start"); + //queue_work(workqueue_dvfs_table_scan, &work_dvfs_table_scan); + //dvfs_table_scan_timer.expires = jiffies + msecs_to_jiffies(DVFS_TABLE_T_MSEC); + //add_timer(&dvfs_table_scan_timer); + uart_deinit(); + + } else if (0 == strncmp(cmd, "alive", strlen("alive"))) { + uart_init(); + file_write(TTYS3_FILE_PATH, "alive"); + uart_deinit(); + + } else if (0 == strncmp(cmd, "stop", strlen("stop"))) { + uart_init(); + file_write(TTYS3_FILE_PATH, "stop"); + dvfs_table_scan_run = 0; + uart_deinit(); + } + return n; +} + +static int __init dvfs_table_scan_init(void) +{ + workqueue_dvfs_table_scan = create_singlethread_workqueue("workqueue_dvfs_table_scan"); + INIT_WORK(&work_dvfs_table_scan, handler_dvfs_table_scan); + setup_timer(&dvfs_table_scan_timer, dvfs_table_scan_timer_handler, (unsigned int)NULL); + return 0; +} +late_initcall(dvfs_table_scan_init); diff --git a/arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.h b/arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.h new file mode 100644 index 000000000000..bef9f7bba0e8 --- /dev/null +++ b/arch/arm/plat-rk/rk_pm_tests/dvfs_table_scan.h @@ -0,0 +1,8 @@ +#ifndef _DVFS_TABLE_SCAN_H_ +#define _DVFS_TABLE_SCAN_H_ +ssize_t dvfs_table_scan_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); +ssize_t dvfs_table_scan_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n); + +#endif diff --git a/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c b/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c index 239e0759fb43..ee42d8334c92 100755 --- a/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c +++ b/arch/arm/plat-rk/rk_pm_tests/rk_pm_tests.c @@ -55,6 +55,7 @@ REVISION 0.01 #include "cpu_usage.h" #include "rk_suspend_test.h" #include "clk_auto_volt.h" +#include "dvfs_table_scan.h" #include "delayline.h" //#include "rk2928_freq.h" //#include "rk2928_max_freq.h" @@ -78,7 +79,7 @@ static struct pm_attribute pm_attrs[] = { __ATTR(clk_rate, S_IRUGO | S_IWUSR, clk_rate_show, clk_rate_store), #endif #ifdef CONFIG_PM_TEST_CLK_VOLT - __ATTR(clk_volt, S_IRUGO | S_IWUSR, clk_volt_show, clk_volt_store), + __ATTR(clk_volt, S_IRUGO | S_IWUSR | S_IWUGO, clk_volt_show, clk_volt_store), #endif #ifdef CONFIG_PM_TEST_MAXFREQ __ATTR(maxfreq_volt, S_IRUGO | S_IWUSR, maxfreq_show, maxfreq_store), @@ -96,6 +97,9 @@ static struct pm_attribute pm_attrs[] = { #ifdef CONFIG_PM_TEST_CLK_AUTO_VOLT __ATTR(clk_auto_volt, S_IRUGO | S_IWUSR, clk_auto_volt_show, clk_auto_volt_store), #endif +#ifdef CONFIG_PM_TEST_DVFS_TABLE_SCAN + __ATTR(dvfs_table_scan, S_IRUGO | S_IWUSR | S_IWUGO, dvfs_table_scan_show, dvfs_table_scan_store), +#endif #ifdef CONFIG_PM_TEST_DELAYLINE __ATTR(delayline, S_IRUGO | S_IWUSR, delayline_show, delayline_store), #endif -- 2.34.1