LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC PATCH 14/19] powerpc: allow ioremap within reserved fake ram  regions
From: Albert Herranz @ 2009-11-24 17:09 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1259019909.31172.63.camel@concordia>

Michael Ellerman wrote:
>> Would it be acceptable to create a global var __allow_ioremap_normal_ram that by default would have a value of 0 and would be set _only_ for those platforms needing it?
>>
>> The other solutions I see is:
>> - add support for discontiguous memory to powerpc 32-bits (which is not something that I can look into now)
>> - don't use the precious second 64MB area (which is a waste)
> 
> - Implement your own ppc_md.ioremap(), see iseries & cell for example.
> 
> Currently that's only called on 64-bit, but you could change that.
> 
> If I'm reading your patch right, you should be able to do that check in
> your platform's ioremap() and then call the generic implementation to do
> the actual work.
> 
> cheers

I could use ppc_md.ioremap to duplicate ioremap except for the ioremap ram check.
But calling the stock ioremap without modifying it is not possible because it checks and bails out when ioremapping a region marked as ram (even if it's not real ram and it's memreserved).

Is the list of memreserved areas preserved once the kernel is running?
If it is preserved another option would be to unban ioremapping ram if memreserved.

Thanks for your input,
Albert

^ permalink raw reply

* Re: [PATCH 2/3] powerpc: Add support for creating FIT uImages
From: Peter Tyser @ 2009-11-24 16:48 UTC (permalink / raw)
  To: Stefano Babic; +Cc: linuxppc-dev, linux-kbuild
In-Reply-To: <4B0BB654.9030604@denx.de>

Hi Stefano,
Thanks for trying the patches out.

On Tue, 2009-11-24 at 11:32 +0100, Stefano Babic wrote:
> Peter Tyser <ptyser wrote:
> > +uboot.fit)
> > +    rm -f "$ofile"
> > +    ${MKITS} -A ppc -C gzip -a $membase -e $membase -v $version \
> > +	-d "$srctree/$dtb" -k "$srctree/$vmz" -o "$object/uImage.its"
> > +    ${MKIMAGE} -f "$object/uImage.its" "$ofile"
> 
> Hi,
> 
> I have tested your patches against last mkimage utility provided with
> u-boot. The utility requires to pass the type of the image (flat_dt),
> even if this is not mentioned in the help output. Without the image type
> parameter, no image is generated, and no error is reported.
> It should be:
> 
>     ${MKIMAGE} -f "$object/uImage.its" - T flat_dt "$ofile"

Argh, I'm seeing the same behavior with the latest mkimage source too.
It looks like there was a regression in the mkimage utility - the "-T"
option shouldn't be necessary to create a FIT image.  I'll send a patch
to U-Boot to fix this behavior.

> I have tried to get an image for the lite5200b board, because I have the
> possibility to test the result on the target. However, dtc fails to
> compile the its generated by your script (Version: DTC 1.2.0-g0ef21055,
> cloned from jdt).

I did my testing using the dtc in the linux kernel source
(scripts/dtc/dtc, version 1.2.0) and version 1.2.0-rc1.  I see the same
error as you when using version 1.2.0-g0ef21055.

> DTC: dts->dtb  on file "arch/powerpc/boot/uImage.its"
> Error: arch/powerpc/boot/uImage.its 1:0 syntax error
> 
> Do you test in different conditions ?

Applying the following change should resolve the dtc syntax error.

diff --git a/scripts/mkits.sh b/scripts/mkits.sh
index 88411dd..75edc27 100755
--- a/scripts/mkits.sh
+++ b/scripts/mkits.sh
@@ -64,7 +64,9 @@ ENTRY_ADDR=`echo $ENTRY_ADDR | sed 's/0x//'`
 RAMFS_ADDR=`echo $RAMFS_ADDR | sed 's/0x//'`
 
 # Create a default, fully populated DTS file
-DATA="/ {
+DATA="/dts-v1/;
+
+/ {
        description = \"Linux kernel ${VERSION}\";
        #address-cells = <1>;
 

I'll wait a few more days for feedback then resubmit with the dts syntax
fix

Thanks for testing,
Peter

^ permalink raw reply related

* Re: [PATCH] PPC: Sync guest visible MMU state
From: Avi Kivity @ 2009-11-24 16:05 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm, linuxppc-dev
In-Reply-To: <A6B88177-8F90-4C87-B404-63078E3D3D2C@suse.de>

On 11/24/2009 05:04 PM, Alexander Graf wrote:
>>
>>> index 92045a9..1240fcb 100644
>>> --- a/include/linux/kvm.h
>>> +++ b/include/linux/kvm.h
>>> @@ -492,6 +492,7 @@ struct kvm_ioeventfd {
>>>   #ifdef __KVM_HAVE_VCPU_EVENTS
>>>   #define KVM_CAP_VCPU_EVENTS 41
>>>   #endif
>>> +#define KVM_CAP_PPC_SEGSTATE 42
>>>
>>>
>>>        
>> 42 is already taken (s390 psw and D. Adams), please use 43.
>>      
> Aww. Any reason I didn't get the s390 patch in a git pull yet? (damn that Carsten - he got the cool number)
>
>    

It's in the next branch only ('git fetch blah').

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply

* Re: [PATCH 7/8] spi_mpc8xxx: Turn qe_mode into flags
From: Anton Vorontsov @ 2009-11-24 15:41 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
	spi-devel-general, Andrew Morton
In-Reply-To: <1259039016.16367.118.camel@pasglop>

On Tue, Nov 24, 2009 at 04:03:36PM +1100, Benjamin Herrenschmidt wrote:
[...]
> This patch breaks my 6xx config:
> 
> /home/benh/linux-powerpc-test/arch/powerpc/platforms/83xx/mpc832x_rdb.c: In function ‘of_fsl_spi_probe’:
> /home/benh/linux-powerpc-test/arch/powerpc/platforms/83xx/mpc832x_rdb.c:77: error: ‘struct fsl_spi_platform_data’ has no member named ‘qe_
> 
> The reason is that the mpc832x_rdb.c code still uses the legacy probing
> method. The fix is not totally trivial as the new flags are defined inside
> spi_mpc8xxx.c

Thanks for noticing. I indeed forgot about the legacy stuff. :-/

> If you are going to keep the flags in the .c file you probably also want
> to remove the platform device definition from fsl_devices.h anyways as
> there's no point exposing to the world a structure with a "flags" member
> if the definition of those flags isn't also exposed.

Yep. Though, IIRC Joakim asked to keep the legacy bindings for some
time (until we implement SPI chip-select framework?)... so for now
we'll have to leave we the exposed flags.

Thanks again,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: [PATCH] PPC: Sync guest visible MMU state
From: Alexander Graf @ 2009-11-24 15:04 UTC (permalink / raw)
  To: Avi Kivity; +Cc: kvm-ppc, kvm, linuxppc-dev
In-Reply-To: <4B0BF592.9020802@redhat.com>


On 24.11.2009, at 16:02, Avi Kivity wrote:

> On 11/24/2009 09:50 AM, Alexander Graf wrote:
>> Currently userspace has no chance to find out which virtual address =
space we're
>> in and resolve addresses. While that is a big problem for migration, =
it's also
>> unpleasent when debugging, as gdb and the monitor don't work on =
virtual
>> addresses.
>>  =20
>=20
>> index 92045a9..1240fcb 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -492,6 +492,7 @@ struct kvm_ioeventfd {
>>  #ifdef __KVM_HAVE_VCPU_EVENTS
>>  #define KVM_CAP_VCPU_EVENTS 41
>>  #endif
>> +#define KVM_CAP_PPC_SEGSTATE 42
>>=20
>>  =20
>=20
> 42 is already taken (s390 psw and D. Adams), please use 43.

Aww. Any reason I didn't get the s390 patch in a git pull yet? (damn =
that Carsten - he got the cool number)

Alex

^ permalink raw reply

* Re: [PATCH] PPC: Sync guest visible MMU state
From: Avi Kivity @ 2009-11-24 15:02 UTC (permalink / raw)
  To: Alexander Graf; +Cc: kvm-ppc, kvm, linuxppc-dev
In-Reply-To: <1259049003-8028-1-git-send-email-agraf@suse.de>

On 11/24/2009 09:50 AM, Alexander Graf wrote:
> Currently userspace has no chance to find out which virtual address space we're
> in and resolve addresses. While that is a big problem for migration, it's also
> unpleasent when debugging, as gdb and the monitor don't work on virtual
> addresses.
>    

> index 92045a9..1240fcb 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -492,6 +492,7 @@ struct kvm_ioeventfd {
>   #ifdef __KVM_HAVE_VCPU_EVENTS
>   #define KVM_CAP_VCPU_EVENTS 41
>   #endif
> +#define KVM_CAP_PPC_SEGSTATE 42
>
>    

42 is already taken (s390 psw and D. Adams), please use 43.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply

* Re: [PATCH] ppc64: re-enable kexec to allow module loads with CONFIG_MODVERSIONS and CONFIG_RELOCATABLE turned on
From: Neil Horman @ 2009-11-24 14:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus, nhorman
In-Reply-To: <20091119195216.GC11414@hmsreliant.think-freely.org>

On Thu, Nov 19, 2009 at 02:52:16PM -0500, Neil Horman wrote:
> Hey there-
> 	Before anyone flames me for what a oddball solution this is, let me just
> say I'm trying to get the ball rolling here.  I think there may be better
> solutions that can be impemented in reloc_64.S, but I've yet to make any of the
> ones I've tried work successfully.  I'm open to suggestions, but this solution
> is the only one so far that I've been able to get to work. thanks :)
> 
> 
> Adjust crcs in __kcrctab_* sections if relocs are used with CONFIG_RELOCATABLE
> 
> When CONFIG_MODVERSIONS and CONFIG_RELOCATABLE are enabled on powerpc platforms,
> kdump has been failing in a rather odd way.  specifically modules will not
> install.  This is because when validating the crcs of symbols that the module
> needs, the crc of the module never matches the crc that is stored in the kernel.
> 
> The underlying cause of this is how CONFIG_MODVERSIONS is implemented, and how
> CONFIG_RELOCATABLE are implemented.  with CONFIG_MODVERSIONS enabled, for every
> exported symbol in the kernel we emit 2 symbols, __crc_#sym which is declared
> extern and __kcrctab_##sym, which is placed in the __kcrctab section of the
> binary.  The latter has its value set equal to the address of the former
> (recalling it is declared extern).  After the object file is built, genksyms is
> run on the processed source, and crcs are computed for each exported symbol.
> genksyms then emits a linker script which defines each of the needed __crc_##sym
> symbols, and sets their addresses euqal to their respective crcs.  This script
> is then used in a secondary link to the previously build object file, so that
> the crcs of the missing symbol can be validated on module insert.
> 
> The problem here is that because __kcrctab_sym is set equal to &__crc_##sym, a
> relocation entry is emitted by the compiler for the __kcrctab__##sym.  Normally
> this is not a problem, since relocation on other arches is done without the aid
> of .rel.dyn sections.  PPC however uses these relocations when
> CONFIG_RELOCATABLE is enabled.  nominally, since addressing starts at 0 for ppc,
> its irrelevant, but if we start at a non-zero address (like we do when booting
> via kexec from reserved crashkernel memory), the ppc boot code iterates over the
> relocation entries, and winds up adding that relocation offset to all symbols,
> including the symbols that are actually the aforementioned crc values in the
> __kcrctab_* sections.  This effectively corrupts the crcs and prevents any
> module loads from happening during a kdump.
> 
> My solution is to 'undo' these relocations prior to boot up.  If
> ARCH_USES_RELOC_ENTRIES is defined, we add a symbol at address zero to the
> linker script for that arch (I call it reloc_start, so that &reloc_start = 0).
> This symbol will then indicate the relocation offset for any given boot.  We
> also add an initcall to the module code that, during boot, scans the __kcrctab_*
> sections and subtracts &reloc_start from every entry in those sections,
> restoring the appropriate crc value.
> 
> I've verified that this allows kexec to work properly on ppc64 systems myself.
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> 
Ping, any thoughts here?  As I've been mulling this over, I'm beginning to like
this solution better than a completely arch-specific section, as this approach
makes common the bits that any arch is going to need if they implement
CONFIG_RELOCATABLE with a .rel[a].* section set.  The alternative is of course
to simply skip the appropriate relocations, but thats something that every arch
will need to discover on their own.  This makes it a bit more clear whats
happening I think.

Regards
Neil

^ permalink raw reply

* PMP hot plug issue in kernel
From: Bhartiya Anju-B07263 @ 2009-11-24 12:35 UTC (permalink / raw)
  To: linux-ide; +Cc: linuxppc-dev, Chen, Eric, Kalra Ashish-B00888, Ensheng.Huang

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

Hi All,
 
Recently came across an issue which is decribed below.
 
Setup: Port Multiplier with 2 HDD's connected to it; Port multiplier is
connected to a SATA port of the Host Controller.
 
Test: HDD1 is mounted and using dd command a file of size 512MB is being
written on it.
Command: time sh -c "dd if=/dev/zero of=/mnt/hd/ddfile bs=1k
count=512000 && sync"
 
While this command is running, if the second HDD on PMP is plugged out,
the R/W speed of the first HDD gets affected.
Please see the results of experiments on 2.6.31 kernel.
 
Plug Out	 Plug in	 Normal	
real    0m34.433s
user    0m0.932s
sys     0m21.352s	 real    0m23.726s
user    0m0.908s
sys     0m21.388s	 real    0m23.329s
user    0m1.132s
sys     0m20.968s	
 
The results are similiar with multiple Port Multipliers (Si3726, Si4726
and EXAR PMP) and multiple Host controllers (Si3132  and sata_fsl).
 
As the behaviour with multiple Host controllers and Port Multipliers is
the same so this seems to be an issue with libata stack.
Is there already a patch for this issue? Any pointers or help to fix
this will be greatly appreciated.
 
Best Regards,
Anju
Applications Engineer 
Freescale Semiconductor

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

^ permalink raw reply

* [PATCH] tty/of_serial: add missing ns16550a id
From: Arnd Bergmann @ 2009-11-24 10:22 UTC (permalink / raw)
  To: greg, devicetree-discuss
  Cc: linux-kernel, linux-serial, linuxppc-dev, john.williams

From: Michal Simek <monstr@monstr.eu>

Many boards have a bug-free ns16550 compatible serial port, which we should
register as PORT_16550A. This introduces a new value "ns16550a" for the
compatible property of of_serial to let a firmware choose that model instead
of using the crippled PORT_16550 mode.

Reported-by: Alon Ziv <alonz@nolaviz.org>
Signed-off-by: Michal Simek <monstr@monstr.eu>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

---
Please apply to the tty tree for 2.6.33

--- a/drivers/serial/of_serial.c
+++ b/drivers/serial/of_serial.c
@@ -161,6 +161,7 @@ static int of_platform_serial_remove(struct of_device *ofdev)
 static struct of_device_id __devinitdata of_platform_serial_table[] = {
 	{ .type = "serial", .compatible = "ns8250",   .data = (void *)PORT_8250, },
 	{ .type = "serial", .compatible = "ns16450",  .data = (void *)PORT_16450, },
+	{ .type = "serial", .compatible = "ns16550a", .data = (void *)PORT_16550A, },
 	{ .type = "serial", .compatible = "ns16550",  .data = (void *)PORT_16550, },
 	{ .type = "serial", .compatible = "ns16750",  .data = (void *)PORT_16750, },
 	{ .type = "serial", .compatible = "ns16850",  .data = (void *)PORT_16850, },

^ permalink raw reply

* [PATCH 11/11] of: unify phandle name in struct device_node
From: Grant Likely @ 2009-11-24  8:20 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

In struct device_node, the phandle is named 'linux_phandle' for PowerPC
and MicroBlaze, and 'node' for SPARC.  There is no good reason for the
difference, it is just an artifact of the code diverging over a couple
of years.  This patch renames .node to .linux_phandle for SPARC.

Note: the .node also existed in PowerPC/MicroBlaze, but the only user
seems to be arch/powerpc/platforms/powermac/pfunc_core.c.  It doesn't
look like the assignment between .linux_phandle and .node is
significantly different enough to warrant the separate code paths
unless ibm,phandle properties actually appear in Apple device trees.

I think it is safe to eliminate the old .node property and use
linux_phandle everywhere.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/powerpc/platforms/powermac/pfunc_core.c |    2 +-
 arch/sparc/kernel/devices.c                  |    2 +-
 arch/sparc/kernel/of_device_32.c             |    2 +-
 arch/sparc/kernel/of_device_64.c             |    2 +-
 arch/sparc/kernel/prom_common.c              |    8 ++++----
 arch/sparc/kernel/smp_64.c                   |    2 +-
 drivers/of/fdt.c                             |    3 +--
 drivers/sbus/char/openprom.c                 |   10 +++++-----
 drivers/video/aty/atyfb_base.c               |    2 +-
 include/linux/of.h                           |    3 ---
 10 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index 96d5ce5..2004b19 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -842,7 +842,7 @@ struct pmf_function *__pmf_find_function(struct device_node *target,
 	list_for_each_entry(func, &dev->functions, link) {
 		if (name && strcmp(name, func->name))
 			continue;
-		if (func->phandle && target->node != func->phandle)
+		if (func->phandle && target->linux_phandle != func->phandle)
 			continue;
 		if ((func->flags & flags) == 0)
 			continue;
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index b171ae8..2196e71 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -59,7 +59,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
 
 	cur_inst = 0;
 	for_each_node_by_type(dp, "cpu") {
-		int err = check_cpu_node(dp->node, &cur_inst,
+		int err = check_cpu_node(dp->linux_phandle, &cur_inst,
 					 compare, compare_arg,
 					 prom_node, mid);
 		if (!err) {
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 4c26eb5..27f4c2e 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -433,7 +433,7 @@ build_resources:
 	if (!parent)
 		dev_set_name(&op->dev, "root");
 	else
-		dev_set_name(&op->dev, "%08x", dp->node);
+		dev_set_name(&op->dev, "%08x", dp->linux_phandle);
 
 	if (of_device_register(op)) {
 		printk("%s: Could not register of device.\n",
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index 881947e..9a6245d 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -666,7 +666,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
 	if (!parent)
 		dev_set_name(&op->dev, "root");
 	else
-		dev_set_name(&op->dev, "%08x", dp->node);
+		dev_set_name(&op->dev, "%08x", dp->linux_phandle);
 
 	if (of_device_register(op)) {
 		printk("%s: Could not register of device.\n",
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index d80a65d..2a3e302 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -42,7 +42,7 @@ struct device_node *of_find_node_by_phandle(phandle handle)
 	struct device_node *np;
 
 	for (np = allnodes; np; np = np->allnext)
-		if (np->node == handle)
+		if (np->linux_phandle == handle)
 			break;
 
 	return np;
@@ -89,7 +89,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
 			void *old_val = prop->value;
 			int ret;
 
-			ret = prom_setprop(dp->node, name, val, len);
+			ret = prom_setprop(dp->linux_phandle, name, val, len);
 
 			err = -EINVAL;
 			if (ret >= 0) {
@@ -236,7 +236,7 @@ static struct device_node * __init prom_create_node(phandle node,
 
 	dp->name = get_one_property(node, "name");
 	dp->type = get_one_property(node, "device_type");
-	dp->node = node;
+	dp->linux_phandle = node;
 
 	dp->properties = build_prop_list(node);
 
@@ -313,7 +313,7 @@ void __init prom_build_devicetree(void)
 
 	nextp = &allnodes->allnext;
 	allnodes->child = prom_build_tree(allnodes,
-					  prom_getchild(allnodes->node),
+					  prom_getchild(allnodes->linux_phandle),
 					  &nextp);
 	of_console_init();
 
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index aa36223..9222700 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -370,7 +370,7 @@ static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
 	} else {
 		struct device_node *dp = of_find_node_by_cpuid(cpu);
 
-		prom_startcpu(dp->node, entry, cookie);
+		prom_startcpu(dp->linux_phandle, entry, cookie);
 	}
 
 	for (timeout = 0; timeout < 50000; timeout++) {
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 6164781..07ae161 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -315,9 +315,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 					__alignof__(struct property));
 		if (allnextpp) {
 			if (strcmp(pname, "linux,phandle") == 0) {
-				np->node = *((u32 *)*p);
 				if (np->linux_phandle == 0)
-					np->linux_phandle = np->node;
+					np->linux_phandle = *((u32 *)*p);
 			}
 			if (strcmp(pname, "ibm,phandle") == 0)
 				np->linux_phandle = *((u32 *)*p);
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 75ac19b..a776e65 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -233,7 +233,7 @@ static int opromnext(void __user *argp, unsigned int cmd, struct device_node *dp
 
 	ph = 0;
 	if (dp)
-		ph = dp->node;
+		ph = dp->linux_phandle;
 
 	data->current_node = dp;
 	*((int *) op->oprom_array) = ph;
@@ -256,7 +256,7 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp
 
 		dp = pci_device_to_OF_node(pdev);
 		data->current_node = dp;
-		*((int *)op->oprom_array) = dp->node;
+		*((int *)op->oprom_array) = dp->linux_phandle;
 		op->oprom_size = sizeof(int);
 		err = copyout(argp, op, bufsize + sizeof(int));
 
@@ -273,7 +273,7 @@ static int oprompath2node(void __user *argp, struct device_node *dp, struct open
 
 	dp = of_find_node_by_path(op->oprom_array);
 	if (dp)
-		ph = dp->node;
+		ph = dp->linux_phandle;
 	data->current_node = dp;
 	*((int *)op->oprom_array) = ph;
 	op->oprom_size = sizeof(int);
@@ -540,7 +540,7 @@ static int opiocgetnext(unsigned int cmd, void __user *argp)
 		}
 	}
 	if (dp)
-		nd = dp->node;
+		nd = dp->linux_phandle;
 	if (copy_to_user(argp, &nd, sizeof(phandle)))
 		return -EFAULT;
 
@@ -570,7 +570,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
 	case OPIOCGETOPTNODE:
 		BUILD_BUG_ON(sizeof(phandle) != sizeof(int));
 
-		if (copy_to_user(argp, &options_node->node, sizeof(phandle)))
+		if (copy_to_user(argp, &options_node->linux_phandle, sizeof(phandle)))
 			return -EFAULT;
 
 		return 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 913b4a4..8357927 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -3104,7 +3104,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
 	}
 
 	dp = pci_device_to_OF_node(pdev);
-	if (node == dp->node) {
+	if (node == dp->linux_phandle) {
 		struct fb_var_screeninfo *var = &default_var;
 		unsigned int N, P, Q, M, T, R;
 		u32 v_total, h_total;
diff --git a/include/linux/of.h b/include/linux/of.h
index 0a51742..0ddd985 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -39,10 +39,7 @@ struct of_irq_controller;
 struct device_node {
 	const char *name;
 	const char *type;
-	phandle	node;
-#if !defined(CONFIG_SPARC)
 	phandle linux_phandle;
-#endif
 	char	*full_name;
 
 	struct	property *properties;

^ permalink raw reply related

* [PATCH 10/11] microblaze: gut implementation of early_init_dt_scan_cpus()
From: Grant Likely @ 2009-11-24  8:19 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Microblaze only has one CPU, it isn't SMP at all.  This function is
effectively just a no-op, so remove it.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   54 -----------------------------------------
 1 files changed, 0 insertions(+), 54 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 8c00457..1f79e4d 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -50,60 +50,6 @@ struct device_node *of_chosen;
 int __init early_init_dt_scan_cpus(unsigned long node, const char *uname,
 				   int depth, void *data)
 {
-	static int logical_cpuid;
-	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-	const u32 *intserv;
-	int i, nthreads;
-	int found = 0;
-
-	/* We are scanning "cpu" nodes only */
-	if (type == NULL || strcmp(type, "cpu") != 0)
-		return 0;
-
-	/* Get physical cpuid */
-	intserv = of_get_flat_dt_prop(node, "reg", NULL);
-	nthreads = 1;
-
-	/*
-	 * Now see if any of these threads match our boot cpu.
-	 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
-	 */
-	for (i = 0; i < nthreads; i++) {
-		/*
-		 * version 2 of the kexec param format adds the phys cpuid of
-		 * booted proc.
-		 */
-		if (initial_boot_params && initial_boot_params->version >= 2) {
-			if (intserv[i] ==
-					initial_boot_params->boot_cpuid_phys) {
-				found = 1;
-				break;
-			}
-		} else {
-			/*
-			 * Check if it's the boot-cpu, set it's hw index now,
-			 * unfortunately this format did not support booting
-			 * off secondary threads.
-			 */
-			if (of_get_flat_dt_prop(node,
-					"linux,boot-cpu", NULL) != NULL) {
-				found = 1;
-				break;
-			}
-		}
-
-#ifdef CONFIG_SMP
-		/* logical cpu id is always 0 on UP kernels */
-		logical_cpuid++;
-#endif
-	}
-
-	if (found) {
-		pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid,
-			intserv[i]);
-		boot_cpuid = logical_cpuid;
-	}
-
 	return 0;
 }
 

^ permalink raw reply related

* [PATCH 09/11] of: merge of_attach_node() & of_detach_node()
From: Grant Likely @ 2009-11-24  8:19 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/include/asm/prom.h |    4 --
 arch/microblaze/kernel/prom.c      |   59 -----------------------------------
 arch/powerpc/include/asm/prom.h    |    4 --
 arch/powerpc/kernel/prom.c         |   59 -----------------------------------
 drivers/of/base.c                  |   60 ++++++++++++++++++++++++++++++++++++
 include/linux/of.h                 |    4 ++
 6 files changed, 64 insertions(+), 126 deletions(-)

diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h
index 07d1063..6c6b386 100644
--- a/arch/microblaze/include/asm/prom.h
+++ b/arch/microblaze/include/asm/prom.h
@@ -39,10 +39,6 @@ extern struct device_node *of_chosen;
 
 extern rwlock_t devtree_lock;	/* temporary while merging */
 
-/* For updating the device tree at runtime */
-extern void of_attach_node(struct device_node *);
-extern void of_detach_node(struct device_node *);
-
 /* Other Prototypes */
 extern int early_uartlite_console(void);
 
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index c0d53b7..8c00457 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -313,65 +313,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
 }
 EXPORT_SYMBOL(of_find_node_by_phandle);
 
-/*
- * Plug a device node into the tree and global list.
- */
-void of_attach_node(struct device_node *np)
-{
-	unsigned long flags;
-
-	write_lock_irqsave(&devtree_lock, flags);
-	np->sibling = np->parent->child;
-	np->allnext = allnodes;
-	np->parent->child = np;
-	allnodes = np;
-	write_unlock_irqrestore(&devtree_lock, flags);
-}
-
-/*
- * "Unplug" a node from the device tree.  The caller must hold
- * a reference to the node.  The memory associated with the node
- * is not freed until its refcount goes to zero.
- */
-void of_detach_node(struct device_node *np)
-{
-	struct device_node *parent;
-	unsigned long flags;
-
-	write_lock_irqsave(&devtree_lock, flags);
-
-	parent = np->parent;
-	if (!parent)
-		goto out_unlock;
-
-	if (allnodes == np)
-		allnodes = np->allnext;
-	else {
-		struct device_node *prev;
-		for (prev = allnodes;
-		     prev->allnext != np;
-		     prev = prev->allnext)
-			;
-		prev->allnext = np->allnext;
-	}
-
-	if (parent->child == np)
-		parent->child = np->sibling;
-	else {
-		struct device_node *prevsib;
-		for (prevsib = np->parent->child;
-		     prevsib->sibling != np;
-		     prevsib = prevsib->sibling)
-			;
-		prevsib->sibling = np->sibling;
-	}
-
-	of_node_set_flag(np, OF_DETACHED);
-
-out_unlock:
-	write_unlock_irqrestore(&devtree_lock, flags);
-}
-
 #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
 static struct debugfs_blob_wrapper flat_dt_blob;
 
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index 2ab9cbd..f384db8 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -34,10 +34,6 @@ extern struct device_node *of_chosen;
 
 #define HAVE_ARCH_DEVTREE_FIXUPS
 
-/* For updating the device tree at runtime */
-extern void of_attach_node(struct device_node *);
-extern void of_detach_node(struct device_node *);
-
 #ifdef CONFIG_PPC32
 /*
  * PCI <-> OF matching functions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 6873db9..7d0beeb 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -740,65 +740,6 @@ struct device_node *of_find_next_cache_node(struct device_node *np)
 	return NULL;
 }
 
-/*
- * Plug a device node into the tree and global list.
- */
-void of_attach_node(struct device_node *np)
-{
-	unsigned long flags;
-
-	write_lock_irqsave(&devtree_lock, flags);
-	np->sibling = np->parent->child;
-	np->allnext = allnodes;
-	np->parent->child = np;
-	allnodes = np;
-	write_unlock_irqrestore(&devtree_lock, flags);
-}
-
-/*
- * "Unplug" a node from the device tree.  The caller must hold
- * a reference to the node.  The memory associated with the node
- * is not freed until its refcount goes to zero.
- */
-void of_detach_node(struct device_node *np)
-{
-	struct device_node *parent;
-	unsigned long flags;
-
-	write_lock_irqsave(&devtree_lock, flags);
-
-	parent = np->parent;
-	if (!parent)
-		goto out_unlock;
-
-	if (allnodes == np)
-		allnodes = np->allnext;
-	else {
-		struct device_node *prev;
-		for (prev = allnodes;
-		     prev->allnext != np;
-		     prev = prev->allnext)
-			;
-		prev->allnext = np->allnext;
-	}
-
-	if (parent->child == np)
-		parent->child = np->sibling;
-	else {
-		struct device_node *prevsib;
-		for (prevsib = np->parent->child;
-		     prevsib->sibling != np;
-		     prevsib = prevsib->sibling)
-			;
-		prevsib->sibling = np->sibling;
-	}
-
-	of_node_set_flag(np, OF_DETACHED);
-
-out_unlock:
-	write_unlock_irqrestore(&devtree_lock, flags);
-}
-
 #ifdef CONFIG_PPC_PSERIES
 /*
  * Fix up the uninitialized fields in a new device node:
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 4b10c89..9212b87 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -60,6 +60,66 @@ int of_n_size_cells(struct device_node *np)
 }
 EXPORT_SYMBOL(of_n_size_cells);
 
+/**
+ * of_attach_node - Plug a device node into the tree and global list.
+ */
+void of_attach_node(struct device_node *np)
+{
+	unsigned long flags;
+
+	write_lock_irqsave(&devtree_lock, flags);
+	np->sibling = np->parent->child;
+	np->allnext = allnodes;
+	np->parent->child = np;
+	allnodes = np;
+	write_unlock_irqrestore(&devtree_lock, flags);
+}
+
+/**
+ * of_detach_node - "Unplug" a node from the device tree.
+ *
+ * The caller must hold a reference to the node.  The memory associated with
+ * the node is not freed until its refcount goes to zero.
+ */
+void of_detach_node(struct device_node *np)
+{
+	struct device_node *parent;
+	unsigned long flags;
+
+	write_lock_irqsave(&devtree_lock, flags);
+
+	parent = np->parent;
+	if (!parent)
+		goto out_unlock;
+
+	if (allnodes == np)
+		allnodes = np->allnext;
+	else {
+		struct device_node *prev;
+		for (prev = allnodes;
+		     prev->allnext != np;
+		     prev = prev->allnext)
+			;
+		prev->allnext = np->allnext;
+	}
+
+	if (parent->child == np)
+		parent->child = np->sibling;
+	else {
+		struct device_node *prevsib;
+		for (prevsib = np->parent->child;
+		     prevsib->sibling != np;
+		     prevsib = prevsib->sibling)
+			;
+		prevsib->sibling = np->sibling;
+	}
+
+	of_node_set_flag(np, OF_DETACHED);
+
+out_unlock:
+	write_unlock_irqrestore(&devtree_lock, flags);
+}
+
 #if !defined(CONFIG_SPARC)   /* SPARC doesn't do ref counting (yet) */
 /**
  *	of_node_get - Increment refcount of a node
diff --git a/include/linux/of.h b/include/linux/of.h
index d4c014a..0a51742 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -130,6 +130,10 @@ static inline unsigned long of_read_ulong(const u32 *cell, int size)
 
 #define OF_BAD_ADDR	((u64)-1)
 
+/* For updating the device tree at runtime */
+extern void of_attach_node(struct device_node *);
+extern void of_detach_node(struct device_node *);
+
 extern struct device_node *of_find_node_by_name(struct device_node *from,
 	const char *name);
 #define for_each_node_by_name(dn, name) \

^ permalink raw reply related

* [PATCH 08/11] of: Merge of_node_get() and of_node_put()
From: Grant Likely @ 2009-11-24  8:19 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and MicroBlaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   74 ----------------------------------------
 arch/powerpc/kernel/prom.c    |   73 ----------------------------------------
 drivers/of/base.c             |   75 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 147 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index c97192d..c0d53b7 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -313,80 +313,6 @@ struct device_node *of_find_node_by_phandle(phandle handle)
 }
 EXPORT_SYMBOL(of_find_node_by_phandle);
 
-/**
- *	of_node_get - Increment refcount of a node
- *	@node:	Node to inc refcount, NULL is supported to
- *		simplify writing of callers
- *
- *	Returns node.
- */
-struct device_node *of_node_get(struct device_node *node)
-{
-	if (node)
-		kref_get(&node->kref);
-	return node;
-}
-EXPORT_SYMBOL(of_node_get);
-
-static inline struct device_node *kref_to_device_node(struct kref *kref)
-{
-	return container_of(kref, struct device_node, kref);
-}
-
-/**
- *	of_node_release - release a dynamically allocated node
- *	@kref:  kref element of the node to be released
- *
- *	In of_node_put() this function is passed to kref_put()
- *	as the destructor.
- */
-static void of_node_release(struct kref *kref)
-{
-	struct device_node *node = kref_to_device_node(kref);
-	struct property *prop = node->properties;
-
-	/* We should never be releasing nodes that haven't been detached. */
-	if (!of_node_check_flag(node, OF_DETACHED)) {
-		printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n",
-			node->full_name);
-		dump_stack();
-		kref_init(&node->kref);
-		return;
-	}
-
-	if (!of_node_check_flag(node, OF_DYNAMIC))
-		return;
-
-	while (prop) {
-		struct property *next = prop->next;
-		kfree(prop->name);
-		kfree(prop->value);
-		kfree(prop);
-		prop = next;
-
-		if (!prop) {
-			prop = node->deadprops;
-			node->deadprops = NULL;
-		}
-	}
-	kfree(node->full_name);
-	kfree(node->data);
-	kfree(node);
-}
-
-/**
- *	of_node_put - Decrement refcount of a node
- *	@node:	Node to dec refcount, NULL is supported to
- *		simplify writing of callers
- *
- */
-void of_node_put(struct device_node *node)
-{
-	if (node)
-		kref_put(&node->kref, of_node_release);
-}
-EXPORT_SYMBOL(of_node_put);
-
 /*
  * Plug a device node into the tree and global list.
  */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 65de093..6873db9 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -740,79 +740,6 @@ struct device_node *of_find_next_cache_node(struct device_node *np)
 	return NULL;
 }
 
-/**
- *	of_node_get - Increment refcount of a node
- *	@node:	Node to inc refcount, NULL is supported to
- *		simplify writing of callers
- *
- *	Returns node.
- */
-struct device_node *of_node_get(struct device_node *node)
-{
-	if (node)
-		kref_get(&node->kref);
-	return node;
-}
-EXPORT_SYMBOL(of_node_get);
-
-static inline struct device_node * kref_to_device_node(struct kref *kref)
-{
-	return container_of(kref, struct device_node, kref);
-}
-
-/**
- *	of_node_release - release a dynamically allocated node
- *	@kref:  kref element of the node to be released
- *
- *	In of_node_put() this function is passed to kref_put()
- *	as the destructor.
- */
-static void of_node_release(struct kref *kref)
-{
-	struct device_node *node = kref_to_device_node(kref);
-	struct property *prop = node->properties;
-
-	/* We should never be releasing nodes that haven't been detached. */
-	if (!of_node_check_flag(node, OF_DETACHED)) {
-		printk("WARNING: Bad of_node_put() on %s\n", node->full_name);
-		dump_stack();
-		kref_init(&node->kref);
-		return;
-	}
-
-	if (!of_node_check_flag(node, OF_DYNAMIC))
-		return;
-
-	while (prop) {
-		struct property *next = prop->next;
-		kfree(prop->name);
-		kfree(prop->value);
-		kfree(prop);
-		prop = next;
-
-		if (!prop) {
-			prop = node->deadprops;
-			node->deadprops = NULL;
-		}
-	}
-	kfree(node->full_name);
-	kfree(node->data);
-	kfree(node);
-}
-
-/**
- *	of_node_put - Decrement refcount of a node
- *	@node:	Node to dec refcount, NULL is supported to
- *		simplify writing of callers
- *
- */
-void of_node_put(struct device_node *node)
-{
-	if (node)
-		kref_put(&node->kref, of_node_release);
-}
-EXPORT_SYMBOL(of_node_put);
-
 /*
  * Plug a device node into the tree and global list.
  */
diff --git a/drivers/of/base.c b/drivers/of/base.c
index e81558f..4b10c89 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -60,6 +60,81 @@ int of_n_size_cells(struct device_node *np)
 }
 EXPORT_SYMBOL(of_n_size_cells);
 
+#if !defined(CONFIG_SPARC)   /* SPARC doesn't do ref counting (yet) */
+/**
+ *	of_node_get - Increment refcount of a node
+ *	@node:	Node to inc refcount, NULL is supported to
+ *		simplify writing of callers
+ *
+ *	Returns node.
+ */
+struct device_node *of_node_get(struct device_node *node)
+{
+	if (node)
+		kref_get(&node->kref);
+	return node;
+}
+EXPORT_SYMBOL(of_node_get);
+
+static inline struct device_node *kref_to_device_node(struct kref *kref)
+{
+	return container_of(kref, struct device_node, kref);
+}
+
+/**
+ *	of_node_release - release a dynamically allocated node
+ *	@kref:  kref element of the node to be released
+ *
+ *	In of_node_put() this function is passed to kref_put()
+ *	as the destructor.
+ */
+static void of_node_release(struct kref *kref)
+{
+	struct device_node *node = kref_to_device_node(kref);
+	struct property *prop = node->properties;
+
+	/* We should never be releasing nodes that haven't been detached. */
+	if (!of_node_check_flag(node, OF_DETACHED)) {
+		pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
+		dump_stack();
+		kref_init(&node->kref);
+		return;
+	}
+
+	if (!of_node_check_flag(node, OF_DYNAMIC))
+		return;
+
+	while (prop) {
+		struct property *next = prop->next;
+		kfree(prop->name);
+		kfree(prop->value);
+		kfree(prop);
+		prop = next;
+
+		if (!prop) {
+			prop = node->deadprops;
+			node->deadprops = NULL;
+		}
+	}
+	kfree(node->full_name);
+	kfree(node->data);
+	kfree(node);
+}
+
+/**
+ *	of_node_put - Decrement refcount of a node
+ *	@node:	Node to dec refcount, NULL is supported to
+ *		simplify writing of callers
+ *
+ */
+void of_node_put(struct device_node *node)
+{
+	if (node)
+		kref_put(&node->kref, of_node_release);
+}
+EXPORT_SYMBOL(of_node_put);
+#endif /* !CONFIG_SPARC */
+
 struct property *of_find_property(const struct device_node *np,
 				  const char *name,
 				  int *lenp)

^ permalink raw reply related

* [PATCH 07/11] of: merge machine_is_compatible()
From: Grant Likely @ 2009-11-24  8:19 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   18 ------------------
 arch/powerpc/kernel/prom.c    |   18 ------------------
 drivers/of/base.c             |   18 ++++++++++++++++++
 3 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 543465a..c97192d 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -281,24 +281,6 @@ void __init early_init_devtree_arch(void)
 	/* No Microblaze specific code here */
 }
 
-/**
- * Indicates whether the root node has a given value in its
- * compatible property.
- */
-int machine_is_compatible(const char *compat)
-{
-	struct device_node *root;
-	int rc = 0;
-
-	root = of_find_node_by_path("/");
-	if (root) {
-		rc = of_device_is_compatible(root, compat);
-		of_node_put(root);
-	}
-	return rc;
-}
-EXPORT_SYMBOL(machine_is_compatible);
-
 /*******
  *
  * New implementation of the OF "find" APIs, return a refcounted
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index a5b3b9d..65de093 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -677,24 +677,6 @@ void __init early_init_devtree_arch(void)
 	lmb_enforce_memory_limit(limit);
 }
 
-/**
- * Indicates whether the root node has a given value in its
- * compatible property.
- */
-int machine_is_compatible(const char *compat)
-{
-	struct device_node *root;
-	int rc = 0;
-
-	root = of_find_node_by_path("/");
-	if (root) {
-		rc = of_device_is_compatible(root, compat);
-		of_node_put(root);
-	}
-	return rc;
-}
-EXPORT_SYMBOL(machine_is_compatible);
-
 /*******
  *
  * New implementation of the OF "find" APIs, return a refcounted
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ec56739..e81558f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -144,6 +144,24 @@ int of_device_is_compatible(const struct device_node *device,
 EXPORT_SYMBOL(of_device_is_compatible);
 
 /**
+ * Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+int machine_is_compatible(const char *compat)
+{
+	struct device_node *root;
+	int rc = 0;
+
+	root = of_find_node_by_path("/");
+	if (root) {
+		rc = of_device_is_compatible(root, compat);
+		of_node_put(root);
+	}
+	return rc;
+}
+EXPORT_SYMBOL(machine_is_compatible);
+
+/**
  *  of_device_is_available - check if a device is available for use
  *
  *  @device: Node to check for availability

^ permalink raw reply related

* [PATCH 06/11] of/flattree: merge early_init_devtree() and early_init_move_devtree()
From: Grant Likely @ 2009-11-24  8:19 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between Microblaze and PowerPC

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   53 +++--------------------
 arch/powerpc/kernel/prom.c    |   94 +++--------------------------------------
 drivers/of/fdt.c              |   92 ++++++++++++++++++++++++++++++++++++++++
 include/linux/of_fdt.h        |    7 +++
 4 files changed, 115 insertions(+), 131 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 7ee021f..543465a 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -47,9 +47,8 @@ struct device_node *of_chosen;
 
 #define early_init_dt_scan_drconf_memory(node) 0
 
-static int __init early_init_dt_scan_cpus(unsigned long node,
-					  const char *uname, int depth,
-					  void *data)
+int __init early_init_dt_scan_cpus(unsigned long node, const char *uname,
+				   int depth, void *data)
 {
 	static int logical_cpuid;
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
@@ -113,8 +112,8 @@ void __init early_init_dt_scan_chosen_arch(unsigned long node)
 	/* No Microblaze specific code here */
 }
 
-static int __init early_init_dt_scan_memory(unsigned long node,
-				const char *uname, int depth, void *data)
+int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
+				     int depth, void *data)
 {
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 	u32 *reg, *endp;
@@ -201,7 +200,7 @@ static inline unsigned long phyp_dump_calculate_reserve_size(void)
  * without reserving anything. The memory in case of dump being
  * active is freed when the dump is collected (by userland tools).
  */
-static void __init phyp_dump_reserve_mem(void)
+void __init phyp_dump_reserve_mem(void)
 {
 	unsigned long base, size;
 	unsigned long variable_reserve_size;
@@ -240,7 +239,7 @@ static void __init phyp_dump_reserve_mem(void)
 	}
 }
 #else
-static inline void __init phyp_dump_reserve_mem(void) {}
+inline void __init phyp_dump_reserve_mem(void) {}
 #endif /* CONFIG_PHYP_DUMP  && CONFIG_PPC_RTAS */
 
 #ifdef CONFIG_EARLY_PRINTK
@@ -277,45 +276,9 @@ int __init early_uartlite_console(void)
 }
 #endif
 
-void __init early_init_devtree(void *params)
+void __init early_init_devtree_arch(void)
 {
-	pr_debug(" -> early_init_devtree(%p)\n", params);
-
-	/* Setup flat device-tree pointer */
-	initial_boot_params = params;
-
-#ifdef CONFIG_PHYP_DUMP
-	/* scan tree to see if dump occured during last boot */
-	of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
-#endif
-
-	/* Retrieve various informations from the /chosen node of the
-	 * device-tree, including the platform type, initrd location and
-	 * size, TCE reserve, and more ...
-	 */
-	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
-
-	/* Scan memory nodes and rebuild LMBs */
-	lmb_init();
-	of_scan_flat_dt(early_init_dt_scan_root, NULL);
-	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
-
-	/* Save command line for /proc/cmdline and then parse parameters */
-	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
-	parse_early_param();
-
-	lmb_analyze();
-
-	pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size());
-
-	pr_debug("Scanning CPUs ...\n");
-
-	/* Retreive CPU related informations from the flat tree
-	 * (altivec support, boot CPU ID, ...)
-	 */
-	of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
-
-	pr_debug(" <- early_init_devtree()\n");
+	/* No Microblaze specific code here */
 }
 
 /**
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 2c7d4a3..a5b3b9d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -84,33 +84,6 @@ static int __init early_parse_mem(char *p)
 }
 early_param("mem", early_parse_mem);
 
-/**
- * move_device_tree - move tree to an unused area, if needed.
- *
- * The device tree may be allocated beyond our memory limit, or inside the
- * crash kernel region for kdump. If so, move it out of the way.
- */
-static void __init move_device_tree(void)
-{
-	unsigned long start, size;
-	void *p;
-
-	DBG("-> move_device_tree\n");
-
-	start = __pa(initial_boot_params);
-	size = initial_boot_params->totalsize;
-
-	if ((memory_limit && (start + size) > memory_limit) ||
-			overlaps_crashkernel(start, size)) {
-		p = __va(lmb_alloc_base(size, PAGE_SIZE, lmb.rmo_size));
-		memcpy(p, initial_boot_params, size);
-		initial_boot_params = (struct boot_param_header *)p;
-		DBG("Moved device tree to 0x%p\n", p);
-	}
-
-	DBG("<- move_device_tree\n");
-}
-
 /*
  * ibm,pa-features is a per-cpu property that contains a string of
  * attribute descriptors, each of which has a 2 byte header plus up
@@ -267,9 +240,8 @@ static void __init check_cpu_feature_properties(unsigned long node)
 	}
 }
 
-static int __init early_init_dt_scan_cpus(unsigned long node,
-					  const char *uname, int depth,
-					  void *data)
+int __init early_init_dt_scan_cpus(unsigned long node, const char *uname,
+				   int depth, void *data)
 {
 	static int logical_cpuid = 0;
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
@@ -483,8 +455,8 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 #define early_init_dt_scan_drconf_memory(node)	0
 #endif /* CONFIG_PPC_PSERIES */
 
-static int __init early_init_dt_scan_memory(unsigned long node,
-					    const char *uname, int depth, void *data)
+int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
+				     int depth, void *data)
 {
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 	u32 *reg, *endp;
@@ -543,7 +515,7 @@ static int __init early_init_dt_scan_memory(unsigned long node,
 	return 0;
 }
 
-static void __init early_reserve_mem(void)
+void __init early_reserve_mem(void)
 {
 	u64 base, size;
 	u64 *reserve_map;
@@ -635,7 +607,7 @@ static inline unsigned long phyp_dump_calculate_reserve_size(void)
  * without reserving anything. The memory in case of dump being
  * active is freed when the dump is collected (by userland tools).
  */
-static void __init phyp_dump_reserve_mem(void)
+void __init phyp_dump_reserve_mem(void)
 {
 	unsigned long base, size;
 	unsigned long variable_reserve_size;
@@ -674,44 +646,13 @@ static void __init phyp_dump_reserve_mem(void)
 	}
 }
 #else
-static inline void __init phyp_dump_reserve_mem(void) {}
+inline void __init phyp_dump_reserve_mem(void) {}
 #endif /* CONFIG_PHYP_DUMP  && CONFIG_PPC_RTAS */
 
-
-void __init early_init_devtree(void *params)
+void __init early_init_devtree_arch(void)
 {
 	phys_addr_t limit;
 
-	DBG(" -> early_init_devtree(%p)\n", params);
-
-	/* Setup flat device-tree pointer */
-	initial_boot_params = params;
-
-#ifdef CONFIG_PPC_RTAS
-	/* Some machines might need RTAS info for debugging, grab it now. */
-	of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
-#endif
-
-#ifdef CONFIG_PHYP_DUMP
-	/* scan tree to see if dump occured during last boot */
-	of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
-#endif
-
-	/* Retrieve various informations from the /chosen node of the
-	 * device-tree, including the platform type, initrd location and
-	 * size, TCE reserve, and more ...
-	 */
-	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
-
-	/* Scan memory nodes and rebuild LMBs */
-	lmb_init();
-	of_scan_flat_dt(early_init_dt_scan_root, NULL);
-	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
-
-	/* Save command line for /proc/cmdline and then parse parameters */
-	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
-	parse_early_param();
-
 	/* Reserve LMB regions used by kernel, initrd, dt, etc... */
 	lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
 	/* If relocatable, reserve first 32k for interrupt vectors etc. */
@@ -734,27 +675,8 @@ void __init early_init_devtree(void *params)
 			limit = memsize & PAGE_MASK;
 	}
 	lmb_enforce_memory_limit(limit);
-
-	lmb_analyze();
-	lmb_dump_all();
-
-	DBG("Phys. mem: %llx\n", lmb_phys_mem_size());
-
-	/* We may need to relocate the flat tree, do it now.
-	 * FIXME .. and the initrd too? */
-	move_device_tree();
-
-	DBG("Scanning CPUs ...\n");
-
-	/* Retreive CPU related informations from the flat tree
-	 * (altivec support, boot CPU ID, ...)
-	 */
-	of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
-
-	DBG(" <- early_init_devtree()\n");
 }
 
-
 /**
  * Indicates whether the root node has a given value in its
  * compatible property.
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 616a476..6164781 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -16,7 +16,12 @@
 #include <linux/of_fdt.h>
 
 #ifdef CONFIG_PPC
+#include <asm/kexec.h>
 #include <asm/machdep.h>
+
+#ifdef CONFIG_PPC_RTAS
+#include <asm/rtas.h>
+#endif
 #endif /* CONFIG_PPC */
 
 int __initdata dt_root_addr_cells;
@@ -479,6 +484,93 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 }
 
 /**
+ * early_init_move_devtree - move tree to an unused area, if needed.
+ *
+ * The device tree may be allocated beyond our memory limit, or inside the
+ * crash kernel region for kdump. If so, move it out of the way.
+ */
+#if defined(CONFIG_PPC)
+static void __init early_init_move_devtree(void)
+{
+	unsigned long start, size;
+	void *p;
+
+	pr_debug("-> %s()\n", __func__);
+
+	start = __pa(initial_boot_params);
+	size = initial_boot_params->totalsize;
+
+	if ((memory_limit && (start + size) > memory_limit) ||
+			overlaps_crashkernel(start, size)) {
+		p = __va(lmb_alloc_base(size, PAGE_SIZE, lmb.rmo_size));
+		memcpy(p, initial_boot_params, size);
+		initial_boot_params = (struct boot_param_header *)p;
+		pr_debug("Moved device tree to 0x%p\n", p);
+	}
+
+	pr_debug("<- %s()\n", __func__);
+}
+#else
+static void __init early_init_move_devtree(void) {}
+#endif
+
+void __init early_init_devtree(void *params)
+{
+	pr_debug(" -> early_init_devtree(%p)\n", params);
+
+	/* Setup flat device-tree pointer */
+	initial_boot_params = params;
+
+#ifdef CONFIG_PPC_RTAS
+	/* Some machines might need RTAS info for debugging, grab it now. */
+	of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
+#endif
+
+#ifdef CONFIG_PHYP_DUMP
+	/* scan tree to see if dump occured during last boot */
+	of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL);
+#endif
+
+	/* Retrieve various informations from the /chosen node of the
+	 * device-tree, including the platform type, initrd location and
+	 * size, TCE reserve, and more ...
+	 */
+	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+
+	/* Scan memory nodes and rebuild LMBs */
+	lmb_init();
+	of_scan_flat_dt(early_init_dt_scan_root, NULL);
+	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+	/* Save command line for /proc/cmdline and then parse parameters */
+	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+	parse_early_param();
+
+	/* This is in an arbitrary spot, but it is temporary.  After all
+	 * the common code is merged, the structure of the early init
+	 * code will be reevaluated and refactored */
+	early_init_devtree_arch();
+
+	lmb_analyze();
+	lmb_dump_all();
+
+	pr_debug("Phys. mem: %llx\n", lmb_phys_mem_size());
+
+	/* We may need to relocate the flat tree, do it now.
+	 * FIXME .. and the initrd too? */
+	early_init_move_devtree();
+
+	pr_debug("Scanning CPUs ...\n");
+
+	/* Retreive CPU related informations from the flat tree
+	 * (altivec support, boot CPU ID, ...)
+	 */
+	of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
+
+	pr_debug(" <- early_init_devtree()\n");
+}
+
+/**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
  * unflattens the device-tree passed by the firmware, creating the
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 8118d45..d1b1571 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -75,6 +75,13 @@ extern void early_init_dt_scan_chosen_arch(unsigned long node);
 extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
 				     int depth, void *data);
 extern void early_init_dt_check_for_initrd(unsigned long node);
+extern int early_init_dt_scan_cpus(unsigned long node, const char *uname,
+				   int depth, void *data);
+extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
+				     int depth, void *data);
+extern void early_reserve_mem(void);
+extern void early_init_devtree_arch(void);
+extern void phyp_dump_reserve_mem(void);
 extern u64 dt_mem_next_cell(int s, u32 **cellp);
 
 /* Early flat tree scan hooks */

^ permalink raw reply related

* [PATCH 05/11] of/flattree: merge early_init_dt_scan_chosen()
From: Grant Likely @ 2009-11-24  8:18 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze.  This patch
splits the arch-specific stuff out into a new function,
early_init_dt_scan_chosen_arch().

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   44 ++-------------------------------------
 arch/powerpc/kernel/prom.c    |   46 +++++++++--------------------------------
 drivers/of/fdt.c              |   38 ++++++++++++++++++++++++++++++++++
 include/linux/of_fdt.h        |    3 +++
 4 files changed, 53 insertions(+), 78 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 7760186..7ee021f 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -108,49 +108,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 	return 0;
 }
 
-static int __init early_init_dt_scan_chosen(unsigned long node,
-				const char *uname, int depth, void *data)
+void __init early_init_dt_scan_chosen_arch(unsigned long node)
 {
-	unsigned long l;
-	char *p;
-
-	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
-
-	if (depth != 1 ||
-		(strcmp(uname, "chosen") != 0 &&
-				strcmp(uname, "chosen@0") != 0))
-		return 0;
-
-#ifdef CONFIG_KEXEC
-	lprop = (u64 *)of_get_flat_dt_prop(node,
-				"linux,crashkernel-base", NULL);
-	if (lprop)
-		crashk_res.start = *lprop;
-
-	lprop = (u64 *)of_get_flat_dt_prop(node,
-				"linux,crashkernel-size", NULL);
-	if (lprop)
-		crashk_res.end = crashk_res.start + *lprop - 1;
-#endif
-
-	early_init_dt_check_for_initrd(node);
-
-	/* Retreive command line */
-	p = of_get_flat_dt_prop(node, "bootargs", &l);
-	if (p != NULL && l > 0)
-		strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
-
-#ifdef CONFIG_CMDLINE
-#ifndef CONFIG_CMDLINE_FORCE
-	if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
-#endif
-		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
-#endif /* CONFIG_CMDLINE */
-
-	pr_debug("Command line is: %s\n", cmd_line);
-
-	/* break now */
-	return 1;
+	/* No Microblaze specific code here */
 }
 
 static int __init early_init_dt_scan_memory(unsigned long node,
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 43cdba2..2c7d4a3 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -367,18 +367,9 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 	return 0;
 }
 
-static int __init early_init_dt_scan_chosen(unsigned long node,
-					    const char *uname, int depth, void *data)
+void __init early_init_dt_scan_chosen_arch(unsigned long node)
 {
 	unsigned long *lprop;
-	unsigned long l;
-	char *p;
-
-	DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
-
-	if (depth != 1 ||
-	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
-		return 0;
 
 #ifdef CONFIG_PPC64
 	/* check if iommu is forced on or off */
@@ -389,17 +380,17 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 #endif
 
 	/* mem=x on the command line is the preferred mechanism */
- 	lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
- 	if (lprop)
- 		memory_limit = *lprop;
+	lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
+	if (lprop)
+		memory_limit = *lprop;
 
 #ifdef CONFIG_PPC64
- 	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
- 	if (lprop)
- 		tce_alloc_start = *lprop;
- 	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
- 	if (lprop)
- 		tce_alloc_end = *lprop;
+	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-start", NULL);
+	if (lprop)
+		tce_alloc_start = *lprop;
+	lprop = of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
+	if (lprop)
+		tce_alloc_end = *lprop;
 #endif
 
 #ifdef CONFIG_KEXEC
@@ -411,23 +402,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	if (lprop)
 		crashk_res.end = crashk_res.start + *lprop - 1;
 #endif
-
-	early_init_dt_check_for_initrd(node);
-
-	/* Retreive command line */
- 	p = of_get_flat_dt_prop(node, "bootargs", &l);
-	if (p != NULL && l > 0)
-		strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
-
-#ifdef CONFIG_CMDLINE
-	if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
-		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
-#endif /* CONFIG_CMDLINE */
-
-	DBG("Command line is: %s\n", cmd_line);
-
-	/* break now */
-	return 1;
 }
 
 #ifdef CONFIG_PPC_PSERIES
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index ebce509..616a476 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,10 @@
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 
+#ifdef CONFIG_PPC
+#include <asm/machdep.h>
+#endif /* CONFIG_PPC */
+
 int __initdata dt_root_addr_cells;
 int __initdata dt_root_size_cells;
 
@@ -440,6 +444,40 @@ u64 __init dt_mem_next_cell(int s, u32 **cellp)
 	return of_read_number(p, s);
 }
 
+int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
+				     int depth, void *data)
+{
+	unsigned long l;
+	char *p;
+
+	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
+
+	if (depth != 1 ||
+	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
+		return 0;
+
+	early_init_dt_check_for_initrd(node);
+
+	/* Retreive command line */
+	p = of_get_flat_dt_prop(node, "bootargs", &l);
+	if (p != NULL && l > 0)
+		strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE));
+
+#ifdef CONFIG_CMDLINE
+#ifndef CONFIG_CMDLINE_FORCE
+	if (p == NULL || l == 0 || (l == 1 && (*p) == 0))
+#endif
+		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+#endif /* CONFIG_CMDLINE */
+
+	early_init_dt_scan_chosen_arch(node);
+
+	pr_debug("Command line is: %s\n", cmd_line);
+
+	/* break now */
+	return 1;
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index d1a37e5..8118d45 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -71,6 +71,9 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
 				 unsigned long *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern unsigned long of_get_flat_dt_root(void);
+extern void early_init_dt_scan_chosen_arch(unsigned long node);
+extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
+				     int depth, void *data);
 extern void early_init_dt_check_for_initrd(unsigned long node);
 extern u64 dt_mem_next_cell(int s, u32 **cellp);
 

^ permalink raw reply related

* [PATCH 04/11] of/flattree: eliminate cell_t typedef
From: Grant Likely @ 2009-11-24  8:18 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

A cell is firmly established as a u32.  No need to do an ugly typedef
to redefine it to cell_t.  Eliminate the unnecessary typedef so that
it doesn't have to be added to the of_fdt header file

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   10 ++++------
 arch/powerpc/kernel/prom.c    |   14 ++++++--------
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index e0f4c34..7760186 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,8 +42,6 @@
 #include <asm/sections.h>
 #include <asm/pci-bridge.h>
 
-typedef u32 cell_t;
-
 /* export that to outside world */
 struct device_node *of_chosen;
 
@@ -159,7 +157,7 @@ static int __init early_init_dt_scan_memory(unsigned long node,
 				const char *uname, int depth, void *data)
 {
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-	cell_t *reg, *endp;
+	u32 *reg, *endp;
 	unsigned long l;
 
 	/* Look for the ibm,dynamic-reconfiguration-memory node */
@@ -178,13 +176,13 @@ static int __init early_init_dt_scan_memory(unsigned long node,
 	} else if (strcmp(type, "memory") != 0)
 		return 0;
 
-	reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
+	reg = (u32 *)of_get_flat_dt_prop(node, "linux,usable-memory", &l);
 	if (reg == NULL)
-		reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
+		reg = (u32 *)of_get_flat_dt_prop(node, "reg", &l);
 	if (reg == NULL)
 		return 0;
 
-	endp = reg + (l / sizeof(cell_t));
+	endp = reg + (l / sizeof(u32));
 
 	pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
 		uname, l, reg[0], reg[1], reg[2], reg[3]);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 048e3a3..43cdba2 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -67,8 +67,6 @@ int __initdata iommu_force_on;
 unsigned long tce_alloc_start, tce_alloc_end;
 #endif
 
-typedef u32 cell_t;
-
 extern rwlock_t devtree_lock;	/* temporary while merging */
 
 /* export that to outside world */
@@ -441,22 +439,22 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
  */
 static int __init early_init_dt_scan_drconf_memory(unsigned long node)
 {
-	cell_t *dm, *ls, *usm;
+	u32 *dm, *ls, *usm;
 	unsigned long l, n, flags;
 	u64 base, size, lmb_size;
 	unsigned int is_kexec_kdump = 0, rngs;
 
 	ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l);
-	if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t))
+	if (ls == NULL || l < dt_root_size_cells * sizeof(u32))
 		return 0;
 	lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls);
 
 	dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l);
-	if (dm == NULL || l < sizeof(cell_t))
+	if (dm == NULL || l < sizeof(u32))
 		return 0;
 
 	n = *dm++;	/* number of entries */
-	if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t))
+	if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(u32))
 		return 0;
 
 	/* check if this is a kexec/kdump kernel. */
@@ -515,7 +513,7 @@ static int __init early_init_dt_scan_memory(unsigned long node,
 					    const char *uname, int depth, void *data)
 {
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-	cell_t *reg, *endp;
+	u32 *reg, *endp;
 	unsigned long l;
 
 	/* Look for the ibm,dynamic-reconfiguration-memory node */
@@ -540,7 +538,7 @@ static int __init early_init_dt_scan_memory(unsigned long node,
 	if (reg == NULL)
 		return 0;
 
-	endp = reg + (l / sizeof(cell_t));
+	endp = reg + (l / sizeof(u32));
 
 	DBG("memory scan node %s, reg size %ld, data: %x %x %x %x,\n",
 	    uname, l, reg[0], reg[1], reg[2], reg[3]);

^ permalink raw reply related

* [PATCH 03/11] of/flattree: merge dt_mem_next_cell
From: Grant Likely @ 2009-11-24  8:18 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |    8 --------
 arch/powerpc/kernel/prom.c    |    8 --------
 drivers/of/fdt.c              |    8 ++++++++
 include/linux/of_fdt.h        |    1 +
 4 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 189179a..e0f4c34 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -155,14 +155,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	return 1;
 }
 
-static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
-{
-	cell_t *p = *cellp;
-
-	*cellp = p + s;
-	return of_read_number(p, s);
-}
-
 static int __init early_init_dt_scan_memory(unsigned long node,
 				const char *uname, int depth, void *data)
 {
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 78f65a4..048e3a3 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -432,14 +432,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	return 1;
 }
 
-static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
-{
-	cell_t *p = *cellp;
-
-	*cellp = p + s;
-	return of_read_number(p, s);
-}
-
 #ifdef CONFIG_PPC_PSERIES
 /*
  * Interpret the ibm,dynamic-memory property in the
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index be200be..ebce509 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -432,6 +432,14 @@ int __init early_init_dt_scan_root(unsigned long node, const char *uname,
 	return 1;
 }
 
+u64 __init dt_mem_next_cell(int s, u32 **cellp)
+{
+	u32 *p = *cellp;
+
+	*cellp = p + s;
+	return of_read_number(p, s);
+}
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 828c3cd..d1a37e5 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -72,6 +72,7 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern unsigned long of_get_flat_dt_root(void);
 extern void early_init_dt_check_for_initrd(unsigned long node);
+extern u64 dt_mem_next_cell(int s, u32 **cellp);
 
 /* Early flat tree scan hooks */
 extern int early_init_dt_scan_root(unsigned long node, const char *uname,

^ permalink raw reply related

* [PATCH 02/11] of/flattree: Merge earlyinit_dt_scan_root()
From: Grant Likely @ 2009-11-24  8:18 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---

 arch/microblaze/kernel/prom.c |   23 -----------------------
 arch/powerpc/kernel/prom.c    |   24 ------------------------
 drivers/of/fdt.c              |   26 ++++++++++++++++++++++++++
 include/linux/of_fdt.h        |    6 ++++++
 4 files changed, 32 insertions(+), 47 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 7959495..189179a 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,9 +42,6 @@
 #include <asm/sections.h>
 #include <asm/pci-bridge.h>
 
-static int __initdata dt_root_addr_cells;
-static int __initdata dt_root_size_cells;
-
 typedef u32 cell_t;
 
 /* export that to outside world */
@@ -158,26 +155,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	return 1;
 }
 
-static int __init early_init_dt_scan_root(unsigned long node,
-				const char *uname, int depth, void *data)
-{
-	u32 *prop;
-
-	if (depth != 0)
-		return 0;
-
-	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
-	pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
-
-	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
-	pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
-
-	/* break now */
-	return 1;
-}
-
 static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
 {
 	cell_t *p = *cellp;
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 1ecd6c6..78f65a4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -61,10 +61,6 @@
 #define DBG(fmt...)
 #endif
 
-
-static int __initdata dt_root_addr_cells;
-static int __initdata dt_root_size_cells;
-
 #ifdef CONFIG_PPC64
 int __initdata iommu_is_off;
 int __initdata iommu_force_on;
@@ -436,26 +432,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 	return 1;
 }
 
-static int __init early_init_dt_scan_root(unsigned long node,
-					  const char *uname, int depth, void *data)
-{
-	u32 *prop;
-
-	if (depth != 0)
-		return 0;
-
-	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
-	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
-	DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
-
-	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
-	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
-	DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
-	
-	/* break now */
-	return 1;
-}
-
 static u64 __init dt_mem_next_cell(int s, cell_t **cellp)
 {
 	cell_t *p = *cellp;
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 6ad98e8..be200be 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,9 @@
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 
+int __initdata dt_root_addr_cells;
+int __initdata dt_root_size_cells;
+
 struct boot_param_header *initial_boot_params;
 
 char *find_flat_dt_string(u32 offset)
@@ -407,6 +410,29 @@ inline void early_init_dt_check_for_initrd(unsigned long node)
 #endif /* CONFIG_BLK_DEV_INITRD */
 
 /**
+ * early_init_dt_scan_root - fetch the top level address and size cells
+ */
+int __init early_init_dt_scan_root(unsigned long node, const char *uname,
+				   int depth, void *data)
+{
+	u32 *prop;
+
+	if (depth != 0)
+		return 0;
+
+	prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
+	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
+	pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
+
+	prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
+	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
+	pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
+
+	/* break now */
+	return 1;
+}
+
+/**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
  * unflattens the device-tree passed by the firmware, creating the
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index ec2db82..828c3cd 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -58,6 +58,8 @@ struct boot_param_header {
 };
 
 /* TBD: Temporary export of fdt globals - remove when code fully merged */
+extern int __initdata dt_root_addr_cells;
+extern int __initdata dt_root_size_cells;
 extern struct boot_param_header *initial_boot_params;
 
 /* For scanning the flat device-tree at boot time */
@@ -71,6 +73,10 @@ extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern unsigned long of_get_flat_dt_root(void);
 extern void early_init_dt_check_for_initrd(unsigned long node);
 
+/* Early flat tree scan hooks */
+extern int early_init_dt_scan_root(unsigned long node, const char *uname,
+				   int depth, void *data);
+
 /* Other Prototypes */
 extern void finish_device_tree(void);
 extern void unflatten_device_tree(void);

^ permalink raw reply related

* [PATCH 01/11] of/flattree: Merge early_init_dt_check_for_initrd()
From: Grant Likely @ 2009-11-24  8:17 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr
In-Reply-To: <20091124081316.6216.66310.stgit@angua>

Merge common code between PowerPC and Microblaze

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by: Michal Simek <monstr@monstr.eu>
---

 arch/microblaze/kernel/prom.c |   32 --------------------------------
 arch/powerpc/kernel/prom.c    |   30 ------------------------------
 drivers/of/fdt.c              |   37 +++++++++++++++++++++++++++++++++++++
 include/linux/of_fdt.h        |    1 +
 4 files changed, 38 insertions(+), 62 deletions(-)

diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index a38e373..7959495 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -113,38 +113,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init early_init_dt_check_for_initrd(unsigned long node)
-{
-	unsigned long l;
-	u32 *prop;
-
-	pr_debug("Looking for initrd properties... ");
-
-	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
-	if (prop) {
-		initrd_start = (unsigned long)
-					__va((u32)of_read_ulong(prop, l/4));
-
-		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
-		if (prop) {
-			initrd_end = (unsigned long)
-					__va((u32)of_read_ulong(prop, 1/4));
-			initrd_below_start_ok = 1;
-		} else {
-			initrd_start = 0;
-		}
-	}
-
-	pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
-					initrd_start, initrd_end);
-}
-#else
-static inline void early_init_dt_check_for_initrd(unsigned long node)
-{
-}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
 static int __init early_init_dt_scan_chosen(unsigned long node,
 				const char *uname, int depth, void *data)
 {
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 7f88566..1ecd6c6 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -373,36 +373,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
 	return 0;
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static void __init early_init_dt_check_for_initrd(unsigned long node)
-{
-	unsigned long l;
-	u32 *prop;
-
-	DBG("Looking for initrd properties... ");
-
-	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
-	if (prop) {
-		initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
-
-		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
-		if (prop) {
-			initrd_end = (unsigned long)
-					__va(of_read_ulong(prop, l/4));
-			initrd_below_start_ok = 1;
-		} else {
-			initrd_start = 0;
-		}
-	}
-
-	DBG("initrd_start=0x%lx  initrd_end=0x%lx\n", initrd_start, initrd_end);
-}
-#else
-static inline void early_init_dt_check_for_initrd(unsigned long node)
-{
-}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
 static int __init early_init_dt_scan_chosen(unsigned long node,
 					    const char *uname, int depth, void *data)
 {
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 43d236c..6ad98e8 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/lmb.h>
+#include <linux/initrd.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 
@@ -369,6 +370,42 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
 	return mem;
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+/**
+ * early_init_dt_check_for_initrd - Decode initrd location from flat tree
+ * @node: reference to node containing initrd location ('chosen')
+ */
+void __init early_init_dt_check_for_initrd(unsigned long node)
+{
+	unsigned long len;
+	u32 *prop;
+
+	pr_debug("Looking for initrd properties... ");
+
+	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
+	if (prop) {
+		initrd_start = (unsigned long)
+				__va(of_read_ulong(prop, len/4));
+
+		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
+		if (prop) {
+			initrd_end = (unsigned long)
+				__va(of_read_ulong(prop, len/4));
+			initrd_below_start_ok = 1;
+		} else {
+			initrd_start = 0;
+		}
+	}
+
+	pr_debug("initrd_start=0x%lx  initrd_end=0x%lx\n",
+		 initrd_start, initrd_end);
+}
+#else
+inline void early_init_dt_check_for_initrd(unsigned long node)
+{
+}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 /**
  * unflatten_device_tree - create tree of device_nodes from flat blob
  *
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 81231e0..ec2db82 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -69,6 +69,7 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
 				 unsigned long *size);
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern unsigned long of_get_flat_dt_root(void);
+extern void early_init_dt_check_for_initrd(unsigned long node);
 
 /* Other Prototypes */
 extern void finish_device_tree(void);

^ permalink raw reply related

* [PATCH 00/11] Yet another series of OF merge patches.
From: Grant Likely @ 2009-11-24  8:17 UTC (permalink / raw)
  To: linuxppc-dev, devicetree-discuss, sparclinux, microblaze-uclinux,
	benh, sfr, davem, monstr

Nothing much to say here other than mostly mechanical merging of OF
support code.  Some of it remains a little ugly, but I'm taking the
approach of merging the code first, and refactoring it second.

I've pushed this series out to my test-devicetree branch on my git
server if anyone wants to test.  That branch also includes the
previous 2 patch series that I've sent out.

git://git.secretlab.ca/git/linux-2.6 test-devicetree

Compile tested on: ppc64, ppc32, microblaze, sparc64, sparc32.
Boot tested on mpc5200 (ppc32) platform.

---

Grant Likely (11):
      of: unify phandle name in struct device_node
      microblaze: gut implementation of early_init_dt_scan_cpus()
      of: merge of_attach_node() & of_detach_node()
      of: Merge of_node_get() and of_node_put()
      of: merge machine_is_compatible()
      of/flattree: merge early_init_devtree() and early_init_move_devtree()
      of/flattree: merge early_init_dt_scan_chosen()
      of/flattree: eliminate cell_t typedef
      of/flattree: merge dt_mem_next_cell
      of/flattree: Merge earlyinit_dt_scan_root()
      of/flattree: Merge early_init_dt_check_for_initrd()


 arch/microblaze/include/asm/prom.h           |    4 
 arch/microblaze/kernel/prom.c                |  375 +-------------------------
 arch/powerpc/include/asm/prom.h              |    4 
 arch/powerpc/kernel/prom.c                   |  366 ++-----------------------
 arch/powerpc/platforms/powermac/pfunc_core.c |    2 
 arch/sparc/kernel/devices.c                  |    2 
 arch/sparc/kernel/of_device_32.c             |    2 
 arch/sparc/kernel/of_device_64.c             |    2 
 arch/sparc/kernel/prom_common.c              |    8 -
 arch/sparc/kernel/smp_64.c                   |    2 
 drivers/of/base.c                            |  153 +++++++++++
 drivers/of/fdt.c                             |  204 ++++++++++++++
 drivers/sbus/char/openprom.c                 |   10 -
 drivers/video/aty/atyfb_base.c               |    2 
 include/linux/of.h                           |    7 
 include/linux/of_fdt.h                       |   18 +
 16 files changed, 430 insertions(+), 731 deletions(-)

-- 
Signature

^ permalink raw reply

* [PATCH] PPC: Sync guest visible MMU state
From: Alexander Graf @ 2009-11-24  7:50 UTC (permalink / raw)
  To: kvm; +Cc: kvm-ppc, linuxppc-dev

Currently userspace has no chance to find out which virtual address space we're
in and resolve addresses. While that is a big problem for migration, it's also
unpleasent when debugging, as gdb and the monitor don't work on virtual
addresses.

This patch exports enough of the MMU segment state to userspace to make
debugging work and thus also includes the groundwork for migration.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 arch/powerpc/include/asm/kvm.h        |   20 ++++++++++++-
 arch/powerpc/include/asm/kvm_asm.h    |    1 +
 arch/powerpc/include/asm/kvm_book3s.h |    3 ++
 arch/powerpc/kvm/book3s.c             |   47 +++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/book3s_64_emulate.c  |   38 ++++++++++++++++----------
 arch/powerpc/kvm/book3s_64_mmu.c      |    2 +
 arch/powerpc/kvm/powerpc.c            |    3 ++
 include/linux/kvm.h                   |    1 +
 8 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index c9ca97f..bc0aeba 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -46,8 +46,24 @@ struct kvm_regs {
 };
 
 struct kvm_sregs {
-	__u32 pvr;
-	char pad[1020];
+	union {
+		struct {
+			__u32 pvr;
+			__u64 sdr1;
+			struct {
+				struct {
+					__u64 slbe;
+					__u64 slbv;
+				} slb[64];
+			} ppc64;
+			struct {
+				__u32 sr[16];
+				__u64 ibat[8]; 
+				__u64 dbat[8]; 
+			} ppc32;
+		};
+		__u8 pad[1024];
+	};
 };
 
 struct kvm_fpu {
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 19ddb35..af2abe7 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -87,6 +87,7 @@
 #define BOOK3S_IRQPRIO_MAX			16
 
 #define BOOK3S_HFLAG_DCBZ32			0x1
+#define BOOK3S_HFLAG_SLB			0x2
 
 #define RESUME_FLAG_NV          (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST        (1<<1)  /* Resume host? */
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index c601133..74b7369 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -46,6 +46,7 @@ struct kvmppc_sr {
 };
 
 struct kvmppc_bat {
+	u64 raw;
 	u32 bepi;
 	u32 bepi_mask;
 	bool vs;
@@ -113,6 +114,8 @@ extern struct kvmppc_pte *kvmppc_mmu_find_pte(struct kvm_vcpu *vcpu, u64 ea, boo
 extern int kvmppc_ld(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr, bool data);
 extern int kvmppc_st(struct kvm_vcpu *vcpu, ulong eaddr, int size, void *ptr);
 extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec);
+extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
+			   bool upper, u32 val);
 
 extern u32 kvmppc_trampoline_lowmem;
 extern u32 kvmppc_trampoline_enter;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 42037d4..650ebf8 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -281,6 +281,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
 
 void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
 {
+	vcpu->arch.hflags &= ~BOOK3S_HFLAG_SLB;
 	vcpu->arch.pvr = pvr;
 	if ((pvr >= 0x330000) && (pvr < 0x70330000)) {
 		kvmppc_mmu_book3s_64_init(vcpu);
@@ -762,14 +763,60 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
                                   struct kvm_sregs *sregs)
 {
+	int i;
+
 	sregs->pvr = vcpu->arch.pvr;
+
+	sregs->sdr1 = to_book3s(vcpu)->sdr1;
+	if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
+		for (i = 0; i < 64; i++) {
+			sregs->ppc64.slb[i].slbe = to_book3s(vcpu)->slb[i].orige | i;
+			sregs->ppc64.slb[i].slbv = to_book3s(vcpu)->slb[i].origv;
+		}
+	} else {
+		for (i = 0; i < 16; i++) {
+			sregs->ppc32.sr[i] = to_book3s(vcpu)->sr[i].raw;
+			sregs->ppc32.sr[i] = to_book3s(vcpu)->sr[i].raw;
+		}
+		for (i = 0; i < 8; i++) {
+			sregs->ppc32.ibat[i] = to_book3s(vcpu)->ibat[i].raw;
+			sregs->ppc32.dbat[i] = to_book3s(vcpu)->dbat[i].raw;
+		}
+	}
 	return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
                                   struct kvm_sregs *sregs)
 {
+	int i;
+
 	kvmppc_set_pvr(vcpu, sregs->pvr);
+
+	to_book3s(vcpu)->sdr1 = sregs->sdr1;
+	if (vcpu->arch.hflags & BOOK3S_HFLAG_SLB) {
+		for (i = 0; i < 64; i++) {
+			vcpu->arch.mmu.slbmte(vcpu, sregs->ppc64.slb[i].slbv,
+						    sregs->ppc64.slb[i].slbe);
+		}
+	} else {
+		for (i = 0; i < 16; i++) {
+			vcpu->arch.mmu.mtsrin(vcpu, i, sregs->ppc32.sr[i]);
+		}
+		for (i = 0; i < 8; i++) {
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->ibat[i]), false,
+				       (u32)sregs->ppc32.ibat[i]);
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->ibat[i]), true,
+				       (u32)(sregs->ppc32.ibat[i] >> 32));
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->dbat[i]), false,
+				       (u32)sregs->ppc32.dbat[i]);
+			kvmppc_set_bat(vcpu, &(to_book3s(vcpu)->dbat[i]), true,
+				       (u32)(sregs->ppc32.dbat[i] >> 32));
+		}
+	}
+
+	/* Flush the MMU after messing with the segments */
+	kvmppc_mmu_pte_flush(vcpu, 0, 0);
 	return 0;
 }
 
diff --git a/arch/powerpc/kvm/book3s_64_emulate.c b/arch/powerpc/kvm/book3s_64_emulate.c
index c343e67..1027eac 100644
--- a/arch/powerpc/kvm/book3s_64_emulate.c
+++ b/arch/powerpc/kvm/book3s_64_emulate.c
@@ -185,7 +185,27 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
 	return emulated;
 }
 
-static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
+void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat, bool upper,
+                    u32 val)
+{
+	if (upper) {
+		/* Upper BAT */
+		u32 bl = (val >> 2) & 0x7ff;
+		bat->bepi_mask = (~bl << 17);
+		bat->bepi = val & 0xfffe0000;
+		bat->vs = (val & 2) ? 1 : 0;
+		bat->vp = (val & 1) ? 1 : 0;
+		bat->raw = (bat->raw & 0xffffffff00000000ULL) | val;
+	} else {
+		/* Lower BAT */
+		bat->brpn = val & 0xfffe0000;
+		bat->wimg = (val >> 3) & 0xf;
+		bat->pp = val & 3;
+		bat->raw = (bat->raw & 0x00000000ffffffffULL) | ((u64)val << 32);
+	}
+}
+
+static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u32 val)
 {
 	struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
 	struct kvmppc_bat *bat;
@@ -207,19 +227,7 @@ static void kvmppc_write_bat(struct kvm_vcpu *vcpu, int sprn, u64 val)
 		BUG();
 	}
 
-	if (!(sprn % 2)) {
-		/* Upper BAT */
-		u32 bl = (val >> 2) & 0x7ff;
-		bat->bepi_mask = (~bl << 17);
-		bat->bepi = val & 0xfffe0000;
-		bat->vs = (val & 2) ? 1 : 0;
-		bat->vp = (val & 1) ? 1 : 0;
-	} else {
-		/* Lower BAT */
-		bat->brpn = val & 0xfffe0000;
-		bat->wimg = (val >> 3) & 0xf;
-		bat->pp = val & 3;
-	}
+	kvmppc_set_bat(vcpu, bat, !(sprn % 2), val);
 }
 
 int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
@@ -243,7 +251,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
 	case SPRN_IBAT4U ... SPRN_IBAT7L:
 	case SPRN_DBAT0U ... SPRN_DBAT3L:
 	case SPRN_DBAT4U ... SPRN_DBAT7L:
-		kvmppc_write_bat(vcpu, sprn, vcpu->arch.gpr[rs]);
+		kvmppc_write_bat(vcpu, sprn, (u32)vcpu->arch.gpr[rs]);
 		/* BAT writes happen so rarely that we're ok to flush
 		 * everything here */
 		kvmppc_mmu_pte_flush(vcpu, 0, 0);
diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c
index a31f9c6..5598f88 100644
--- a/arch/powerpc/kvm/book3s_64_mmu.c
+++ b/arch/powerpc/kvm/book3s_64_mmu.c
@@ -473,4 +473,6 @@ void kvmppc_mmu_book3s_64_init(struct kvm_vcpu *vcpu)
 	mmu->esid_to_vsid = kvmppc_mmu_book3s_64_esid_to_vsid;
 	mmu->ea_to_vp = kvmppc_mmu_book3s_64_ea_to_vp;
 	mmu->is_dcbz32 = kvmppc_mmu_book3s_64_is_dcbz32;
+
+	vcpu->arch.hflags |= BOOK3S_HFLAG_SLB;
 }
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 4c582ed..f06cf93 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -145,6 +145,9 @@ int kvm_dev_ioctl_check_extension(long ext)
 	int r;
 
 	switch (ext) {
+	case KVM_CAP_PPC_SEGSTATE:
+		r = 1;
+		break;
 	case KVM_CAP_COALESCED_MMIO:
 		r = KVM_COALESCED_MMIO_PAGE_OFFSET;
 		break;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 92045a9..1240fcb 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -492,6 +492,7 @@ struct kvm_ioeventfd {
 #ifdef __KVM_HAVE_VCPU_EVENTS
 #define KVM_CAP_VCPU_EVENTS 41
 #endif
+#define KVM_CAP_PPC_SEGSTATE 42
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
1.6.0.2

^ permalink raw reply related

* Re: Fix bug in pagetable cache cleanup with CONFIG_PPC_SUBPAGE_PROT
From: Sachin Sant @ 2009-11-24  6:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <20091124053114.GD2737@yookeroo>

David Gibson wrote:
> Commit a0668cdc154e54bf0c85182e0535eea237d53146 cleans up the handling
> of kmem_caches for allocating various levels of pagetables.
> Unfortunately, it conflicts badly with CONFIG_PPC_SUBPAGE_PROT, due to
> the latter's cleverly hidden technique of adding some extra allocation
> space to the top level page directory to store the extra information
> it needs.
>
> Since that extra allocation really doesn't fit into the cleaned up
> page directory allocating scheme, this patch alters
> CONFIG_PPC_SUBPAGE_PROT to instead allocate its struct
> subpage_prot_table as part of the mm_context_t.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Thanks David for the patch. With this patch on top of next-20091123
my test machine boots fine. 

Regards
-Sachin

-- 

---------------------------------
Sachin Sant
IBM Linux Technology Center
India Systems and Technology Labs
Bangalore, India
---------------------------------

^ permalink raw reply

* Re: Fix bug in gup_hugepd()
From: Stephen Rothwell @ 2009-11-24  6:25 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20091124060340.GE2737@yookeroo>

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

Hi David,

On Tue, 24 Nov 2009 17:03:40 +1100 David Gibson <david@gibson.dropbear.id.au> wrote:
>
> Commit a4fe3ce7699bfe1bd88f816b55d42d8fe1dac655 introduced a new

When you quote a SHA1, please also quote the summary line for the commit
so those without git access may find it.

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

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

^ permalink raw reply

* Fix bug in gup_hugepd()
From: David Gibson @ 2009-11-24  6:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Commit a4fe3ce7699bfe1bd88f816b55d42d8fe1dac655 introduced a new
get_user_pages() path for hugepages on powerpc.  Unfortunately, there
is a bug in it's loop logic, which can cause it to overrun the end of
the intended region.  This came about by copying the logic from the
normal page path, which assumes the address and end parameters have
been pagesize aligned at the top-level.  Since they're not *hugepage*
size aligned, the simplistic logic could step over the end of the gup
region without triggering the loop end condition.

This patch fixes the bug by using the technique that the normal page
path uses in levels above the lowest to truncate the ending address to
something we know we'll match with.

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

Index: working-2.6/arch/powerpc/mm/hugetlbpage.c
===================================================================
--- working-2.6.orig/arch/powerpc/mm/hugetlbpage.c	2009-11-24 14:25:36.488330625 +1100
+++ working-2.6/arch/powerpc/mm/hugetlbpage.c	2009-11-24 15:55:27.296455938 +1100
@@ -436,18 +436,27 @@ static noinline int gup_hugepte(pte_t *p
 	return 1;
 }
 
+static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
+				      unsigned long sz)
+{
+	unsigned long __boundary = (addr + sz) & ~(sz-1);
+	return (__boundary - 1 < end - 1) ? __boundary : end;
+}
+
 int gup_hugepd(hugepd_t *hugepd, unsigned pdshift,
 	       unsigned long addr, unsigned long end,
 	       int write, struct page **pages, int *nr)
 {
 	pte_t *ptep;
 	unsigned long sz = 1UL << hugepd_shift(*hugepd);
+	unsigned long next;
 
 	ptep = hugepte_offset(hugepd, addr, pdshift);
 	do {
+		next = hugepte_addr_end(addr, end, sz);
 		if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr))
 			return 0;
-	} while (ptep++, addr += sz, addr != end);
+	} while (ptep++, addr = next, addr != end);
 
 	return 1;
 }


-- 
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


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