aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/Kconfig.arm9
-rw-r--r--drivers/cpufreq/Makefile3
-rw-r--r--drivers/cpufreq/arm_dt_big_little.c101
3 files changed, 113 insertions, 0 deletions
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 55c53bd742e..84d08cabbac 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -118,6 +118,15 @@ config ARM_BIG_LITTLE_CPUFREQ
tristate
depends on ARM_CPU_TOPOLOGY
+config ARM_DT_BL_CPUFREQ
+ tristate "Generic ARM big LITTLE CPUfreq driver probed via DT"
+ select ARM_BIG_LITTLE_CPUFREQ
+ depends on OF
+ default y
+ help
+ This enables the Generic CPUfreq driver for ARM big.LITTLE platform.
+ This gets frequency tables from DT.
+
config ARM_VEXPRESS_BL_CPUFREQ
tristate "ARM Vexpress big LITTLE CPUfreq driver"
select ARM_BIG_LITTLE_CPUFREQ
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index f26fd28849e..6148eac24fc 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -59,6 +59,9 @@ obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ) += highbank-cpufreq.o
obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ) += arm_big_little.o
obj-$(CONFIG_ARM_VEXPRESS_BL_CPUFREQ) += vexpress_big_little.o
+#Keep DT_BL_CPUFREQ as the last entry in all big LITTLE drivers, so that it is
+#probed last.
+obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_dt_big_little.o
##################################################################################
# PowerPC platform drivers
diff --git a/drivers/cpufreq/arm_dt_big_little.c b/drivers/cpufreq/arm_dt_big_little.c
new file mode 100644
index 00000000000..2a41854bd4c
--- /dev/null
+++ b/drivers/cpufreq/arm_dt_big_little.c
@@ -0,0 +1,101 @@
+/*
+ * Generic big.LITTLE CPUFreq Interface driver
+ *
+ * It provides necessary ops to arm_big_little cpufreq driver and gets
+ * Frequency information from Device Tree. Freq table in DT must be in KHz.
+ *
+ * Copyright (C) 2012 Linaro.
+ * Viresh Kumar <viresh.kumar@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/cpufreq.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include "arm_big_little.h"
+
+static struct cpufreq_frequency_table *generic_get_freq_tbl(u32 cluster,
+ int *count)
+{
+ struct device_node *np = NULL;
+ const struct property *pp;
+ unsigned int *table = NULL;
+ int cluster_id;
+ struct cpufreq_frequency_table *cpufreq_table;
+
+ while ((np = of_find_node_by_name(np, "cluster"))) {
+ if (of_property_read_u32(np, "reg", &cluster_id))
+ continue;
+
+ if (cluster_id != cluster)
+ continue;
+
+ pp = of_find_property(np, "freqs", NULL);
+ if (!pp)
+ continue;
+
+ *count = pp->length / sizeof(u32);
+ if (!*count)
+ continue;
+
+ table = kmalloc(sizeof(*table) * (*count), GFP_KERNEL);
+ if (!table) {
+ pr_err("%s: Failed to allocate memory for table\n",
+ __func__);
+ return NULL;
+ }
+
+ of_property_read_u32_array(np, "freqs", table, *count);
+ break;
+ }
+
+ if (!table) {
+ pr_err("%s: Unable to retrieve Freq table from Device Tree",
+ __func__);
+ return NULL;
+ }
+
+ cpufreq_table = arm_bl_copy_table_from_array(table, *count);
+ kfree(table);
+
+ return cpufreq_table;
+}
+
+static void generic_put_freq_tbl(u32 cluster)
+{
+ arm_bl_free_freq_table(cluster);
+}
+
+static struct cpufreq_arm_bl_ops generic_bl_ops = {
+ .name = "generic-bl",
+ .get_freq_tbl = generic_get_freq_tbl,
+ .put_freq_tbl = generic_put_freq_tbl,
+};
+
+static int generic_bl_init(void)
+{
+ return bl_cpufreq_register(&generic_bl_ops);
+}
+module_init(generic_bl_init);
+
+static void generic_bl_exit(void)
+{
+ return bl_cpufreq_unregister(&generic_bl_ops);
+}
+module_exit(generic_bl_exit);
+
+MODULE_DESCRIPTION("Generic ARM big LITTLE cpufreq driver");
+MODULE_LICENSE("GPL");