[PATCH 3/3] ux500: Add CPUFreq support

Sundar Iyer sundar.iyer at stericsson.com
Tue May 18 04:36:26 EDT 2010


From: Sundar R Iyer <sundar.iyer at stericsson.com>

Acked-by: Linus Walleij <linus.walleij at stericsson.com>
Signed-off-by: Sundar R Iyer <sundar.iyer at stericsson.com>
---
 arch/arm/mach-ux500/Kconfig                       |    1 +
 arch/arm/mach-ux500/Makefile                      |    2 +
 arch/arm/mach-ux500/include/mach/u8500-prcm-api.h |   21 ++++++
 arch/arm/mach-ux500/u8500-prcm.c                  |   74 +++++++++++++++++++++
 4 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 6625e5b..2df43be 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -6,6 +6,7 @@ config UX500_SOC_COMMON
 	select ARM_GIC
 	select HAS_MTU
 	select NOMADIK_GPIO
+	select ARCH_HAS_CPUFREQ
 
 config UX500_SOC_DB8500
 	bool
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index d3613ca..5afcd97 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -9,3 +9,5 @@ obj-$(CONFIG_MACH_U8500_MOP)	+= board-mop500.o
 obj-$(CONFIG_MACH_U5500)	+= board-u5500.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o localtimer.o
 obj-$(CONFIG_HOTPLUG_CPU)       += hotplug.o
+obj-$(CONFIG_CPU_FREQ)		+= cpufreq-ux500.o
+
diff --git a/arch/arm/mach-ux500/include/mach/u8500-prcm-api.h b/arch/arm/mach-ux500/include/mach/u8500-prcm-api.h
index 5f113c1..60a4281 100644
--- a/arch/arm/mach-ux500/include/mach/u8500-prcm-api.h
+++ b/arch/arm/mach-ux500/include/mach/u8500-prcm-api.h
@@ -9,13 +9,34 @@
  * U8500 PRCMU APIs
  */
 
+#ifndef __U8500_PRCM_API_H
+#define __U8500_PRCM_API_H
+
+/* PRCM take care to populate the frequencies */
+#include <linux/cpufreq.h>
+
+struct ux500_cpufreq_config {
+	int scaling_available_freqs;
+	struct cpufreq_frequency_table *cpu_freq_table;
+};
+
 /* ux500 subsystem */
 enum ux500_subsys {
 	SUBSYS_ARM,
 	SUBSYS_APE,
 };
 
+/* suported ARM OPPs */
+enum ux500_arm_opp {
+	ARM_OPP_INIT = 0x00,
+	ARM_NO_CHANGE = 0x01,
+	ARM_100_OPP = 0x02,
+	ARM_50_OPP = 0x03,
+	ARM_EXTCLK = 0x07
+};
+
 int prcm_set_subsys_opp(unsigned int subsys_opp_idx,
 		unsigned int subsys);
 int prcm_get_subsys_opp(unsigned int subsys);
 
+#endif /* __U8500_PRCM_API_H */
diff --git a/arch/arm/mach-ux500/u8500-prcm.c b/arch/arm/mach-ux500/u8500-prcm.c
index 2703768..b5be8aa 100644
--- a/arch/arm/mach-ux500/u8500-prcm.c
+++ b/arch/arm/mach-ux500/u8500-prcm.c
@@ -129,6 +129,71 @@ static irqreturn_t prcm_irq_handler (int irq, void *ctrlr)
 }
 
 /**
+ * ux500_prcm_register_device() - Register a device like cpufreq/cpuidle
+ * @dev_name: name of device to be registered
+ * @id: device id
+ * @priv_data: any private data for device
+ *
+ * This function creates and registers a platform device according to the
+ * name and id passed. The device can also be passed platform specific data
+ * this is very needed when client drivers handling SoC specific power mgmnt
+ * are dependent on this PRCM unit for operations.
+ */
+static int prcm_register_device(const char *dev_name, int id,
+		void *priv_data)
+{
+	int ret = 0;
+	struct platform_device *pdev;
+
+	pdev = platform_device_alloc(dev_name, id);
+	if (!pdev)
+		return -ENOMEM;
+
+	pdev->dev.platform_data = priv_data;
+
+	ret = platform_device_add(pdev);
+	if (ret != 0) {
+		printk(KERN_WARNING "Failed to register %s device\n",
+					 dev_name);
+		platform_device_put(pdev);
+		return ret;
+	}
+
+	return ret;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * We make a frequency table until we get the PRCM
+ * supporting us the dynamic table detection
+ */
+struct cpufreq_frequency_table db8500_freq_table[] = {
+	{
+		.index          = 0,
+		.frequency      = 200000,
+	},
+	{
+		.index          = 1,
+		.frequency      = 300000,
+	},
+	{
+		.index          = 2,
+		.frequency      = 600000,
+	},
+	{
+		.index          = 3,
+		.frequency      = CPUFREQ_TABLE_END,
+	},
+};
+
+/* wrap it up into a platform data */
+static struct ux500_cpufreq_config db8500_cpufreq_info = {
+	.scaling_available_freqs = ARRAY_SIZE(db8500_freq_table),
+	.cpu_freq_table = db8500_freq_table,
+};
+#endif
+
+/**
  * u8500_prcm_init() - U8500 PRCM driver init
  */
 static int u8500_prcm_init(void)
@@ -146,6 +211,15 @@ static int u8500_prcm_init(void)
 		return -ENODEV;
 	}
 
+#ifdef CONFIG_CPU_FREQ
+	/* register cpufreq device */
+	err = prcm_register_device("cpufreq-ux500", 0,
+			&db8500_cpufreq_info);
+	if (err < 0)
+		printk(KERN_ERR
+			"ux500-prcm: failed to register cpufreq-ux500\n");
+#endif
+
 	/*
 	 * clear all prcm interrupts.
 	 * possibly some transaction can happen (from u-boot)
-- 
1.6.3.3




More information about the linux-arm-kernel mailing list