LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] powerpc: Cope with duplicate node & property names in /proc/device-tree
From: Michael Ellerman @ 2006-03-27  3:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <1143429985.443737.375094420785.qpush@concordia>

Various dodgy firmware might give us nodes and/or properties in the device
tree with conflicting names. That's generally ok, except for when we export
the device tree via /proc, so check when we're creating the proc device tree
and munge names accordingly.

Tested on a faked device tree with kexec, would be good if someone with
actual bogus firmware could try it, but just for completeness.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 fs/proc/proc_devtree.c |  103 ++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 80 insertions(+), 23 deletions(-)

Index: to-merge/fs/proc/proc_devtree.c
===================================================================
--- to-merge.orig/fs/proc/proc_devtree.c
+++ to-merge/fs/proc/proc_devtree.c
@@ -52,7 +52,8 @@ static int property_read_proc(char *page
  * Add a property to a node
  */
 static struct proc_dir_entry *
-__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp)
+__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp,
+		const char *name)
 {
 	struct proc_dir_entry *ent;
 
@@ -60,14 +61,14 @@ __proc_device_tree_add_prop(struct proc_
 	 * Unfortunately proc_register puts each new entry
 	 * at the beginning of the list.  So we rearrange them.
 	 */
-	ent = create_proc_read_entry(pp->name,
-				     strncmp(pp->name, "security-", 9)
+	ent = create_proc_read_entry(name,
+				     strncmp(name, "security-", 9)
 				     ? S_IRUGO : S_IRUSR, de,
 				     property_read_proc, pp);
 	if (ent == NULL)
 		return NULL;
 
-	if (!strncmp(pp->name, "security-", 9))
+	if (!strncmp(name, "security-", 9))
 		ent->size = 0; /* don't leak number of password chars */
 	else
 		ent->size = pp->length;
@@ -78,7 +79,7 @@ __proc_device_tree_add_prop(struct proc_
 
 void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop)
 {
-	__proc_device_tree_add_prop(pde, prop);
+	__proc_device_tree_add_prop(pde, prop, prop->name);
 }
 
 void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
@@ -106,6 +107,69 @@ void proc_device_tree_update_prop(struct
 }
 
 /*
+ * Various dodgy firmware might give us nodes and/or properties with
+ * conflicting names. That's generally ok, except for exporting via /proc,
+ * so munge names here to ensure they're unique.
+ */
+
+static int duplicate_name(struct proc_dir_entry *de, const char *name)
+{
+	struct proc_dir_entry *ent;
+	int found = 0;
+
+	spin_lock(&proc_subdir_lock);
+
+	for (ent = de->subdir; ent != NULL; ent = ent->next) {
+		if (strcmp(ent->name, name) == 0) {
+			found = 1;
+			break;
+		}
+	}
+
+	spin_unlock(&proc_subdir_lock);
+
+	return found;
+}
+
+static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de,
+		const char *name)
+{
+	char *fixed_name;
+	int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */
+	int i = 1, size;
+
+realloc:
+	fixed_name = kmalloc(fixup_len, GFP_KERNEL);
+	if (fixed_name == NULL) {
+		printk(KERN_ERR "device-tree: Out of memory trying to fixup "
+				"name \"%s\"\n", name);
+		return name;
+	}
+
+retry:
+	size = snprintf(fixed_name, fixup_len, "%s#%d", name, i);
+	size++; /* account for NULL */
+
+	if (size > fixup_len) {
+		/* We ran out of space, free and reallocate. */
+		kfree(fixed_name);
+		fixup_len = size;
+		goto realloc;
+	}
+
+	if (duplicate_name(de, fixed_name)) {
+		/* Multiple duplicates. Retry with a different offset. */
+		i++;
+		goto retry;
+	}
+
+	printk(KERN_WARNING "device-tree: Duplicate name in %s, "
+			"renamed to \"%s\"\n", np->full_name, fixed_name);
+
+	return fixed_name;
+}
+
+/*
  * Process a node, adding entries for its children and its properties.
  */
 void proc_device_tree_add_node(struct device_node *np,
@@ -118,37 +182,30 @@ void proc_device_tree_add_node(struct de
 
 	set_node_proc_entry(np, de);
 	for (child = NULL; (child = of_get_next_child(np, child));) {
+		/* Use everything after the last slash, or the full name */
 		p = strrchr(child->full_name, '/');
 		if (!p)
 			p = child->full_name;
 		else
 			++p;
+
+		if (duplicate_name(de, p))
+			p = fixup_name(np, de, p);
+
 		ent = proc_mkdir(p, de);
 		if (ent == 0)
 			break;
 		proc_device_tree_add_node(child, ent);
 	}
 	of_node_put(child);
+
 	for (pp = np->properties; pp != 0; pp = pp->next) {
-		/*
-		 * Yet another Apple device-tree bogosity: on some machines,
-		 * they have properties & nodes with the same name. Those
-		 * properties are quite unimportant for us though, thus we
-		 * simply "skip" them here, but we do have to check.
-		 */
-		spin_lock(&proc_subdir_lock);
-		for (ent = de->subdir; ent != NULL; ent = ent->next)
-			if (!strcmp(ent->name, pp->name))
-				break;
-		spin_unlock(&proc_subdir_lock);
-		if (ent != NULL) {
-			printk(KERN_WARNING "device-tree: property \"%s\" name"
-			       " conflicts with node in %s\n", pp->name,
-			       np->full_name);
-			continue;
-		}
+		p = pp->name;
+
+		if (duplicate_name(de, p))
+			p = fixup_name(np, de, p);
 
-		ent = __proc_device_tree_add_prop(de, pp);
+		ent = __proc_device_tree_add_prop(de, pp, p);
 		if (ent == 0)
 			break;
 	}

^ permalink raw reply

* [PATCH 1/2] powerpc: Rename and export ppc64_firmware_features
From: Michael Ellerman @ 2006-03-27  3:26 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

We need to export ppc64_firmware_features for modules. Before we do that
I think we should probably rename it to powerpc_firmware_features.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---

 arch/powerpc/kernel/firmware.c            |    4 +++-
 arch/powerpc/platforms/iseries/setup.c    |    4 ++--
 arch/powerpc/platforms/pseries/firmware.c |    2 +-
 arch/powerpc/platforms/pseries/setup.c    |    2 +-
 include/asm-powerpc/firmware.h            |    4 ++--
 5 files changed, 9 insertions(+), 7 deletions(-)

Index: to-merge/arch/powerpc/kernel/firmware.c
===================================================================
--- to-merge.orig/arch/powerpc/kernel/firmware.c
+++ to-merge/arch/powerpc/kernel/firmware.c
@@ -14,7 +14,9 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 
 #include <asm/firmware.h>
 
-unsigned long ppc64_firmware_features;
+unsigned long powerpc_firmware_features;
+EXPORT_SYMBOL_GPL(powerpc_firmware_features);
Index: to-merge/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/iseries/setup.c
+++ to-merge/arch/powerpc/platforms/iseries/setup.c
@@ -680,8 +680,8 @@ static int __init iseries_probe(int plat
 	if (PLATFORM_ISERIES_LPAR != platform)
 		return 0;
 
-	ppc64_firmware_features |= FW_FEATURE_ISERIES;
-	ppc64_firmware_features |= FW_FEATURE_LPAR;
+	powerpc_firmware_features |= FW_FEATURE_ISERIES;
+	powerpc_firmware_features |= FW_FEATURE_LPAR;
 
 	return 1;
 }
Index: to-merge/arch/powerpc/platforms/pseries/firmware.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/pseries/firmware.c
+++ to-merge/arch/powerpc/platforms/pseries/firmware.c
@@ -91,7 +91,7 @@ void __init fw_feature_init(void)
 				continue;
 
 			/* we have a match */
-			ppc64_firmware_features |=
+			powerpc_firmware_features |=
 				firmware_features_table[i].val;
 			break;
 		}
Index: to-merge/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- to-merge.orig/arch/powerpc/platforms/pseries/setup.c
+++ to-merge/arch/powerpc/platforms/pseries/setup.c
@@ -386,7 +386,7 @@ static int __init pSeries_probe(int plat
 	 */
 
 	if (platform == PLATFORM_PSERIES_LPAR)
-		ppc64_firmware_features |= FW_FEATURE_LPAR;
+		powerpc_firmware_features |= FW_FEATURE_LPAR;
 
 	return 1;
 }
Index: to-merge/include/asm-powerpc/firmware.h
===================================================================
--- to-merge.orig/include/asm-powerpc/firmware.h
+++ to-merge/include/asm-powerpc/firmware.h
@@ -82,11 +82,11 @@ enum {
 /* This is used to identify firmware features which are available
  * to the kernel.
  */
-extern unsigned long	ppc64_firmware_features;
+extern unsigned long	powerpc_firmware_features;
 
 #define firmware_has_feature(feature)					\
 	((FW_FEATURE_ALWAYS & (feature)) ||				\
-		(FW_FEATURE_POSSIBLE & ppc64_firmware_features & (feature)))
+		(FW_FEATURE_POSSIBLE & powerpc_firmware_features & (feature)))
 
 extern void system_reset_fwnmi(void);
 extern void machine_check_fwnmi(void);

^ permalink raw reply

* Re: make install on ppc
From: Brent Cook @ 2006-03-27  1:56 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <OF06763F9B.91995CDB-ON4825713E.000850DE-4825713E.000949FE@cn.ibm.com>

On Sunday 26 March 2006 19:42, Jin Qi Huang wrote:
> I also think the 'make install' is very useful, now on ia32, the 'make
> install' provided by the latest kernel linux-2.6.16 not only create
> initrd, copy vmlinuz and System.map to /boot directory, but also update
> grub, ppc32 does not provide this useful feature, maybe it is a pity!
>

Maybe narrow it to define 'make install' for new world/old world Macintoshes, 
or IBM machines? I can't see a generic make install being useful for the 
wider range of platforms that fall under ppc.

'make install' appears to me to be very platform dependent. Sure, on x86, you 
can reasonably assume that the majority of systems have the kernel on a disk 
under /boot and the bootloader is grub or lilo. I have 5 ppc machines 
currently, and no two use the same bootloader or kernel image. I've seen 
u-boot, yaboot, quik, powerboot (Motorola/Force), xmon (XES) and more, and 
they all required different post-processing to the kernel image to boot. For 
most of these, there is no way to programmatically guess where a particular 
kernel image should go to work with the boot loader.

 - Brent

^ permalink raw reply

* Re: [PATCH] kdump: clear and EOI IPI for kexec CPU
From: Paul Mackerras @ 2006-03-27  2:04 UTC (permalink / raw)
  To: Haren Myneni; +Cc: linuxppc-dev, ellerman, Milton Miller, Olaf Hering
In-Reply-To: <44222FA0.90902@us.ibm.com>

Haren Myneni writes:

> Paul, Sorry, Please ignore the previous patch since it has one tab/space 
> issue. Tested this one and kdump-dma-fault-fix.patch on P5, P4 
> (non-lpar), JS21 and JS20.
> 
> Thanks
> Haren
> 
> Some times, the kexec CPU is not reponding to an IPI during kdump boot. 
> It is causing the system in xmon. Noticed on power-4 (non-lpar). This 
> patch clears and EOI IPI for kexec CPU as well before the kdump boot 
> started.

Sorry, that commit message is quite opaque to me.  Could you explain
in more detail what the problem is and how this fixes it?

Thanks,
Paul.

^ permalink raw reply

* Re: make install on ppc
From: Jin Qi Huang @ 2006-03-27  1:42 UTC (permalink / raw)
  To: Hans Fugal; +Cc: linuxppc-dev list, linuxppc-dev-bounces+huangjq=cn.ibm.com
In-Reply-To: <44270B34.3070406@fugal.net>

[-- Attachment #1: Type: text/plain, Size: 1357 bytes --]

I also think the 'make install' is very useful, now on ia32, the 'make 
install' provided by the latest kernel linux-2.6.16 not only create 
initrd, copy vmlinuz and System.map to /boot directory, but also update 
grub, ppc32 does not provide this useful feature, maybe it is a pity!

--
Regards,

MCP Test, Linux Technology Center, China Systems & Technology Lab
China Development Labs, Beijing      Email: huangjq@cn.ibm.com



Hans Fugal <hans@fugal.net> 
Sent by: linuxppc-dev-bounces+huangjq=cn.ibm.com@ozlabs.org
2006-03-27 05:44

To
Hollis Blanchard <hollis@penguinppc.org>
cc
linuxppc-dev list <linuxppc-dev@ozlabs.org>
Subject
Re: make install on ppc






Hollis Blanchard wrote:
> On Mar 21, 2006, at 8:08 AM, Hans Fugal wrote:
> 
>> Is there something that stops us from having a make install target for 
>> ppc?
> 
> Why do you want it, and what would it do? Clearly not many people have 
> needed it so far...

I bet a lot of people have typed it, wished it was there, then worked 
around it. That's what I've been doing for a year now.

It doesn't do much - basically it has the proper dependencies and runs 
installkernel with the appropriate arguments (as indicated by `make 
help`).

Thanks
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[-- Attachment #2: Type: text/html, Size: 2305 bytes --]

^ permalink raw reply

* Re: [PATCH] powerpc: ibmveth: Harden driver initilisation for kexec
From: Michael Ellerman @ 2006-03-27  1:11 UTC (permalink / raw)
  To: jgarzik; +Cc: linuxppc64-dev, netdev
In-Reply-To: <44074A22.8060705@us.ibm.com>

On Thu, 2006-03-02 at 13:40 -0600, Santiago Leon wrote:
> From: Michael Ellerman <michael@ellerman.id.au>
> 
> After a kexec the veth driver will fail when trying to register with the
> Hypervisor because the previous kernel has not unregistered.
> 
> So if the registration fails, we unregister and then try again.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> Acked-by: Anton Blanchard <anton@samba.org>
> Signed-off-by: Santiago Leon <santil@us.ibm.com>
> ---
> 
>   drivers/net/ibmveth.c |   32 ++++++++++++++++++++++++++------
>   1 files changed, 26 insertions(+), 6 deletions(-)

Looks like this hit the floor. Any chance of getting it into to 2.6.17
Jeff? AFAICT it should still apply cleanly.

cheers

-- 
Michael Ellerman
IBM OzLabs

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

^ permalink raw reply

* [PATCH] powerpc: Add oprofile calltrace support to all powerpc cpus
From: Anton Blanchard @ 2006-03-27  1:03 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20060327010045.GD4962@krispykreme>


Add calltrace support for other powerpc cpus. Tested on 7450.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/oprofile/op_model_7450.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_7450.c	2006-01-19 12:29:53.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_7450.c	2006-03-26 23:00:02.000000000 +1100
@@ -176,13 +176,13 @@ static void fsl7450_handle_interrupt(str
 	mtmsr(mfmsr() | MSR_PMM);
 
 	pc = mfspr(SPRN_SIAR);
-	is_kernel = (pc >= KERNELBASE);
+	is_kernel = is_kernel_addr(pc);
 
 	for (i = 0; i < NUM_CTRS; ++i) {
 		val = ctr_read(i);
 		if (val < 0) {
 			if (oprofile_running && ctr[i].enabled) {
-				oprofile_add_pc(pc, is_kernel, i);
+				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				ctr_write(i, reset_value[i]);
 			} else {
 				ctr_write(i, 0);
Index: linux-2.6/arch/powerpc/oprofile/op_model_fsl_booke.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_fsl_booke.c	2005-11-16 03:21:49.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_fsl_booke.c	2006-03-26 22:58:08.000000000 +1100
@@ -154,13 +154,13 @@ static void fsl_booke_handle_interrupt(s
 	mtmsr(mfmsr() | MSR_PMM);
 
 	pc = regs->nip;
-	is_kernel = (pc >= KERNELBASE);
+	is_kernel = is_kernel_addr(pc);
 
 	for (i = 0; i < num_counters; ++i) {
 		val = ctr_read(i);
 		if (val < 0) {
 			if (oprofile_running && ctr[i].enabled) {
-				oprofile_add_pc(pc, is_kernel, i);
+				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				ctr_write(i, reset_value[i]);
 			} else {
 				ctr_write(i, 0);
Index: linux-2.6/arch/powerpc/oprofile/op_model_rs64.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_rs64.c	2006-01-19 12:29:53.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_rs64.c	2006-03-26 23:01:55.000000000 +1100
@@ -175,10 +175,13 @@ static void rs64_handle_interrupt(struct
 				  struct op_counter_config *ctr)
 {
 	unsigned int mmcr0;
+	int is_kernel;
 	int val;
 	int i;
 	unsigned long pc = mfspr(SPRN_SIAR);
 
+	is_kernel = is_kernel_addr(pc);
+
 	/* set the PMM bit (see comment below) */
 	mtmsrd(mfmsr() | MSR_PMM);
 
@@ -186,7 +189,7 @@ static void rs64_handle_interrupt(struct
 		val = ctr_read(i);
 		if (val < 0) {
 			if (ctr[i].enabled) {
-				oprofile_add_pc(pc, is_kernel_addr(pc), i);
+				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				ctr_write(i, reset_value[i]);
 			} else {
 				ctr_write(i, 0);

^ permalink raw reply

* [PATCH] powerpc: Remove oprofile spinlock backtrace code
From: Anton Blanchard @ 2006-03-27  1:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20060327005701.GC4962@krispykreme>


Remove oprofile spinlock backtrace code now we have proper calltrace
support. Also make MMCRA sihv and sipr bits a variable since they may
change in future cpus. Finally, MMCRA should be a 64bit quantity.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/arch/powerpc/oprofile/op_model_power4.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_power4.c	2006-03-26 17:55:19.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/op_model_power4.c	2006-03-26 17:55:19.000000000 +1100
@@ -25,18 +25,14 @@ static unsigned long reset_value[OP_MAX_
 
 static int oprofile_running;
 static int mmcra_has_sihv;
+/* Unfortunately these bits vary between CPUs */
+static unsigned long mmcra_sihv = MMCRA_SIHV;
+static unsigned long mmcra_sipr = MMCRA_SIPR;
 
 /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
 static u32 mmcr0_val;
 static u64 mmcr1_val;
-static u32 mmcra_val;
-
-/*
- * Since we do not have an NMI, backtracing through spinlocks is
- * only a best guess. In light of this, allow it to be disabled at
- * runtime.
- */
-static int backtrace_spinlocks;
+static u64 mmcra_val;
 
 static void power4_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
@@ -63,8 +59,6 @@ static void power4_reg_setup(struct op_c
 	mmcr1_val = sys->mmcr1;
 	mmcra_val = sys->mmcra;
 
-	backtrace_spinlocks = sys->backtrace_spinlocks;
-
 	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
 		reset_value[i] = 0x80000000UL - ctr[i].count;
 
@@ -197,25 +191,6 @@ static void __attribute_used__ kernel_un
 {
 }
 
-static unsigned long check_spinlock_pc(struct pt_regs *regs,
-				       unsigned long profile_pc)
-{
-	unsigned long pc = instruction_pointer(regs);
-
-	/*
-	 * If both the SIAR (sampled instruction) and the perfmon exception
-	 * occurred in a spinlock region then we account the sample to the
-	 * calling function. This isnt 100% correct, we really need soft
-	 * IRQ disable so we always get the perfmon exception at the
-	 * point at which the SIAR is set.
-	 */
-	if (backtrace_spinlocks && in_lock_functions(pc) &&
-			in_lock_functions(profile_pc))
-		return regs->link;
-	else
-		return profile_pc;
-}
-
 /*
  * On GQ and newer the MMCRA stores the HV and PR bits at the time
  * the SIAR was sampled. We use that to work out if the SIAR was sampled in
@@ -228,17 +203,17 @@ static unsigned long get_pc(struct pt_re
 
 	/* Cant do much about it */
 	if (!mmcra_has_sihv)
-		return check_spinlock_pc(regs, pc);
+		return pc;
 
 	mmcra = mfspr(SPRN_MMCRA);
 
 	/* Were we in the hypervisor? */
-	if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & MMCRA_SIHV))
+	if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv))
 		/* function descriptor madness */
 		return *((unsigned long *)hypervisor_bucket);
 
 	/* We were in userspace, nothing to do */
-	if (mmcra & MMCRA_SIPR)
+	if (mmcra & mmcra_sipr)
 		return pc;
 
 #ifdef CONFIG_PPC_RTAS
@@ -257,7 +232,7 @@ static unsigned long get_pc(struct pt_re
 		/* function descriptor madness */
 		return *((unsigned long *)kernel_unknown_bucket);
 
-	return check_spinlock_pc(regs, pc);
+	return pc;
 }
 
 static int get_kernel(unsigned long pc)
@@ -268,7 +243,7 @@ static int get_kernel(unsigned long pc)
 		is_kernel = is_kernel_addr(pc);
 	} else {
 		unsigned long mmcra = mfspr(SPRN_MMCRA);
-		is_kernel = ((mmcra & MMCRA_SIPR) == 0);
+		is_kernel = ((mmcra & mmcra_sipr) == 0);
 	}
 
 	return is_kernel;
Index: linux-2.6/arch/powerpc/oprofile/common.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/common.c	2006-03-26 17:55:19.000000000 +1100
+++ linux-2.6/arch/powerpc/oprofile/common.c	2006-03-26 17:55:19.000000000 +1100
@@ -117,17 +117,10 @@ static int op_powerpc_create_files(struc
 
 	oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
 	oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-#ifdef CONFIG_PPC64
-	oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
-				&sys.backtrace_spinlocks);
-#endif
 
 	/* Default to tracing both kernel and user */
 	sys.enable_kernel = 1;
 	sys.enable_user = 1;
-#ifdef CONFIG_PPC64
-	sys.backtrace_spinlocks = 0;
-#endif
 
 	return 0;
 }
Index: linux-2.6/include/asm-powerpc/oprofile_impl.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/oprofile_impl.h	2006-03-26 17:55:19.000000000 +1100
+++ linux-2.6/include/asm-powerpc/oprofile_impl.h	2006-03-26 17:55:19.000000000 +1100
@@ -35,9 +35,6 @@ struct op_system_config {
 #endif
 	unsigned long enable_kernel;
 	unsigned long enable_user;
-#ifdef CONFIG_PPC64
-	unsigned long backtrace_spinlocks;
-#endif
 };
 
 /* Per-arch configuration */

^ permalink raw reply

* [PATCH] powerpc: Add oprofile calltrace support
From: Anton Blanchard @ 2006-03-27  0:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: bcr6, paulus
In-Reply-To: <20060327004618.GB4962@krispykreme>


From: Brian Rogan <bcr6@cornell.edu>

Add oprofile calltrace support to powerpc. Disable spinlock backtracing
now we can use calltrace info.

(Updated to work on both 32bit and 64bit by me).

Signed-off-by: Anton Blanchard <anton@samba.org>
---

This patch depends on a patch currently in -mm:

http://marc.theaimsgroup.com/?l=linux-kernel&m=114333745914386&w=2

Index: build/arch/powerpc/oprofile/backtrace.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ build/arch/powerpc/oprofile/backtrace.c	2006-03-26 15:13:57.000000000 +1000
@@ -0,0 +1,126 @@
+/**
+ * Copyright (C) 2005 Brian Rogan <bcr6@cornell.edu>, IBM
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+**/
+
+#include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+#define STACK_SP(STACK)		*(STACK)
+
+#define STACK_LR64(STACK)	*((unsigned long *)(STACK) + 2)
+#define STACK_LR32(STACK)	*((unsigned int *)(STACK) + 1)
+
+#ifdef CONFIG_PPC64
+#define STACK_LR(STACK)		STACK_LR64(STACK)
+#else
+#define STACK_LR(STACK)		STACK_LR32(STACK)
+#endif
+
+static unsigned int user_getsp32(unsigned int sp, int is_first)
+{
+	unsigned int stack_frame[2];
+
+	if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+		return 0;
+
+	/*
+	 * The most likely reason for this is that we returned -EFAULT,
+	 * which means that we've done all that we can do from
+	 * interrupt context.
+	 */
+	if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
+					sizeof(stack_frame)))
+		return 0;
+
+	if (!is_first)
+		oprofile_add_trace(STACK_LR32(stack_frame));
+
+	/*
+	 * We do not enforce increasing stack addresses here because
+	 * we may transition to a different stack, eg a signal handler.
+	 */
+	return STACK_SP(stack_frame);
+}
+
+#ifdef CONFIG_PPC64
+static unsigned long user_getsp64(unsigned long sp, int is_first)
+{
+	unsigned long stack_frame[3];
+
+	if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
+		return 0;
+
+	if (__copy_from_user_inatomic(stack_frame, (void *)sp,
+					sizeof(stack_frame)))
+		return 0;
+
+	if (!is_first)
+		oprofile_add_trace(STACK_LR64(stack_frame));
+
+	return STACK_SP(stack_frame);
+}
+#endif
+
+static unsigned long kernel_getsp(unsigned long sp, int is_first)
+{
+	unsigned long *stack_frame = (unsigned long *)sp;
+
+	if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
+		return 0;
+
+	if (!is_first)
+		oprofile_add_trace(STACK_LR(stack_frame));
+
+	/*
+	 * We do not enforce increasing stack addresses here because
+	 * we might be transitioning from an interrupt stack to a kernel
+	 * stack. validate_sp() is designed to understand this, so just
+	 * use it.
+	 */
+	return STACK_SP(stack_frame);
+}
+
+void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	unsigned long sp = regs->gpr[1];
+	int first_frame = 1;
+
+	/* We ditch the top stackframe so need to loop through an extra time */
+	depth += 1;
+
+	if (!user_mode(regs)) {
+		while (depth--) {
+			sp = kernel_getsp(sp, first_frame);
+			if (!sp)
+				break;
+			first_frame = 0;
+		}
+	} else {
+#ifdef CONFIG_PPC64
+		if (!test_thread_flag(TIF_32BIT)) {
+			while (depth--) {
+				sp = user_getsp64(sp, first_frame);
+				if (!sp)
+					break;
+				first_frame = 0;
+			}
+
+			return;
+		}
+#endif
+
+		while (depth--) {
+			sp = user_getsp32(sp, first_frame);
+			if (!sp)
+				break;
+			first_frame = 0;
+		}
+	}
+}
Index: build/arch/powerpc/oprofile/common.c
===================================================================
--- build.orig/arch/powerpc/oprofile/common.c	2006-01-16 00:05:48.000000000 +1100
+++ build/arch/powerpc/oprofile/common.c	2006-03-26 13:09:34.000000000 +1000
@@ -126,8 +126,7 @@ static int op_powerpc_create_files(struc
 	sys.enable_kernel = 1;
 	sys.enable_user = 1;
 #ifdef CONFIG_PPC64
-	/* Turn on backtracing through spinlocks by default */
-	sys.backtrace_spinlocks = 1;
+	sys.backtrace_spinlocks = 0;
 #endif
 
 	return 0;
@@ -168,6 +167,7 @@ int __init oprofile_arch_init(struct opr
 	ops->shutdown = op_powerpc_shutdown;
 	ops->start = op_powerpc_start;
 	ops->stop = op_powerpc_stop;
+	ops->backtrace = op_powerpc_backtrace;
 
 	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
 	       ops->cpu_type);
Index: build/arch/powerpc/oprofile/Makefile
===================================================================
--- build.orig/arch/powerpc/oprofile/Makefile	2006-03-26 10:40:14.000000000 +1000
+++ build/arch/powerpc/oprofile/Makefile	2006-03-26 13:09:34.000000000 +1000
@@ -10,7 +10,7 @@ DRIVER_OBJS := $(addprefix ../../../driv
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-oprofile-y := $(DRIVER_OBJS) common.o
+oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
 oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
 oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
 oprofile-$(CONFIG_PPC32) += op_model_7450.o
Index: build/arch/powerpc/oprofile/op_model_power4.c
===================================================================
--- build.orig/arch/powerpc/oprofile/op_model_power4.c	2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/oprofile/op_model_power4.c	2006-03-26 13:09:34.000000000 +1000
@@ -293,7 +293,7 @@ static void power4_handle_interrupt(stru
 		val = ctr_read(i);
 		if (val < 0) {
 			if (oprofile_running && ctr[i].enabled) {
-				oprofile_add_pc(pc, is_kernel, i);
+				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				ctr_write(i, reset_value[i]);
 			} else {
 				ctr_write(i, 0);
Index: build/include/asm-powerpc/oprofile_impl.h
===================================================================
--- build.orig/include/asm-powerpc/oprofile_impl.h	2006-03-26 12:48:01.000000000 +1000
+++ build/include/asm-powerpc/oprofile_impl.h	2006-03-26 13:09:34.000000000 +1000
@@ -126,5 +126,7 @@ static inline void ctr_write(unsigned in
 }
 #endif /* !CONFIG_FSL_BOOKE */
 
+extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_OPROFILE_IMPL_H */

^ permalink raw reply

* [PATCH] powerpc: export validate_sp for oprofile calltrace
From: Anton Blanchard @ 2006-03-27  0:46 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20060327002329.GA4962@krispykreme>


Export validate_sp so we can use it in the oprofile calltrace code.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: build/arch/powerpc/kernel/process.c
===================================================================
--- build.orig/arch/powerpc/kernel/process.c	2006-03-26 10:39:29.000000000 +1000
+++ build/arch/powerpc/kernel/process.c	2006-03-26 12:48:03.000000000 +1000
@@ -767,7 +767,7 @@ out:
 	return error;
 }
 
-static int validate_sp(unsigned long sp, struct task_struct *p,
+int validate_sp(unsigned long sp, struct task_struct *p,
 		       unsigned long nbytes)
 {
 	unsigned long stack_page = (unsigned long)task_stack_page(p);
@@ -805,6 +805,8 @@ static int validate_sp(unsigned long sp,
 #define FRAME_MARKER	2
 #endif
 
+EXPORT_SYMBOL(validate_sp);
+
 unsigned long get_wchan(struct task_struct *p)
 {
 	unsigned long ip, sp;
Index: build/include/asm-powerpc/processor.h
===================================================================
--- build.orig/include/asm-powerpc/processor.h	2006-03-24 15:51:22.000000000 +1100
+++ build/include/asm-powerpc/processor.h	2006-03-26 12:48:03.000000000 +1000
@@ -251,6 +251,10 @@ static inline unsigned long __pack_fe01(
 #define cpu_relax()	barrier()
 #endif
 
+/* Check that a certain kernel stack pointer is valid in task_struct p */
+int validate_sp(unsigned long sp, struct task_struct *p,
+                       unsigned long nbytes);
+
 /*
  * Prefetch macros.
  */

^ permalink raw reply

* [PATCH] powerpc: Remove some ifdefs in oprofile_impl.h
From: Anton Blanchard @ 2006-03-27  0:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus


- No one uses op_counter_config.valid, so remove it
- No need to ifdef around function protypes.

Signed-off-by: Anton Blanchard <anton@samba.org>
---

Index: linux-2.6/include/asm-powerpc/oprofile_impl.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/oprofile_impl.h	2006-03-26 12:17:23.000000000 +1100
+++ linux-2.6/include/asm-powerpc/oprofile_impl.h	2006-03-26 12:21:13.000000000 +1100
@@ -17,9 +17,6 @@
 
 /* Per-counter configuration as set via oprofilefs.  */
 struct op_counter_config {
-#ifdef __powerpc64__
-	unsigned long valid;
-#endif
 	unsigned long enabled;
 	unsigned long event;
 	unsigned long count;
@@ -56,17 +53,12 @@ struct op_powerpc_model {
 	int num_counters;
 };
 
-#ifdef CONFIG_FSL_BOOKE
 extern struct op_powerpc_model op_model_fsl_booke;
-#else /* Otherwise, it's classic */
-
-#ifdef CONFIG_PPC64
 extern struct op_powerpc_model op_model_rs64;
 extern struct op_powerpc_model op_model_power4;
-
-#else /* Otherwise, CONFIG_PPC32 */
 extern struct op_powerpc_model op_model_7450;
-#endif
+
+#ifndef CONFIG_FSL_BOOKE
 
 /* All the classic PPC parts use these */
 static inline unsigned int ctr_read(unsigned int i)

^ permalink raw reply

* Re: [PATCH 0/4] MPC52xx updates : lite5200b + ide support
From: Paul Mackerras @ 2006-03-26 22:20 UTC (permalink / raw)
  To: Sylvain Munaut; +Cc: Linux PPC embedded
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>

Sylvain Munaut writes:

> This set of updates mainly adds support for the new lite5200B
> devboard from Freescale and support for IDE.
> 
> Theses have been posted on the ppc-embedded mailing list some
> time ago, they've been tested and reported working by a few people,
> so Paul it'd be nice to get those merged upstream. If you were
> not the one to cc about this, let me know, I'll forward those
> to Andrew.

I'll handle patches 1-3, but you will need to send the IDE patch to
the IDE maintainer, Bartlomiej Zolnierkiewicz
<B.Zolnierkiewicz@elka.pw.edu.pl>.

Paul.

^ permalink raw reply

* Re: make install on ppc
From: Hans Fugal @ 2006-03-26 21:44 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: linuxppc-dev list
In-Reply-To: <ce3dc94b4e52e43d812f3783b6fc8b42@penguinppc.org>

Hollis Blanchard wrote:
> On Mar 21, 2006, at 8:08 AM, Hans Fugal wrote:
> 
>> Is there something that stops us from having a make install target for 
>> ppc?
> 
> Why do you want it, and what would it do? Clearly not many people have 
> needed it so far...

I bet a lot of people have typed it, wished it was there, then worked 
around it. That's what I've been doing for a year now.

It doesn't do much - basically it has the proper dependencies and runs 
installkernel with the appropriate arguments (as indicated by `make help`).

Thanks

^ permalink raw reply

* Re: make install on ppc
From: Arnd Bergmann @ 2006-03-26 20:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Hans Fugal
In-Reply-To: <ce3dc94b4e52e43d812f3783b6fc8b42@penguinppc.org>

Am Sunday 26 March 2006 21:26 schrieb Hollis Blanchard:
> On Mar 21, 2006, at 8:08 AM, Hans Fugal wrote:
> > Is there something that stops us from having a make install target for
> > ppc?
>
> Why do you want it, and what would it do? Clearly not many people have
> needed it so far...

I've missed it a few times, typing 'make install' by habit, but thought
it was a bug in my own setup, so I didn't bother looking what was
missing.

	Arnd <><

^ permalink raw reply

* Re: make install on ppc
From: Hollis Blanchard @ 2006-03-26 19:26 UTC (permalink / raw)
  To: Hans Fugal; +Cc: linuxppc-dev list
In-Reply-To: <442008EE.6040808@fugal.net>

On Mar 21, 2006, at 8:08 AM, Hans Fugal wrote:

> Is there something that stops us from having a make install target for 
> ppc?

Why do you want it, and what would it do? Clearly not many people have 
needed it so far...

-Hollis

^ permalink raw reply

* [PATCH 4/4] ppc32/ide: Add support for MPC52xx on-chip ATA controller
From: Sylvain Munaut @ 2006-03-26 11:38 UTC (permalink / raw)
  To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>

ppc32/ide: Add support for MPC52xx on-chip ATA controller

This patch adds initial support for Freescale MPC52xx on-chip ATA
controller. It's currently PIO-mode only and all the erratas are
not handled since some of them requires hw tricks ...

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit f3180ffadd5dddcfa9d11da4f7637e3e907e6aaa
tree d9bf294057a0dcdda25ba6c6ea3fcc9748d87e93
parent 67015426ff51ba857b7678a993f4ffd6def1941e
author Sylvain Munaut <tnt@246tNt.com> 1139147442 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143312600 +0100

 drivers/ide/Kconfig                |    4 
 drivers/ide/Makefile               |    1 
 drivers/ide/ppc/mpc52xx_ide.c      |  420 +++++++++++++++++++++++++++++++++++++
 drivers/ide/ppc/mpc52xx_ide.h      |  129 +++++++++++
 drivers/ide/ppc/mpc52xx_ide_iops.c |  151 +++++++++++++
 include/linux/ide.h                |    2 
 6 files changed, 706 insertions(+), 1 deletion(-)

---
f3180ffadd5dddcfa9d11da4f7637e3e907e6aaa
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index d633081..3a10fec 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -962,6 +962,10 @@ config IDE_EXT_DIRECT
 
 endchoice
 
+config BLK_DEV_MPC52xx_IDE
+	tristate "MPC52xx Builtin IDE support"
+	depends on PPC_MPC52xx && IDE=y
+
 # no isa -> no vlb
 config IDE_CHIPSETS
 	bool "Other IDE chipset support"
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 569fae7..fcca1f3 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -34,6 +34,7 @@ ide-core-$(CONFIG_BLK_DEV_MAC_IDE)	+= le
 ide-core-$(CONFIG_BLK_DEV_Q40IDE)	+= legacy/q40ide.o
 
 # built-in only drivers from ppc/
+ide-core-$(CONFIG_BLK_DEV_MPC52xx_IDE)	+= ppc/mpc52xx_ide.o ppc/mpc52xx_ide_iops.o
 ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ppc/mpc8xx.o
 ide-core-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ppc/pmac.o
 
diff --git a/drivers/ide/ppc/mpc52xx_ide.c b/drivers/ide/ppc/mpc52xx_ide.c
new file mode 100644
index 0000000..5970f7b
--- /dev/null
+++ b/drivers/ide/ppc/mpc52xx_ide.c
@@ -0,0 +1,420 @@
+/*
+ * drivers/ide/ppc/mpc52xx_ide.h
+ *
+ * Driver for the Freescale MPC52xx on-chip IDE interface
+ *
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#undef REALLY_SLOW_IO	/* most systems can safely undef this */
+
+#include <linux/config.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+
+#include <asm/io.h>
+#include <asm/ppcboot.h>
+
+#include "mpc52xx_ide.h"
+
+
+
+/* Private structures used by the driver */
+struct mpc52xx_ata_timings {
+	u32 pio1;
+	u32 pio2;
+	u32 mdma1;
+	u32 mdma2;
+	u32 udma1;
+	u32 udma2;
+	u32 udma3;
+	u32 udma4;
+	u32 udma5;
+	int using_udma;
+};
+
+struct mpc52xx_ide_priv {
+	unsigned int ipb_period;	/* in ps */
+	struct mpc52xx_ata __iomem *ata_regs;
+	struct mpc52xx_ata_timings  timings[2];
+};
+
+/* ATAPI-4 PIO specs (arranged for the 5200, cfr User Manual) */
+/* numbers in ns, extrapolation done by code */
+static int ataspec_t0[5]    = {600, 383, 240, 180, 120};
+static int ataspec_t1[5]    = { 70,  50,  30,  30,  25};
+static int ataspec_t2_8[5]  = {290, 290, 290,  80,  70};
+static int ataspec_t2_16[5] = {165, 125, 100,  80,  70};
+static int ataspec_t2i[5]   = {  0,   0,   0,  70,  25};
+static int ataspec_t4[5]    = { 30,  20,  15,  10,  10};
+static int ataspec_ta[5]    = { 35,  35,  35,  35,  35};
+
+/* Helpers to compute timing parameters */
+#define CALC_CLK_VALUE_UP(c,v) (((v) + c - 1) / c)
+
+
+/* ======================================================================== */
+/* IDE Driver & Aux functions                                               */
+/* ======================================================================== */
+
+static void
+mpc52xx_ide_apply_timing(
+	struct mpc52xx_ata __iomem *regs, struct mpc52xx_ata_timings *timing)
+{
+	out_be32(&regs->pio1,  timing->pio1);
+	out_be32(&regs->pio2,  timing->pio2);
+	out_be32(&regs->mdma1, timing->mdma1);
+	out_be32(&regs->mdma2, timing->mdma2);
+	out_be32(&regs->udma1, timing->udma1);
+	out_be32(&regs->udma2, timing->udma2);
+	out_be32(&regs->udma3, timing->udma3);
+	out_be32(&regs->udma4, timing->udma4);
+	out_be32(&regs->udma5, timing->udma5);
+}
+
+static void
+mpc52xx_ide_compute_pio_timing(
+	struct mpc52xx_ata_timings *timing, unsigned int ipb_period, u8 pio)
+{
+	u32 t0, t2_8, t2_16, t2i, t4, t1, ta;
+
+		/* We add 1 as a 'margin' */
+	t0    = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_t0[pio]);
+	t2_8  = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_t2_8[pio]);
+	t2_16 = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_t2_16[pio]);
+	t2i   = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_t2i[pio]);
+	t4    = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_t4[pio]);
+	t1    = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_t1[pio]);
+	ta    = 1 + CALC_CLK_VALUE_UP(ipb_period, 1000*ataspec_ta[pio]);
+
+	timing->pio1 = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8) | (t2i);
+	timing->pio2 = (t4 << 24) | (t1 << 16) | (ta << 8);
+}
+
+
+static void
+mpc52xx_ide_tuneproc(ide_drive_t *drive, u8 pio)
+{
+	struct mpc52xx_ide_priv *priv = drive->hwif->hwif_data;
+	struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+	int w = drive->select.b.unit & 0x01;
+
+	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
+
+	printk("%s: Setting PIO %d timings\n", drive->name, pio);
+
+	mpc52xx_ide_compute_pio_timing(&priv->timings[w], priv->ipb_period, pio);
+
+	if (drive->select.all == HWIF(drive)->INB(IDE_SELECT_REG))
+		mpc52xx_ide_apply_timing(regs, &priv->timings[w]);
+
+		/* Should we do it here or only in speedproc ? */
+	ide_config_drive_speed(drive, pio + XFER_PIO_0);
+}
+
+static int
+mpc52xx_ide_speedproc(ide_drive_t *drive, u8 speed)
+{
+	/* Configure PIO Mode */
+	if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+		mpc52xx_ide_tuneproc(drive, speed - XFER_PIO_0);
+		return 0;
+	}
+
+	/* DMA settings currently unsupported */
+	printk(KERN_ERR
+		"mpc52xx-ide: speedproc called with unsupported mode %d\n",
+		speed);
+
+	return 1;
+}
+
+static void
+mpc52xx_ide_selectproc(ide_drive_t *drive)
+{
+	/* Change the PIO timings to the ones of the
+	   currently selected drive */
+	struct mpc52xx_ide_priv *priv = drive->hwif->hwif_data;
+	struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+
+	mpc52xx_ide_apply_timing(regs,
+		&priv->timings[drive->select.b.unit & 0x01]);
+}
+
+
+static int
+mpc52xx_ide_setup(
+	struct mpc52xx_ata __iomem *regs, struct mpc52xx_ide_priv *priv)
+{
+	/* Vars */
+	extern bd_t __res;
+	bd_t *bd = (bd_t *)&__res;
+	int tslot;
+
+	/* All sample code do this */
+	out_be32(&regs->share_cnt, 0);
+
+	/* Configure & Reset host */
+	out_be32(&regs->config,
+		MPC52xx_ATA_HOSTCONF_IE |
+		MPC52xx_ATA_HOSTCONF_IORDY |
+		MPC52xx_ATA_HOSTCONF_SMR |
+		MPC52xx_ATA_HOSTCONF_FR);
+	udelay(10);
+	out_be32(&regs->config,
+		MPC52xx_ATA_HOSTCONF_IE |
+		MPC52xx_ATA_HOSTCONF_IORDY);
+
+	/* Get IPB bus period */
+	priv->ipb_period = 1000000000 / (bd->bi_ipbfreq/1000);
+
+	/* Try to set the time slot to around 1us = 1000000 ps */
+	tslot = CALC_CLK_VALUE_UP(priv->ipb_period, 1000000);
+	out_be32(&regs->share_cnt, tslot << 16);
+
+	/* Init imings to PIO0 (safest) */
+	memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
+
+	mpc52xx_ide_compute_pio_timing(&priv->timings[0], priv->ipb_period, 0);
+	mpc52xx_ide_compute_pio_timing(&priv->timings[1], priv->ipb_period, 0);
+
+	mpc52xx_ide_apply_timing(regs, &priv->timings[0]);
+
+	return 0;
+}
+
+static void
+mpc52xx_ide_setup_hwif_ports(hw_regs_t *hw, struct mpc52xx_ata __iomem *regs)
+{
+	/* It's MMIO and we handle all the io ops ourself, */
+	/* so theses address are really virtual addresses  */
+	hw->io_ports[IDE_DATA_OFFSET]    = (unsigned long) &regs->tf_data;
+	hw->io_ports[IDE_ERROR_OFFSET]   = (unsigned long) &regs->tf_features;
+	hw->io_ports[IDE_NSECTOR_OFFSET] = (unsigned long) &regs->tf_sec_count;
+	hw->io_ports[IDE_SECTOR_OFFSET]  = (unsigned long) &regs->tf_sec_num;
+	hw->io_ports[IDE_LCYL_OFFSET]    = (unsigned long) &regs->tf_cyl_low;
+	hw->io_ports[IDE_HCYL_OFFSET]    = (unsigned long) &regs->tf_cyl_high;
+	hw->io_ports[IDE_SELECT_OFFSET]  = (unsigned long) &regs->tf_dev_head;
+	hw->io_ports[IDE_STATUS_OFFSET]  = (unsigned long) &regs->tf_command;
+	hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long) &regs->tf_control;
+}
+
+
+/* ======================================================================== */
+/* Platform Driver                                                          */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_ide_probe(struct platform_device *dev)
+{
+	/* Vars */
+	ide_hwif_t *hwif;
+	struct mpc52xx_ide_priv *priv;
+	struct mpc52xx_gpio __iomem *gpio_regs = NULL;
+	struct mpc52xx_ata __iomem *ata_regs = NULL;
+	int ata_irq;
+	struct resource *res_mem;
+	u32 reg;
+	int i, rv;
+
+	/* Get an empty slot */
+	for (i=0; i<MAX_HWIFS && ide_hwifs[i].io_ports[IDE_DATA_OFFSET]; i++);
+	if (i >= MAX_HWIFS) {
+		printk(KERN_ERR "mpc52xx-ide: No free hwif slot !\n");
+		return -ENOMEM;
+	}
+
+	hwif = &ide_hwifs[i];
+
+	/* Check port muxing for compatibility */
+	gpio_regs = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
+	if (!gpio_regs) {
+		printk(KERN_ERR
+			"mpc52xx-ide: Unable to ioremap MPC52xx_GPIO zone\n");
+		return -ENOMEM;
+	}
+
+	reg = in_be32(&gpio_regs->port_config);
+	iounmap(gpio_regs);
+
+	if (!(reg & 0x03000000ul)) {
+		printk(KERN_ERR
+			"mpc52xx-ide: Invalid port config, no ATA CS !\n");
+		return -ENODEV;
+	}
+
+	/* Get the resources of this device */
+	ata_irq = platform_get_irq(dev, 0);
+	res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
+	if (ata_irq<0 || res_mem==NULL) {
+		printk(KERN_ERR "mpc52xx-ide: Invalid resource set !\n");
+		return -EINVAL;
+	}
+
+	if (!request_mem_region(res_mem->start, sizeof(struct mpc52xx_ata),
+				"mpc52xx-ide")) {
+		printk(KERN_ERR "mpc52xx-ide: Memory zone unavailable !\n");
+		return -EBUSY;
+	}
+
+	ata_regs = ioremap(res_mem->start, sizeof(struct mpc52xx_ata));
+	if (!ata_regs) {
+		printk(KERN_ERR
+			"mpc52xx-ide: Unable to ioremap ATA registers\n");
+		rv = -ENOMEM;
+		goto error;
+	}
+
+	/* Setup private structure */
+	priv = kmalloc(sizeof(struct mpc52xx_ide_priv), GFP_ATOMIC);
+	if (!priv) {
+		printk(KERN_ERR
+			"mpc52xx-ide: Can't allocate private structure !\n");
+		rv = -ENOMEM;
+		goto error;
+	}
+
+	priv->ata_regs = ata_regs;
+
+	/* Setup the ATA controller */
+	rv = mpc52xx_ide_setup(ata_regs, priv);
+	if (rv) {
+		printk(KERN_ERR "mpc52xx-ide: Controller setup failed !\n");
+		goto error;
+	}
+
+	/* Setup the hwif structure */
+	hwif->irq = ata_irq;
+	hwif->mmio = 2;
+	mpc52xx_ide_setup_hwif_iops(hwif);
+	mpc52xx_ide_setup_hwif_ports(&hwif->hw, ata_regs);
+	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+
+	hwif->atapi_dma = 0;
+	hwif->ultra_mask = 0x00;
+	hwif->mwdma_mask = 0x00;
+	hwif->swdma_mask = 0x00;
+	hwif->chipset = ide_mpc52xx;
+	hwif->tuneproc = mpc52xx_ide_tuneproc;
+	hwif->speedproc = mpc52xx_ide_speedproc;
+	hwif->selectproc = mpc52xx_ide_selectproc;
+	hwif->noprobe = 0;
+	hwif->hold = 1;
+	hwif->autodma = 0;
+	hwif->udma_four = 0;
+	hwif->no_lba48 = 1;	/* FIXME ? Did some one test that ? */
+	hwif->no_lba48_dma = 1;
+
+	hwif->drives[0].unmask = 1;
+	hwif->drives[0].autotune = 0; /* default */
+	hwif->drives[0].autodma = hwif->autodma;
+	hwif->drives[0].no_io_32bit = 1;	/* Anyone tried ? */
+
+	hwif->drives[1].unmask = 1;
+	hwif->drives[1].autotune = 0; /* default */
+	hwif->drives[1].autodma = hwif->autodma;
+	hwif->drives[1].no_io_32bit = 1;	/* Anyone tried ? */
+
+	hwif->hwif_data = priv;
+	platform_set_drvdata(dev, hwif);
+
+	/* Lauch probe */
+	probe_hwif_init(hwif);
+
+	/* We're good ! */
+	printk(KERN_INFO
+	  "mpc52xx-ide: Setup successful for %s (mem=%08lx-%08lx irq=%d)\n",
+	  hwif->name, res_mem->start, res_mem->end, ata_irq);
+
+	return 0;
+
+
+	/* Error path */
+error:
+	if (ata_regs)
+		iounmap(ata_regs);
+
+	release_mem_region(res_mem->start, sizeof(struct mpc52xx_ata));
+
+	return rv;
+}
+
+static int
+mpc52xx_ide_remove(struct platform_device *dev)
+{
+	ide_hwif_t *hwif = platform_get_drvdata(dev);
+	struct mpc52xx_ide_priv *priv = hwif->hwif_data;
+	struct resource *res_mem;
+
+	ide_unregister(hwif - ide_hwifs);
+
+	iounmap(priv->ata_regs);
+
+	res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	release_mem_region(res_mem->start, sizeof(struct mpc52xx_ata));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+mpc52xx_ide_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return 0;	/* FIXME : What to do here ? */
+}
+
+static int
+mpc52xx_ide_resume(struct platform_device *dev)
+{
+	return 0;	/* FIXME : What to do here ? */
+}
+#endif
+
+static struct platform_driver mpc52xx_ide_platform_driver = {
+	.probe		= mpc52xx_ide_probe,
+	.remove		= mpc52xx_ide_remove,
+#ifdef CONFIG_PM
+	.suspend	= mpc52xx_ide_suspend,
+	.resume		= mpc52xx_ide_resume,
+#endif
+	.driver		= {
+		.name	= "mpc52xx-ata",
+	},
+};
+
+
+/* ======================================================================== */
+/* Module                                                                   */
+/* ======================================================================== */
+
+static int __init
+mpc52xx_ide_init(void)
+{
+	printk(KERN_INFO "ide: MPC52xx IDE/ATA driver\n");
+	return platform_driver_register(&mpc52xx_ide_platform_driver);
+}
+
+static void __exit
+mpc52xx_ide_exit(void)
+{
+	platform_driver_unregister(&mpc52xx_ide_platform_driver);
+}
+
+
+module_init(mpc52xx_ide_init);
+module_exit(mpc52xx_ide_exit);
+
+MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
+MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/ide/ppc/mpc52xx_ide.h b/drivers/ide/ppc/mpc52xx_ide.h
new file mode 100644
index 0000000..e2490a8
--- /dev/null
+++ b/drivers/ide/ppc/mpc52xx_ide.h
@@ -0,0 +1,129 @@
+/*
+ * drivers/ide/ppc/mpc52xx_ide.h
+ *
+ * Definitions for the Freescale MPC52xx on-chip IDE interface
+ *
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __MPC52xx_IDE_H__
+#define __MPC52xx_IDE_H__
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <asm/types.h>
+#include <asm/io.h>
+
+
+
+/* Bit definitions inside the registers */
+
+#define MPC52xx_ATA_HOSTCONF_SMR	0x80000000UL /* State machine reset */
+#define MPC52xx_ATA_HOSTCONF_FR		0x40000000UL /* FIFO Reset */
+#define MPC52xx_ATA_HOSTCONF_IE		0x02000000UL /* Enable interrupt in PIO */
+#define MPC52xx_ATA_HOSTCONF_IORDY	0x01000000UL /* Drive supports IORDY protocol */
+
+#define MPC52xx_ATA_HOSTSTAT_TIP	0x80000000UL /* Transaction in progress */
+#define MPC52xx_ATA_HOSTSTAT_UREP	0x40000000UL /* UDMA Read Extended Pause */
+#define MPC52xx_ATA_HOSTSTAT_RERR	0x02000000UL /* Read Error */
+#define MPC52xx_ATA_HOSTSTAT_WERR	0x01000000UL /* Write Error */
+
+#define MPC52xx_ATA_FIFOSTAT_EMPTY	0x01 /* FIFO Empty */
+
+#define MPC52xx_ATA_DMAMODE_WRITE	0x01 /* Write DMA */
+#define MPC52xx_ATA_DMAMODE_READ	0x02 /* Read DMA */
+#define MPC52xx_ATA_DMAMODE_UDMA	0x04 /* UDMA enabled */
+#define MPC52xx_ATA_DMAMODE_IE		0x08 /* Enable drive interrupt to CPU in DMA mode */
+#define MPC52xx_ATA_DMAMODE_FE		0x10 /* FIFO Flush enable in Rx mode */
+#define MPC52xx_ATA_DMAMODE_FR		0x20 /* FIFO Reset */
+#define MPC52xx_ATA_DMAMODE_HUT		0x40 /* Host UDMA burst terminate */
+
+
+/* Structure of the hardware registers */
+struct mpc52xx_ata {
+
+	/* Host interface registers */
+	u32 config;		/* ATA + 0x00 Host configuration */
+	u32 host_status;	/* ATA + 0x04 Host controller status */
+	u32 pio1;		/* ATA + 0x08 PIO Timing 1 */
+	u32 pio2;		/* ATA + 0x0c PIO Timing 2 */
+	u32 mdma1;		/* ATA + 0x10 MDMA Timing 1 */
+	u32 mdma2;		/* ATA + 0x14 MDMA Timing 2 */
+	u32 udma1;		/* ATA + 0x18 UDMA Timing 1 */
+	u32 udma2;		/* ATA + 0x1c UDMA Timing 2 */
+	u32 udma3;		/* ATA + 0x20 UDMA Timing 3 */
+	u32 udma4;		/* ATA + 0x24 UDMA Timing 4 */
+	u32 udma5;		/* ATA + 0x28 UDMA Timing 5 */
+	u32 share_cnt;		/* ATA + 0x2c ATA share counter */
+	u32 reserved0[3];
+
+	/* FIFO registers */
+	u32 fifo_data;		/* ATA + 0x3c */
+	u8  fifo_status_frame;	/* ATA + 0x40 */
+	u8  fifo_status;	/* ATA + 0x41 */
+	u16 reserved7[1];
+	u8  fifo_control;	/* ATA + 0x44 */
+	u8  reserved8[5];
+	u16 fifo_alarm;		/* ATA + 0x4a */
+	u16 reserved9;
+	u16 fifo_rdp;		/* ATA + 0x4e */
+	u16 reserved10;
+	u16 fifo_wrp;		/* ATA + 0x52 */
+	u16 reserved11;
+	u16 fifo_lfrdp;		/* ATA + 0x56 */
+	u16 reserved12;
+	u16 fifo_lfwrp;		/* ATA + 0x5a */
+
+	/* Drive TaskFile registers */
+	u8  tf_control;		/* ATA + 0x5c TASKFILE Control/Alt Status */
+	u8  reserved13[3];
+	u16 tf_data;		/* ATA + 0x60 TASKFILE Data */
+	u16 reserved14;
+	u8  tf_features;	/* ATA + 0x64 TASKFILE Features/Error */
+	u8  reserved15[3];
+	u8  tf_sec_count;	/* ATA + 0x68 TASKFILE Sector Count */
+	u8  reserved16[3];
+	u8  tf_sec_num;		/* ATA + 0x6c TASKFILE Sector Number */
+	u8  reserved17[3];
+	u8  tf_cyl_low;		/* ATA + 0x70 TASKFILE Cylinder Low */
+	u8  reserved18[3];
+	u8  tf_cyl_high;	/* ATA + 0x74 TASKFILE Cylinder High */
+	u8  reserved19[3];
+	u8  tf_dev_head;	/* ATA + 0x78 TASKFILE Device/Head */
+	u8  reserved20[3];
+	u8  tf_command;		/* ATA + 0x7c TASKFILE Command/Status */
+	u8  dma_mode;		/* ATA + 0x7d ATA Host DMA Mode configuration */
+	u8  reserved21[2];
+};
+
+
+/* Function definition */
+
+static inline void
+mpc52xx_ide_wait_tip_bit_clear(struct mpc52xx_ata __iomem *regs)
+{
+	int timeout = 1000;
+
+	while (in_be32(&regs->host_status) & MPC52xx_ATA_HOSTSTAT_TIP)
+		if (timeout-- == 0) {
+			printk(KERN_ERR
+				"mpc52xx-ide: Timeout waiting for TIP clear\n");
+			break;
+		}
+	udelay(10);	/* FIXME: Necessary ??? */
+}
+
+extern void mpc52xx_ide_setup_hwif_iops(ide_hwif_t *hwif);
+
+
+#endif /* __MPC52xx_IDE_H__ */
+
diff --git a/drivers/ide/ppc/mpc52xx_ide_iops.c b/drivers/ide/ppc/mpc52xx_ide_iops.c
new file mode 100644
index 0000000..6ced54e
--- /dev/null
+++ b/drivers/ide/ppc/mpc52xx_ide_iops.c
@@ -0,0 +1,151 @@
+/*
+ * drivers/ide/ppc/mpc52xx_ide_iops.c
+ *
+ * Utility functions for MPC52xx on-chip IDE interface
+ *
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <asm/io.h>
+
+#include "mpc52xx_ide.h"
+
+
+
+static u8
+mpc52xx_ide_inb(unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	return (u8) readb((void __iomem *) port);
+}
+
+static u16
+mpc52xx_ide_inw(unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	return (u16) readw((void __iomem *) port);
+}
+
+static void
+mpc52xx_ide_insw(unsigned long port, void *addr, u32 count)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	__ide_mm_insw((void __iomem *) port, addr, count);
+}
+
+static u32
+mpc52xx_ide_inl(unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	return (u32) readl((void __iomem *) port);
+}
+
+static void
+mpc52xx_ide_insl(unsigned long port, void *addr, u32 count)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	__ide_mm_insl((void __iomem *) port, addr, count);
+}
+
+static void
+mpc52xx_ide_outb(u8 value, unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	writeb(value, (void __iomem *) port);
+}
+
+static void
+mpc52xx_ide_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	writeb(value, (void __iomem *) port);
+}
+
+
+static void
+mpc52xx_ide_outw(u16 value, unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	writew(value, (void __iomem *) port);
+}
+
+static void
+mpc52xx_ide_outsw(unsigned long port, void *addr, u32 count)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	__ide_mm_outsw((void __iomem *) port, addr, count);
+}
+
+static void
+mpc52xx_ide_outl(u32 value, unsigned long port)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	writel(value, (void __iomem *) port);
+}
+
+static void
+mpc52xx_ide_outsl(unsigned long port, void *addr, u32 count)
+{
+	struct mpc52xx_ata __iomem *ata_regs =
+		(struct mpc52xx_ata __iomem *)(port & ~0xfful);
+
+	mpc52xx_ide_wait_tip_bit_clear(ata_regs);
+	__ide_mm_outsl((void __iomem *) port, addr, count);
+}
+
+
+void
+mpc52xx_ide_setup_hwif_iops(ide_hwif_t *hwif)
+{
+	hwif->OUTB	= mpc52xx_ide_outb;
+	hwif->OUTBSYNC	= mpc52xx_ide_outbsync;
+	hwif->OUTW	= mpc52xx_ide_outw;
+	hwif->OUTL	= mpc52xx_ide_outl;
+	hwif->OUTSW	= mpc52xx_ide_outsw;
+	hwif->OUTSL	= mpc52xx_ide_outsl;
+	hwif->INB	= mpc52xx_ide_inb;
+	hwif->INW	= mpc52xx_ide_inw;
+	hwif->INL	= mpc52xx_ide_inl;
+	hwif->INSW	= mpc52xx_ide_insw;
+	hwif->INSL	= mpc52xx_ide_insl;
+}
+
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 8d2db41..793c70a 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -203,7 +203,7 @@ typedef enum {	ide_unknown,	ide_generic,
 		ide_rz1000,	ide_trm290,
 		ide_cmd646,	ide_cy82c693,	ide_4drives,
 		ide_pmac,	ide_etrax100,	ide_acorn,
-		ide_au1xxx, ide_forced
+		ide_au1xxx,	ide_mpc52xx,	ide_forced
 } hwif_chipset_t;
 
 /*

^ permalink raw reply related

* [PATCH 3/4] ppc32: Reorganize and complete MPC52xx initial cpu setup
From: Sylvain Munaut @ 2006-03-26 11:38 UTC (permalink / raw)
  To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>

ppc32: Reorganize and complete MPC52xx initial cpu setup

This patch splits up the CPU setup into a generic part and a
platform specific part. We also add a few missing init at the
same time.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 67015426ff51ba857b7678a993f4ffd6def1941e
tree cca92c1916ede8f67fe8d16987a54303c76f31f8
parent 37ffaaccad4fb48c8416e610aab4d3bed41dfc80
author Sylvain Munaut <tnt@246tNt.com> 1143311892 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143311892 +0100

 arch/ppc/platforms/lite5200.c   |   38 ++++++++-----------------------
 arch/ppc/syslib/mpc52xx_setup.c |   48 ++++++++++++++++++++++++++++++++++++++++
 include/asm-ppc/mpc52xx.h       |    4 +++
 3 files changed, 62 insertions(+), 28 deletions(-)

---
67015426ff51ba857b7678a993f4ffd6def1941e
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index d91efe1..fecbe9a 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -36,8 +36,6 @@
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
 
-#include <syslib/mpc52xx_pci.h>
-
 
 extern int powersave_nap;
 
@@ -99,34 +97,23 @@ lite5200_map_irq(struct pci_dev *dev, un
 static void __init
 lite5200_setup_cpu(void)
 {
-	struct mpc52xx_cdm  __iomem *cdm;
 	struct mpc52xx_gpio __iomem *gpio;
 	struct mpc52xx_intr __iomem *intr;
-	struct mpc52xx_xlb  __iomem *xlb;
 
 	u32 port_config;
 	u32 intr_ctrl;
 
 	/* Map zones */
-	cdm  = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
 	gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
-	xlb  = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
 	intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
 
-	if (!cdm || !gpio || !xlb || !intr) {
-		printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during"
-				"lite5200_setup_cpu\n");
+	if (!gpio || !intr) {
+		printk(KERN_ERR __FILE__ ": "
+			"Error while mapping GPIO/INTR during "
+			"lite5200_setup_cpu\n");
 		goto unmap_regs;
 	}
 
-	/* Use internal 48 Mhz */
-	out_8(&cdm->ext_48mhz_en, 0x00);
-	out_8(&cdm->fd_enable, 0x01);
-	if (in_be32(&cdm->rstcfg) & 0x40)	/* Assumes 33Mhz clock */
-		out_be16(&cdm->fd_counters, 0x0001);
-	else
-		out_be16(&cdm->fd_counters, 0x5555);
-
 	/* Get port mux config */
 	port_config = in_be32(&gpio->port_config);
 
@@ -137,17 +124,13 @@ lite5200_setup_cpu(void)
 	port_config &= ~0x00007000;	/* Differential mode - USB1 only */
 	port_config |=  0x00001000;
 
+	/* ATA CS is on csb_4/5 */
+	port_config &= ~0x03000000;
+	port_config |=  0x01000000;
+
 	/* Commit port config */
 	out_be32(&gpio->port_config, port_config);
 
-	/* Configure the XLB Arbiter */
-	out_be32(&xlb->master_pri_enable, 0xff);
-	out_be32(&xlb->master_priority, 0x11111111);
-
-	/* Enable ram snooping for 1GB window */
-	out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
-	out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
-
 	/* IRQ[0-3] setup */
 	intr_ctrl = in_be32(&intr->ctrl);
 	intr_ctrl &= ~0x00ff0000;
@@ -163,9 +146,7 @@ lite5200_setup_cpu(void)
 
 	/* Unmap reg zone */
 unmap_regs:
-	if (cdm)  iounmap(cdm);
 	if (gpio) iounmap(gpio);
-	if (xlb)  iounmap(xlb);
 	if (intr) iounmap(intr);
 }
 
@@ -173,7 +154,8 @@ static void __init
 lite5200_setup_arch(void)
 {
 	/* CPU & Port mux setup */
-	lite5200_setup_cpu();
+	mpc52xx_setup_cpu();	/* Generic */
+	lite5200_setup_cpu();	/* Platform specific */
 
 #ifdef CONFIG_PCI
 	/* PCI Bridge setup */
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index 2ee48ce..ee6379b 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -24,6 +24,8 @@
 #include <asm/pgtable.h>
 #include <asm/ppcboot.h>
 
+#include <syslib/mpc52xx_pci.h>
+
 extern bd_t __res;
 
 static int core_mult[] = {		/* CPU Frequency multiplier, taken    */
@@ -216,6 +218,52 @@ mpc52xx_calibrate_decr(void)
 	tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
 }
 
+
+void __init
+mpc52xx_setup_cpu(void)
+{
+	struct mpc52xx_cdm  __iomem *cdm;
+	struct mpc52xx_xlb  __iomem *xlb;
+
+	/* Map zones */
+	cdm  = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
+	xlb  = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
+
+	if (!cdm || !xlb) {
+		printk(KERN_ERR __FILE__ ": "
+			"Error while mapping CDM/XLB during "
+			"mpc52xx_setup_cpu\n");
+		goto unmap_regs;
+	}
+
+	/* Use internal 48 Mhz */
+	out_8(&cdm->ext_48mhz_en, 0x00);
+	out_8(&cdm->fd_enable, 0x01);
+	if (in_be32(&cdm->rstcfg) & 0x40)	/* Assumes 33Mhz clock */
+		out_be16(&cdm->fd_counters, 0x0001);
+	else
+		out_be16(&cdm->fd_counters, 0x5555);
+
+	/* Configure the XLB Arbiter priorities */
+	out_be32(&xlb->master_pri_enable, 0xff);
+	out_be32(&xlb->master_priority, 0x11111111);
+
+	/* Enable ram snooping for 1GB window */
+	out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
+	out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
+
+	/* Disable XLB pipelining */
+	/* (cfr errate 292. We could do this only just before ATA PIO
+	    transaction and re-enable it after ...) */
+	out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
+
+	/* Unmap reg zone */
+unmap_regs:
+	if (cdm)  iounmap(cdm);
+	if (xlb)  iounmap(xlb);
+}
+
+
 int mpc52xx_match_psc_function(int psc_idx, const char *func)
 {
 	struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index 6167f74..7e98428 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -355,6 +355,7 @@ struct mpc52xx_xlb {
 	u32	snoop_window;		/* XLB + 0x70 */
 };
 
+#define MPC52xx_XLB_CFG_PLDIS		(1 << 31)
 #define MPC52xx_XLB_CFG_SNOOP		(1 << 15)
 
 /* Clock Distribution control */
@@ -427,6 +428,9 @@ extern void mpc52xx_calibrate_decr(void)
 
 extern void mpc52xx_find_bridges(void);
 
+extern void mpc52xx_setup_cpu(void);
+
+
 
 	/* Matching of PSC function */
 struct mpc52xx_psc_func {

^ permalink raw reply related

* [PATCH 2/4] ppc32: Adds support for the LITE5200B dev board
From: Sylvain Munaut @ 2006-03-26 11:37 UTC (permalink / raw)
  To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>

ppc32: Adds support for the LITE5200B dev board

This LITE5200B devboard is the new development board for the
Freescale MPC5200 processor. It has two PCI slots and so a
different PCI IRQ routing.

Signed-off-by: John Rigby <jrigby@freescale.com>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 37ffaaccad4fb48c8416e610aab4d3bed41dfc80
tree 3f7b1b661e3ea7c6830c020e42948c575e73d52f
parent d2c9f75189b6bd63b94cc78f8522a44c4476939a
author Sylvain Munaut <tnt@246tNt.com> 1138562427 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143311804 +0100

 Kconfig              |    7 +++++++
 platforms/lite5200.c |   33 ++++++++++++++++++++++++++++++---
 2 files changed, 37 insertions(+), 3 deletions(-)

---
37ffaaccad4fb48c8416e610aab4d3bed41dfc80
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 54a0a9b..1c12da2 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -711,6 +711,13 @@ config LITE5200
 	  much but it's only been tested on this board version. I think this
 	  board is also known as IceCube.
 
+config LITE5200B
+	bool "Freescale LITE5200B"
+	depends LITE5200
+	help
+	  Support for the LITE5200B dev board for the MPC5200 from Freescale.
+	  This is the new board with 2 PCI slots.
+
 config MPC834x_SYS
 	bool "Freescale MPC834x SYS"
 	help
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index 5171b53..d91efe1 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -34,6 +34,7 @@
 #include <asm/mpc52xx.h>
 #include <asm/ppc_sys.h>
 #include <asm/machdep.h>
+#include <asm/pci-bridge.h>
 
 #include <syslib/mpc52xx_pci.h>
 
@@ -68,12 +69,32 @@ lite5200_show_cpuinfo(struct seq_file *m
 }
 
 #ifdef CONFIG_PCI
+#ifdef CONFIG_LITE5200B
+static int
+lite5200_map_irq(struct pci_dev *dev, unsigned char idsel,
+		    unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *      PCI IDSEL/INTPIN->INTLINE
+	 *        A             B             C             D
+	 */
+	{
+		{MPC52xx_IRQ0, MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3},
+		{MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3, MPC52xx_IRQ0},
+	};
+
+	const long min_idsel = 24, max_idsel = 25, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+#else /* Original Lite */
 static int
 lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
 {
 	return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1;
 }
 #endif
+#endif
 
 static void __init
 lite5200_setup_cpu(void)
@@ -127,11 +148,17 @@ lite5200_setup_cpu(void)
 	out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
 	out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
 
-	/* IRQ[0-3] setup : IRQ0     - Level Active Low  */
-	/*                  IRQ[1-3] - Level Active High */
+	/* IRQ[0-3] setup */
 	intr_ctrl = in_be32(&intr->ctrl);
 	intr_ctrl &= ~0x00ff0000;
-	intr_ctrl |=  0x00c00000;
+#ifdef CONFIG_LITE5200B
+	/* IRQ[0-3] Level Active Low */
+	intr_ctrl |=  0x00ff0000;
+#else
+	/* IRQ0 Level Active Low
+	 * IRQ[1-3] Level Active High */
+ 	intr_ctrl |=  0x00c00000;
+#endif
 	out_be32(&intr->ctrl, intr_ctrl);
 
 	/* Unmap reg zone */

^ permalink raw reply related

* [PATCH 1/4] ppc32: Adds support for the PCI hostbridge in MPC5200B
From: Sylvain Munaut @ 2006-03-26 11:37 UTC (permalink / raw)
  To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>

ppc32: Adds support for the PCI hostbridge in MPC5200B

Signed-off-by: John Rigby <jrigby@freescale.com>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit d2c9f75189b6bd63b94cc78f8522a44c4476939a
tree 384ab1d358439be5cddbab68cfa542390ac784f4
parent 3cbb90a9cb7854b1110663919d5bc3da3f46d5e3
author Sylvain Munaut <tnt@246tNt.com> 1138559991 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143311787 +0100

 arch/ppc/syslib/mpc52xx_pci.c |    3 ++-
 include/linux/pci_ids.h       |    1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

---
d2c9f75189b6bd63b94cc78f8522a44c4476939a
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 9ec525f..5a5a7a9 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -225,7 +225,8 @@ mpc52xx_pci_fixup_resources(struct pci_d
 	/* The PCI Host bridge of MPC52xx has a prefetch memory resource
 	   fixed to 1Gb. Doesn't fit in the resource system so we remove it */
 	if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
-	     (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200) ) {
+	     (   dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
+	      || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
 		struct resource *res = &dev->resource[1];
 		res->start = res->end = res->flags = 0;
 	}
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 6f080ae..72d1b67 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -772,6 +772,7 @@
 #define PCI_DEVICE_ID_MOTOROLA_HAWK	0x4803
 #define PCI_DEVICE_ID_MOTOROLA_HARRIER	0x480b
 #define PCI_DEVICE_ID_MOTOROLA_MPC5200	0x5803
+#define PCI_DEVICE_ID_MOTOROLA_MPC5200B	0x5809
 
 #define PCI_VENDOR_ID_PROMISE		0x105a
 #define PCI_DEVICE_ID_PROMISE_20265	0x0d30

^ permalink raw reply related

* [PATCH 0/4] MPC52xx updates : lite5200b + ide support
From: Sylvain Munaut @ 2006-03-26 11:36 UTC (permalink / raw)
  To: Linux PPC embedded; +Cc: Paul Mackerras


Hi Paul,
Hi everyone,


This set of updates mainly adds support for the new lite5200B
devboard from Freescale and support for IDE.

Theses have been posted on the ppc-embedded mailing list some
time ago, they've been tested and reported working by a few people,
so Paul it'd be nice to get those merged upstream. If you were
not the one to cc about this, let me know, I'll forward those
to Andrew.

Thanks !


Regards,
	Sylvain

^ permalink raw reply

* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Michael Neuling @ 2006-03-26  0:07 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: michael, linuxppc-dev
In-Reply-To: <20060325180535.0a680b4d.sfr@canb.auug.org.au>

> > +static void __init setup_legacy_serial_console(int console)
> > +{
> > +	struct legacy_serial_info *info =3D
> > +		&legacy_serial_infos[legacy_serial_console];
> 
> Except that you don't want to do that ^  (assuming you meant "console")
> 
> > +	void __iomem *addr;
> > +
> > +	if (console < 0)
> > +		return;
> 
> before this ^ ...   :-)

Indeed, thanks.  Updated patch below. This time for sure! :-)

Mikey

We only ever execute the loop once, so let's move it to a function
making it more readable.  Cleanup patch, no functional change.  

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/legacy_serial.c |   38 ++++++++++++++++++------------------
 1 files changed, 19 insertions(+), 19 deletions(-)

Index: linux-2.6-powerpc-merge/arch/powerpc/kernel/legacy_serial.c
===================================================================
--- linux-2.6-powerpc-merge.orig/arch/powerpc/kernel/legacy_serial.c
+++ linux-2.6-powerpc-merge/arch/powerpc/kernel/legacy_serial.c
@@ -236,6 +236,23 @@ static int __init add_legacy_pci_port(st
 }
 #endif
 
+static void __init setup_legacy_serial_console(int console)
+{
+	struct legacy_serial_info *info =
+		&legacy_serial_infos[console];
+	void __iomem *addr;
+
+	if (info->taddr == 0)
+		return;
+	addr = ioremap(info->taddr, 0x1000);
+	if (addr == NULL)
+		return;
+	if (info->speed == 0)
+		info->speed = udbg_probe_uart_speed(addr, info->clock);
+	DBG("default console speed = %d\n", info->speed);
+	udbg_init_uart(addr, info->speed, info->clock);
+}
+
 /*
  * This is called very early, as part of setup_system() or eventually
  * setup_arch(), basically before anything else in this file. This function
@@ -318,25 +335,8 @@ void __init find_legacy_serial_ports(voi
 #endif
 
 	DBG("legacy_serial_console = %d\n", legacy_serial_console);
-
-	/* udbg is 64 bits only for now, that will change soon though ... */
-	while (legacy_serial_console >= 0) {
-		struct legacy_serial_info *info =
-			&legacy_serial_infos[legacy_serial_console];
-		void __iomem *addr;
-
-		if (info->taddr == 0)
-			break;
-		addr = ioremap(info->taddr, 0x1000);
-		if (addr == NULL)
-			break;
-		if (info->speed == 0)
-			info->speed = udbg_probe_uart_speed(addr, info->clock);
-		DBG("default console speed = %d\n", info->speed);
-		udbg_init_uart(addr, info->speed, info->clock);
-		break;
-	}
-
+	if (legacy_serial_console >= 0)
+		setup_legacy_serial_console(legacy_serial_console);
 	DBG(" <- find_legacy_serial_port()\n");
 }
 

^ permalink raw reply

* Re: [PATCH] powerpc: Add FSL SEC node to documentation
From: Doug Maxey @ 2006-03-25 22:27 UTC (permalink / raw)
  To: Paul Nasrat; +Cc: linuxppc-dev
In-Reply-To: <1142976221.2751.22.camel@enki.eridu>


On Tue, 21 Mar 2006 16:23:41 EST, Paul Nasrat wrote:
>On Tue, 2006-03-21 at 13:28 -0600, Hollis Blanchard wrote:
>> On Tue, 2006-03-21 at 12:25 -0600, Kumar Gala wrote:
>> > On Mar 20, 2006, at 8:14 PM, Hollis Blanchard wrote:
>
>> > > Have you consulted with any other vendors regarding these  
>> > > properties? I know
>> > > there is no IEEE1275 binding for these sorts of devices, but we can  
>> > > at least
>> > > attempt to standardize it (even in the absence of the Open Firmware  
>> > > Working
>> > > Group)...
>> > 
>> > Beyond the device_type, I'm not sure if there is much more one could  
>> > standardize one.  The other fields that Kim spec'd are either generic  
>> > OF fields (reg, interrupts, etc.) or specific to the Freescale devices.
>> 
>> The device_type and compatible properties are exactly what I'm talking
>> about.
>
>The Working Group lists still exist but are pretty dead.  I agree we
>really want to ensure that both OF based and dtc based new hardware is
>consistent.  I'm not sure how we want to do this, but we can document in
>Documentation and then use eg SLOF to mock out the OF interfaces and
>create proposals and kick some life into the OF working group.  

Sorry for the delayed reply, my procmail filter was pumping mails to
the old list name without telling me. :)

Other than IBM, Motorola, and possibly Sun, what groups are using 
OFW on new platforms anymore?  

Power.org may be a vehicle to publish.  

The Power TSC leader indicated a willingness to look into a process to 
get out some purely internal bindings (at the moment) that _really_ 
need some fresh air to flourish.

++doug

^ permalink raw reply

* snd-aoa & rates
From: Benjamin Herrenschmidt @ 2006-03-25 22:06 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev list

Hi Johannes

Current snd-aoa blew up on me at module load btw ... anyway, that's not
my point here :)

I wonder if you may be doing something a bit too complicated and maybe
not perfectly wanted for your bitrates thingy... you basically end up
with min/max limits and bit size limits, sort-of
assuming that on analog, any rates you have in your list that fits those
limits will be available on a given codec. That may not be the case for
all codecs no ? Then you end up with a similar list for digital but
since you need discrete bitrates, you end up with a list with min==max.

Why not do something much simpler which is to define the known bitrates
as a bitmask and have the codec expose a bitmask of supported analog and
digital rates ?

In fact, I would have been even nastier and only exposed the
intersection of the above so I don't have to bother about rates that
digital won't support :) But I suppose that if you really want to
support 8k or 96k it might make sense to support others.

Also, for the sample sizes, same comment. Number of bits are not that
useful. I'd rather have a bitmask of formats: 8 bits, 16 bits msb, 24
bits msb, maybe lsb versions if supported, ac3, floating point if
supported, etc... That or an array. I'm sure Alsa already have constants
defined for those no ? I would then have the codec have a function
returning the required clocks for a given bitrate/format combination...

That is all suggestions of course, if you feel that what you do is
better, then stick to it :)

Another thing I wouldn't have bothered with is again with whatever
digital supports or doesn't ... rather that trying to prevent some rates
from being useable by alsa based on a control that users will typically
not have means to set at the right time (what about a sound server
running all the time keeping the drier running, you want to block the
digital switch ?) what I would do is just "mute" the digital output if a
format is selected that isn't supported for digital. I would let the
user chose the formats they want at all time, and only clamp the digital
enable/disable switch. On this switch, btw, you should then remember the
user setting: if the user switches it off, remember off. If the user
switches it on, remember on, If the user sets it on but you have to mute
it, remember that so that when the sample size/format changes again,
unmute.

Sames goes for things that may be supported by the digital output and
not analog (ac3 ?). In this case, mute the analog outputs. The mutes of
these are controlled externally via the amps so it may be a bit
complicated, unless you define specific messages to the core for that,
or maybe just clamp the master volume down in the codec driver.

Ben.
 

^ permalink raw reply

* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Benjamin Herrenschmidt @ 2006-03-25 12:44 UTC (permalink / raw)
  To: mikey; +Cc: michael, linuxppc-dev
In-Reply-To: <20060324041727.F131267B56@ozlabs.org>


> +static void __init setup_legacy_serial_console(int console)
> +{
> +	if (console >= 0) {
> +		struct legacy_serial_info *info =
> +			&legacy_serial_infos[legacy_serial_console];
> +		void __iomem *addr;
> +
> +		if (info->taddr == 0)
> +			return;
> +		addr = ioremap(info->taddr, 0x1000);
> +		if (addr == NULL)
> +			return;
> +		if (info->speed == 0)
> +			info->speed = udbg_probe_uart_speed(addr, info->clock);
> +		DBG("default console speed = %d\n", info->speed);
> +		udbg_init_uart(addr, info->speed, info->clock);
> +	}
> +	return;

Hrm... What is the point of having a function ending with return; ?

What about, instead, something like:

	if (consoles < 0)
		return;
	do shit ...


Ben.

^ permalink raw reply

* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Stephen Rothwell @ 2006-03-25  7:05 UTC (permalink / raw)
  To: Michael Neuling; +Cc: michael, linuxppc-dev
In-Reply-To: <20060325044501.D32A267A58@ozlabs.org>

[-- Attachment #1: Type: text/plain, Size: 564 bytes --]

On Sat, 25 Mar 2006 15:45:11 +1100 Michael Neuling <mikey@neuling.org> wrote:
>
> Agreed.  Updated patch below.
>	.
>	.
> +static void __init setup_legacy_serial_console(int console)
> +{
> +	struct legacy_serial_info *info =
> +		&legacy_serial_infos[legacy_serial_console];

Except that you don't want to do that ^  (assuming you meant "console")

> +	void __iomem *addr;
> +
> +	if (console < 0)
> +		return;

before this ^ ...   :-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox