GPU: fix 2d OC, kernel mpdecision

file:c32ce179eeaeb88a6dfac0e8ce6ecbe87b7af83c -> file:d84d6bf13ae132a1736002aa65e4ccc092963b9f
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -672,7 +672,9 @@ void handle_IPI(int ipinr, struct pt_reg
break;
case IPI_CPU_BACKTRACE:
+ irq_enter();
ipi_cpu_backtrace(cpu, regs);
+ irq_exit();
break;
default:
file:51b347af328bb1a6ff6be214dfa7e531b2a963b6 -> file:d2de4ce52f07d729b6346c35df4cae0c56583a93
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1517,6 +1517,38 @@ config MSM_DALRPC_TEST
help
Exercises DAL RPC calls to QDSP6.
+config MSM_MPDEC
+ bool "Enable kernel based mpdecision"
+ depends on MSM_SMP
+ default y
+ help
+ This enables kernel based multi core control.
+ (up/down hotplug based on load)
+config MSM_MPDEC_STARTDELAY
+ int "Deplay before starting MP DECISION"
+ default 70000
+ depends on MSM_MPDEC
+
+config MSM_MPDEC_DELAY
+ int "Deplay before resuming MP DECISION"
+ default 500
+ depends on MSM_MPDEC
+
+config MSM_MPDEC_PAUSE
+ int "How long to pause after external process controls cpu"
+ default 10000
+ depends on MSM_MPDEC
+
+config MSM_MPDEC_SCROFF_FREQ
+ int "Screen Off MAX CPU"
+ default 384000
+ depends on MSM_MPDEC
+
+config MSM_MPDEC_IDLE_FREQ
+ int "Idle MAX CPU"
+ default 384000
+ depends on MSM_MPDEC
+
if CPU_FREQ_MSM
config MSM_CPU_FREQ_SET_MIN_MAX
file:7b73ca6e8a190d71a6f7e659a88590ec68d1e2c4 -> file:a27565988a4e64884f4216a7510f8ae4251f9107
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -3244,7 +3244,7 @@ static struct clk_freq_tbl clk_tbl_gfx2d
F_GFX2D(160000000, pll2, 1, 5),
F_GFX2D(177778000, pll2, 2, 9),
F_GFX2D(200000000, pll2, 1, 4),
- F_GFX2D(228571000, pll2, 2, 7),
+ F_GFX2D(300000000, pll2, 2, 7),
F_END
};
@@ -3287,7 +3287,7 @@ static struct rcg_clk gfx2d0_clk = {
.dbg_name = "gfx2d0_clk",
.ops = &clk_ops_rcg_8960,
VDD_DIG_FMAX_MAP3(LOW, 100000000, NOMINAL, 200000000,
- HIGH, 228571000),
+ HIGH, 300000000),
CLK_INIT(gfx2d0_clk.c),
},
};
@@ -3331,7 +3331,7 @@ static struct rcg_clk gfx2d1_clk = {
.dbg_name = "gfx2d1_clk",
.ops = &clk_ops_rcg_8960,
VDD_DIG_FMAX_MAP3(LOW, 100000000, NOMINAL, 200000000,
- HIGH, 228571000),
+ HIGH, 300000000),
CLK_INIT(gfx2d1_clk.c),
},
};
file:3c5865ecd7bf0c01aeab877d8ce2ef92937f8c8a -> file:bec5ffe9cefefc5553a165f77b33958020ead839
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -2696,7 +2696,7 @@ static struct msm_bus_vectors grp2d0_max
.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE0,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ab = 0,
- .ib = KGSL_CONVERT_TO_MBPS(1840), //2228 MHz
+ .ib = KGSL_CONVERT_TO_MBPS(2400), //300MHz GPU = 2400 Mbps
},
};
@@ -2744,7 +2744,7 @@ static struct msm_bus_vectors grp2d1_max
.src = MSM_BUS_MASTER_GRAPHICS_2D_CORE1,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ab = 0,
- .ib = KGSL_CONVERT_TO_MBPS(1840), //228MHz GPU
+ .ib = KGSL_CONVERT_TO_MBPS(2400), // 300Mhz = 2400 Mbps
},
};
@@ -2853,7 +2853,7 @@ static struct resource kgsl_2d0_resource
static struct kgsl_device_platform_data kgsl_2d0_pdata = {
.pwrlevel = {
{
- .gpu_freq = 228571000,
+ .gpu_freq = 300000000,
.bus_freq = 2,
},
{
@@ -2906,7 +2906,7 @@ static struct resource kgsl_2d1_resource
static struct kgsl_device_platform_data kgsl_2d1_pdata = {
.pwrlevel = {
{
- .gpu_freq = 228571000,
+ .gpu_freq = 300000000,
.bus_freq = 2,
},
{
file:79823be3729f2005032395efd93ecb71f467830d(new)
--- /dev/null
+++ b/arch/arm/mach-msm/msm_mpdecision.c
@@ -0,0 +1,551 @@
+#include <linux/earlysuspend.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <asm-generic/cputime.h>
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+
+#include "acpuclock.h"
+#include <mach/board_htc.h>
+
+#define MPDEC_TAG "[AnthraX-MPD]: "
+
+enum {
+ MSM_MPDEC_DISABLED = 0,
+ MSM_MPDEC_IDLE,
+ MSM_MPDEC_DOWN,
+ MSM_MPDEC_UP,
+};
+
+struct msm_mpdec_cpudata_t {
+ struct mutex suspend_mutex;
+ int online;
+ int device_suspended;
+ cputime64_t on_time;
+};
+static DEFINE_PER_CPU(struct msm_mpdec_cpudata_t, msm_mpdec_cpudata);
+
+static struct delayed_work msm_mpdec_work;
+static DEFINE_MUTEX(msm_cpu_lock);
+
+static struct msm_mpdec_tuners {
+ unsigned int startdelay;
+ unsigned int delay;
+ unsigned int pause;
+ bool scroff_single_core;
+ unsigned long int idle_freq;
+} msm_mpdec_tuners_ins = {
+ .startdelay = CONFIG_MSM_MPDEC_STARTDELAY,
+ .delay = CONFIG_MSM_MPDEC_DELAY,
+ .pause = CONFIG_MSM_MPDEC_PAUSE,
+ .scroff_single_core = true,
+ .idle_freq = CONFIG_MSM_MPDEC_IDLE_FREQ,
+};
+
+static unsigned int NwNs_Threshold[4] = {35, 0, 0, 5};
+static unsigned int TwTs_Threshold[4] = {250, 0, 0, 250};
+
+extern unsigned int get_rq_info(void);
+extern unsigned long acpuclk_get_rate(int);
+
+unsigned int state = MSM_MPDEC_IDLE;
+bool was_paused = false;
+
+static int mp_decision(void)
+{
+ static bool first_call = true;
+ int new_state = MSM_MPDEC_IDLE;
+ int nr_cpu_online;
+ int index;
+ unsigned int rq_depth;
+ static cputime64_t total_time = 0;
+ static cputime64_t last_time;
+ cputime64_t current_time;
+ cputime64_t this_time = 0;
+
+ if (state == MSM_MPDEC_DISABLED)
+ return MSM_MPDEC_DISABLED;
+
+ current_time = ktime_to_ms(ktime_get());
+ if (current_time <= msm_mpdec_tuners_ins.startdelay)
+ return MSM_MPDEC_IDLE;
+
+ if (first_call) {
+ first_call = false;
+ } else {
+ this_time = current_time - last_time;
+ }
+ total_time += this_time;
+
+ rq_depth = get_rq_info();
+ nr_cpu_online = num_online_cpus();
+
+ if (nr_cpu_online) {
+ index = (nr_cpu_online - 1) * 2;
+ if ((nr_cpu_online < 2) && (rq_depth >= NwNs_Threshold[index])) {
+ if (total_time >= TwTs_Threshold[index]) {
+ new_state = MSM_MPDEC_UP;
+ if (acpuclk_get_rate((CONFIG_NR_CPUS - 2)) <=
+ msm_mpdec_tuners_ins.idle_freq)
+ new_state = MSM_MPDEC_IDLE;
+ }
+ } else if (rq_depth <= NwNs_Threshold[index+1]) {
+ if (total_time >= TwTs_Threshold[index+1] ) {
+ new_state = MSM_MPDEC_DOWN;
+ if (cpu_online((CONFIG_NR_CPUS - 1)))
+ if (acpuclk_get_rate((CONFIG_NR_CPUS - 1)) >
+ msm_mpdec_tuners_ins.idle_freq)
+ new_state = MSM_MPDEC_IDLE;
+ }
+ } else {
+ new_state = MSM_MPDEC_IDLE;
+ total_time = 0;
+ }
+ } else {
+ total_time = 0;
+ }
+
+ if (new_state != MSM_MPDEC_IDLE) {
+ total_time = 0;
+ }
+
+ last_time = ktime_to_ms(ktime_get());
+
+ return new_state;
+}
+
+static void msm_mpdec_work_thread(struct work_struct *work)
+{
+ unsigned int cpu = nr_cpu_ids;
+ cputime64_t on_time = 0;
+
+ if (per_cpu(msm_mpdec_cpudata, (CONFIG_NR_CPUS - 1)).device_suspended == true)
+ goto out;
+
+ if (!mutex_trylock(&msm_cpu_lock))
+ goto out;
+
+ /* if sth messed with the cpus, update the check vars so we can proceed */
+ if (was_paused) {
+ for_each_possible_cpu(cpu) {
+ if (cpu_online(cpu))
+ per_cpu(msm_mpdec_cpudata, cpu).online = true;
+ else if (!cpu_online(cpu))
+ per_cpu(msm_mpdec_cpudata, cpu).online = false;
+ }
+ was_paused = false;
+ }
+
+ state = mp_decision();
+ switch (state) {
+ case MSM_MPDEC_DISABLED:
+ case MSM_MPDEC_IDLE:
+ break;
+ case MSM_MPDEC_DOWN:
+ cpu = (CONFIG_NR_CPUS - 1);
+ if (cpu < nr_cpu_ids) {
+ if ((per_cpu(msm_mpdec_cpudata, cpu).online == true) && (cpu_online(cpu))) {
+ cpu_down(cpu);
+ per_cpu(msm_mpdec_cpudata, cpu).online = false;
+ on_time = ktime_to_ms(ktime_get()) - per_cpu(msm_mpdec_cpudata, cpu).on_time;
+ pr_info(MPDEC_TAG"CPU[%d] on->off | Mask=[%d%d] | time online: %llu\n",
+ cpu, cpu_online(0), cpu_online(1), on_time);
+ } else if (per_cpu(msm_mpdec_cpudata, cpu).online != cpu_online(cpu)) {
+ pr_info(MPDEC_TAG"CPU[%d] was controlled outside of mpdecision! | pausing [%d]ms\n",
+ cpu, msm_mpdec_tuners_ins.pause);
+ msleep(msm_mpdec_tuners_ins.pause);
+ was_paused = true;
+ }
+ }
+ break;
+ case MSM_MPDEC_UP:
+ cpu = (CONFIG_NR_CPUS - 1);
+ if (cpu < nr_cpu_ids) {
+ if ((per_cpu(msm_mpdec_cpudata, cpu).online == false) && (!cpu_online(cpu))) {
+ cpu_up(cpu);
+ per_cpu(msm_mpdec_cpudata, cpu).online = true;
+ per_cpu(msm_mpdec_cpudata, cpu).on_time = ktime_to_ms(ktime_get());
+ pr_info(MPDEC_TAG"CPU[%d] off->on | Mask=[%d%d]\n",
+ cpu, cpu_online(0), cpu_online(1));
+ } else if (per_cpu(msm_mpdec_cpudata, cpu).online != cpu_online(cpu)) {
+ pr_info(MPDEC_TAG"CPU[%d] was controlled outside of mpdecision! | pausing [%d]ms\n",
+ cpu, msm_mpdec_tuners_ins.pause);
+ msleep(msm_mpdec_tuners_ins.pause);
+ was_paused = true;
+ }
+ }
+ break;
+ default:
+ pr_err(MPDEC_TAG"%s: invalid mpdec hotplug state %d\n",
+ __func__, state);
+ }
+ mutex_unlock(&msm_cpu_lock);
+
+out:
+ if (state != MSM_MPDEC_DISABLED)
+ schedule_delayed_work(&msm_mpdec_work,
+ msecs_to_jiffies(msm_mpdec_tuners_ins.delay));
+ return;
+}
+
+static void msm_mpdec_early_suspend(struct early_suspend *h)
+{
+ int cpu = 0;
+ for_each_possible_cpu(cpu) {
+ mutex_lock(&per_cpu(msm_mpdec_cpudata, cpu).suspend_mutex);
+ if (((cpu >= (CONFIG_NR_CPUS - 1)) && (num_online_cpus() > 1)) && (msm_mpdec_tuners_ins.scroff_single_core)) {
+ cpu_down(cpu);
+ pr_info(MPDEC_TAG"Screen -> off. Suspended CPU%d | Mask=[%d%d]\n",
+ cpu, cpu_online(0), cpu_online(1));
+ per_cpu(msm_mpdec_cpudata, cpu).online = false;
+ }
+ per_cpu(msm_mpdec_cpudata, cpu).device_suspended = true;
+ mutex_unlock(&per_cpu(msm_mpdec_cpudata, cpu).suspend_mutex);
+ }
+}
+
+static void msm_mpdec_late_resume(struct early_suspend *h)
+{
+ int cpu = 0;
+ for_each_possible_cpu(cpu) {
+ mutex_lock(&per_cpu(msm_mpdec_cpudata, cpu).suspend_mutex);
+ if ((cpu >= (CONFIG_NR_CPUS - 1)) && (num_online_cpus() < CONFIG_NR_CPUS)) {
+ /* Always enable cpus when screen comes online.
+ * This boosts the wakeup process.
+ */
+ cpu_up(cpu);
+ per_cpu(msm_mpdec_cpudata, cpu).on_time = ktime_to_ms(ktime_get());
+ per_cpu(msm_mpdec_cpudata, cpu).online = true;
+ pr_info(MPDEC_TAG"Screen -> on. Hot plugged CPU%d | Mask=[%d%d]\n",
+ cpu, cpu_online(0), cpu_online(1));
+ }
+ per_cpu(msm_mpdec_cpudata, cpu).device_suspended = false;
+ mutex_unlock(&per_cpu(msm_mpdec_cpudata, cpu).suspend_mutex);
+ }
+}
+
+static struct early_suspend msm_mpdec_early_suspend_handler = {
+ .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
+ .suspend = msm_mpdec_early_suspend,
+ .resume = msm_mpdec_late_resume,
+};
+
+/**************************** SYSFS START ****************************/
+struct kobject *msm_mpdec_kobject;
+
+#define show_one(file_name, object) \
+static ssize_t show_##file_name \
+(struct kobject *kobj, struct attribute *attr, char *buf) \
+{ \
+ return sprintf(buf, "%u\n", msm_mpdec_tuners_ins.object); \
+}
+
+show_one(startdelay, startdelay);
+show_one(delay, delay);
+show_one(pause, pause);
+show_one(scroff_single_core, scroff_single_core);
+
+static ssize_t show_idle_freq (struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lu\n", msm_mpdec_tuners_ins.idle_freq);
+}
+
+static ssize_t show_enabled(struct kobject *a, struct attribute *b,
+ char *buf)
+{
+ unsigned int enabled;
+ switch (state) {
+ case MSM_MPDEC_DISABLED:
+ enabled = 0;
+ break;
+ case MSM_MPDEC_IDLE:
+ case MSM_MPDEC_DOWN:
+ case MSM_MPDEC_UP:
+ enabled = 1;
+ break;
+ default:
+ enabled = 333;
+ }
+ return sprintf(buf, "%u\n", enabled);
+}
+
+static ssize_t show_nwns_threshold_up(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", NwNs_Threshold[0]);
+}
+
+static ssize_t show_nwns_threshold_down(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", NwNs_Threshold[3]);
+}
+
+static ssize_t show_twts_threshold_up(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", TwTs_Threshold[0]);
+}
+
+static ssize_t show_twts_threshold_down(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%u\n", TwTs_Threshold[3]);
+}
+
+static ssize_t store_startdelay(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ msm_mpdec_tuners_ins.startdelay = input;
+
+ return count;
+}
+
+static ssize_t store_delay(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ msm_mpdec_tuners_ins.delay = input;
+
+ return count;
+}
+
+static ssize_t store_pause(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ msm_mpdec_tuners_ins.pause = input;
+
+ return count;
+}
+
+static ssize_t store_idle_freq(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ long unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%lu", &input);
+ if (ret != 1)
+ return -EINVAL;
+ msm_mpdec_tuners_ins.idle_freq = acpu_check_khz_value(input);
+
+ return count;
+}
+
+static ssize_t store_scroff_single_core(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+ switch (buf[0]) {
+ case '0':
+ msm_mpdec_tuners_ins.scroff_single_core = input;
+ break;
+ case '1':
+ msm_mpdec_tuners_ins.scroff_single_core = input;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return count;
+}
+
+static ssize_t store_enabled(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int cpu, input, enabled;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ switch (state) {
+ case MSM_MPDEC_DISABLED:
+ enabled = 0;
+ break;
+ case MSM_MPDEC_IDLE:
+ case MSM_MPDEC_DOWN:
+ case MSM_MPDEC_UP:
+ enabled = 1;
+ break;
+ default:
+ enabled = 333;
+ }
+
+ if (buf[0] == enabled)
+ return -EINVAL;
+
+ switch (buf[0]) {
+ case '0':
+ state = MSM_MPDEC_DISABLED;
+ cpu = (CONFIG_NR_CPUS - 1);
+ if (!cpu_online(cpu)) {
+ per_cpu(msm_mpdec_cpudata, cpu).on_time = ktime_to_ms(ktime_get());
+ per_cpu(msm_mpdec_cpudata, cpu).online = true;
+ cpu_up(cpu);
+ pr_info(MPDEC_TAG"disabled... Hot plugged CPU[%d] | Mask=[%d%d]\n",
+ cpu, cpu_online(0), cpu_online(1));
+ } else {
+ pr_info(MPDEC_TAG"disabled...\n");
+ }
+ break;
+ case '1':
+ state = MSM_MPDEC_IDLE;
+ was_paused = true;
+ schedule_delayed_work(&msm_mpdec_work, 0);
+ pr_info(MPDEC_TAG" mpdecision enabled...\n");
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return count;
+}
+
+static ssize_t store_nwns_threshold_up(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ NwNs_Threshold[0] = input;
+
+ return count;
+}
+
+static ssize_t store_nwns_threshold_down(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ NwNs_Threshold[3] = input;
+
+ return count;
+}
+
+static ssize_t store_twts_threshold_up(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ TwTs_Threshold[0] = input;
+
+ return count;
+}
+
+static ssize_t store_twts_threshold_down(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ unsigned int input;
+ int ret;
+ ret = sscanf(buf, "%u", &input);
+ if (ret != 1)
+ return -EINVAL;
+
+ TwTs_Threshold[3] = input;
+
+ return count;
+}
+
+define_one_global_rw(startdelay);
+define_one_global_rw(delay);
+define_one_global_rw(pause);
+define_one_global_rw(scroff_single_core);
+define_one_global_rw(idle_freq);
+define_one_global_rw(enabled);
+define_one_global_rw(nwns_threshold_up);
+define_one_global_rw(nwns_threshold_down);
+define_one_global_rw(twts_threshold_up);
+define_one_global_rw(twts_threshold_down);
+
+static struct attribute *msm_mpdec_attributes[] = {
+ &startdelay.attr,
+ &delay.attr,
+ &pause.attr,
+ &scroff_single_core.attr,
+ &idle_freq.attr,
+ &enabled.attr,
+ &nwns_threshold_up.attr,
+ &nwns_threshold_down.attr,
+ &twts_threshold_up.attr,
+ &twts_threshold_down.attr,
+ NULL
+};
+
+
+static struct attribute_group msm_mpdec_attr_group = {
+ .attrs = msm_mpdec_attributes,
+ .name = "conf",
+};
+/**************************** SYSFS END ****************************/
+
+static int __init msm_mpdec(void)
+{
+ int cpu, rc, err = 0;
+
+ for_each_possible_cpu(cpu) {
+ mutex_init(&(per_cpu(msm_mpdec_cpudata, cpu).suspend_mutex));
+ per_cpu(msm_mpdec_cpudata, cpu).device_suspended = false;
+ per_cpu(msm_mpdec_cpudata, cpu).online = true;
+ }
+
+ INIT_DELAYED_WORK(&msm_mpdec_work, msm_mpdec_work_thread);
+ if (state != MSM_MPDEC_DISABLED)
+ schedule_delayed_work(&msm_mpdec_work, 0);
+
+ register_early_suspend(&msm_mpdec_early_suspend_handler);
+
+ msm_mpdec_kobject = kobject_create_and_add("msm_mpdecision", kernel_kobj);
+ if (msm_mpdec_kobject) {
+ rc = sysfs_create_group(msm_mpdec_kobject,
+ &msm_mpdec_attr_group);
+ if (rc) {
+ pr_warn(MPDEC_TAG"sysfs: ERROR, could not create sysfs group");
+ }
+ } else
+ pr_warn(MPDEC_TAG"sysfs: ERROR, could not create sysfs kobj");
+
+ pr_info(MPDEC_TAG"%s init complete.", __func__);
+
+ return err;
+}
+
+late_initcall(msm_mpdec);
+
+MODULE_DESCRIPTION("Kernel based MPDECISION (C) 2011 Chad Goodman");
+
+
file:b3b122f4630dcc199f3096456df5787e79d5b7e9 -> file:b12833f3b6858424cc65b38d46121492327939ca
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -232,7 +232,9 @@ static int __init default_bdi_init(void)
sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
BUG_ON(IS_ERR(sync_supers_tsk));
- setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
+ init_timer_deferrable(&sync_supers_timer);
+ sync_supers_timer.function = sync_supers_timer_fn;
+ sync_supers_timer.data = 0;
bdi_arm_supers_timer();
err = bdi_init(&default_backing_dev_info);