Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 1859888
b: refs/heads/develop-4.4
c: 0d162fd
h: refs/heads/develop-4.4
  • Loading branch information
Chen Liang authored and rkhuangtao committed Sep 5, 2016
1 parent 42cd924 commit 3448832
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ refs/tags/release-20171213: 2801809213b2ebda0ab877ede0354d48fe95cde1
refs/heads/develop-4.4-rt: 12829b49ca46b63580b365f979fcff3fcbd9fa87
refs/heads/stable-4.4-rk3288-linux: 28c018740a5b4eea52017150363d747dd09bd008
refs/heads/stable-4.4-rk3399-linux: 27f039b43ada8d0301867505ce9a91d8b5c604bc
refs/heads/develop-4.4: 5d9ccf47cac2f9bd8d1f92695cf70a3c4c4ffa61
refs/heads/develop-4.4: 0d162fd338537952190c6447a42c8331516ebdc6
170 changes: 169 additions & 1 deletion trunk/drivers/cpufreq/cpufreq_interactive.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cpufreq.h>
#ifdef CONFIG_ARCH_ROCKCHIP
#include <linux/input.h>
#endif
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/rwsem.h>
Expand Down Expand Up @@ -106,6 +109,14 @@ struct cpufreq_interactive_tunables {
int boostpulse_duration_val;
/* End time of boost pulse in ktime converted to usecs */
u64 boostpulse_endtime;
#ifdef CONFIG_ARCH_ROCKCHIP
/* Frequency to which a touch boost takes the cpus to */
unsigned long touchboost_freq;
/* Duration of a touchboost pulse in usecs */
int touchboostpulse_duration_val;
/* End time of touchboost pulse in ktime converted to usecs */
u64 touchboostpulse_endtime;
#endif
bool boosted;
/*
* Max additional time to wait in idle, beyond timer_rate, at speeds
Expand Down Expand Up @@ -383,7 +394,12 @@ static void cpufreq_interactive_timer(unsigned long data)
pcpu->policy->cur < tunables->hispeed_freq)
new_freq = tunables->hispeed_freq;
}

#ifdef CONFIG_ARCH_ROCKCHIP
if ((now < tunables->touchboostpulse_endtime) &&
(new_freq < tunables->touchboost_freq)) {
new_freq = tunables->touchboost_freq;
}
#endif
if (pcpu->policy->cur >= tunables->hispeed_freq &&
new_freq > pcpu->policy->cur &&
now - pcpu->pol_hispeed_val_time <
Expand Down Expand Up @@ -1133,6 +1149,147 @@ static struct notifier_block cpufreq_interactive_idle_nb = {
.notifier_call = cpufreq_interactive_idle_notifier,
};

#ifdef CONFIG_ARCH_ROCKCHIP
static void cpufreq_interactive_input_event(struct input_handle *handle,
unsigned int type,
unsigned int code,
int value)
{
u64 now, endtime;
int i;
int anyboost = 0;
unsigned long flags[2];
struct cpufreq_interactive_cpuinfo *pcpu;
struct cpufreq_interactive_tunables *tunables;

if ((type != EV_ABS) && (type != EV_KEY))
return;

trace_cpufreq_interactive_boost("touch");
spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]);

now = ktime_to_us(ktime_get());
for_each_online_cpu(i) {
pcpu = &per_cpu(cpuinfo, i);
if (have_governor_per_policy())
tunables = pcpu->policy->governor_data;
else
tunables = common_tunables;
if (!tunables)
continue;

endtime = now + tunables->touchboostpulse_duration_val;
if (endtime < (tunables->touchboostpulse_endtime +
10 * USEC_PER_MSEC))
continue;
tunables->touchboostpulse_endtime = endtime;

spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]);
if (pcpu->target_freq < tunables->touchboost_freq) {
pcpu->target_freq = tunables->touchboost_freq;
cpumask_set_cpu(i, &speedchange_cpumask);
pcpu->loc_hispeed_val_time =
ktime_to_us(ktime_get());
anyboost = 1;
}

pcpu->floor_freq = tunables->touchboost_freq;
pcpu->loc_floor_val_time = ktime_to_us(ktime_get());

spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]);
}

spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]);

if (anyboost)
wake_up_process(speedchange_task);
}

static int cpufreq_interactive_input_connect(struct input_handler *handler,
struct input_dev *dev,
const struct input_device_id *id)
{
struct input_handle *handle;
int error;

handle = kzalloc(sizeof(*handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;

handle->dev = dev;
handle->handler = handler;
handle->name = "cpufreq";

error = input_register_handle(handle);
if (error)
goto err2;

error = input_open_device(handle);
if (error)
goto err1;

return 0;
err1:
input_unregister_handle(handle);
err2:
kfree(handle);
return error;
}

static void cpufreq_interactive_input_disconnect(struct input_handle *handle)
{
input_close_device(handle);
input_unregister_handle(handle);
kfree(handle);
}

static const struct input_device_id cpufreq_interactive_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
.evbit = { BIT_MASK(EV_ABS) },
.absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
BIT_MASK(ABS_MT_POSITION_X) |
BIT_MASK(ABS_MT_POSITION_Y) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
.absbit = { [BIT_WORD(ABS_X)] =
BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT_MASK(EV_KEY) },
},
{ },
};

static struct input_handler cpufreq_interactive_input_handler = {
.event = cpufreq_interactive_input_event,
.connect = cpufreq_interactive_input_connect,
.disconnect = cpufreq_interactive_input_disconnect,
.name = "cpufreq_interactive",
.id_table = cpufreq_interactive_ids,
};

static void rockchip_cpufreq_policy_init(struct cpufreq_policy *policy)
{
struct cpufreq_interactive_tunables *tunables = policy->governor_data;

tunables->min_sample_time = 40 * USEC_PER_MSEC;
tunables->boostpulse_duration_val = 40 * USEC_PER_MSEC;
if (policy->cpu == 0) {
tunables->hispeed_freq = 1008000;
tunables->touchboostpulse_duration_val = 500 * USEC_PER_MSEC;
tunables->touchboost_freq = 1200000;
} else {
tunables->hispeed_freq = 816000;
}
}
#endif

static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
unsigned int event)
{
Expand Down Expand Up @@ -1186,6 +1343,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
common_tunables = tunables;
}

#ifdef CONFIG_ARCH_ROCKCHIP
rockchip_cpufreq_policy_init(policy);
#endif

rc = sysfs_create_group(get_governor_parent_kobj(policy),
get_sysfs_attr());
if (rc) {
Expand All @@ -1201,13 +1362,20 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
idle_notifier_register(&cpufreq_interactive_idle_nb);
cpufreq_register_notifier(&cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
#ifdef CONFIG_ARCH_ROCKCHIP
rc = input_register_handler(&cpufreq_interactive_input_handler);
#endif

}

break;

case CPUFREQ_GOV_POLICY_EXIT:
if (!--tunables->usage_count) {
if (policy->governor->initialized == 1) {
#ifdef CONFIG_ARCH_ROCKCHIP
input_unregister_handler(&cpufreq_interactive_input_handler);
#endif
cpufreq_unregister_notifier(&cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
idle_notifier_unregister(&cpufreq_interactive_idle_nb);
Expand Down

0 comments on commit 3448832

Please sign in to comment.