All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rajendra Nayak" <rnayak@ti.com>
To: linux-omap@vger.kernel.org
Cc: 'Kevin Hilman' <khilman@deeprootsystems.com>
Subject: [PATCH] Fix crash on non-3430SDP platforms with DVFS/CPUFreq
Date: Wed, 26 Nov 2008 18:31:43 +0530	[thread overview]
Message-ID: <04c101c94fc7$22fea610$LocalHost@wipultra1382> (raw)

The SRF/DVFS + CPUFreq patches had issues booting on
non-3430SDP platforms as reported by Kevin Hilman.
This patch puts non-NULL checks in place for mpu_opps/dsp_opps
/l3_opps before accessing them and fixes the issue.

This fix/patch can be applied on top of 
pm-20081119 branch 
+ [PATCH 00/08] OMAP3 SRF: OPP and Frequency resources
+ [PATCH 00/03] OMAP3 PM: CPUFreq driver for OMAP3

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
---
 arch/arm/mach-omap2/clock34xx.c            |   33 ++++++++++++++++++++---------
 arch/arm/mach-omap2/pm.h                   |   18 ---------------
 arch/arm/mach-omap2/resource34xx.c         |   21 ++++++++++++++++++
 arch/arm/plat-omap/cpu-omap.c              |    6 +----
 arch/arm/plat-omap/include/mach/omap34xx.h |   18 +++++++++++++++
 5 files changed, 64 insertions(+), 32 deletions(-)

Index: linux-omap-2.6/arch/arm/mach-omap2/clock34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/clock34xx.c	2008-11-26 17:43:12.011090533 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/clock34xx.c	2008-11-26 17:47:40.551795371 +0530
@@ -666,6 +666,9 @@ void omap2_clk_init_cpufreq_table(struct
 	struct omap_opp *prcm;
 	int i = 0;
 
+	if (!mpu_opps)
+		return;
+
 	/* Avoid registering the 120% Overdrive with CPUFreq */
 	prcm = mpu_opps + MAX_VDD1_OPP - 1;
 	for (; prcm->rate; prcm--) {
@@ -798,20 +801,24 @@ int __init omap2_clk_init(void)
 	dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
 
 	mpu_speed = dpll1_clk->rate;
-	prcm_vdd = mpu_opps + MAX_VDD1_OPP;
-	for (; prcm_vdd->rate; prcm_vdd--) {
-		if (prcm_vdd->rate <= mpu_speed) {
-			curr_vdd1_prcm_set = prcm_vdd;
-			break;
+	if (mpu_opps) {
+		prcm_vdd = mpu_opps + MAX_VDD1_OPP;
+		for (; prcm_vdd->rate; prcm_vdd--) {
+			if (prcm_vdd->rate <= mpu_speed) {
+				curr_vdd1_prcm_set = prcm_vdd;
+				break;
+			}
 		}
 	}
 
 	core_speed = dpll3_clk->rate;
-	prcm_vdd = l3_opps + MAX_VDD2_OPP;
-	for (; prcm_vdd->rate; prcm_vdd--) {
-		if (prcm_vdd->rate <= core_speed) {
-			curr_vdd2_prcm_set = prcm_vdd;
-			break;
+	if (l3_opps) {
+		prcm_vdd = l3_opps + MAX_VDD2_OPP;
+		for (; prcm_vdd->rate; prcm_vdd--) {
+			if (prcm_vdd->rate <= core_speed) {
+				curr_vdd2_prcm_set = prcm_vdd;
+				break;
+			}
 		}
 	}
 
@@ -878,6 +885,9 @@ static long omap3_round_to_table_rate(st
 	if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
 		return -EINVAL;
 
+	if (!mpu_opps || !dsp_opps || !l3_opps)
+		return -EINVAL;
+
 	highest_rate = -EINVAL;
 
 	if (clk == &virt_vdd1_prcm_set)
@@ -904,6 +914,9 @@ static int omap3_select_table_rate(struc
 	if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
 		return -EINVAL;
 
+	if (!mpu_opps || !dsp_opps || !l3_opps)
+		return -EINVAL;
+
 	if (clk == &virt_vdd1_prcm_set) {
 		prcm_vdd = mpu_opps + MAX_VDD1_OPP;
 		index = MAX_VDD1_OPP;
Index: linux-omap-2.6/arch/arm/mach-omap2/pm.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.h	2008-11-26 17:43:12.011090533 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/pm.h	2008-11-26 17:47:40.552795340 +0530
@@ -39,24 +39,6 @@ extern void omap3_pm_off_mode_enable(int
 #endif
 extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
 
-
-/* VDD1 OPPS */
-#define VDD1_OPP1	0x1
-#define VDD1_OPP2	0x2
-#define VDD1_OPP3	0x3
-#define VDD1_OPP4	0x4
-#define VDD1_OPP5	0x5
-
-/* VDD2 OPPS */
-#define VDD2_OPP1	0x1
-#define VDD2_OPP2	0x2
-#define VDD2_OPP3	0x3
-
-#define MIN_VDD1_OPP	VDD1_OPP1
-#define MAX_VDD1_OPP	VDD1_OPP5
-#define MIN_VDD2_OPP	VDD2_OPP1
-#define MAX_VDD2_OPP	VDD2_OPP3
-
 #ifdef CONFIG_PM_DEBUG
 extern u32 omap2_read_32k_sync_counter(void);
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
Index: linux-omap-2.6/arch/arm/mach-omap2/resource34xx.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/resource34xx.c	2008-11-26 17:43:12.011090533 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/resource34xx.c	2008-11-26 18:16:28.376582736 +0530
@@ -144,6 +144,10 @@ static struct device dummy_dsp_dev;
 void init_opp(struct shared_resource *resp)
 {
 	resp->no_of_users = 0;
+	
+	if (!mpu_opps || !dsp_opps || !l3_opps)
+		return 0;
+
 	/* Initialize the current level of the OPP resource
 	* to the  opp set by u-boot.
 	*/
@@ -167,6 +171,9 @@ int set_opp(struct shared_resource *resp
 	if (resp->curr_level == target_level)
 		return 0;
 
+	if (!mpu_opps || !dsp_opps || !l3_opps)
+		return 0;
+
 	if (strcmp(resp->name, "vdd1_opp") == 0) {
 		mpu_old_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
 					curr_vdd1_prcm_set->opp_id);
@@ -184,12 +191,16 @@ int set_opp(struct shared_resource *resp
 		if (resp->curr_level > target_level) {
 			/* Scale Frequency and then voltage */
 			clk_set_rate(vdd1_clk, mpu_freq);
+#ifdef CONFIG_OMAP_SMARTREFLEX
 			sr_voltagescale_vcbypass(t_opp,
 					mpu_opps[target_level].vsel);
+#endif
 		} else {
+#ifdef CONFIG_OMAP_SMARTREFLEX
 			/* Scale Voltage and then frequency */
 			sr_voltagescale_vcbypass(t_opp,
 					mpu_opps[target_level].vsel);
+#endif
 			clk_set_rate(vdd1_clk, mpu_freq);
 		}
 		resp->curr_level = curr_vdd1_prcm_set->opp_id;
@@ -221,12 +232,16 @@ int set_opp(struct shared_resource *resp
 		if (resp->curr_level > target_level) {
 			/* Scale Frequency and then voltage */
 			clk_set_rate(vdd2_clk, l3_freq);
+#ifdef CONFIG_OMAP_SMARTREFLEX
 			sr_voltagescale_vcbypass(t_opp,
 					l3_opps[target_level].vsel);
+#endif
 		} else {
+#ifdef CONFIG_OMAP_SMARTREFLEX
 			/* Scale Voltage and then frequency */
 			sr_voltagescale_vcbypass(t_opp,
 					l3_opps[target_level].vsel);
+#endif
 			clk_set_rate(vdd2_clk, l3_freq);
 		}
 		resp->curr_level = curr_vdd2_prcm_set->opp_id;
@@ -253,6 +268,9 @@ void init_freq(struct shared_resource *r
 	char *linked_res_name;
 	resp->no_of_users = 0;
 
+	if (!mpu_opps || !dsp_opps)
+		return;
+
 	linked_res_name = (char *)resp->resource_data;
 	/* Initialize the current level of the Freq resource
 	* to the frequency set by u-boot.
@@ -271,6 +289,9 @@ int set_freq(struct shared_resource *res
 {
 	unsigned int vdd1_opp;
 
+	if (!mpu_opps || !dsp_opps)
+		return 0;
+
 	if (strcmp(resp->name, "mpu_freq") == 0) {
 		vdd1_opp = get_opp(mpu_opps + MAX_VDD1_OPP, target_level);
 		resource_request("vdd1_opp", &dummy_mpu_dev, vdd1_opp);
Index: linux-omap-2.6/arch/arm/plat-omap/cpu-omap.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/plat-omap/cpu-omap.c	2008-11-26 17:43:12.011090533 +0530
+++ linux-omap-2.6/arch/arm/plat-omap/cpu-omap.c	2008-11-26 17:47:40.552795340 +0530
@@ -31,7 +31,6 @@
 #include <mach/clock.h>
 #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
 #include <mach/omap-pm.h>
-#include "../mach-omap2/pm.h"
 #endif
 
 #define VERY_HI_RATE	900000000
@@ -107,9 +106,8 @@ static int omap_target(struct cpufreq_po
 #endif
 	ret = clk_set_rate(mpu_clk, freqs.new * 1000);
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)\
-	&& defined(CONFIG_MACH_OMAP_3430SDP)
-	{
+#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+	if (mpu_opps) {
 		int ind;
 		for (ind = 1; ind <= MAX_VDD1_OPP; ind++) {
 			if (mpu_opps[ind].rate/1000 >= freqs.new) {
Index: linux-omap-2.6/arch/arm/plat-omap/include/mach/omap34xx.h
===================================================================
--- linux-omap-2.6.orig/arch/arm/plat-omap/include/mach/omap34xx.h	2008-11-26 17:43:12.011090533 +0530
+++ linux-omap-2.6/arch/arm/plat-omap/include/mach/omap34xx.h	2008-11-26 17:47:40.553795309 +0530
@@ -71,5 +71,23 @@
 #define OMAP34XX_DSP_MEM_BASE	(OMAP34XX_DSP_BASE + 0x0)
 #define OMAP34XX_DSP_IPI_BASE	(OMAP34XX_DSP_BASE + 0x1000000)
 #define OMAP34XX_DSP_MMU_BASE	(OMAP34XX_DSP_BASE + 0x2000000)
+
+/* VDD1 OPPS */
+#define VDD1_OPP1	0x1
+#define VDD1_OPP2	0x2
+#define VDD1_OPP3	0x3
+#define VDD1_OPP4	0x4
+#define VDD1_OPP5	0x5
+
+/* VDD2 OPPS */
+#define VDD2_OPP1	0x1
+#define VDD2_OPP2	0x2
+#define VDD2_OPP3	0x3
+
+#define MIN_VDD1_OPP	VDD1_OPP1
+#define MAX_VDD1_OPP	VDD1_OPP5
+#define MIN_VDD2_OPP	VDD2_OPP1
+#define MAX_VDD2_OPP	VDD2_OPP3
+
 #endif /* __ASM_ARCH_OMAP34XX_H */
 


             reply	other threads:[~2008-11-26 13:01 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-26 13:01 Rajendra Nayak [this message]
2008-11-26 19:45 ` [PATCH] Fix crash on non-3430SDP platforms with DVFS/CPUFreq Kevin Hilman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='04c101c94fc7$22fea610$LocalHost@wipultra1382' \
    --to=rnayak@ti.com \
    --cc=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.