forked from rubenslte/android_kernel_samsung_msm8226
devfreq: Add MSM CPUfreq governor
The MSM CPUfreq devfreq governor determines the CPU to DDR bandwidth vote based on the current CPU frequency of all the active CPUs. This functionality used to be a part of the MSM CPUfreq driver that directly voted for the CPU to DDR bandwidth using MSM bus scaling APIs. This refactor decouples CPU to DDR BW scaling from CPU frequency and allows switch between various CPU BW governors. The bandwidth values in the msm-cpufreq table have to be updated since the new CPU BW driver does the MBps to Bps conversion correctly. The MSM CPUfreq driver used to do * 1000 * 1000 to convert from MBps to Bps instead of doing * 1024 * 1024. Change-Id: I184f09d628a1b27d52506d2f760d65831f1a1110 Signed-off-by: Saravana Kannan <skannan@codeaurora.org>
This commit is contained in:
committed by
Amir Vajid
parent
cadc893a75
commit
4bbc993b17
@@ -9,23 +9,15 @@ Required properties:
|
||||
- compatible: Must be "qcom,msm-cpufreq"
|
||||
- qcom,cpufreq-table: A list of tuples where each tuple consists of a
|
||||
usable CPU frequency (KHz), an optional cache
|
||||
frequency (KHz) and an optional memory bandwidth
|
||||
frequency (KHz) and a mandatory memory bandwidth
|
||||
value (MBPS) listed in that order. The cache
|
||||
frequencies shall not be listed if the device cannot
|
||||
run the cache asynchronous to one or more CPUs. The
|
||||
memory bandwidth values shall not be listed if the
|
||||
optional cpu-mem-ports property is not supplied.
|
||||
|
||||
Optional properties:
|
||||
- qcom,cpu-mem-ports: A list of tuples where each tuple consists of a bus
|
||||
master (CPU) port number and a bus slave (memory)
|
||||
port number.
|
||||
run the cache asynchronous to one or more CPUs.
|
||||
|
||||
Example:
|
||||
qcom,msm-cpufreq@0 {
|
||||
regs = <0 4>
|
||||
compatible = "qcom,msm-cpufreq";
|
||||
qcom,cpu-mem-ports = <1 512>, <2 513>;
|
||||
qcom,cpufreq-table =
|
||||
< 300000 300000 600 >,
|
||||
< 422400 422400 1200 >,
|
||||
|
||||
@@ -1018,23 +1018,32 @@
|
||||
cpu-vdd-supply = <&apc_vreg_corner>;
|
||||
};
|
||||
|
||||
qcom,cpubw {
|
||||
compatible = "qcom,cpubw";
|
||||
qcom,cpu-mem-ports = <1 512>;
|
||||
qcom,bw-tbl =
|
||||
< 1525 /* 200 MHz */ >,
|
||||
< 2441 /* 320 MHz */ >,
|
||||
< 3051 /* 400 MHz */ >,
|
||||
< 4066 /* 533 MHz */ >;
|
||||
};
|
||||
|
||||
qcom,msm-cpufreq@0 {
|
||||
reg = <0 4>;
|
||||
compatible = "qcom,msm-cpufreq";
|
||||
qcom,cpu-mem-ports = <1 512>;
|
||||
qcom,cpufreq-table =
|
||||
< 300000 1600 /* 200 MHz */ >,
|
||||
< 384000 1600 /* 200 MHz */ >,
|
||||
< 600000 1600 /* 200 MHz */ >,
|
||||
< 787200 3200 /* 400 MHz */ >,
|
||||
< 998400 4264 /* 533 MHz */ >,
|
||||
< 1094400 4264 /* 533 MHz */ >,
|
||||
< 1190400 4264 /* 533 MHz */ >,
|
||||
< 1305600 4264 /* 533 MHz */ >,
|
||||
< 1344000 4264 /* 533 MHz */ >,
|
||||
< 1401600 4264 /* 533 MHz */ >,
|
||||
< 1497600 4264 /* 533 MHz */ >,
|
||||
< 1593600 4264 /* 533 MHz */ >;
|
||||
< 300000 1525 >,
|
||||
< 384000 1525 >,
|
||||
< 600000 1525 >,
|
||||
< 787200 3051 >,
|
||||
< 998400 4066 >,
|
||||
< 1094400 4066 >,
|
||||
< 1190400 4066 >,
|
||||
< 1305600 4066 >,
|
||||
< 1344000 4066 >,
|
||||
< 1401600 4066 >,
|
||||
< 1497600 4066 >,
|
||||
< 1593600 4066 >;
|
||||
};
|
||||
|
||||
qcom,ocmem@fdd00000 {
|
||||
|
||||
@@ -1515,25 +1515,39 @@
|
||||
< 2265600000 925000 691 >;
|
||||
};
|
||||
|
||||
qcom,cpubw {
|
||||
compatible = "qcom,cpubw";
|
||||
qcom,cpu-mem-ports = <1 512>, <2 512>;
|
||||
qcom,bw-tbl =
|
||||
< 572 /* 75 MHz */ >,
|
||||
< 1144 /* 150 MHz */ >,
|
||||
< 1525 /* 200 MHz */ >,
|
||||
< 2342 /* 307 MHz */ >,
|
||||
< 3509 /* 460 MHz */ >,
|
||||
< 4684 /* 614 MHz */ >,
|
||||
< 6103 /* 800 MHz */ >,
|
||||
< 7102 /* 931 MHz */ >;
|
||||
};
|
||||
|
||||
qcom,msm-cpufreq@0 {
|
||||
reg = <0 4>;
|
||||
compatible = "qcom,msm-cpufreq";
|
||||
qcom,cpu-mem-ports = <1 512>, <2 512>;
|
||||
qcom,cpufreq-table =
|
||||
< 300000 300000 600 /* 75 MHz */ >,
|
||||
< 422400 422400 1200 /* 150 MHz */ >,
|
||||
< 652800 499200 1600 /* 200 MHz */ >,
|
||||
< 729600 576000 2456 /* 307 MHz */ >,
|
||||
< 883200 576000 2456 /* 307 MHz */ >,
|
||||
< 960000 960000 3680 /* 460 MHz */ >,
|
||||
< 1036800 1036800 3680 /* 460 MHz */ >,
|
||||
< 1190400 1036800 3680 /* 460 MHz */ >,
|
||||
< 1267200 1267200 4912 /* 614 MHz */ >,
|
||||
< 1497600 1497600 4912 /* 614 MHz */ >,
|
||||
< 1574400 1574400 6400 /* 800 MHz */ >,
|
||||
< 1728000 1651200 6400 /* 800 MHz */ >,
|
||||
< 1958400 1728000 7448 /* 931 MHz */ >,
|
||||
< 2265600 1728000 7448 /* 931 MHz */ >;
|
||||
< 300000 300000 572 >,
|
||||
< 422400 422400 1144 >,
|
||||
< 652800 499200 1525 >,
|
||||
< 729600 576000 2342 >,
|
||||
< 883200 576000 2342 >,
|
||||
< 960000 960000 3509 >,
|
||||
< 1036800 1036800 3509 >,
|
||||
< 1190400 1036800 3509 >,
|
||||
< 1267200 1267200 4684 >,
|
||||
< 1497600 1497600 4684 >,
|
||||
< 1574400 1574400 6103 >,
|
||||
< 1728000 1651200 6103 >,
|
||||
< 1958400 1728000 7102 >,
|
||||
< 2265600 1728000 7102 >,
|
||||
< 2457600 1728000 7102 >;
|
||||
};
|
||||
|
||||
usb3: qcom,ssusb@f9200000 {
|
||||
|
||||
@@ -1548,25 +1548,6 @@
|
||||
< 2457600000 970000 802 >;
|
||||
};
|
||||
|
||||
qcom,msm-cpufreq@0 {
|
||||
qcom,cpufreq-table =
|
||||
< 300000 300000 300 /* 37.5 MHz */ >,
|
||||
< 422400 422400 300 /* 37.5 MHz */ >,
|
||||
< 652800 499200 300 /* 37.5 MHz */ >,
|
||||
< 729600 576000 300 /* 37.5 MHz */ >,
|
||||
< 883200 576000 300 /* 37.5 MHz */ >,
|
||||
< 960000 960000 300 /* 37.5 MHz */ >,
|
||||
< 1036800 1036800 300 /* 37.5 MHz */ >,
|
||||
< 1190400 1036800 300 /* 37.5 MHz */ >,
|
||||
< 1267200 1267200 300 /* 37.5 MHz */ >,
|
||||
< 1497600 1497600 300 /* 37.5 MHz */ >,
|
||||
< 1574400 1574400 300 /* 37.5 MHz */ >,
|
||||
< 1728000 1651200 300 /* 37.5 MHz */ >,
|
||||
< 1958400 1728000 300 /* 37.5 MHz */ >,
|
||||
< 2265600 1728000 300 /* 37.5 MHz */ >,
|
||||
< 2496000 1728000 300 /* 37.5 MHz */ >;
|
||||
};
|
||||
|
||||
i2c@f9928000 { /* BLSP-1 QUP-6 */
|
||||
cell-index = <3>;
|
||||
compatible = "qcom,i2c-qup";
|
||||
|
||||
@@ -1955,6 +1955,7 @@ config MSM_DEVFREQ_CPUBW
|
||||
select DEVFREQ_GOV_PERFORMANCE
|
||||
select DEVFREQ_GOV_POWERSAVE
|
||||
select DEVFREQ_GOV_USERSPACE
|
||||
select DEVFREQ_GOV_MSM_CPUFREQ
|
||||
default n
|
||||
help
|
||||
Different devfreq governors use this devfreq device to make CPU to
|
||||
|
||||
+23
-68
@@ -32,7 +32,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <trace/events/power.h>
|
||||
#include <mach/socinfo.h>
|
||||
#include <mach/msm_bus.h>
|
||||
#include <mach/cpufreq.h>
|
||||
|
||||
#include "acpuclock.h"
|
||||
|
||||
@@ -47,16 +47,12 @@ static DEFINE_MUTEX(l2bw_lock);
|
||||
static struct clk *cpu_clk[NR_CPUS];
|
||||
static struct clk *l2_clk;
|
||||
static unsigned int freq_index[NR_CPUS];
|
||||
static unsigned int max_freq_index;
|
||||
static struct cpufreq_frequency_table *freq_table;
|
||||
static unsigned int *l2_khz;
|
||||
static bool is_clk;
|
||||
static bool is_sync;
|
||||
static struct msm_bus_vectors *bus_vec_lst;
|
||||
static struct msm_bus_scale_pdata bus_bw = {
|
||||
.name = "msm-cpufreq",
|
||||
.active_only = 1,
|
||||
};
|
||||
static u32 bus_client;
|
||||
static unsigned long *mem_bw;
|
||||
|
||||
struct cpufreq_work_struct {
|
||||
struct work_struct work;
|
||||
@@ -77,6 +73,11 @@ struct cpufreq_suspend_t {
|
||||
|
||||
static DEFINE_PER_CPU(struct cpufreq_suspend_t, cpufreq_suspend);
|
||||
|
||||
unsigned long msm_cpufreq_get_bw(void)
|
||||
{
|
||||
return mem_bw[max_freq_index];
|
||||
}
|
||||
|
||||
static void update_l2_bw(int *also_cpu)
|
||||
{
|
||||
int rc = 0, cpu;
|
||||
@@ -98,10 +99,10 @@ static void update_l2_bw(int *also_cpu)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bus_client)
|
||||
rc = msm_bus_scale_client_update_request(bus_client, index);
|
||||
max_freq_index = index;
|
||||
rc = devfreq_msm_cpufreq_update_bw();
|
||||
if (rc)
|
||||
pr_err("Bandwidth req failed (%d)\n", rc);
|
||||
pr_err("Unable to update BW (%d)\n", rc);
|
||||
|
||||
out:
|
||||
mutex_unlock(&l2bw_lock);
|
||||
@@ -397,33 +398,14 @@ static struct cpufreq_driver msm_cpufreq_driver = {
|
||||
};
|
||||
|
||||
#define PROP_TBL "qcom,cpufreq-table"
|
||||
#define PROP_PORTS "qcom,cpu-mem-ports"
|
||||
static int cpufreq_parse_dt(struct device *dev)
|
||||
{
|
||||
int ret, len, nf, num_cols = 1, num_paths = 0, i, j, k;
|
||||
u32 *data, *ports = NULL;
|
||||
struct msm_bus_vectors *v = NULL;
|
||||
int ret, len, nf, num_cols = 2, i, j;
|
||||
u32 *data;
|
||||
|
||||
if (l2_clk)
|
||||
num_cols++;
|
||||
|
||||
/* Parse optional bus ports parameter */
|
||||
if (of_find_property(dev->of_node, PROP_PORTS, &len)) {
|
||||
len /= sizeof(*ports);
|
||||
if (len % 2)
|
||||
return -EINVAL;
|
||||
|
||||
ports = devm_kzalloc(dev, len * sizeof(*ports), GFP_KERNEL);
|
||||
if (!ports)
|
||||
return -ENOMEM;
|
||||
ret = of_property_read_u32_array(dev->of_node, PROP_PORTS,
|
||||
ports, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
num_paths = len / 2;
|
||||
num_cols++;
|
||||
}
|
||||
|
||||
/* Parse CPU freq -> L2/Mem BW map table. */
|
||||
if (!of_find_property(dev->of_node, PROP_TBL, &len))
|
||||
return -EINVAL;
|
||||
@@ -444,7 +426,9 @@ static int cpufreq_parse_dt(struct device *dev)
|
||||
/* Allocate all data structures. */
|
||||
freq_table = devm_kzalloc(dev, (nf + 1) * sizeof(*freq_table),
|
||||
GFP_KERNEL);
|
||||
if (!freq_table)
|
||||
mem_bw = devm_kzalloc(dev, nf * sizeof(*mem_bw), GFP_KERNEL);
|
||||
|
||||
if (!freq_table || !mem_bw)
|
||||
return -ENOMEM;
|
||||
|
||||
if (l2_clk) {
|
||||
@@ -453,15 +437,6 @@ static int cpufreq_parse_dt(struct device *dev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (num_paths) {
|
||||
int sz_u = nf * sizeof(*bus_bw.usecase);
|
||||
int sz_v = nf * num_paths * sizeof(*bus_vec_lst);
|
||||
bus_bw.usecase = devm_kzalloc(dev, sz_u, GFP_KERNEL);
|
||||
v = bus_vec_lst = devm_kzalloc(dev, sz_v, GFP_KERNEL);
|
||||
if (!bus_bw.usecase || !bus_vec_lst)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < nf; i++) {
|
||||
unsigned long f;
|
||||
@@ -504,25 +479,12 @@ static int cpufreq_parse_dt(struct device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
if (num_paths) {
|
||||
unsigned int bw_mbps = data[j++];
|
||||
bus_bw.usecase[i].num_paths = num_paths;
|
||||
bus_bw.usecase[i].vectors = v;
|
||||
for (k = 0; k < num_paths; k++) {
|
||||
v->src = ports[k * 2];
|
||||
v->dst = ports[k * 2 + 1];
|
||||
v->ib = bw_mbps * 1000000ULL;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
mem_bw[i] = data[j++];
|
||||
}
|
||||
|
||||
bus_bw.num_usecases = i;
|
||||
freq_table[i].index = i;
|
||||
freq_table[i].frequency = CPUFREQ_TABLE_END;
|
||||
|
||||
if (ports)
|
||||
devm_kfree(dev, ports);
|
||||
devm_kfree(dev, data);
|
||||
|
||||
return 0;
|
||||
@@ -532,15 +494,12 @@ static int cpufreq_parse_dt(struct device *dev)
|
||||
static int msm_cpufreq_show(struct seq_file *m, void *unused)
|
||||
{
|
||||
unsigned int i, cpu_freq;
|
||||
uint64_t ib;
|
||||
|
||||
if (!freq_table)
|
||||
return 0;
|
||||
|
||||
seq_printf(m, "%10s%10s", "CPU (KHz)", "L2 (KHz)");
|
||||
if (bus_bw.usecase)
|
||||
seq_printf(m, "%12s", "Mem (MBps)");
|
||||
seq_printf(m, "\n");
|
||||
seq_printf(m, "%12s\n", "Mem (MBps)");
|
||||
|
||||
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
|
||||
cpu_freq = freq_table[i].frequency;
|
||||
@@ -548,11 +507,7 @@ static int msm_cpufreq_show(struct seq_file *m, void *unused)
|
||||
continue;
|
||||
seq_printf(m, "%10d", cpu_freq);
|
||||
seq_printf(m, "%10d", l2_khz ? l2_khz[i] : cpu_freq);
|
||||
if (bus_bw.usecase) {
|
||||
ib = bus_bw.usecase[i].vectors[0].ib;
|
||||
do_div(ib, 1000000);
|
||||
seq_printf(m, "%12llu", ib);
|
||||
}
|
||||
seq_printf(m, "%12lu", mem_bw[i]);
|
||||
seq_printf(m, "\n");
|
||||
}
|
||||
return 0;
|
||||
@@ -602,10 +557,10 @@ static int __init msm_cpufreq_probe(struct platform_device *pdev)
|
||||
cpufreq_frequency_table_get_attr(freq_table, cpu);
|
||||
}
|
||||
|
||||
if (bus_bw.usecase) {
|
||||
bus_client = msm_bus_scale_register_client(&bus_bw);
|
||||
if (!bus_client)
|
||||
dev_warn(dev, "Unable to register bus client\n");
|
||||
ret = register_devfreq_msm_cpufreq();
|
||||
if (ret) {
|
||||
pr_err("devfreq governor registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
is_clk = true;
|
||||
|
||||
@@ -112,6 +112,7 @@ static struct devfreq_governor_data gov_data[] = {
|
||||
{ .name = "performance" },
|
||||
{ .name = "powersave" },
|
||||
{ .name = "userspace" },
|
||||
{ .name = "msm_cpufreq" },
|
||||
};
|
||||
struct devfreq_dev_profile cpubw_profile = {
|
||||
.polling_ms = 50,
|
||||
@@ -185,7 +186,7 @@ static int __init cpubw_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
df = devfreq_add_device(dev, &cpubw_profile, "powersave", NULL);
|
||||
df = devfreq_add_device(dev, &cpubw_profile, "msm_cpufreq", NULL);
|
||||
if (IS_ERR(df)) {
|
||||
msm_bus_scale_unregister_client(bus_client);
|
||||
return PTR_ERR(df);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __MACH_CPUFREQ_H
|
||||
#define __MACH_CPUFREQ_H
|
||||
|
||||
#if defined(CONFIG_DEVFREQ_GOV_MSM_CPUFREQ)
|
||||
extern int devfreq_msm_cpufreq_update_bw(void);
|
||||
extern int register_devfreq_msm_cpufreq(void);
|
||||
#else
|
||||
static int devfreq_msm_cpufreq_update_bw(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int register_devfreq_msm_cpufreq(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CPU_FREQ_MSM)
|
||||
extern unsigned long msm_cpufreq_get_bw(void);
|
||||
#else
|
||||
extern unsigned long msm_cpufreq_get_bw(void)
|
||||
{
|
||||
return ULONG_MAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -71,6 +71,14 @@ config DEVFREQ_GOV_MSM_ADRENO_TZ
|
||||
Sets the frequency using a "on-demand" algorithm.
|
||||
This governor is unlikely to be useful for other devices.
|
||||
|
||||
config DEVFREQ_GOV_MSM_CPUFREQ
|
||||
bool "MSM CPUfreq"
|
||||
depends on CPU_FREQ_MSM
|
||||
help
|
||||
MSM CPUfreq based governor for CPU bandwidth voting. Sets the CPU
|
||||
to DDR BW vote based on the current CPU frequency. This governor
|
||||
is unlikely to be useful for non-MSM devices.
|
||||
|
||||
comment "DEVFREQ Drivers"
|
||||
|
||||
config ARM_EXYNOS4_BUS_DEVFREQ
|
||||
|
||||
@@ -4,6 +4,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o
|
||||
obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o
|
||||
obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
|
||||
obj-$(CONFIG_DEVFREQ_GOV_MSM_ADRENO_TZ) += governor_msm_adreno_tz.o
|
||||
obj-$(CONFIG_DEVFREQ_GOV_MSM_CPUFREQ) += governor_msm_cpufreq.o
|
||||
|
||||
# DEVFREQ Drivers
|
||||
obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos4_bus.o
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/devfreq.h>
|
||||
#include <mach/cpufreq.h>
|
||||
#include "governor.h"
|
||||
|
||||
DEFINE_MUTEX(df_lock);
|
||||
static struct devfreq *df;
|
||||
|
||||
static int devfreq_msm_cpufreq_get_freq(struct devfreq *df,
|
||||
unsigned long *freq,
|
||||
u32 *flag)
|
||||
{
|
||||
*freq = msm_cpufreq_get_bw();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devfreq_msm_cpufreq_update_bw(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&df_lock);
|
||||
if (df) {
|
||||
mutex_lock(&df->lock);
|
||||
ret = update_devfreq(df);
|
||||
mutex_unlock(&df->lock);
|
||||
}
|
||||
mutex_unlock(&df_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int devfreq_msm_cpufreq_ev_handler(struct devfreq *devfreq,
|
||||
unsigned int event, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (event) {
|
||||
case DEVFREQ_GOV_START:
|
||||
mutex_lock(&df_lock);
|
||||
df = devfreq;
|
||||
mutex_unlock(&df_lock);
|
||||
|
||||
ret = devfreq_msm_cpufreq_update_bw();
|
||||
if (ret) {
|
||||
pr_err("Unable to update BW! Gov start failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
devfreq_monitor_stop(df);
|
||||
pr_debug("Enabled MSM CPUfreq governor\n");
|
||||
break;
|
||||
|
||||
case DEVFREQ_GOV_STOP:
|
||||
mutex_lock(&df_lock);
|
||||
df = NULL;
|
||||
mutex_unlock(&df_lock);
|
||||
|
||||
pr_debug("Disabled MSM CPUfreq governor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct devfreq_governor devfreq_msm_cpufreq = {
|
||||
.name = "msm_cpufreq",
|
||||
.get_target_freq = devfreq_msm_cpufreq_get_freq,
|
||||
.event_handler = devfreq_msm_cpufreq_ev_handler,
|
||||
};
|
||||
|
||||
int register_devfreq_msm_cpufreq(void)
|
||||
{
|
||||
return devfreq_add_governor(&devfreq_msm_cpufreq);
|
||||
}
|
||||
Reference in New Issue
Block a user