diff options
author | jk7744.park <jk7744.park@samsung.com> | 2016-03-04 13:08:37 +0900 |
---|---|---|
committer | jk7744.park <jk7744.park@samsung.com> | 2016-03-04 13:08:37 +0900 |
commit | 9bc6f5b38c467117617633695b191d4bc82b9b79 (patch) | |
tree | 8d4dff985cb43aa7f20d05798bcd1546dfdd32c0 | |
parent | 5c52bf2c2fa03561871834acbf2cd87ee24c9c49 (diff) | |
download | swap-modules-accepted/tizen_2.3.1_mobile.tar.gz swap-modules-accepted/tizen_2.3.1_mobile.tar.bz2 swap-modules-accepted/tizen_2.3.1_mobile.zip |
Tizen 2.4.0 rev3 SDK Public Releasesubmit/tizen_2.3.1/20160304.093515accepted/tizen/2.3.1/wearable/20160306.221758accepted/tizen/2.3.1/mobile/20160306.221536tizen_2.3.1accepted/tizen_2.3.1_wearableaccepted/tizen_2.3.1_mobile
-rw-r--r-- | energy/Kbuild | 7 | ||||
-rw-r--r-- | energy/debugfs_energy.c | 223 | ||||
-rw-r--r-- | energy/energy.c | 497 | ||||
-rw-r--r-- | energy/energy.h | 14 | ||||
-rw-r--r-- | energy/lcd/lcd_base.c | 18 | ||||
-rw-r--r-- | energy/lcd/s6e63j0x03.c | 186 | ||||
-rw-r--r-- | master/Kbuild | 3 | ||||
-rw-r--r-- | master/swap_deps.c | 69 | ||||
-rw-r--r-- | master/swap_deps.h | 38 | ||||
-rw-r--r-- | master/swap_initializer.c | 5 | ||||
-rwxr-xr-x | packaging/swap-modules.spec | 12 |
11 files changed, 1034 insertions, 38 deletions
diff --git a/energy/Kbuild b/energy/Kbuild index 80d23c9c..d7e9e638 100644 --- a/energy/Kbuild +++ b/energy/Kbuild @@ -39,6 +39,13 @@ ifeq ($(CONFIG_DISPLAY_PANEL_S6E8AA0), y) endif +# S6E63J0X03 +ifeq ($(CONFIG_EXYNOS_LCD_S6E63J0X03), y) + swap_energy-y += lcd/s6e63j0x03.o + LCD_FUNC_LIST += s6e63j0x03 +endif + + # MARU: ifeq ($(CONFIG_MARU_BACKLIGHT), y) swap_energy-y += lcd/maru.o diff --git a/energy/debugfs_energy.c b/energy/debugfs_energy.c index 3d3da06e..a9e0618e 100644 --- a/energy/debugfs_energy.c +++ b/energy/debugfs_energy.c @@ -32,21 +32,35 @@ #include "debugfs_energy.h" #include "rational_debugfs.h" #include "lcd/lcd_debugfs.h" +#include "lcd/lcd_base.h" /* CPU running */ static DEFINE_RATIONAL(cpu0_running_coef); /* boot core uses distinct coeff */ static DEFINE_RATIONAL(cpuN_running_coef); -static u64 __energy_cpu(enum parameter_energy pe) +static u64 __energy_cpu0(enum parameter_energy pe) { u64 times[NR_CPUS] = { 0 }; u64 val = 0; - int i; + /* TODO: make for only cpu0 */ if (get_parameter_energy(pe, times, sizeof(times)) == 0) { val = div_u64(times[0] * cpu0_running_coef.num, cpu0_running_coef.denom); + } + + return val; +} + +static u64 __energy_cpuN(enum parameter_energy pe) +{ + u64 times[NR_CPUS] = { 0 }; + u64 val = 0; + + if (get_parameter_energy(pe, times, sizeof(times)) == 0) { + int i; + for (i = 1; i < NR_CPUS; i++) val += div_u64(times[i] * cpuN_running_coef.num, cpuN_running_coef.denom); @@ -55,14 +69,24 @@ static u64 __energy_cpu(enum parameter_energy pe) return val; } -static u64 cpu_system(void) +static u64 cpu0_system(void) { - return __energy_cpu(PE_TIME_SYSTEM); + return __energy_cpu0(PE_TIME_SYSTEM); } -static u64 cpu_apps(void) +static u64 cpuN_system(void) { - return __energy_cpu(PE_TIME_APPS); + return __energy_cpuN(PE_TIME_SYSTEM); +} + +static u64 cpu0_apps(void) +{ + return __energy_cpu0(PE_TIME_APPS); +} + +static u64 cpuN_apps(void) +{ + return __energy_cpuN(PE_TIME_APPS); } @@ -118,6 +142,137 @@ static u64 fw_apps(void) } +/* wifi recv */ +static DEFINE_RATIONAL(wf_recv_coef); + +static u64 wf_recv_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_RECV_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * wf_recv_coef.num, wf_recv_coef.denom); +} + +static u64 wf_recv_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_RECV_APPS, &byte, sizeof(byte)); + + return div_u64(byte * wf_recv_coef.num, wf_recv_coef.denom); +} + +/* wifi send */ +static DEFINE_RATIONAL(wf_send_coef); + +static u64 wf_send_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_SEND_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * wf_send_coef.num, wf_send_coef.denom); +} + +static u64 wf_send_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_WF_SEND_APPS, &byte, sizeof(byte)); + + return div_u64(byte * wf_send_coef.num, wf_send_coef.denom); +} + +/* l2cap_recv_acldata */ +static DEFINE_RATIONAL(l2cap_recv_acldata_coef); + +static u64 l2cap_recv_acldata_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_L2CAP_RECV_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * l2cap_recv_acldata_coef.num, + l2cap_recv_acldata_coef.denom); +} + +static u64 l2cap_recv_acldata_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_L2CAP_RECV_APPS, &byte, sizeof(byte)); + + return div_u64(byte * l2cap_recv_acldata_coef.num, + l2cap_recv_acldata_coef.denom); +} + +/* sco_recv_scodata */ +static DEFINE_RATIONAL(sco_recv_scodata_coef); + +static u64 sco_recv_scodata_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_SCO_RECV_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * sco_recv_scodata_coef.num, + sco_recv_scodata_coef.denom); +} + +static u64 sco_recv_scodata_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PE_SCO_RECV_APPS, &byte, sizeof(byte)); + + return div_u64(byte * sco_recv_scodata_coef.num, + sco_recv_scodata_coef.denom); +} + +/* hci_send_acl */ +static DEFINE_RATIONAL(hci_send_acl_coef); + +static u64 hci_send_acl_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_ACL_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_acl_coef.num, hci_send_acl_coef.denom); +} + +static u64 hci_send_acl_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_ACL_APPS, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_acl_coef.num, hci_send_acl_coef.denom); +} + +/* hci_send_sco */ +static DEFINE_RATIONAL(hci_send_sco_coef); + +static u64 hci_send_sco_system(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_SCO_SYSTEM, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_sco_coef.num, hci_send_sco_coef.denom); +} + +static u64 hci_send_sco_apps(void) +{ + u64 byte = 0; + + get_parameter_energy(PT_SEND_SCO_APPS, &byte, sizeof(byte)); + + return div_u64(byte * hci_send_sco_coef.num, hci_send_sco_coef.denom); +} + + @@ -184,14 +339,14 @@ struct param_data parameters[] = { { .name = "cpu_running", .coef = &cpu0_running_coef, - .system = cpu_system, - .apps = cpu_apps + .system = cpu0_system, + .apps = cpu0_apps }, { .name = "cpuN_running", .coef = &cpuN_running_coef, - .system = cpu_system, - .apps = cpu_apps + .system = cpuN_system, + .apps = cpuN_apps }, { .name = "cpu_idle", @@ -210,6 +365,42 @@ struct param_data parameters[] = { .coef = &fw_coef, .system = fw_system, .apps = fw_apps + }, + { + .name = "wf_recv", + .coef = &wf_recv_coef, + .system = wf_recv_system, + .apps = wf_recv_apps + }, + { + .name = "wf_send", + .coef = &wf_send_coef, + .system = wf_send_system, + .apps = wf_send_apps + }, + { + .name = "sco_recv_scodata", + .coef = &sco_recv_scodata_coef, + .system = sco_recv_scodata_system, + .apps = sco_recv_scodata_apps + }, + { + .name = "l2cap_recv_acldata", + .coef = &l2cap_recv_acldata_coef, + .system = l2cap_recv_acldata_system, + .apps = l2cap_recv_acldata_apps + }, + { + .name = "hci_send_acl", + .coef = &hci_send_acl_coef, + .system = hci_send_acl_system, + .apps = hci_send_acl_apps + }, + { + .name = "hci_send_sco", + .coef = &hci_send_sco_coef, + .system = hci_send_sco_system, + .apps = hci_send_sco_apps } }; @@ -244,6 +435,9 @@ struct dentry *get_energy_dir(void) */ void exit_debugfs_energy(void) { + lcd_exit(); + exit_lcd_debugfs(); + if (energy_dir) debugfs_remove_recursive(energy_dir); @@ -274,6 +468,15 @@ int init_debugfs_energy(void) goto fail; } + if (init_lcd_debugfs(energy_dir)) + goto fail; + + /* Actually, the only goal of lcd_init() is to register lcd screen's + debugfs, so it is called here. */ + if (lcd_init()) { + exit_lcd_debugfs(); + } + return 0; fail: diff --git a/energy/energy.c b/energy/energy.c index 465bb1a7..a5a27eef 100644 --- a/energy/energy.c +++ b/energy/energy.c @@ -30,8 +30,15 @@ #include <linux/magic.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/net.h> +#include <linux/socket.h> +#include <linux/skbuff.h> +#include <linux/string.h> +#include <linux/fdtable.h> +#include <net/sock.h> #include <kprobe/swap_kprobes.h> #include <ksyms/ksyms.h> +#include <master/swap_deps.h> #include <us_manager/sspt/sspt_proc.h> #include <us_manager/sspt/sspt_feature.h> #include <linux/atomic.h> @@ -41,6 +48,75 @@ /* ============================================================================ + * = ENERGY_XXX = + * ============================================================================ + */ +struct kern_probe { + const char *name; + struct kretprobe *rp; +}; + +static int energy_xxx_once(struct kern_probe p[], int size) +{ + int i; + const char *sym; + + for (i = 0; i < size; ++i) { + struct kretprobe *rp = p[i].rp; + + sym = p[i].name; + rp->kp.addr = (kprobe_opcode_t *)swap_ksyms(sym); + if (rp->kp.addr == NULL) + goto not_found; + } + + return 0; + +not_found: + printk(KERN_INFO "ERROR: symbol '%s' not found\n", sym); + return -ESRCH; +} + +static int energy_xxx_set(struct kern_probe p[], int size, int *flag) +{ + int i, ret; + + for (i = 0; i < size; ++i) { + ret = swap_register_kretprobe(p[i].rp); + if (ret) + goto fail; + } + + *flag = 1; + return 0; + +fail: + pr_err("swap_register_kretprobe(%s) ret=%d\n", p[i].name, ret); + + for (--i; i != -1; --i) + swap_unregister_kretprobe(p[i].rp); + + return ret; +} + +static void energy_xxx_unset(struct kern_probe p[], int size, int *flag) +{ + int i; + + if (*flag == 0) + return; + + for (i = size - 1; i != -1; --i) + swap_unregister_kretprobe(p[i].rp); + + *flag = 0; +} + + + + + +/* ============================================================================ * = CPUS_TIME = * ============================================================================ */ @@ -129,6 +205,23 @@ struct energy_data { /*for sys_write */ atomic64_t bytes_written; + /*for recvmsg*/ + atomic64_t bytes_recv; + + /* for sock_send */ + atomic64_t bytes_send; + + /* for l2cap_recv */ + atomic64_t bytes_l2cap_recv_acldata; + + /* for sco_recv_scodata */ + atomic64_t bytes_sco_recv_scodata; + + /* for hci_send_acl */ + atomic64_t bytes_hci_send_acl; + + /* for hci_send_sco */ + atomic64_t bytes_hci_send_sco; }; static sspt_feature_id_t feature_id = SSPT_FEATURE_ID_BAD; @@ -141,6 +234,12 @@ static void init_ed(struct energy_data *ed) cpus_time_init(&ed->ct, 0); atomic64_set(&ed->bytes_read, 0); atomic64_set(&ed->bytes_written, 0); + atomic64_set(&ed->bytes_recv, 0); + atomic64_set(&ed->bytes_send, 0); + atomic64_set(&ed->bytes_l2cap_recv_acldata, 0); + atomic64_set(&ed->bytes_sco_recv_scodata, 0); + atomic64_set(&ed->bytes_hci_send_acl, 0); + atomic64_set(&ed->bytes_hci_send_sco, 0); } static void uninit_ed(struct energy_data *ed) @@ -148,6 +247,12 @@ static void uninit_ed(struct energy_data *ed) cpus_time_init(&ed->ct, 0); atomic64_set(&ed->bytes_read, 0); atomic64_set(&ed->bytes_written, 0); + atomic64_set(&ed->bytes_recv, 0); + atomic64_set(&ed->bytes_send, 0); + atomic64_set(&ed->bytes_l2cap_recv_acldata, 0); + atomic64_set(&ed->bytes_sco_recv_scodata, 0); + atomic64_set(&ed->bytes_hci_send_acl, 0); + atomic64_set(&ed->bytes_hci_send_sco, 0); } static void *create_ed(void) @@ -433,10 +538,327 @@ static struct kretprobe sys_write_krp = { +/* ============================================================================ + * = wifi = + * ============================================================================ + */ +static bool check_wlan0(struct socket *sock) +{ + /* FIXME: hardcode interface */ + const char *name_intrf = "wlan0"; + + if (sock->sk->sk_dst_cache && + sock->sk->sk_dst_cache->dev && + !strcmp(sock->sk->sk_dst_cache->dev->name, name_intrf)) + return true; + + return false; +} + +static bool check_socket(struct task_struct *task, struct socket *socket) +{ + bool ret = false; + unsigned int fd; + struct files_struct *files; + + files = swap_get_files_struct(task); + if (files == NULL) + return false; + + rcu_read_lock(); + for (fd = 0; fd < files_fdtable(files)->max_fds; ++fd) { + if (fcheck_files(files, fd) == socket->file) { + ret = true; + goto unlock; + } + } + +unlock: + rcu_read_unlock(); + swap_put_files_struct(files); + return ret; +} + +static struct energy_data *get_energy_data_by_socket(struct task_struct *task, + struct socket *socket) +{ + struct energy_data *ed; + + ed = get_energy_data(task); + if (ed) + ed = check_socket(task, socket) ? ed : NULL; + + return ed; +} + +static int wf_sock_eh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + struct socket *socket = (struct socket *)swap_get_karg(regs, 0); + + *(struct socket **)ri->data = check_wlan0(socket) ? socket : NULL; + + return 0; +} + +static int wf_sock_aio_eh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + struct kiocb *iocb = (struct kiocb *)swap_get_karg(regs, 0); + struct socket *socket = iocb->ki_filp->private_data; + + *(struct socket **)ri->data = check_wlan0(socket) ? socket : NULL; + + return 0; +} + +static int wf_sock_recv_rh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + + if (ret > 0) { + struct socket *socket = *(struct socket **)ri->data; + + if (socket) { + struct energy_data *ed; + + ed = get_energy_data_by_socket(current, socket); + if (ed) + atomic64_add(ret, &ed->bytes_recv); + atomic64_add(ret, &ed_system.bytes_recv); + } + } + + return 0; +} + +static int wf_sock_send_rh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + + if (ret > 0) { + struct socket *socket = *(struct socket **)ri->data; + + if (socket) { + struct energy_data *ed; + + ed = get_energy_data_by_socket(current, socket); + if (ed) + atomic64_add(ret, &ed->bytes_send); + atomic64_add(ret, &ed_system.bytes_send); + } + } + + return 0; +} + +static struct kretprobe sock_recv_krp = { + .entry_handler = wf_sock_eh, + .handler = wf_sock_recv_rh, + .data_size = sizeof(struct socket *) +}; + +static struct kretprobe sock_send_krp = { + .entry_handler = wf_sock_eh, + .handler = wf_sock_send_rh, + .data_size = sizeof(struct socket *) +}; + +static struct kretprobe sock_aio_read_krp = { + .entry_handler = wf_sock_aio_eh, + .handler = wf_sock_recv_rh, + .data_size = sizeof(struct socket *) +}; + +static struct kretprobe sock_aio_write_krp = { + .entry_handler = wf_sock_aio_eh, + .handler = wf_sock_send_rh, + .data_size = sizeof(struct socket *) +}; + +static struct kern_probe wifi_probes[] = { + { + .name = "sock_recvmsg", + .rp = &sock_recv_krp, + }, + { + .name = "sock_sendmsg", + .rp = &sock_send_krp, + }, + { + .name = "sock_aio_read", + .rp = &sock_aio_read_krp, + }, + { + .name = "sock_aio_write", + .rp = &sock_aio_write_krp, + } +}; + +enum { wifi_probes_cnt = ARRAY_SIZE(wifi_probes) }; +static int wifi_flag = 0; + + + + + +/* ============================================================================ + * = bluetooth = + * ============================================================================ + */ + +struct swap_bt_data { + struct socket *socket; +}; + +static int bt_entry_handler(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + struct swap_bt_data *data = (struct swap_bt_data *)ri->data; + struct socket *sock = (struct socket *)swap_get_sarg(regs, 1); + + data->socket = sock ? sock : NULL; + + return 0; +} + +static int bt_recvmsg_handler(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + struct swap_bt_data *data = (struct swap_bt_data *)ri->data; + + if (ret > 0) { + struct socket *socket = data->socket; + + if (socket) { + struct energy_data *ed; + + ed = get_energy_data_by_socket(current, socket); + if (ed) + atomic64_add(ret, &ed->bytes_l2cap_recv_acldata); + } + atomic64_add(ret, &ed_system.bytes_l2cap_recv_acldata); + } + + return 0; +} + +static int bt_sendmsg_handler(struct kretprobe_instance *ri, + struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + struct swap_bt_data *data = (struct swap_bt_data *)ri->data; + + if (ret > 0) { + struct socket *socket = data->socket; + + if (socket) { + struct energy_data *ed; + + ed = get_energy_data_by_socket(current, socket); + if (ed) + atomic64_add(ret, &ed->bytes_hci_send_sco); + } + atomic64_add(ret, &ed_system.bytes_hci_send_sco); + } + + return 0; +} + +static struct kretprobe rfcomm_sock_recvmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_recvmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kretprobe l2cap_sock_recvmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_recvmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kretprobe hci_sock_recvmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_recvmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kretprobe sco_sock_recvmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_recvmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; +static struct kretprobe rfcomm_sock_sendmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_sendmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kretprobe l2cap_sock_sendmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_sendmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kretprobe hci_sock_sendmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_sendmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kretprobe sco_sock_sendmsg_krp = { + .entry_handler = bt_entry_handler, + .handler = bt_sendmsg_handler, + .data_size = sizeof(struct swap_bt_data) +}; + +static struct kern_probe bt_probes[] = { + { + .name = "rfcomm_sock_recvmsg", + .rp = &rfcomm_sock_recvmsg_krp, + }, + { + .name = "l2cap_sock_recvmsg", + .rp = &l2cap_sock_recvmsg_krp, + }, + { + .name = "hci_sock_recvmsg", + .rp = &hci_sock_recvmsg_krp, + }, + { + .name = "sco_sock_recvmsg", + .rp = &sco_sock_recvmsg_krp, + }, + { + .name = "rfcomm_sock_sendmsg", + .rp = &rfcomm_sock_sendmsg_krp, + }, + { + .name = "l2cap_sock_sendmsg", + .rp = &l2cap_sock_sendmsg_krp, + }, + { + .name = "hci_sock_sendmsg", + .rp = &hci_sock_sendmsg_krp, + }, + { + .name = "sco_sock_sendmsg", + .rp = &sco_sock_sendmsg_krp, + } +}; + +enum { bt_probes_cnt = ARRAY_SIZE(bt_probes) }; +static int energy_bt_flag = 0; + enum parameter_type { PT_CPU, PT_READ, - PT_WRITE + PT_WRITE, + PT_WF_RECV, + PT_WF_SEND, + PT_L2CAP_RECV, + PT_SCO_RECV, + PT_SEND_ACL, + PT_SEND_SCO }; struct cmd_pt { @@ -467,6 +889,24 @@ static void callback_for_proc(struct sspt_proc *proc, void *data) case PT_WRITE: *val += atomic64_read(&ed->bytes_written); break; + case PT_WF_RECV: + *val += atomic64_read(&ed->bytes_recv); + break; + case PT_WF_SEND: + *val += atomic64_read(&ed->bytes_send); + break; + case PT_L2CAP_RECV: + *val += atomic64_read(&ed->bytes_l2cap_recv_acldata); + break; + case PT_SCO_RECV: + *val += atomic64_read(&ed->bytes_sco_recv_scodata); + break; + case PT_SEND_ACL: + *val += atomic64_read(&ed->bytes_hci_send_acl); + break; + case PT_SEND_SCO: + *val += atomic64_read(&ed->bytes_hci_send_sco); + break; default: break; } @@ -521,12 +961,48 @@ int get_parameter_energy(enum parameter_energy pe, void *buf, size_t sz) case PE_WRITE_SYSTEM: *val = atomic64_read(&ed_system.bytes_written); break; + case PE_WF_RECV_SYSTEM: + *val = atomic64_read(&ed_system.bytes_recv); + break; + case PE_WF_SEND_SYSTEM: + *val = atomic64_read(&ed_system.bytes_send); + break; + case PE_L2CAP_RECV_SYSTEM: + *val = atomic64_read(&ed_system.bytes_l2cap_recv_acldata); + break; + case PE_SCO_RECV_SYSTEM: + *val = atomic64_read(&ed_system.bytes_sco_recv_scodata); + break; + case PT_SEND_ACL_SYSTEM: + *val = atomic64_read(&ed_system.bytes_hci_send_acl); + break; + case PT_SEND_SCO_SYSTEM: + *val = atomic64_read(&ed_system.bytes_hci_send_sco); + break; case PE_READ_APPS: current_parameter_apps(PT_READ, buf, sz); break; case PE_WRITE_APPS: current_parameter_apps(PT_WRITE, buf, sz); break; + case PE_WF_RECV_APPS: + current_parameter_apps(PT_WF_RECV, buf, sz); + break; + case PE_WF_SEND_APPS: + current_parameter_apps(PT_WF_SEND, buf, sz); + break; + case PE_L2CAP_RECV_APPS: + current_parameter_apps(PT_L2CAP_RECV, buf, sz); + break; + case PE_SCO_RECV_APPS: + current_parameter_apps(PT_SCO_RECV, buf, sz); + break; + case PT_SEND_ACL_APPS: + current_parameter_apps(PT_SEND_ACL, buf, sz); + break; + case PT_SEND_SCO_APPS: + current_parameter_apps(PT_SEND_SCO, buf, sz); + break; default: ret = -EINVAL; break; @@ -560,6 +1036,9 @@ int do_set_energy(void) goto unregister_sys_write; } + energy_xxx_set(bt_probes, bt_probes_cnt, &energy_bt_flag); + energy_xxx_set(wifi_probes, wifi_probes_cnt, &wifi_flag); + /* TODO: check return value */ lcd_set_energy(); @@ -577,6 +1056,8 @@ unregister_sys_write: void do_unset_energy(void) { lcd_unset_energy(); + energy_xxx_unset(wifi_probes, wifi_probes_cnt, &wifi_flag); + energy_xxx_unset(bt_probes, bt_probes_cnt, &energy_bt_flag); swap_unregister_kretprobe(&switch_to_krp); swap_unregister_kretprobe(&sys_write_krp); @@ -659,6 +1140,9 @@ int energy_once(void) if (sys_write_krp.kp.addr == NULL) goto not_found; + energy_xxx_once(bt_probes, bt_probes_cnt); + energy_xxx_once(wifi_probes, wifi_probes_cnt); + return 0; not_found: @@ -676,16 +1160,10 @@ int energy_init(void) int ret; ret = init_feature(); - if (ret) { - printk("Cannot init feature\n"); - return ret; - } - - ret = lcd_init(); if (ret) - printk("Cannot init LCD, ret=%d\n", ret); + printk(KERN_INFO "Cannot init feature\n"); - return 0; + return ret; } /** @@ -695,7 +1173,6 @@ int energy_init(void) */ void energy_uninit(void) { - lcd_exit(); uninit_feature(); if (energy_enable) diff --git a/energy/energy.h b/energy/energy.h index 9626d1d4..7466570d 100644 --- a/energy/energy.h +++ b/energy/energy.h @@ -39,7 +39,19 @@ enum parameter_energy { PE_READ_SYSTEM, /**< number of bytes are read by system */ PE_WRITE_SYSTEM, /**< number of bytes are write by system */ PE_READ_APPS, /**< number of bytes are read by apps */ - PE_WRITE_APPS /**< number of bytes are write by apps*/ + PE_WRITE_APPS, /**< number of bytes are write by apps */ + PE_WF_RECV_SYSTEM, /**< number of bytes are receive by system through wifi */ + PE_WF_SEND_SYSTEM, /**< number of bytes are send by system through wifi */ + PE_WF_RECV_APPS, /**< number of bytes are receive by apps through wifi */ + PE_WF_SEND_APPS, /**< number of bytes are send by apps through wifi */ + PE_L2CAP_RECV_SYSTEM, /**< number of bytes(ACL packets) are recv by system through bluetooth */ + PE_L2CAP_RECV_APPS, /**< number of bytes(ACL packets) are recv by apps through bluetooth */ + PE_SCO_RECV_SYSTEM, /**< number of bytes(SCO packets) are recv by system through bluetooth */ + PE_SCO_RECV_APPS, /**< number of bytes(SCO packets) are recv by apps through bluetooth */ + PT_SEND_ACL_SYSTEM, /**< number of bytes(ACL packets) are send by system through bluetooth */ + PT_SEND_ACL_APPS, /**< number of bytes(ACL packets) are send by apps through bluetooth */ + PT_SEND_SCO_SYSTEM, /**< number of bytes(SCO packets) are send by system through bluetooth */ + PT_SEND_SCO_APPS, /**< number of bytes(SCO packets) are send by apps through bluetooth */ }; diff --git a/energy/lcd/lcd_base.c b/energy/lcd/lcd_base.c index f40cc25e..e106dec6 100644 --- a/energy/lcd/lcd_base.c +++ b/energy/lcd/lcd_base.c @@ -376,7 +376,6 @@ static void do_lcd_exit(void) void lcd_exit(void) { do_lcd_exit(); - exit_lcd_debugfs(); } static int do_lcd_init(void) @@ -419,23 +418,10 @@ static int do_lcd_init(void) int lcd_init(void) { int ret; - struct dentry *energy_dir; - - energy_dir = get_energy_dir(); - if (energy_dir == NULL) { - printk("Cannot energy_dir\n"); - return -ENOENT; - } - - ret = init_lcd_debugfs(energy_dir); - if (ret) - return ret; ret = do_lcd_init(); - if (ret) { - printk("LCD is not supported\n"); - exit_lcd_debugfs(); - } + if (ret) + printk(KERN_INFO "LCD is not supported\n"); return ret; } diff --git a/energy/lcd/s6e63j0x03.c b/energy/lcd/s6e63j0x03.c new file mode 100644 index 00000000..c6cff8f1 --- /dev/null +++ b/energy/lcd/s6e63j0x03.c @@ -0,0 +1,186 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) Samsung Electronics, 2015 + * + * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com> + * + */ + + +#include <linux/backlight.h> +#include <kprobe/swap_kprobes.h> +#include "lcd_base.h" + + +static const char path_backlight[] = "/sys/class/backlight/s6e63j0x03-bl/brightness"; +static const char path_backlight_max[] = "/sys/class/backlight/s6e63j0x03-bl/max_brightness"; +static const char path_power[] = "/sys/class/lcd/s6e63j0x03/lcd_power"; + +static const char * const all_path[] = { + path_backlight, + path_backlight_max, + path_power +}; + + +static int s6e63j0x03_check(struct lcd_ops *ops) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(all_path); ++i) { + int ret = read_val(all_path[i]); + + if (IS_ERR_VALUE(ret)) + return 0; + } + + return 1; +} + +static unsigned long s6e63j0x03_get_parameter(struct lcd_ops *ops, + enum lcd_parameter_type type) +{ + switch (type) { + case LPD_MIN_BRIGHTNESS: + return 0; + case LPD_MAX_BRIGHTNESS: + return read_val(path_backlight_max); + case LPD_BRIGHTNESS: + return read_val(path_backlight); + case LPD_POWER: + return read_val(path_power); + } + + return -EINVAL; +} + +static int set_power_eh(struct kretprobe_instance *ri, struct pt_regs *regs); +static int set_power_rh(struct kretprobe_instance *ri, struct pt_regs *regs); + +static struct kretprobe set_power_krp = { + .kp.symbol_name = "panel_set_power", + .entry_handler = set_power_eh, + .handler = set_power_rh, + .data_size = sizeof(int) +}; + + +static int set_backlight_eh(struct kretprobe_instance *ri, struct pt_regs *regs); +static int set_backlight_rh(struct kretprobe_instance *ri, struct pt_regs *regs); + +static struct kretprobe set_backlight_krp = { + .kp.symbol_name = "panel_set_brightness", + .entry_handler = set_backlight_eh, + .handler = set_backlight_rh, + .data_size = sizeof(int) +}; + + +static int s6e63j0x03_set(struct lcd_ops *ops) +{ + int ret; + + ret = swap_register_kretprobe(&set_power_krp); + if (ret) + return ret; + + ret = swap_register_kretprobe(&set_backlight_krp); + if (ret) + swap_unregister_kretprobe(&set_power_krp); + + return ret; +} + +static int s6e63j0x03_unset(struct lcd_ops *ops) +{ + swap_unregister_kretprobe(&set_backlight_krp); + swap_unregister_kretprobe(&set_power_krp); + + return 0; +} + + +static struct lcd_ops s6e63j0x03_ops = { + .name = "s6e63j0x03", + .check = s6e63j0x03_check, + .set = s6e63j0x03_set, + .unset = s6e63j0x03_unset, + .get = s6e63j0x03_get_parameter +}; + +struct lcd_ops *LCD_MAKE_FNAME(s6e63j0x03)(void) +{ + return &s6e63j0x03_ops; +} + + + + + +/* ============================================================================ + * === POWER === + * ============================================================================ + */ +static int set_power_eh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int *power = (int *)ri->data; + + *power = (int)swap_get_karg(regs, 1); + + return 0; +} + +static int set_power_rh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + int *power = (int *)ri->data; + + if (!ret && s6e63j0x03_ops.notifier) + s6e63j0x03_ops.notifier(&s6e63j0x03_ops, LAT_POWER, + (void *)*power); + return 0; +} + + + + + +/* ============================================================================ + * === BACKLIGHT === + * ============================================================================ + */ +static int set_backlight_eh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int *brightness = (int *)ri->data; + struct backlight_device *bd; + + bd = (struct backlight_device *)swap_get_karg(regs, 0); + *brightness = bd->props.brightness; + + return 0; +} + +static int set_backlight_rh(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int ret = regs_return_value(regs); + int *brightness = (int *)ri->data; + + if (!ret && s6e63j0x03_ops.notifier) + s6e63j0x03_ops.notifier(&s6e63j0x03_ops, LAT_BRIGHTNESS, + (void *)*brightness); + + return 0; +} diff --git a/master/Kbuild b/master/Kbuild index 83733a74..cd1b1c57 100644 --- a/master/Kbuild +++ b/master/Kbuild @@ -3,4 +3,5 @@ EXTRA_CFLAGS := $(extra_cflags) obj-m := swap_master.o swap_master-y := master_module.o \ swap_debugfs.o \ - swap_initializer.o + swap_initializer.o \ + swap_deps.o diff --git a/master/swap_deps.c b/master/swap_deps.c new file mode 100644 index 00000000..0c566c14 --- /dev/null +++ b/master/swap_deps.c @@ -0,0 +1,69 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) Samsung Electronics, 2015 + * + * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com> + * + */ + + +#include <linux/module.h> +#include <ksyms/ksyms.h> +#include "swap_deps.h" + + +static struct files_struct *(*__get_files_struct)(struct task_struct *); +static void (*__put_files_struct)(struct files_struct *fs); + +struct files_struct *swap_get_files_struct(struct task_struct *task) +{ + return __get_files_struct(task); +} +EXPORT_SYMBOL_GPL(swap_get_files_struct); + +void swap_put_files_struct(struct files_struct *fs) +{ + __put_files_struct(fs); +} +EXPORT_SYMBOL_GPL(swap_put_files_struct); + + +int chef_once(void) +{ + const char *sym; + static unsigned once_flag = 0; + + if (once_flag) + return 0; + + sym = "get_files_struct"; + __get_files_struct = (void *)swap_ksyms(sym); + if (__get_files_struct == NULL) + goto not_found; + + sym = "put_files_struct"; + __put_files_struct = (void *)swap_ksyms(sym); + if (__put_files_struct == NULL) + goto not_found; + + once_flag = 1; + return 0; + +not_found: + printk("ERROR: symbol '%s' not found\n", sym); + return -ESRCH; +} + diff --git a/master/swap_deps.h b/master/swap_deps.h new file mode 100644 index 00000000..ca4c978f --- /dev/null +++ b/master/swap_deps.h @@ -0,0 +1,38 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) Samsung Electronics, 2015 + * + * 2015 Vyacheslav Cherkashin <v.cherkashin@samsung.com> + * + */ + + +#ifndef _SWAP_DEPS_H +#define _SWAP_DEPS_H + + +struct task_struct; +struct files_struct; + + +struct files_struct *swap_get_files_struct(struct task_struct *task); +void swap_put_files_struct(struct files_struct *fs); + + +int chef_once(void); + + +#endif /* _SWAP_DEPS_H */ diff --git a/master/swap_initializer.c b/master/swap_initializer.c index 597ea880..ddec8481 100644 --- a/master/swap_initializer.c +++ b/master/swap_initializer.c @@ -26,6 +26,7 @@ #include <linux/types.h> #include <linux/spinlock.h> #include "swap_initializer.h" +#include "swap_deps.h" enum init_level { @@ -166,6 +167,10 @@ static int do_once(void) int ret; struct swap_init_struct *init; + ret = chef_once(); + if (ret) + return ret; + list_for_each_entry(init, &init_list, list) { ret = sis_once(init); if (ret) diff --git a/packaging/swap-modules.spec b/packaging/swap-modules.spec index 22f7f5ac..ef2f867f 100755 --- a/packaging/swap-modules.spec +++ b/packaging/swap-modules.spec @@ -10,9 +10,21 @@ Source: swap-modules-3.0.tar.gz BuildRequires: perl BuildRequires: python %ifarch %{arm} + %if "%{?tizen_profile_name}" == "wearable" + %if "%{?tizen_target_name}" == "B3" +BuildRequires: kernel-devel-3.4-msm8x26 + %define build_arch arm + %define kernel_path /var/tmp/kernel/devel/kernel-devel-tizen_b3/ + %else +BuildRequires: kernel-devel-3.4-exynos3250 + %define build_arch arm + %define kernel_path /var/tmp/kernel/devel/kernel-devel-tizen_b2/ + %endif + %else BuildRequires: kernel-devel %define build_arch arm %define kernel_path /usr/src/linux-kernel-build-3.0.101-trats2_defconfig + %endif %else %define build_arch i386 BuildRequires: emulator-kernel-devel |