LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [patch 5/7] Use extended crashkernel command line on ppc64
From: Bernhard Walle @ 2007-09-25 18:23 UTC (permalink / raw)
  To: kexec, akpm; +Cc: linux-arch, linuxppc-dev, linux-kernel
In-Reply-To: <20070925182257.900701776@strauss.suse.de>

This patch adapts the ppc64 code to use the generic parse_crashkernel()
function introduced in the generic patch of that series.


Signed-off-by: Bernhard Walle <bwalle@suse.de>

---
 arch/powerpc/kernel/machine_kexec.c |   52 ++++++++++++++++++------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -61,45 +61,39 @@ NORET_TYPE void machine_kexec(struct kim
 	for(;;);
 }
 
-static int __init early_parse_crashk(char *p)
+void __init reserve_crashkernel(void)
 {
-	unsigned long size;
-
-	if (!p)
-		return 1;
-
-	size = memparse(p, &p);
+	unsigned long long crash_size, crash_base;
+	int ret;
 
-	if (*p == '@')
-		crashk_res.start = memparse(p + 1, &p);
-	else
-		crashk_res.start = KDUMP_KERNELBASE;
-
-	crashk_res.end = crashk_res.start + size - 1;
-
-	return 0;
-}
-early_param("crashkernel", early_parse_crashk);
+	/* this is necessary because of lmb_phys_mem_size() */
+	lmb_analyze();
 
-void __init reserve_crashkernel(void)
-{
-	unsigned long size;
+	/* use common parsing */
+	ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+			&crash_size, &crash_base);
+	if (ret == 0 && crash_size > 0) {
+		if (crash_base == 0)
+			crash_base = KDUMP_KERNELBASE;
+		crashk_res.start = crash_base;
+	} else {
+		/* handle the device tree */
+		crash_size = crashk_res.end - crashk_res.start + 1;
+	}
 
-	if (crashk_res.start == 0)
+	if (crash_size == 0)
 		return;
 
 	/* We might have got these values via the command line or the
 	 * device tree, either way sanitise them now. */
 
-	size = crashk_res.end - crashk_res.start + 1;
-
 	if (crashk_res.start != KDUMP_KERNELBASE)
 		printk("Crash kernel location must be 0x%x\n",
 				KDUMP_KERNELBASE);
 
 	crashk_res.start = KDUMP_KERNELBASE;
-	size = PAGE_ALIGN(size);
-	crashk_res.end = crashk_res.start + size - 1;
+	crash_size = PAGE_ALIGN(crash_size);
+	crashk_res.end = crashk_res.start + crash_size - 1;
 
 	/* Crash kernel trumps memory limit */
 	if (memory_limit && memory_limit <= crashk_res.end) {
@@ -108,7 +102,13 @@ void __init reserve_crashkernel(void)
 				memory_limit);
 	}
 
-	lmb_reserve(crashk_res.start, size);
+	printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+			"for crashkernel (System RAM: %ldMB)\n",
+			(unsigned long)(crash_size >> 20),
+			(unsigned long)(crashk_res.start >> 20),
+			(unsigned long)(lmb_phys_mem_size() >> 20));
+
+	lmb_reserve(crashk_res.start, crash_size);
 }
 
 int overlaps_crashkernel(unsigned long start, unsigned long size)

-- 

^ permalink raw reply

* Re: Local bus binding
From: Segher Boessenkool @ 2007-09-25 19:20 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev@ozlabs.org list
In-Reply-To: <46F94E10.40906@freescale.com>

> Segher,
> Kumar said he wants an ack from you on the local bus node binding 
> before he applies it -- can you review this patch?
>
> http://patchwork.ozlabs.org/linuxppc/patch?id=13591

As discussed on IRC a bit already...

- All three "should"s should be "typically"s.
- The relevant values for "compatible" should be included.
- It is wrong to require the localbus node to be a direct child of
   the root node.  This isn't in the binding /per se/, but both the
   commit message and the code do mention it.


Segher

^ permalink raw reply

* Re: [patch 5/7] Use extended crashkernel command line on ppc64
From: Andrew Morton @ 2007-09-25 19:45 UTC (permalink / raw)
  To: Bernhard Walle; +Cc: linux-arch, linuxppc-dev, kexec, linux-kernel
In-Reply-To: <20070925182259.398924232@strauss.suse.de>

On Tue, 25 Sep 2007 20:23:02 +0200 Bernhard Walle <bwalle@suse.de> wrote:

> This patch adapts the ppc64 code to use the generic parse_crashkernel()
> function introduced in the generic patch of that series.
> 
> 

I really don't like to see patches get a wholesale replacement, especially
when they've been looked at by a few people and have had some testing, etc.
It's not possible to see what changed and people need to re-review stuff
they've already reviewed, etc.

So I almost always undo this mess, turn the patches back into incremental
ones, see what pops out.

This patch is actually:


diff -puN arch/powerpc/kernel/machine_kexec.c~use-extended-crashkernel-command-line-on-ppc64-update arch/powerpc/kernel/machine_kexec.c
--- a/arch/powerpc/kernel/machine_kexec.c~use-extended-crashkernel-command-line-on-ppc64-update
+++ a/arch/powerpc/kernel/machine_kexec.c
@@ -63,7 +63,7 @@ NORET_TYPE void machine_kexec(struct kim
 
 void __init reserve_crashkernel(void)
 {
-	unsigned long long crash_size = 0, crash_base;
+	unsigned long long crash_size, crash_base;
 	int ret;
 
 	/* this is necessary because of lmb_phys_mem_size() */
_


which I suspect will now create a compiler warning.


	unsigned long long crash_size, crash_base;
	int ret;

	/* this is necessary because of lmb_phys_mem_size() */
	lmb_analyze();

	/* use common parsing */
	ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
			&crash_size, &crash_base);
	if (ret == 0 && crash_size > 0) {
		if (crash_base == 0)
			crash_base = KDUMP_KERNELBASE;
		crashk_res.start = crash_base;
	} else {
		/* handle the device tree */
		crash_size = crashk_res.end - crashk_res.start + 1;
	}

	if (crash_size == 0)
		return;

If so, the use of uninitialized_var() would be better than the unneeded
initialization-to-zero.

^ permalink raw reply

* [PATCH v2] Make instruction dumping work in real mode.
From: Scott Wood @ 2007-09-25 20:19 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

On non-book-E-or-4xx, exceptions execute in real mode.  If a fault happens
that leads to a register dump, the kernel currently prints XXXXXXXX because
it doesn't realize that PC is a physical address.

This patch checks the state of the IMMU, and if necessary converts PC into a
virtual address.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
This version uses MSR_IR rather than address heuristics, and fixes breakage
that somehow crept into the address adjustment in the previous patch.

 arch/powerpc/kernel/process.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 57c589c..6dbde7f 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -354,6 +354,14 @@ static void show_instructions(struct pt_regs *regs)
 		if (!(i % 8))
 			printk("\n");
 
+#if !defined(CONFIG_BOOKE) && !defined(CONFIG_40x)
+		/* If executing with the IMMU off, adjust pc rather
+		 * than print XXXXXXXX.
+		 */
+		if (!(regs->msr & MSR_IR))
+			pc = (unsigned long)phys_to_virt(pc);
+#endif
+
 		/* We use __get_user here *only* to avoid an OOPS on a
 		 * bad address because the pc *should* only be a
 		 * kernel address.
-- 
1.5.3.1

^ permalink raw reply related

* Re: [PATCH 2/2] fsl/embedded6xx: don't cast the result of of_get_property
From: Kumar Gala @ 2007-09-25 20:27 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: PowerPC dev list
In-Reply-To: <1189748800.165997.810365539433.2.gpush@pokey>


On Sep 14, 2007, at 12:46 AM, Jeremy Kerr wrote:

> Use a temporary variable of the correct type instead.
>
> Also, this allows us to check the return value in ls_uarts_init, to
> avoid dereferencing a null pointer if required properties aren't
> present.
>
> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>

Can I get you to respin this against for-2.6.24.  For some reason  
this doesn't apply cleanly for me.

- k

^ permalink raw reply

* Re: [patch 3/3] mpc8349emitx.dts: Add ds1339 RTC
From: Segher Boessenkool @ 2007-09-25 20:33 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, Timur Tabi
In-Reply-To: <20070925021144.GF30338@localhost.localdomain>

>>> Hrm... we probably want an "i2c" device_type class, but I don't think
>>> we've actually defined one, which is a problem
>>
>> By defining new device_type's, or new semantics for device_type,
>> you open the door to (accidentally) becoming incompatible with
>> "real" OF.
>
> Hrm... perhaps.  But is it a realistic danger - I'll have to think
> more about that.

It is trivial to avoid these dangers completely by not overloading
the meaning of "device_type".

>>> I think we want to think a bit more carefully about how to do  
>>> bindings
>>> for RTC devices.  No "rtc" device_type is defined, but again we might
>>> want to.
>>
>> Actually, "device_type" = "rtc" _is_ defined (in the "device support
>> extensions" recommended practice), and there is no useful way a flat
>> device tree can implement it (it merely defines get-time and set-time
>> methods).
>
> Ah.. right.  That changes things a bit, in that we might want to
> include device_type purely for similarity with real OF tree.

You should include the device_type only if you implement its binding,
and a flat device tree does not, and cannot.  (In almost all cases,
a flat device tree cannot implement device_type's semantics -- this
means that pretty much the only case where a flat tree should use
device_type is to have it as a workaround for bad kernel requirements).

> Real OF has a device_type == "nvram" too, doesn't it?

Yes, same "device support extensions" document.

> AFAICT the real
> OF systems I have (which I think all have ISA-like CMOS RTC/NVRAM
> chips) the RTC is labelled as "nvram" rather than "rtc".

Sounds buggy.

>>> The fact that NVRAM+RTC chips are so common is a bit of an issue from
>>> the point of view of defining a device class binding - a device can't
>>> have type "rtc" and "nvram".
>>
>> You should match OS drivers on "compatible" only anyway.
>
> Absolutely.  I was only thinking of defining "device classes" where
> for some reason it is useful to examine them without needing to pick a
> particular driver.

Yeah I understand.  In what situations would this be useful?
Answering that question will make the requirements for this more
clear; or maybe it will show we do not need this at all.

>> Those cases where OS drivers don't nicely 1-1 match device nodes are a
>> bit of a headache; for RTC/NVRAM devices, these problems are nicely
>> side-stepped by handling this from platform code.
>
> Not necessarily.  The new RTC class drivers are just drivers like
> anything other and are not especially instantiated from the platform
> code.

I meant "can be nicely side-stepped", or "usually are ..." :-)

Obviously, when you cannot avoid the problem, you have a problem.

> And drat.  I was only really mentioning stuff about device_type in
> passing, but it's the only thing anyone's responded to.  I was also
> mostly suggesting changing the format of compatible, for greater
> similarity with the existing ds1385 binding.

Okay, quoting from your earlier message:

> I did find one real OF binding for a different Dallas RTC (and NVRAM),
> see:
>
> http://playground.sun.com/1275/proposals/Closed/Remanded/Accepted/346- 
> it.txt
>
> It's a little different from the example above.

That is a binding for the nvram part only, not for the RTC.


Segher

^ permalink raw reply

* Re: [PATCH] add Altivec/VMX state to coredumps
From: Benjamin Herrenschmidt @ 2007-09-25 22:18 UTC (permalink / raw)
  To: Matt Sealey; +Cc: linuxppc-dev
In-Reply-To: <46F94CBA.2060901@genesi-usa.com>


On Tue, 2007-09-25 at 19:00 +0100, Matt Sealey wrote:
> Kumar Gala wrote:
> > On Sep 24, 2007, at 11:03 PM, Mark Nelson wrote:
> > 
> >> Update dump_task_altivec() (that has so far never been put to use)
> >> so that it dumps the Altivec/VMX registers (VR[0] - VR[31], VSCR
> >> and VRSAVE) in the same format as the ptrace get_vrregs() and add
> >> the appropriate glue typedefs and #defines to
> >> include/asm-powerpc/elf.h for it to work.
> > 
> > Is there some way to tell if the core dump has altivec registers  
> > state in it?
> > 
> > I'm wondering how we distinguish a core dump w/altivec state vs one  
> > with SPE state.
> 
> Sheer number of registers saved?
> 
> Why not put the PVR in core dumps that'd make it all easier..

PVR wouldn't be very useful...  What if you have altivec disabled ? Also
that would mean your gdb has to know about all new processors...

Ben.

^ permalink raw reply

* Build failure on treeboot-walnut.c
From: Grant Likely @ 2007-09-25 22:46 UTC (permalink / raw)
  To: linuxppc-dev, Paul Mackerras, Josh Boyer

Building Paul's current powerpc branch with a ppc6xx compiler causes
the following build failure:

  SYSMAP  System.map
  BOOTCC  arch/powerpc/boot/treeboot-walnut.o
{standard input}: Assembler messages:
{standard input}:184: Error: Unrecognized opcode: `mfdcr'
{standard input}:185: Error: Unrecognized opcode: `mfdcr'
{standard input}:186: Error: Unrecognized opcode: `mfdcr'
{standard input}:217: Error: Unrecognized opcode: `mtdcr'
make[1]: *** [arch/powerpc/boot/treeboot-walnut.o] Error 1
make: *** [uImage] Error 2

This is using ELDK 4.1:
GNU assembler version 2.16.1 (powerpc-linux) using BFD version 2.16.1
gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: Build failure on treeboot-walnut.c
From: Josh Boyer @ 2007-09-26  0:15 UTC (permalink / raw)
  To: Grant Likely; +Cc: Paul Mackerras, linuxppc-dev
In-Reply-To: <fa686aa40709251546p725e66dcsbc0483cadb3ec3fb@mail.gmail.com>

On Tue, 25 Sep 2007 16:46:17 -0600
"Grant Likely" <grant.likely@secretlab.ca> wrote:

> Building Paul's current powerpc branch with a ppc6xx compiler causes
> the following build failure:
> 
>   SYSMAP  System.map
>   BOOTCC  arch/powerpc/boot/treeboot-walnut.o
> {standard input}: Assembler messages:
> {standard input}:184: Error: Unrecognized opcode: `mfdcr'
> {standard input}:185: Error: Unrecognized opcode: `mfdcr'
> {standard input}:186: Error: Unrecognized opcode: `mfdcr'
> {standard input}:217: Error: Unrecognized opcode: `mtdcr'
> make[1]: *** [arch/powerpc/boot/treeboot-walnut.o] Error 1
> make: *** [uImage] Error 2
> 
> This is using ELDK 4.1:
> GNU assembler version 2.16.1 (powerpc-linux) using BFD version 2.16.1
> gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)

Fixed in my tree.  I'll ask Paul to pull soon.

josh

^ permalink raw reply

* Re: [PATCH 2/2] fsl/embedded6xx: don't cast the result of of_get_property
From: Stephen Rothwell @ 2007-09-26  0:44 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linuxppc-dev
In-Reply-To: <1189748800.165997.810365539433.2.gpush@pokey>

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

On Fri, 14 Sep 2007 15:46:40 +1000 Jeremy Kerr <jk@ozlabs.org> wrote:
>
> -	avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);
> -	phys_addr = ((u32*)of_get_property(avr, "reg", &len))[0];
> +	phys_addr = of_get_property(avr, "reg", &len);
> +	avr_clock_prop = of_get_property(avr, "clock-frequency", &len);

If you don't use the value of the len variable, then you can pass NULL to
of_get_property.

> +	if (!avr_clock || !phys_addr[0])

Not *phys_addr?

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

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

^ permalink raw reply

* Re: [PATCH 2/2] fsl/embedded6xx: don't cast the result of of_get_property
From: Jeremy Kerr @ 2007-09-26  0:52 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linuxppc-dev
In-Reply-To: <20070926104419.1b92002e.sfr@canb.auug.org.au>

Stephen,

> If you don't use the value of the len variable, then you can pass
> NULL to of_get_property.

Sure, but that's probably a separate patch, no ?

> Not *phys_addr?

That's what the existing code does. I'm guessing that it treats 
phys_addr as an array with one entry, not a single u32.

Cheers,


Jeremy

^ permalink raw reply

* Re: [PATCH 2/2] fsl/embedded6xx: don't cast the result of of_get_property
From: Stephen Rothwell @ 2007-09-26  0:59 UTC (permalink / raw)
  To: Jeremy Kerr; +Cc: linuxppc-dev
In-Reply-To: <200709261052.25044.jk@ozlabs.org>

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

On Wed, 26 Sep 2007 10:52:23 +1000 Jeremy Kerr <jk@ozlabs.org> wrote:
>
> Stephen,
> 
> > If you don't use the value of the len variable, then you can pass
> > NULL to of_get_property.
> 
> Sure, but that's probably a separate patch, no ?

OK.

> > Not *phys_addr?
> 
> That's what the existing code does. I'm guessing that it treats 
> phys_addr as an array with one entry, not a single u32.

OK.

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

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

^ permalink raw reply

* Re: [PATCH] add Altivec/VMX state to coredumps
From: Mark Nelson @ 2007-09-26  1:22 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <E4CA12E1-888D-4A8B-B687-02F9D2850E1F@kernel.crashing.org>

Kumar Gala wrote:
> 
> On Sep 24, 2007, at 11:03 PM, Mark Nelson wrote:
> 
>> Update dump_task_altivec() (that has so far never been put to use)
>> so that it dumps the Altivec/VMX registers (VR[0] - VR[31], VSCR
>> and VRSAVE) in the same format as the ptrace get_vrregs() and add
>> the appropriate glue typedefs and #defines to
>> include/asm-powerpc/elf.h for it to work.
> 
> Is there some way to tell if the core dump has altivec registers state
> in it?
> 
> I'm wondering how we distinguish a core dump w/altivec state vs one with
> SPE state.
> 
> - k
> 
> 

If the core dump has the Altivec registers saved in there it will have a
note called LINUX as shown below:

$ readelf -n core

Notes at offset 0x000002b4 with length 0x000005c8:
  Owner         Data size       Description
  CORE          0x0000010c      NT_PRSTATUS (prstatus structure)
  CORE          0x00000080      NT_PRPSINFO (prpsinfo structure)
  CORE          0x000000b0      NT_AUXV (auxiliary vector)
  CORE          0x00000108      NT_FPREGSET (floating point registers)
  LINUX         0x00000220      NT_PRXFPREG (user_xfpregs structure)

This mirrors what occurs with the SSE registers on i386 core dumps in
order to keep things as similar as possible.

I can't find any place where dump_spe() is called at the moment, but I
suppose if it were to be hooked up in the future it could cause confusion.
The Altivec register state in the core file is much larger than what
would be dumped by the current dump_spe(), but I'm not sure if that
matters...

There's a patch for GDB that currently reads the contents of these vector
registers from the core file, but it's being held until this patch has
been commented on and/or approved of, so if it comes to it the note name
could be changed to ALTIVEC (or something similar).


Thanks!
Mark.

^ permalink raw reply

* dtc: Use libfdt/fdt.h instead of flat_dt.h
From: David Gibson @ 2007-09-26  3:11 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

In the dtc tree, both flat_dt.h and libfdt/fdt.h have structures and
constants relating to the flattened device tree format derived from
asm-powerpc/prom.h in the kernel.  The former is used in dtc, the
latter in libfdt.

libfdt/fdt.h is the more recent, revised version, so use that
throughout, removing flat_dt.h.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: dtc/flat_dt.h
===================================================================
--- dtc.orig/flat_dt.h	2007-09-26 12:41:39.000000000 +1000
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,51 +0,0 @@
-#ifndef _FLAT_DT_H_
-#define _FLAT_DT_H_
-
-
-#define OF_DEFAULT_VERSION	17
-
-#define OF_DT_HEADER            0xd00dfeed      /* 4: version, 4: total size */
-
-#define OF_DT_BEGIN_NODE	0x1             /* Start node: full name */
-#define OF_DT_END_NODE		0x2             /* End node */
-#define OF_DT_PROP		0x3             /* Property: name off,
-						   size, content */
-#define OF_DT_NOP		0x4		/* nop */
-#define OF_DT_END               0x9
-
-struct boot_param_header {
-	uint32_t magic;                  /* magic word OF_DT_HEADER */
-	uint32_t totalsize;              /* total size of DT block */
-	uint32_t off_dt_struct;          /* offset to structure */
-	uint32_t off_dt_strings;         /* offset to strings */
-	uint32_t off_mem_rsvmap;         /* offset to memory reserve map */
-	uint32_t version;                /* format version */
-	uint32_t last_comp_version;      /* last compatible version */
-
-        /* version 2 fields below */
-	uint32_t boot_cpuid_phys;        /* Which physical CPU id we're
-					    booting on */
-	/* version 3 fields below */
-        uint32_t size_dt_strings;        /* size of the strings block */
-
-	/* version 17 fields below */
-	uint32_t size_dt_struct;         /* size of the DT structure block */
-};
-
-#define BPH_V1_SIZE	(7*sizeof(uint32_t))
-#define BPH_V2_SIZE	(BPH_V1_SIZE + sizeof(uint32_t))
-#define BPH_V3_SIZE	(BPH_V2_SIZE + sizeof(uint32_t))
-#define BPH_V17_SIZE	(BPH_V3_SIZE + sizeof(uint32_t))
-
-struct reserve_entry {
-	uint64_t address;
-	uint64_t size;
-};
-
-struct flat_dt_property {
-	uint32_t len;
-	uint32_t nameoff;
-	char data[0];
-};
-
-#endif /* _FLAT_DT_H_ */
Index: dtc/dtc.h
===================================================================
--- dtc.orig/dtc.h	2007-09-26 12:42:04.000000000 +1000
+++ dtc/dtc.h	2007-09-26 12:44:39.000000000 +1000
@@ -34,8 +34,9 @@
 #include <endian.h>
 #include <byteswap.h>
 
-#include "flat_dt.h"
+#include <fdt.h>
 
+#define DEFAULT_FDT_VERSION	17
 /*
  * Command line options
  */
@@ -128,7 +129,7 @@ struct data data_copy_file(FILE *f, size
 struct data data_append_data(struct data d, void *p, int len);
 struct data data_merge(struct data d1, struct data d2);
 struct data data_append_cell(struct data d, cell_t word);
-struct data data_append_re(struct data d, struct reserve_entry *re);
+struct data data_append_re(struct data d, struct fdt_reserve_entry *re);
 struct data data_append_addr(struct data d, u64 addr);
 struct data data_append_byte(struct data d, uint8_t byte);
 struct data data_append_zeroes(struct data d, int len);
@@ -192,7 +193,7 @@ int check_device_tree(struct node *dt, i
 /* Boot info (tree plus memreserve information */
 
 struct reserve_info {
-	struct reserve_entry re;
+	struct fdt_reserve_entry re;
 
 	struct reserve_info *next;
 
Index: dtc/dtc.c
===================================================================
--- dtc.orig/dtc.c	2007-09-26 12:44:44.000000000 +1000
+++ dtc/dtc.c	2007-09-26 12:45:11.000000000 +1000
@@ -92,7 +92,7 @@ static void  __attribute__ ((noreturn)) 
 	fprintf(stderr, "\t\t\tdtb - device tree blob\n");
 	fprintf(stderr, "\t\t\tasm - assembler source\n");
 	fprintf(stderr, "\t-V <output version>\n");
-	fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", OF_DEFAULT_VERSION);
+	fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
 	fprintf(stderr, "\t-R <number>\n");
 	fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
 	fprintf(stderr, "\t-S <bytes>\n");
@@ -117,7 +117,7 @@ int main(int argc, char *argv[])
 	int opt;
 	FILE *inf = NULL;
 	FILE *outf = NULL;
-	int outversion = OF_DEFAULT_VERSION;
+	int outversion = DEFAULT_FDT_VERSION;
 	int boot_cpuid_phys = 0xfeedbeef;
 
 	quiet      = 0;
Index: dtc/ftdump.c
===================================================================
--- dtc.orig/ftdump.c	2007-09-26 12:45:20.000000000 +1000
+++ dtc/ftdump.c	2007-09-26 12:47:11.000000000 +1000
@@ -9,7 +9,7 @@
 #include <netinet/in.h>
 #include <byteswap.h>
 
-#include "flat_dt.h"
+#include <fdt.h>
 
 #define cpu_to_be16(x)	htons(x)
 #define be16_to_cpu(x)	ntohs(x)
@@ -80,10 +80,10 @@ static void print_data(const void *data,
 
 static void dump_blob(void *blob)
 {
-	struct boot_param_header *bph = blob;
-	struct reserve_entry *p_rsvmap =
-		(struct reserve_entry *)(blob
-					 + be32_to_cpu(bph->off_mem_rsvmap));
+	struct fdt_header *bph = blob;
+	struct fdt_reserve_entry *p_rsvmap =
+		(struct fdt_reserve_entry *)(blob
+					     + be32_to_cpu(bph->off_mem_rsvmap));
 	char *p_struct = blob + be32_to_cpu(bph->off_dt_struct);
 	char *p_strings = blob + be32_to_cpu(bph->off_dt_strings);
 	uint32_t version = be32_to_cpu(bph->version);
@@ -109,11 +109,11 @@ static void dump_blob(void *blob)
 	}
 
 	p = p_struct;
-	while ((tag = be32_to_cpu(GET_CELL(p))) != OF_DT_END) {
+	while ((tag = be32_to_cpu(GET_CELL(p))) != FDT_END) {
 
 		/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
 
-		if (tag == OF_DT_BEGIN_NODE) {
+		if (tag == FDT_BEGIN_NODE) {
 			s = p;
 			p = PALIGN(p + strlen(s) + 1, 4);
 
@@ -126,19 +126,19 @@ static void dump_blob(void *blob)
 			continue;
 		}
 
-		if (tag == OF_DT_END_NODE) {
+		if (tag == FDT_END_NODE) {
 			depth--;
 
 			printf("%*s};\n", depth * shift, "");
 			continue;
 		}
 
-		if (tag == OF_DT_NOP) {
+		if (tag == FDT_NOP) {
 			printf("%*s// [NOP]\n", depth * shift, "");
 			continue;
 		}
 
-		if (tag != OF_DT_PROP) {
+		if (tag != FDT_PROP) {
 			fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
 			break;
 		}
Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c	2007-09-26 12:48:42.000000000 +1000
+++ dtc/flattree.c	2007-09-26 12:54:38.000000000 +1000
@@ -19,7 +19,6 @@
  */
 
 #include "dtc.h"
-#include "flat_dt.h"
 
 #define FTF_FULLPATH	0x1
 #define FTF_VARALIGN	0x2
@@ -35,15 +34,15 @@ static struct version_info {
 	int hdr_size;
 	int flags;
 } version_table[] = {
-	{1, 1, BPH_V1_SIZE,
+	{1, 1, FDT_V1_SIZE,
 	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
-	{2, 1, BPH_V2_SIZE,
+	{2, 1, FDT_V2_SIZE,
 	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
-	{3, 1, BPH_V3_SIZE,
+	{3, 1, FDT_V3_SIZE,
 	 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
-	{16, 16, BPH_V3_SIZE,
+	{16, 16, FDT_V3_SIZE,
 	 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
-	{17, 16, BPH_V17_SIZE,
+	{17, 16, FDT_V17_SIZE,
 	 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
 };
 
@@ -91,17 +90,17 @@ static void bin_emit_data(void *e, struc
 
 static void bin_emit_beginnode(void *e, char *label)
 {
-	bin_emit_cell(e, OF_DT_BEGIN_NODE);
+	bin_emit_cell(e, FDT_BEGIN_NODE);
 }
 
 static void bin_emit_endnode(void *e, char *label)
 {
-	bin_emit_cell(e, OF_DT_END_NODE);
+	bin_emit_cell(e, FDT_END_NODE);
 }
 
 static void bin_emit_property(void *e, char *label)
 {
-	bin_emit_cell(e, OF_DT_PROP);
+	bin_emit_cell(e, FDT_PROP);
 }
 
 static struct emitter bin_emitter = {
@@ -199,14 +198,14 @@ static void asm_emit_beginnode(void *e, 
 		fprintf(f, "\t.globl\t%s\n", label);
 		fprintf(f, "%s:\n", label);
 	}
-	fprintf(f, "\t.long\tOF_DT_BEGIN_NODE\n");
+	fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
 }
 
 static void asm_emit_endnode(void *e, char *label)
 {
 	FILE *f = e;
 
-	fprintf(f, "\t.long\tOF_DT_END_NODE\n");
+	fprintf(f, "\t.long\tFDT_END_NODE\n");
 	if (label) {
 		fprintf(f, "\t.globl\t%s_end\n", label);
 		fprintf(f, "%s_end:\n", label);
@@ -221,7 +220,7 @@ static void asm_emit_property(void *e, c
 		fprintf(f, "\t.globl\t%s\n", label);
 		fprintf(f, "%s:\n", label);
 	}
-	fprintf(f, "\t.long\tOF_DT_PROP\n");
+	fprintf(f, "\t.long\tFDT_PROP\n");
 }
 
 static struct emitter asm_emitter = {
@@ -309,7 +308,7 @@ static struct data flatten_reserve_list(
 {
 	struct reserve_info *re;
 	struct data d = empty_data;
-	static struct reserve_entry null_re = {0,0};
+	static struct fdt_reserve_entry null_re = {0,0};
 	int    j;
 
 	for (re = reservelist; re; re = re->next) {
@@ -325,36 +324,36 @@ static struct data flatten_reserve_list(
 	return d;
 }
 
-static void make_bph(struct boot_param_header *bph,
-		     struct version_info *vi,
-		     int reservesize, int dtsize, int strsize,
-		     int boot_cpuid_phys)
+static void make_fdt_header(struct fdt_header *fdt,
+			    struct version_info *vi,
+			    int reservesize, int dtsize, int strsize,
+			    int boot_cpuid_phys)
 {
 	int reserve_off;
 
-	reservesize += sizeof(struct reserve_entry);
+	reservesize += sizeof(struct fdt_reserve_entry);
 
-	memset(bph, 0xff, sizeof(*bph));
+	memset(fdt, 0xff, sizeof(*fdt));
 
-	bph->magic = cpu_to_be32(OF_DT_HEADER);
-	bph->version = cpu_to_be32(vi->version);
-	bph->last_comp_version = cpu_to_be32(vi->last_comp_version);
+	fdt->magic = cpu_to_be32(FDT_MAGIC);
+	fdt->version = cpu_to_be32(vi->version);
+	fdt->last_comp_version = cpu_to_be32(vi->last_comp_version);
 
 	/* Reserve map should be doubleword aligned */
 	reserve_off = ALIGN(vi->hdr_size, 8);
 
-	bph->off_mem_rsvmap = cpu_to_be32(reserve_off);
-	bph->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
-	bph->off_dt_strings = cpu_to_be32(reserve_off + reservesize
+	fdt->off_mem_rsvmap = cpu_to_be32(reserve_off);
+	fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
+	fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize
 					  + dtsize);
-	bph->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
+	fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
 
 	if (vi->flags & FTF_BOOTCPUID)
-		bph->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
+		fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
 	if (vi->flags & FTF_STRTABSIZE)
-		bph->size_dt_strings = cpu_to_be32(strsize);
+		fdt->size_dt_strings = cpu_to_be32(strsize);
 	if (vi->flags & FTF_STRUCTSIZE)
-		bph->size_dt_struct = cpu_to_be32(dtsize);
+		fdt->size_dt_struct = cpu_to_be32(dtsize);
 }
 
 void dt_to_blob(FILE *f, struct boot_info *bi, int version,
@@ -366,7 +365,7 @@ void dt_to_blob(FILE *f, struct boot_inf
 	struct data reservebuf = empty_data;
 	struct data dtbuf      = empty_data;
 	struct data strbuf     = empty_data;
-	struct boot_param_header bph;
+	struct fdt_header fdt;
 	int padlen;
 
 	for (i = 0; i < ARRAY_SIZE(version_table); i++) {
@@ -377,25 +376,25 @@ void dt_to_blob(FILE *f, struct boot_inf
 		die("Unknown device tree blob version %d\n", version);
 
 	flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
-	bin_emit_cell(&dtbuf, OF_DT_END);
+	bin_emit_cell(&dtbuf, FDT_END);
 
 	reservebuf = flatten_reserve_list(bi->reservelist, vi);
 
 	/* Make header */
-	make_bph(&bph, vi, reservebuf.len, dtbuf.len, strbuf.len,
-		 boot_cpuid_phys);
+	make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
+			boot_cpuid_phys);
 
 	/*
 	 * If the user asked for more space than is used, adjust the totalsize.
 	 */
-	padlen = minsize - be32_to_cpu(bph.totalsize);
+	padlen = minsize - be32_to_cpu(fdt.totalsize);
 	if (padlen > 0) {
-		bph.totalsize = cpu_to_be32(minsize);
+		fdt.totalsize = cpu_to_be32(minsize);
 	} else {
 		if ((minsize > 0) && (quiet < 1))
 			fprintf(stderr,
 				"Warning: blob size %d >= minimum size %d\n",
-				be32_to_cpu(bph.totalsize), minsize);
+				be32_to_cpu(fdt.totalsize), minsize);
 	}
 
 	/*
@@ -403,10 +402,10 @@ void dt_to_blob(FILE *f, struct boot_inf
 	 * the reserve buffer, add the reserve map terminating zeroes,
 	 * the device tree itself, and finally the strings.
 	 */
-	blob = data_append_data(blob, &bph, sizeof(bph));
+	blob = data_append_data(blob, &fdt, sizeof(fdt));
 	blob = data_append_align(blob, 8);
 	blob = data_merge(blob, reservebuf);
-	blob = data_append_zeroes(blob, sizeof(struct reserve_entry));
+	blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
 	blob = data_merge(blob, dtbuf);
 	blob = data_merge(blob, strbuf);
 
@@ -415,7 +414,7 @@ void dt_to_blob(FILE *f, struct boot_inf
 	 */
 	if (padlen > 0) {
 		blob = data_append_zeroes(blob, padlen);
-		bph.totalsize = cpu_to_be32(minsize);
+		fdt.totalsize = cpu_to_be32(minsize);
 	}
 
 	fwrite(blob.val, blob.len, 1, f);
@@ -460,16 +459,16 @@ void dt_to_asm(FILE *f, struct boot_info
 		die("Unknown device tree blob version %d\n", version);
 
 	fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
-	fprintf(f, "#define OF_DT_HEADER 0x%x\n", OF_DT_HEADER);
-	fprintf(f, "#define OF_DT_BEGIN_NODE 0x%x\n", OF_DT_BEGIN_NODE);
-	fprintf(f, "#define OF_DT_END_NODE 0x%x\n", OF_DT_END_NODE);
-	fprintf(f, "#define OF_DT_PROP 0x%x\n", OF_DT_PROP);
-	fprintf(f, "#define OF_DT_END 0x%x\n", OF_DT_END);
+	fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
+	fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
+	fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
+	fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
+	fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
 	fprintf(f, "\n");
 
 	emit_label(f, symprefix, "blob_start");
 	emit_label(f, symprefix, "header");
-	fprintf(f, "\t.long\tOF_DT_HEADER\t\t\t\t/* magic */\n");
+	fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
 	fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
 		symprefix, symprefix);
 	fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
@@ -529,7 +528,7 @@ void dt_to_asm(FILE *f, struct boot_info
 
 	emit_label(f, symprefix, "struct_start");
 	flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
-	fprintf(f, "\t.long\tOF_DT_END\n");
+	fprintf(f, "\t.long\tFDT_END\n");
 	emit_label(f, symprefix, "struct_end");
 
 	emit_label(f, symprefix, "strings_start");
@@ -674,7 +673,7 @@ static struct reserve_info *flat_read_me
 	struct reserve_info *reservelist = NULL;
 	struct reserve_info *new;
 	char *p;
-	struct reserve_entry re;
+	struct fdt_reserve_entry re;
 
 	/*
 	 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
@@ -778,7 +777,7 @@ static struct node *unflatten_tree(struc
 
 		val = flat_read_word(dtbuf);
 		switch (val) {
-		case OF_DT_PROP:
+		case FDT_PROP:
 			if (node->children)
 				fprintf(stderr, "Warning: Flat tree input has "
 					"subnodes preceding a property.\n");
@@ -786,20 +785,20 @@ static struct node *unflatten_tree(struc
 			add_property(node, prop);
 			break;
 
-		case OF_DT_BEGIN_NODE:
+		case FDT_BEGIN_NODE:
 			child = unflatten_tree(dtbuf,strbuf, node->fullpath,
 					       flags);
 			add_child(node, child);
 			break;
 
-		case OF_DT_END_NODE:
+		case FDT_END_NODE:
 			break;
 
-		case OF_DT_END:
-			die("Premature OF_DT_END in device tree blob\n");
+		case FDT_END:
+			die("Premature FDT_END in device tree blob\n");
 			break;
 
-		case OF_DT_NOP:
+		case FDT_NOP:
 			if (!(flags & FTF_NOPS))
 				fprintf(stderr, "Warning: NOP tag found in flat tree"
 					" version <16\n");
@@ -811,7 +810,7 @@ static struct node *unflatten_tree(struc
 			die("Invalid opcode word %08x in device tree blob\n",
 			    val);
 		}
-	} while (val != OF_DT_END_NODE);
+	} while (val != FDT_END_NODE);
 
 	return node;
 }
@@ -823,7 +822,7 @@ struct boot_info *dt_from_blob(FILE *f)
 	u32 off_dt, off_str, off_mem_rsvmap;
 	int rc;
 	char *blob;
-	struct boot_param_header *bph;
+	struct fdt_header *fdt;
 	char *p;
 	struct inbuf dtbuf, strbuf;
 	struct inbuf memresvbuf;
@@ -845,7 +844,7 @@ struct boot_info *dt_from_blob(FILE *f)
 	}
 
 	magic = be32_to_cpu(magic);
-	if (magic != OF_DT_HEADER)
+	if (magic != FDT_MAGIC)
 		die("Blob has incorrect magic number\n");
 
 	rc = fread(&totalsize, sizeof(totalsize), 1, f);
@@ -859,14 +858,14 @@ struct boot_info *dt_from_blob(FILE *f)
 	}
 
 	totalsize = be32_to_cpu(totalsize);
-	if (totalsize < BPH_V1_SIZE)
+	if (totalsize < FDT_V1_SIZE)
 		die("DT blob size (%d) is too small\n", totalsize);
 
 	blob = xmalloc(totalsize);
 
-	bph = (struct boot_param_header *)blob;
-	bph->magic = cpu_to_be32(magic);
-	bph->totalsize = cpu_to_be32(totalsize);
+	fdt = (struct fdt_header *)blob;
+	fdt->magic = cpu_to_be32(magic);
+	fdt->totalsize = cpu_to_be32(totalsize);
 
 	sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
 	p = blob + sizeof(magic)  + sizeof(totalsize);
@@ -885,10 +884,10 @@ struct boot_info *dt_from_blob(FILE *f)
 		p += rc;
 	}
 
-	off_dt = be32_to_cpu(bph->off_dt_struct);
-	off_str = be32_to_cpu(bph->off_dt_strings);
-	off_mem_rsvmap = be32_to_cpu(bph->off_mem_rsvmap);
-	version = be32_to_cpu(bph->version);
+	off_dt = be32_to_cpu(fdt->off_dt_struct);
+	off_str = be32_to_cpu(fdt->off_dt_strings);
+	off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap);
+	version = be32_to_cpu(fdt->version);
 
 	fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
 	fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
@@ -897,7 +896,7 @@ struct boot_info *dt_from_blob(FILE *f)
 	fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
 	fprintf(stderr, "\tversion:\t\t0x%x\n", version );
 	fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
-		be32_to_cpu(bph->last_comp_version));
+		be32_to_cpu(fdt->last_comp_version));
 
 	if (off_mem_rsvmap >= totalsize)
 		die("Mem Reserve structure offset exceeds total size\n");
@@ -910,18 +909,18 @@ struct boot_info *dt_from_blob(FILE *f)
 
 	if (version >= 2)
 		fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
-			be32_to_cpu(bph->boot_cpuid_phys));
+			be32_to_cpu(fdt->boot_cpuid_phys));
 
 	size_str = -1;
 	if (version >= 3) {
-		size_str = be32_to_cpu(bph->size_dt_strings);
+		size_str = be32_to_cpu(fdt->size_dt_strings);
 		fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
 		if (off_str+size_str > totalsize)
 			die("String table extends past total size\n");
 	}
 
 	if (version >= 17) {
-		size_dt = be32_to_cpu(bph->size_dt_struct);
+		size_dt = be32_to_cpu(fdt->size_dt_struct);
 		fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
 		if (off_dt+size_dt > totalsize)
 			die("Structure block extends past total size\n");
@@ -945,14 +944,14 @@ struct boot_info *dt_from_blob(FILE *f)
 
 	val = flat_read_word(&dtbuf);
 
-	if (val != OF_DT_BEGIN_NODE)
-		die("Device tree blob doesn't begin with OF_DT_BEGIN_NODE (begins with 0x%08x)\n", val);
+	if (val != FDT_BEGIN_NODE)
+		die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
 
 	tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
 
 	val = flat_read_word(&dtbuf);
-	if (val != OF_DT_END)
-		die("Device tree blob doesn't end with OF_DT_END\n");
+	if (val != FDT_END)
+		die("Device tree blob doesn't end with FDT_END\n");
 
 	free(blob);
 
Index: dtc/data.c
===================================================================
--- dtc.orig/data.c	2007-09-26 12:50:49.000000000 +1000
+++ dtc/data.c	2007-09-26 12:51:03.000000000 +1000
@@ -246,9 +246,9 @@ struct data data_append_cell(struct data
 	return data_append_data(d, &beword, sizeof(beword));
 }
 
-struct data data_append_re(struct data d, struct reserve_entry *re)
+struct data data_append_re(struct data d, struct fdt_reserve_entry *re)
 {
-	struct reserve_entry bere;
+	struct fdt_reserve_entry bere;
 
 	bere.address = cpu_to_be64(re->address);
 	bere.size = cpu_to_be64(re->size);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* CPM_UART_CONSOLE
From: Deepak Gaur @ 2007-09-25 11:14 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20070925104704.M46195@cdotd.ernet.in>

Hi all,

I am writing a kernel module which is required to parse the characters received from a
device attached to MPC8560 SCC2 (UART slave mode) on serial interface. This SCC is
required to be configured for single-buffer, character based operation. Moreover on
another SCC (SCC1 UART master mode) the board debug interface(console) is connected.

While trying to figure out CPM UART device driver interface available in file (Linux ppc)
./drivers/serial/cpm_uart/cpm_uart_core.c for my kernel module I found that some of the
functions are available when CPM_UART_CONSOLE is enabled.

My doubt is regarding status of this flag for my hardware setup. Should this flag be
enabled or not. If it is required to be enabled for supporting SCC1 then how SCC2 will
be handled?

As I am a novice in this area , I shall be grateful if you please guide me in
understanding this driver code.

with regards,

Deepak Gaur

^ permalink raw reply

* Re: 2.6.23-rc6-mm1: Build failure on ppc64 drivers/ata/pata_scc.c
From: Jeff Garzik @ 2007-09-26  3:39 UTC (permalink / raw)
  To: Satyam Sharma
  Cc: linuxppc-dev, Linux Kernel Mailing List, kamalesh, linux-ide,
	Mel Gorman, Andrew Morton, Alan Cox
In-Reply-To: <alpine.LFD.0.999.0709220816170.14412@enigma.security.iitk.ac.in>

Satyam Sharma wrote:
> Hi,
> 
> 
> On Thu, 20 Sep 2007, Alan Cox wrote:
>> On Thu, 20 Sep 2007 14:13:15 +0100
>> mel@skynet.ie (Mel Gorman) wrote:
>>
>>> PPC64 building allmodconfig fails to compile drivers/ata/pata_scc.c . It
>>> doesn't show up on other arches because this driver is specific to the
>>> architecture.
>>>
>>> drivers/ata/pata_scc.c: In function `scc_bmdma_status'
>> Its not been updated to match the libata core changes. Try something like
>> this. Whoever is maintaining it should also remove the prereset cable handling
>> code and use the proper cable detect method.
> 
> It appears you forgot to fix scc_std_softreset() and one of its callsites
> in scc_bdma_stop(). A complete patch is attempted below -- please review.
> 
> 
> [PATCH -mm] pata_scc: Keep up with libata core API changes
> 
> Little fixlets, that the build started erroring / warning about:
> 
> drivers/ata/pata_scc.c: In function 'scc_bmdma_status':
> drivers/ata/pata_scc.c:734: error: structure has no member named 'active_tag'
> drivers/ata/pata_scc.c: In function 'scc_pata_prereset':
> drivers/ata/pata_scc.c:866: warning: passing arg 1 of 'ata_std_prereset' from incompatible pointer type
> drivers/ata/pata_scc.c: In function 'scc_error_handler':
> drivers/ata/pata_scc.c:908: warning: passing arg 2 of 'ata_bmdma_drive_eh' from incompatible pointer type
> drivers/ata/pata_scc.c:908: warning: passing arg 3 of 'ata_bmdma_drive_eh' from incompatible pointer type
> drivers/ata/pata_scc.c:908: warning: passing arg 5 of 'ata_bmdma_drive_eh' from incompatible pointer type
> make[2]: *** [drivers/ata/pata_scc.o] Error 1
> 
> Signed-off-by: Satyam Sharma <satyam@infradead.org>
> Cc: Alan Cox <alan@redhat.com>
> Cc: Mel Gorman <mel@skynet.ie>
> 
> ---
> 
> Andrew, this includes (supercedes) the previous two ones from Mel / Alan.
> 
>  drivers/ata/pata_scc.c |   21 ++++++++++++---------
>  1 file changed, 12 insertions(+), 9 deletions(-)

applied

^ permalink raw reply

* Re: [PATCH] add Altivec/VMX state to coredumps
From: Kumar Gala @ 2007-09-26  3:56 UTC (permalink / raw)
  To: Mark Nelson; +Cc: linuxppc-dev
In-Reply-To: <46F9B454.8010004@au1.ibm.com>


On Sep 25, 2007, at 8:22 PM, Mark Nelson wrote:

> Kumar Gala wrote:
>>
>> On Sep 24, 2007, at 11:03 PM, Mark Nelson wrote:
>>
>>> Update dump_task_altivec() (that has so far never been put to use)
>>> so that it dumps the Altivec/VMX registers (VR[0] - VR[31], VSCR
>>> and VRSAVE) in the same format as the ptrace get_vrregs() and add
>>> the appropriate glue typedefs and #defines to
>>> include/asm-powerpc/elf.h for it to work.
>>
>> Is there some way to tell if the core dump has altivec registers  
>> state
>> in it?
>>
>> I'm wondering how we distinguish a core dump w/altivec state vs  
>> one with
>> SPE state.
>>
>> - k
>>
>>
>
> If the core dump has the Altivec registers saved in there it will  
> have a
> note called LINUX as shown below:
>
> $ readelf -n core
>
> Notes at offset 0x000002b4 with length 0x000005c8:
>   Owner         Data size       Description
>   CORE          0x0000010c      NT_PRSTATUS (prstatus structure)
>   CORE          0x00000080      NT_PRPSINFO (prpsinfo structure)
>   CORE          0x000000b0      NT_AUXV (auxiliary vector)
>   CORE          0x00000108      NT_FPREGSET (floating point registers)
>   LINUX         0x00000220      NT_PRXFPREG (user_xfpregs structure)
>
> This mirrors what occurs with the SSE registers on i386 core dumps in
> order to keep things as similar as possible.
>
> I can't find any place where dump_spe() is called at the moment, but I
> suppose if it were to be hooked up in the future it could cause  
> confusion.
> The Altivec register state in the core file is much larger than what
> would be dumped by the current dump_spe(), but I'm not sure if that
> matters...
>
> There's a patch for GDB that currently reads the contents of these  
> vector
> registers from the core file, but it's being held until this patch has
> been commented on and/or approved of, so if it comes to it the note  
> name
> could be changed to ALTIVEC (or something similar).

I think we should NOT overload NT_PRXFPREG and add proper note types  
NT_ALTIVEC & NT_SPE for those register sets.

Who on the GDB side would we need to coordinate such a change with?

- k

^ permalink raw reply

* Re: [spi-devel-general] [PATCH 7/7] [POWERPC][SPI] spi_mpc83xx: allow use on MPC85xx
From: Kumar Gala @ 2007-09-26  4:00 UTC (permalink / raw)
  To: David Brownell; +Cc: spi-devel-general, linuxppc-dev
In-Reply-To: <20070925165845.40B0E2397FB@adsl-69-226-248-13.dsl.pltn13.pacbell.net>


On Sep 25, 2007, at 11:58 AM, David Brownell wrote:

>>>> -	depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
>>>> +	depends on SPI_MASTER && (PPC_83xx || PPC_85xx) && EXPERIMENTAL
>>>
>>> Should that really be just PPC_83xx || QUICC_ENGINE?
>>
>> Well, I thought about that. By now I'm unsure if every QE
>> implementation will be compatible with further ones.
>
> How many other QE implementations exist?  Is that sort of
> gratuitous breakage something Freescale makes a habit of?

We try not to, but HW people are know to do evil things to keep us  
software guys employed.

>> 	So far
>> I've tested this driver on MPC8323 and MPC8568. If we'll see
>> more and more compatible QE SPI controllers, of course we
>> may just do || QUICC_ENGINE.
>>
>> PPC_83xx || PPC_85xx
>> PPC_83xx || QUICC_ENGINE
>>
>> Today first option saves us four bytes. ;-)
>
> It'd be good if someone would look at the relevant docs.
>
> I'll wait for a PPC signoff before I forward this for
> merge with SPI stuff...

I'm still in favor of making it PPC_83xx || QUICC_ENGINE.

So if when we have 87xx with QUICC_ENGINE we don't have to tweak it  
again, but its a minor thing.

- k

^ permalink raw reply

* dtc: Use a custom name for lexer output
From: David Gibson @ 2007-09-26  4:05 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

This patch makes dtc use the name dtc-lexer.lex.c for the flex output,
instead of the default lex.yy.c.  If nothing else that makes the
filename more obvious when/if dtc is embedded into other projects.

It also explicitly requests flex as the lexer generator, rather than
using make's default $(LEX).

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: dtc/Makefile
===================================================================
--- dtc.orig/Makefile	2007-09-26 13:53:58.000000000 +1000
+++ dtc/Makefile	2007-09-26 13:57:52.000000000 +1000
@@ -49,6 +49,7 @@ CFLAGS = -Wall -g -Os
 LDFLAGS = -Llibfdt
 
 BISON = bison
+LEX = flex
 
 INSTALL = /usr/bin/install
 DESTDIR =
@@ -83,7 +84,7 @@ all: dtc ftdump libfdt tests
 DTC_PROGS = dtc ftdump
 DTC_OBJS = dtc.o flattree.o fstree.o data.o livetree.o \
 		srcpos.o treesource.o \
-		dtc-parser.tab.o lex.yy.o
+		dtc-parser.tab.o dtc-lexer.lex.o
 DTC_DEPFILES = $(DTC_OBJS:%.o=%.d)
 
 BIN += dtc ftdump
@@ -96,9 +97,9 @@ dtc-parser.tab.c dtc-parser.tab.h dtc-pa
 $(VERSION_FILE): Makefile FORCE
 	$(call filechk,version)
 
-lex.yy.c: dtc-lexer.l
+dtc-lexer.lex.c: dtc-lexer.l
 	@$(VECHO) LEX $@
-	$(LEX) $<
+	$(LEX) -o $@ $<
 
 dtc: $(DTC_OBJS)
 
@@ -138,7 +139,7 @@ clean: libfdt_clean tests_clean
 	@$(VECHO) CLEAN
 	rm -f $(STD_CLEANFILES)
 	rm -f $(GEN_CLEANFILES)
-	rm -f *.tab.[ch] lex.yy.c *.output vgcore.*
+	rm -f *.tab.[ch] *.lex.c *.output vgcore.*
 	rm -f $(BIN)
 
 install: all

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH v2] Make instruction dumping work in real mode.
From: Kumar Gala @ 2007-09-26  4:06 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070925201935.GA4792@loki.buserror.net>


On Sep 25, 2007, at 3:19 PM, Scott Wood wrote:

> On non-book-E-or-4xx, exceptions execute in real mode.  If a fault  
> happens
> that leads to a register dump, the kernel currently prints XXXXXXXX  
> because
> it doesn't realize that PC is a physical address.
>
> This patch checks the state of the IMMU, and if necessary converts  
> PC into a
> virtual address.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> This version uses MSR_IR rather than address heuristics, and fixes  
> breakage
> that somehow crept into the address adjustment in the previous patch.
>
>  arch/powerpc/kernel/process.c |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/ 
> process.c
> index 57c589c..6dbde7f 100644
> --- a/arch/powerpc/kernel/process.c
> +++ b/arch/powerpc/kernel/process.c
> @@ -354,6 +354,14 @@ static void show_instructions(struct pt_regs  
> *regs)
>  		if (!(i % 8))
>  			printk("\n");
>
> +#if !defined(CONFIG_BOOKE) && !defined(CONFIG_40x)

40x has a real mode and can have the IMMU off.

> +		/* If executing with the IMMU off, adjust pc rather
> +		 * than print XXXXXXXX.
> +		 */
> +		if (!(regs->msr & MSR_IR))
> +			pc = (unsigned long)phys_to_virt(pc);
> +#endif
> +
>  		/* We use __get_user here *only* to avoid an OOPS on a
>  		 * bad address because the pc *should* only be a
>  		 * kernel address.
> -- 
> 1.5.3.1
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH 1/7] PowerPC64: Not to insert EA=0 entry at initializing SLB
From: Ishizaki Kou @ 2007-09-26  4:20 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a workaround NOT to insert EA=0 entry at initializing SLB.
Without this patch, you can see /sbin/init hanging at a machine
which has less or equal than 256MB memory.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/kernel/setup_64.c
+++ linux-powerpc-git/arch/powerpc/kernel/setup_64.c
@@ -195,6 +195,12 @@ void __init early_setup(unsigned long dt
 	get_paca()->stab_real = __pa((u64)&initial_stab);
 	get_paca()->stab_addr = (u64)&initial_stab;
 
+	/* XXX: It's a hack!
+	 * kstack must be set properly or slb_initialize() go mad to set
+	 * ESID=0 entry in bolted area of SLB.
+	 * TODO: Set correct value */
+	get_paca()->kstack = (u64)__builtin_frame_address(0);
+
 	/* Probe the machine type */
 	probe_machine();
 

^ permalink raw reply

* [PATCH 2/7] Celleb: Move pause, kexec_cpu_down to beat.c
From: Ishizaki Kou @ 2007-09-26  4:23 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This patch is an update for "Beat on Celleb"
  - Move beat_pause(), beat_kexec_cpu_down() from setup.c to beat.c

Signed-off-by: <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.h
@@ -36,5 +36,9 @@ ssize_t beat_nvram_get_size(void);
 ssize_t beat_nvram_read(char *, size_t, loff_t *);
 ssize_t beat_nvram_write(char *, size_t, loff_t *);
 int beat_set_xdabr(unsigned long);
+void beat_power_save(void);
+#ifdef CONFIG_KEXEC
+void beat_kexec_cpu_down(int, int);
+#endif
 
 #endif /* _CELLEB_BEAT_H */
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -111,11 +111,6 @@ static void __init celleb_setup_arch(voi
 #endif
 }
 
-static void beat_power_save(void)
-{
-	beat_pause(0);
-}
-
 static int __init celleb_probe(void)
 {
 	unsigned long root = of_get_flat_dt_root();
@@ -128,13 +123,6 @@ static int __init celleb_probe(void)
 	return 1;
 }
 
-#ifdef CONFIG_KEXEC
-static void celleb_kexec_cpu_down(int crash, int secondary)
-{
-	beatic_deinit_IRQ();
-}
-#endif
-
 static struct of_device_id celleb_bus_ids[] __initdata = {
 	{ .type = "scc", },
 	{ .type = "ioif", },	/* old style */
@@ -175,7 +163,7 @@ define_machine(celleb) {
 	.pci_probe_mode 	= celleb_pci_probe_mode,
 	.pci_setup_phb		= celleb_setup_phb,
 #ifdef CONFIG_KEXEC
-	.kexec_cpu_down		= celleb_kexec_cpu_down,
+	.kexec_cpu_down		= beat_kexec_cpu_down,
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
 	.machine_crash_shutdown	= default_machine_crash_shutdown,
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
@@ -158,6 +158,18 @@ int64_t beat_put_term_char(u64 vterm, u6
 	return beat_put_characters_to_console(vterm, len, (u8*)db);
 }
 
+void beat_power_save(void)
+{
+	beat_pause(0);
+}
+
+#ifdef CONFIG_KEXEC
+void beat_kexec_cpu_down(int crash, int secondary)
+{
+	beatic_deinit_IRQ();
+}
+#endif
+
 EXPORT_SYMBOL(beat_get_term_char);
 EXPORT_SYMBOL(beat_put_term_char);
 EXPORT_SYMBOL(beat_halt_code);

^ permalink raw reply

* [PATCH 3/7] Celleb: Support for Power/Reset buttons
From: Ishizaki Kou @ 2007-09-26  4:25 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch to support Power/Reset buttons on Beat on Celleb.

On Beat, we have an event from Beat if Power button or Reset button
is pressed. This patch catches the event and convert it to a signal
to INIT process.

/sbin/inittab have no entry to turn the machine power off so we have
to detect if power button is pressed or not internally in our driver.
This idea is taken from PS3's event handling subsystem.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

This patch is taken after "[PATCH 2/8] Move pause() and kexec_cpu_down()
to beat.c" applied, so some lines are taken in from that patch.
No functional dependency is incorporated.


Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
@@ -22,16 +22,23 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/rtc.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
 
 #include <asm/hvconsole.h>
 #include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
 
 #include "beat_wrapper.h"
 #include "beat.h"
+#include "interrupt.h"
+
+static int beat_pm_poweroff_flag;
 
 void beat_restart(char *cmd)
 {
-	beat_shutdown_logical_partition(1);
+	beat_shutdown_logical_partition(!beat_pm_poweroff_flag);
 }
 
 void beat_power_off(void)
@@ -170,6 +177,96 @@ void beat_kexec_cpu_down(int crash, int 
 }
 #endif
 
+static irqreturn_t beat_power_event(int virq, void *arg)
+{
+	printk(KERN_DEBUG "Beat: power button pressed\n");
+	beat_pm_poweroff_flag = 1;
+	if (kill_cad_pid(SIGINT, 1)) {
+		/* Just in case killing init process failed */
+		beat_power_off();
+	}
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t beat_reset_event(int virq, void *arg)
+{
+	printk(KERN_DEBUG "Beat: reset button pressed\n");
+	beat_pm_poweroff_flag = 0;
+	if (kill_cad_pid(SIGINT, 1)) {
+		/* Just in case killing init process failed */
+		beat_restart(NULL);
+	}
+	return IRQ_HANDLED;
+}
+
+static struct beat_event_list {
+	const char *typecode;
+	irq_handler_t handler;
+	unsigned int virq;
+} beat_event_list[] = {
+	{ "power", beat_power_event, 0 },
+	{ "reset", beat_reset_event, 0 },
+};
+
+static int __init beat_register_event(void)
+{
+	u64 path[4], data[2];
+	int rc, i;
+	unsigned int virq;
+
+	for (i = 0; i < ARRAY_SIZE(beat_event_list); i++) {
+		struct beat_event_list *ev = &beat_event_list[i];
+
+		if (beat_construct_event_receive_port(data) != 0) {
+			printk(KERN_ERR "Beat: "
+			       "cannot construct event receive port for %s\n",
+			       ev->typecode);
+			return -EINVAL;
+		}
+
+		virq = irq_create_mapping(NULL, data[0]);
+		if (virq == NO_IRQ) {
+			printk(KERN_ERR "Beat: failed to get virtual IRQ"
+			       " for event receive port for %s\n",
+			       ev->typecode);
+			beat_destruct_event_receive_port(data[0]);
+			return -EIO;
+		}
+		ev->virq = virq;
+
+		rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+				      ev->typecode, NULL);
+		if (rc != 0) {
+			printk(KERN_ERR "Beat: failed to request virtual IRQ"
+			       " for event receive port for %s\n",
+			       ev->typecode);
+			beat_destruct_event_receive_port(data[0]);
+			return rc;
+		}
+
+		path[0] = 0x1000000065780000ul;	/* 1,ex */
+		path[1] = 0x627574746f6e0000ul;	/* button */
+		path[2] = 0;
+		strncpy((char *)&path[2], ev->typecode, 8);
+		path[3] = 0;
+		data[1] = 0;
+
+		beat_create_repository_node(path, data);
+	}
+	return 0;
+}
+
+static int __init beat_event_init(void)
+{
+	if (!machine_is(celleb) || !firmware_has_feature(FW_FEATURE_BEAT))
+		return -EINVAL;
+
+	beat_pm_poweroff_flag = 0;
+	return beat_register_event();
+}
+
+device_initcall(beat_event_init);
+
 EXPORT_SYMBOL(beat_get_term_char);
 EXPORT_SYMBOL(beat_put_term_char);
 EXPORT_SYMBOL(beat_halt_code);

^ permalink raw reply

* [PATCH 6/7] Celleb: Serial I/O update
From: Ishizaki Kou @ 2007-09-26  4:37 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is an update patch for Serial I/O on Celleb.
  - Detection algorithm has been changed

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc_sio.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc_sio.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc_sio.c
@@ -1,7 +1,7 @@
 /*
  * setup serial port in SCC
  *
- * (C) Copyright 2006 TOSHIBA CORPORATION
+ * (C) Copyright 2006-2007 TOSHIBA CORPORATION
  *
  * 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
@@ -42,40 +42,40 @@ static struct {
 static int __init txx9_serial_init(void)
 {
 	extern int early_serial_txx9_setup(struct uart_port *port);
-	struct device_node *node;
+	struct device_node *node = NULL;
 	int i;
 	struct uart_port req;
 	struct of_irq irq;
 	struct resource res;
 
-	node = of_find_node_by_path("/ioif1/sio");
-	if (!node)
-		return 0;
-
-	for(i = 0; i < sizeof(txx9_scc_tab)/sizeof(txx9_scc_tab[0]); i++) {
-		if (!(txx9_serial_bitmap & (1<<i)))
-			continue;
-
-		if (of_irq_map_one(node, i, &irq))
-			continue;
-		if (of_address_to_resource(node, txx9_scc_tab[i].index, &res))
-			continue;
-
-		memset(&req, 0, sizeof(req));
-		req.line = i;
-		req.iotype = UPIO_MEM;
-		req.mapbase = res.start + txx9_scc_tab[i].offset;
+	while ((node = of_find_compatible_node(node,
+				"serial", "toshiba,sio-scc")) != NULL) {
+		for (i = 0; i < ARRAY_SIZE(txx9_scc_tab); i++) {
+			if (!(txx9_serial_bitmap & (1<<i)))
+				continue;
+
+			if (of_irq_map_one(node, i, &irq))
+				continue;
+			if (of_address_to_resource(node,
+				txx9_scc_tab[i].index, &res))
+				continue;
+
+			memset(&req, 0, sizeof(req));
+			req.line = i;
+			req.iotype = UPIO_MEM;
+			req.mapbase = res.start + txx9_scc_tab[i].offset;
 #ifdef CONFIG_SERIAL_TXX9_CONSOLE
-		req.membase = ioremap(req.mapbase, 0x24);
+			req.membase = ioremap(req.mapbase, 0x24);
 #endif
-		req.irq = irq_create_of_mapping(irq.controller,
-			irq.specifier, irq.size);
-		req.flags |= UPF_IOREMAP | UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
-		req.uartclk = 83300000;
-		early_serial_txx9_setup(&req);
+			req.irq = irq_create_of_mapping(irq.controller,
+				irq.specifier, irq.size);
+			req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
+				/*HAVE_CTS_LINE*/;
+			req.uartclk = 83300000;
+			early_serial_txx9_setup(&req);
+		}
 	}
 
-	of_node_put(node);
 	return 0;
 }
 

^ permalink raw reply

* [PATCH 7/7] Celleb: update for PCI
From: Ishizaki Kou @ 2007-09-26  4:40 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch kit to support PCI bus on Celleb with new "I/O routines
for PowerPC." External PCI on Celleb must do explicit synchronization
with devices (Bus has no automatic synchronization feature).

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/pci.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/pci.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/pci.h
@@ -25,11 +25,18 @@
 
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
+#include <asm/ppc-pci.h>
 
 extern int celleb_setup_phb(struct pci_controller *);
 extern int celleb_pci_probe_mode(struct pci_bus *);
 
-extern struct pci_ops celleb_epci_ops;
 extern int celleb_setup_epci(struct device_node *, struct pci_controller *);
 
+extern void *celleb_dummy_page_va;
+extern int __init celleb_pci_workaround_init(void);
+extern void __init celleb_pci_add_one(struct pci_controller *,
+				      void (*)(struct pci_controller *));
+extern void fake_pci_workaround_init(struct pci_controller *);
+extern void epci_workaround_init(struct pci_controller *);
+
 #endif /* _CELLEB_PCI_H */
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc.h
@@ -53,7 +53,7 @@
 #define SCC_EPCI_STATUS         0x808
 #define SCC_EPCI_ABTSET         0x80c
 #define SCC_EPCI_WATRP          0x810
-#define SCC_EPCI_DUMMYRADR      0x814
+#define SCC_EPCI_DUMYRADR       0x814
 #define SCC_EPCI_SWRESP         0x818
 #define SCC_EPCI_CNTOPT         0x81c
 #define SCC_EPCI_ECMODE         0xf00
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Makefile
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
@@ -1,6 +1,7 @@
 obj-y				+= interrupt.o iommu.o setup.o \
-				   htab.o beat.o pci.o \
-				   scc_epci.o scc_uhc.o hvCall.o
+				   htab.o beat.o hvCall.o pci.o \
+				   scc_epci.o scc_uhc.o \
+				   io-workarounds.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)	+= udbg_beat.o
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -137,6 +137,8 @@ static int __init celleb_publish_devices
 	/* Publish OF platform devices for southbridge IOs */
 	of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
 
+	celleb_pci_workaround_init();
+
 	return 0;
 }
 device_initcall(celleb_publish_devices);
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/pci.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/pci.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/pci.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/pci_regs.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -435,36 +436,58 @@ static void __init celleb_alloc_private_
 			GFP_KERNEL);
 }
 
+static int __init celleb_setup_fake_pci(struct device_node *dev,
+					struct pci_controller *phb)
+{
+	struct device_node *node;
+
+	phb->ops = &celleb_fake_pci_ops;
+	celleb_alloc_private_mem(phb);
+
+	for (node = of_get_next_child(dev, NULL);
+	     node != NULL; node = of_get_next_child(dev, node))
+		celleb_setup_fake_pci_device(node, phb);
+
+	return 0;
+}
+
+void __init fake_pci_workaround_init(struct pci_controller *phb)
+{
+	/**
+	 *  We will add fake pci bus to scc_pci_bus for the purpose to improve
+	 *  I/O Macro performance. But device-tree and device drivers
+	 *  are not ready to use address with a token.
+	 */
+
+	/* celleb_pci_add_one(phb, NULL); */
+}
+
+static struct of_device_id celleb_phb_match[] __initdata = {
+	{
+		.name = "pci-pseudo",
+		.data = celleb_setup_fake_pci,
+	}, {
+		.name = "epci",
+		.data = celleb_setup_epci,
+	}, {
+	},
+};
+
 int __init celleb_setup_phb(struct pci_controller *phb)
 {
-	const char *name;
 	struct device_node *dev = phb->arch_data;
-	struct device_node *node;
-	unsigned int rlen;
+	const struct of_device_id *match;
+	int (*setup_func)(struct device_node *, struct pci_controller *);
 
-	name = of_get_property(dev, "name", &rlen);
-	if (!name)
+	match = of_match_node(celleb_phb_match, dev);
+	if (!match)
 		return 1;
 
-	pr_debug("PCI: celleb_setup_phb() %s\n", name);
 	phb_set_bus_ranges(dev, phb);
 	phb->buid = 1;
 
-	if (strcmp(name, "epci") == 0) {
-		phb->ops = &celleb_epci_ops;
-		return celleb_setup_epci(dev, phb);
-
-	} else if (strcmp(name, "pci-pseudo") == 0) {
-		phb->ops = &celleb_fake_pci_ops;
-		celleb_alloc_private_mem(phb);
-		for (node = of_get_next_child(dev, NULL);
-		     node != NULL; node = of_get_next_child(dev, node))
-			celleb_setup_fake_pci_device(node, phb);
-
-	} else
-		return 1;
-
-	return 0;
+	setup_func = match->data;
+	return (*setup_func)(dev, phb);
 }
 
 int celleb_pci_probe_mode(struct pci_bus *bus)
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc_epci.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc_epci.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc_epci.c
@@ -43,7 +43,11 @@
 
 #define iob()  __asm__ __volatile__("eieio; sync":::"memory")
 
-static inline volatile void __iomem *celleb_epci_get_epci_base(
+struct epci_private {
+	dma_addr_t	dummy_page_da;
+};
+
+static inline PCI_IO_ADDR celleb_epci_get_epci_base(
 					struct pci_controller *hose)
 {
 	/*
@@ -55,7 +59,7 @@ static inline volatile void __iomem *cel
 	return hose->cfg_addr;
 }
 
-static inline volatile void __iomem *celleb_epci_get_epci_cfg(
+static inline PCI_IO_ADDR celleb_epci_get_epci_cfg(
 					struct pci_controller *hose)
 {
 	/*
@@ -67,20 +71,11 @@ static inline volatile void __iomem *cel
 	return hose->cfg_data;
 }
 
-#if 0 /* test code for epci dummy read */
-static void celleb_epci_dummy_read(struct pci_dev *dev)
+static void scc_epci_dummy_read(struct pci_controller *hose)
 {
-	volatile void __iomem *epci_base;
-	struct device_node *node;
-	struct pci_controller *hose;
+	PCI_IO_ADDR epci_base;
 	u32 val;
 
-	node = (struct device_node *)dev->bus->sysdata;
-	hose = pci_find_hose_for_OF_device(node);
-
-	if (!hose)
-		return;
-
 	epci_base = celleb_epci_get_epci_base(hose);
 
 	val = in_be32(epci_base + SCC_EPCI_WATRP);
@@ -88,21 +83,45 @@ static void celleb_epci_dummy_read(struc
 
 	return;
 }
-#endif
+
+void __init epci_workaround_init(struct pci_controller *hose)
+{
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR reg;
+	struct epci_private *private = hose->private_data;
+
+	BUG_ON(!private);
+
+	private->dummy_page_da = dma_map_single(hose->parent,
+		celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
+	if (private->dummy_page_da == DMA_ERROR_CODE) {
+		printk(KERN_ERR "EPCI: dummy read disabled."
+		       "Map dummy page failed.\n");
+		return;
+	}
+
+	celleb_pci_add_one(hose, scc_epci_dummy_read);
+	epci_base = celleb_epci_get_epci_base(hose);
+
+	reg = epci_base + SCC_EPCI_DUMYRADR;
+	out_be32(reg, private->dummy_page_da);
+}
 
 static inline void clear_and_disable_master_abort_interrupt(
 					struct pci_controller *hose)
 {
-	volatile void __iomem *epci_base, *reg;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR reg;
 	epci_base = celleb_epci_get_epci_base(hose);
 	reg = epci_base + PCI_COMMAND;
 	out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
 }
 
 static int celleb_epci_check_abort(struct pci_controller *hose,
-				   volatile void __iomem *addr)
+				   PCI_IO_ADDR addr)
 {
-	volatile void __iomem *reg, *epci_base;
+	PCI_IO_ADDR reg;
+	PCI_IO_ADDR epci_base;
 	u32 val;
 
 	iob();
@@ -132,12 +151,12 @@ static int celleb_epci_check_abort(struc
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static volatile void __iomem *celleb_epci_make_config_addr(
+static PCI_IO_ADDR celleb_epci_make_config_addr(
 					struct pci_bus *bus,
 					struct pci_controller *hose,
 					unsigned int devfn, int where)
 {
-	volatile void __iomem *addr;
+	PCI_IO_ADDR addr;
 
 	if (bus != hose->bus)
 		addr = celleb_epci_get_epci_cfg(hose) +
@@ -157,7 +176,8 @@ static volatile void __iomem *celleb_epc
 static int celleb_epci_read_config(struct pci_bus *bus,
 			unsigned int devfn, int where, int size, u32 * val)
 {
-	volatile void __iomem *epci_base, *addr;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR addr;
 	struct device_node *node;
 	struct pci_controller *hose;
 
@@ -220,7 +240,8 @@ static int celleb_epci_read_config(struc
 static int celleb_epci_write_config(struct pci_bus *bus,
 			unsigned int devfn, int where, int size, u32 val)
 {
-	volatile void __iomem *epci_base, *addr;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR addr;
 	struct device_node *node;
 	struct pci_controller *hose;
 
@@ -286,7 +307,8 @@ struct pci_ops celleb_epci_ops = {
 static int __init celleb_epci_init(struct pci_controller *hose)
 {
 	u32 val;
-	volatile void __iomem *reg, *epci_base;
+	PCI_IO_ADDR reg;
+	PCI_IO_ADDR epci_base;
 	int hwres = 0;
 
 	epci_base = celleb_epci_get_epci_base(hose);
@@ -440,10 +462,24 @@ int __init celleb_setup_epci(struct devi
 		 r.start, (unsigned long)hose->cfg_data,
 		(r.end - r.start + 1));
 
+	hose->private_data = kzalloc(sizeof(struct epci_private), GFP_KERNEL);
+	if (hose->private_data == NULL) {
+		printk(KERN_ERR "EPCI: no memory for private data.\n");
+		goto error;
+	}
+
+	hose->ops = &celleb_epci_ops;
 	celleb_epci_init(hose);
 
 	return 0;
 
 error:
+	kfree(hose->private_data);
+
+	if (hose->cfg_addr)
+		iounmap(hose->cfg_addr);
+
+	if (hose->cfg_data)
+		iounmap(hose->cfg_data);
 	return 1;
 }
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/io-workarounds.c
===================================================================
--- /dev/null
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/io-workarounds.c
@@ -0,0 +1,279 @@
+/*
+ * Support for Celleb io workarounds
+ *
+ * (C) Copyright 2006-2007 TOSHIBA CORPORATION
+ *
+ * This file is based to arch/powerpc/platform/cell/io-workarounds.c
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/of_device.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+#include "pci.h"
+
+#define MAX_CELLEB_PCI_BUS	4
+
+void *celleb_dummy_page_va;
+
+static struct celleb_pci_bus {
+	struct pci_controller *phb;
+	void (*dummy_read)(struct pci_controller *);
+} celleb_pci_busses[MAX_CELLEB_PCI_BUS];
+
+static int celleb_pci_count = 0;
+
+static struct celleb_pci_bus *celleb_pci_find(unsigned long vaddr,
+					      unsigned long paddr)
+{
+	int i, j;
+	struct resource *res;
+
+	for (i = 0; i < celleb_pci_count; i++) {
+		struct celleb_pci_bus *bus = &celleb_pci_busses[i];
+		struct pci_controller *phb = bus->phb;
+		if (paddr)
+			for (j = 0; j < 3; j++) {
+				res = &phb->mem_resources[j];
+				if (paddr >= res->start && paddr <= res->end)
+					return bus;
+			}
+		res = &phb->io_resource;
+		if (vaddr && vaddr >= res->start && vaddr <= res->end)
+			return bus;
+	}
+	return NULL;
+}
+
+static void celleb_io_flush(const PCI_IO_ADDR addr)
+{
+	struct celleb_pci_bus *bus;
+	int token;
+
+	token = PCI_GET_ADDR_TOKEN(addr);
+
+	if (token && token <= celleb_pci_count)
+		bus = &celleb_pci_busses[token - 1];
+	else {
+		unsigned long vaddr, paddr;
+		pte_t *ptep;
+
+		vaddr = (unsigned long)PCI_FIX_ADDR(addr);
+		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
+			return;
+
+		ptep = find_linux_pte(init_mm.pgd, vaddr);
+		if (ptep == NULL)
+			paddr = 0;
+		else
+			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
+		bus = celleb_pci_find(vaddr, paddr);
+
+		if (bus == NULL)
+			return;
+	}
+
+	if (bus->dummy_read)
+		bus->dummy_read(bus->phb);
+}
+
+static u8 celleb_readb(const PCI_IO_ADDR addr)
+{
+	u8 val;
+	val = __do_readb(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u16 celleb_readw(const PCI_IO_ADDR addr)
+{
+	u16 val;
+	val = __do_readw(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u32 celleb_readl(const PCI_IO_ADDR addr)
+{
+	u32 val;
+	val = __do_readl(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u64 celleb_readq(const PCI_IO_ADDR addr)
+{
+	u64 val;
+	val = __do_readq(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u16 celleb_readw_be(const PCI_IO_ADDR addr)
+{
+	u16 val;
+	val = __do_readw_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u32 celleb_readl_be(const PCI_IO_ADDR addr)
+{
+	u32 val;
+	val = __do_readl_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u64 celleb_readq_be(const PCI_IO_ADDR addr)
+{
+	u64 val;
+	val = __do_readq_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static void celleb_readsb(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsb(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_readsw(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsw(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_readsl(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsl(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_memcpy_fromio(void *dest,
+				 const PCI_IO_ADDR src,
+				 unsigned long n)
+{
+	__do_memcpy_fromio(dest, src, n);
+	celleb_io_flush(src);
+}
+
+static void __iomem *celleb_ioremap(unsigned long addr,
+				     unsigned long size,
+				     unsigned long flags)
+{
+	struct celleb_pci_bus *bus;
+	void __iomem *res = __ioremap(addr, size, flags);
+	int busno;
+
+	bus = celleb_pci_find(0, addr);
+	if (bus != NULL) {
+		busno = bus - celleb_pci_busses;
+		PCI_SET_ADDR_TOKEN(res, busno + 1);
+	}
+	return res;
+}
+
+static void celleb_iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(PCI_FIX_ADDR(addr));
+}
+
+static struct ppc_pci_io celleb_pci_io __initdata = {
+	.readb = celleb_readb,
+	.readw = celleb_readw,
+	.readl = celleb_readl,
+	.readq = celleb_readq,
+	.readw_be = celleb_readw_be,
+	.readl_be = celleb_readl_be,
+	.readq_be = celleb_readq_be,
+	.readsb = celleb_readsb,
+	.readsw = celleb_readsw,
+	.readsl = celleb_readsl,
+	.memcpy_fromio = celleb_memcpy_fromio,
+};
+
+void __init celleb_pci_add_one(struct pci_controller *phb,
+			       void (*dummy_read)(struct pci_controller *))
+{
+	struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
+	struct device_node *np = phb->arch_data;
+
+	if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
+		printk(KERN_ERR "Too many pci bridges, workarounds"
+		       " disabled for %s\n", np->full_name);
+		return;
+	}
+
+	celleb_pci_count++;
+
+	bus->phb = phb;
+	bus->dummy_read = dummy_read;
+}
+
+static struct of_device_id celleb_pci_workaround_match[] __initdata = {
+	{
+		.name = "pci-pseudo",
+		.data = fake_pci_workaround_init,
+	}, {
+		.name = "epci",
+		.data = epci_workaround_init,
+	}, {
+	},
+};
+
+int __init celleb_pci_workaround_init(void)
+{
+	struct pci_controller *phb;
+	struct device_node *node;
+	const struct  of_device_id *match;
+	void (*init_func)(struct pci_controller *);
+
+	celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!celleb_dummy_page_va) {
+		printk(KERN_ERR "Celleb: dummy read disabled."
+			"Alloc celleb_dummy_page_va failed\n");
+		return 1;
+	}
+
+	list_for_each_entry(phb, &hose_list, list_node) {
+		node = phb->arch_data;
+		match = of_match_node(celleb_pci_workaround_match, node);
+
+		if (match) {
+			init_func = match->data;
+			(*init_func)(phb);
+		}
+	}
+
+	ppc_pci_io = celleb_pci_io;
+	ppc_md.ioremap = celleb_ioremap;
+	ppc_md.iounmap = celleb_iounmap;
+
+	return 0;
+}
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Kconfig
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
@@ -2,6 +2,7 @@ config PPC_CELLEB
 	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
 	depends on PPC_MULTIPLATFORM && PPC64
 	select PPC_CELL
+	select PPC_INDIRECT_IO
 	select PPC_OF_PLATFORM_PCI
 	select HAS_TXX9_SERIAL
 	select PPC_UDBG_BEAT

^ 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