* Re: [i2c] i2c-mpc.c driver issues
From: Joakim Tjernlund @ 2007-10-26 11:21 UTC (permalink / raw)
To: Jean Delvare; +Cc: linuxppc-dev, i2c
In-Reply-To: <20071026115329.0307e207@hyperion.delvare>
On Fri, 2007-10-26 at 11:53 +0200, Jean Delvare wrote:
> Hi Jocke,
>
> On Wed, 24 Oct 2007 23:06:13 +0200, Tjernlund wrote:
> > While browsing the i2c-mpc.c driver I noticed some things that look odd
> > to me so I figured I report them. Could not find a maintainer in the MAINTANERS file
> > so I sent here, cc:ed linuxppc-dev as well.
> >
> > 1) There are a lot of return -1 error code that is propagated back to
> > userspace. Should be changed to proper -Exxx codes.
>
> This is true of many Linux i2c bus drivers, unfortunately. While nothing
> actually prevents drivers from returning -1 to userspace on error,
> meaningful error codes would of course be preferred.
>
> > 2) mpc_read(), according to the comment below it sends a STOP condition here but
> > this function does not known if this is the last read or not. mpc_xfer is
> > the one that knows when the transaction is over and should send the stop, which it already
> > does.
> >
> > /* Generate stop on last byte */
> > if (i == length - 1)
> > writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK);
>
> Probably correct, although I am not familiar with this specific
> hardware. I guess that the same is true of mpc_write as well, which is
> even worse because write + read combined transactions are very common
> (while read + write are not.)
Don't think write is a problem, only read. I would have to look at the
HW spec to make sure though.
>
> I'm not completely sure that mpc_xfer sends the stop. mpc_i2c_stop
> doesn't seem to do much.
>
> Now that you've identified these bugs, what about sending patches
> to fix them?
Normally I would do that, but I am too busy with other things. Thats
why I only reported this as I know I won't have time to fix it for some
time.
Jocke
^ permalink raw reply
* Re: [RFC] [PATCH] PowerPC: Workaround for the 440EP(x)/GR(x) processors identical PVR issue.
From: Valentine Barshak @ 2007-10-26 11:05 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, sr
In-Reply-To: <1193345051.7018.15.camel@pasglop>
Benjamin Herrenschmidt wrote:
> On Thu, 2007-10-25 at 22:16 +0400, Valentine Barshak wrote:
>> PowerPC 440EP(x) 440GR(x) processors have the same PVR values, since
>> they have identical cores. However, FPU is not supported on GR(x) and
>> enabling APU instruction broadcast in the CCR0 register (to enable FPU)
>> may cause unpredictable results. There's no safe way to detect FPU
>> support at runtime. This patch provides a workarund for the issue.
>> We use a POWER6 "logical PVR approach". First, we identify all EP(x)
>> and GR(x) processors as GR(x) ones (which is safe). Then we check
>> the device tree cpu path. If we have a EP(x) processor entry,
>> we call identify_cpu again with PVR | 0x8. This bit is always 0
>> in the real PVR. This way we enable FPU only for 440EP(x).
>>
>> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
>
> Why not just or-in the FPU feature bit ?
>
> Ben.
>
>
It's not enough. We need to enable APU instruction broadcast for EP(x)
(call __init_fpu_44x in arch/powerpc/kernel/cpu_setup_44x.S).
Or do you suggest to or-in FPU feature bit and enable APUIB later, not
in the cpu_setup callback?
Thanks,
Valentine.
^ permalink raw reply
* Re: [PATCH 01/16] Add of_get_next_parent()
From: David Miller @ 2007-10-26 10:38 UTC (permalink / raw)
To: michael; +Cc: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
From: Michael Ellerman <michael@ellerman.id.au>
Date: Fri, 26 Oct 2007 16:54:31 +1000 (EST)
> Iterating through a device node's parents is simple enough, but dealing
> with the refcounts properly is a little ugly, and replicating that logic
> is asking for someone to get it wrong or forget it all together, eg:
>
> while (dn != NULL) {
> /* loop body */
> tmp = of_get_parent(dn);
> of_node_put(dn);
> dn = tmp;
> }
>
> So add of_get_next_parent(), inspired by of_get_next_child(). The contract
> is that it returns the parent and drops the reference on the current node,
> this makes the loop look like:
>
> while (dn != NULL) {
> /* loop body */
> dn = of_get_next_parent(dn);
> }
>
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Looks good to me:
Acked-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply
* Re: [i2c] i2c-mpc.c driver issues
From: Jean Delvare @ 2007-10-26 9:53 UTC (permalink / raw)
To: Tjernlund; +Cc: linuxppc-dev, i2c
In-Reply-To: <019001c81681$b5d449c0$5267a8c0@Jocke>
Hi Jocke,
On Wed, 24 Oct 2007 23:06:13 +0200, Tjernlund wrote:
> While browsing the i2c-mpc.c driver I noticed some things that look odd
> to me so I figured I report them. Could not find a maintainer in the MAINTANERS file
> so I sent here, cc:ed linuxppc-dev as well.
>
> 1) There are a lot of return -1 error code that is propagated back to
> userspace. Should be changed to proper -Exxx codes.
This is true of many Linux i2c bus drivers, unfortunately. While nothing
actually prevents drivers from returning -1 to userspace on error,
meaningful error codes would of course be preferred.
> 2) mpc_read(), according to the comment below it sends a STOP condition here but
> this function does not known if this is the last read or not. mpc_xfer is
> the one that knows when the transaction is over and should send the stop, which it already
> does.
>
> /* Generate stop on last byte */
> if (i == length - 1)
> writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK);
Probably correct, although I am not familiar with this specific
hardware. I guess that the same is true of mpc_write as well, which is
even worse because write + read combined transactions are very common
(while read + write are not.)
I'm not completely sure that mpc_xfer sends the stop. mpc_i2c_stop
doesn't seem to do much.
Now that you've identified these bugs, what about sending patches
to fix them?
--
Jean Delvare
^ permalink raw reply
* Re: ppc manual paging question
From: Wang, Baojun @ 2007-10-26 9:50 UTC (permalink / raw)
To: benh, linuxppc-dev
In-Reply-To: <393040796.08064@lzu.edu.cn>
[-- Attachment #1: Type: text/plain, Size: 3456 bytes --]
On Monday 22 October 2007 16:04:14, Benjamin Herrenschmidt wrote:
> > Yup, I've found how does the kernel handle tlbs, I think the most
> > important thing is I forgot read/write the SPRN_SPRG3 register as _switch
> > does.
>
> SPRG3 is for use by the operating system for whatever you want... if you
> are copying linux code, then you probably indeed want to get that right
> but you don't have to use SPRG3.
>
> > I've add the _PAGE_PRESENT flag to the related PTE
>
> Hrm.. that has nothing ot do with the PTE. Bolting is more a property of
> your replacement algorithm in the TLB miss handler.
>
> Ben.
Hi,
First thanks a lot for your help I've finish the tlb code, now I can
manually translate the virtual address correctly, I verified this by printing
out the data within the virtual address and it's fine. now the only thing
left is jump to that address (the address is point to _start function), But I
got an error about unable to access the stack (0xd100fc60 ...), but it is
valid before the instruction:
/**
* XXX: should not defined here
*/
#define EVENTS_USER_ADDR_OFFSET 36
_GLOBAL(jump_xm_dom)
stwu r1,-INT_FRAME_SIZE(r1)
mflr r0
stw r0,INT_FRAME_SIZE+4(r1)
stw r31,INT_FRAME_SIZE+128(r1)
lwz r5,EVENTS_USER_ADDR_OFFSET(r4)
mr r31,r5 /* new_domain->events_user_addr */
cmpwi r3,0
beq 1f
mtctr r3 /* jump to entry_point */
bctrl
li r3,0
1:
lwz r31,INT_FRAME_SIZE+128(r1)
lwz r0,INT_FRAME_SIZE+4(r1)
addi r1,r1,INT_FRAME_SIZE
mtlr r0
blr
the SP is valid before `bctrl', while exec bctrl, I got the error said unable
to access address SP ($r1) from bdigdb, without bdigbd (running directly), an
error is print out while the system is dead:
insn: 94 21 ff 40 7c 08 02 a6 90 01 00 c4 7f e3 fb 78 3d 20 10 01 90 69 07 a0
48 00 02 55 80 01 00 c4
$T0440:10000094;01:d1072e60;#ee
address d1072e60 is the address of SP ($r1) before bctrl.
NOTE entry_point($r3) is address like 0x100000a0 which is loaded from the
userspace by a loader program (it loads all section marked as PT_LOAD, such
as .text, the above insn is the entry of .text section, which is _start), but
the above code is from the kernel space. and here is the _start function:
#define INT_FRAME_SIZE 192
.globl _start
_start:
stwu 1, -INT_FRAME_SIZE(1)
mflr 0
stw 0, INT_FRAME_SIZE+4(1)
mr 3,31 /* new_domain->events_user_addr */
lis 9, event_handling@ha
stw 3, event_handling@l(9)
bl kmain
lwz 0, INT_FRAME_SIZE+4(1);
mtlr 0
addi 1, 1, INT_FRAME_SIZE
blr
.size _start, .-_start
I'm sorry I'm not very familiar with the ppc assembly, is there something
fundamentally wrong? Thank you very much!
Regards,
Wang
--
Wang, Baojun Lanzhou University
Distributed & Embedded System Lab http://dslab.lzu.edu.cn
School of Information Science and Engeneering wangbj@lzu.edu.cn
Tianshui South Road 222. Lanzhou 730000 .P.R.China
Tel:+86-931-8912025 Fax:+86-931-8912022
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* mpc8xx, i2c read DB busy issue
From: Ankur Maheshwari @ 2007-10-26 9:30 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
I am trying to use mpc860 as i2c-SLAVE. Kernel, I am using is
Linux-2.4.4, which I can't change due to some reasons.
I am able to do I2C read/write operations on mpc8xx-i2c slave only after
re-insmoding my driver module (i2c-algo-8xx.c, and adapter layer drive,
code I took form i2c-rpx/r360.c ).
The issue I am facing is when I insmod i2c-driver on fresh Linux boot,
any i2c-mpc860 as slave read/write operation gives me busy status (which
is for Rx BD not available) in Controller's i2c Event Registers. When I
get busy status I have to do force_close() and re-init of bd, then only
busy status goes off.
I tried calling cpm_iic_init(); twice while __init but with no change in
busy status.
After some initial try, i2c slave write works but i2c read gives no data
to the master. After re-insmoding driver, read/write works with some
times (1 out of 15 times) i2c-read failing.
But still I can't understand why busy is coming....
Any help or suggestions are highly appreciated.
thanks,
Ankur Maheshwari
^ permalink raw reply
* Re: [PATCH 11/16] Use of_get_next_child() in eeh_restore_bars()
From: Stephen Rothwell @ 2007-10-26 7:29 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <ef7facd658919117aa7c693b4eeb12241ca859d8.1193381582.git.michael@ellerman.id.au>
[-- Attachment #1: Type: text/plain, Size: 699 bytes --]
On Fri, 26 Oct 2007 16:54:43 +1000 (EST) Michael Ellerman <michael@ellerman.id.au> wrote:
>
> +++ b/arch/powerpc/platforms/pseries/eeh.c
> @@ -841,11 +841,8 @@ void eeh_restore_bars(struct pci_dn *pdn)
> if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
> __restore_bars (pdn);
>
> - dn = pdn->node->child;
> - while (dn) {
> + for (dn = NULL; (dn = of_get_next_child(pdn->node, dn));)
Just wondering if we need
#define for_each_child_node(dn, parent) \
for (dn = of_get_next_child(parent, NULL); dn; \
dn = of_get_next_child(parent, dn))
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 09/16] Use of_get_next_parent() in axon_msi.c
From: Stephen Rothwell @ 2007-10-26 7:24 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <4e749fe7078e2c006cf40921cea904833c75263c.1193381582.git.michael@ellerman.id.au>
[-- Attachment #1: Type: text/plain, Size: 763 bytes --]
On Fri, 26 Oct 2007 16:54:41 +1000 (EST) Michael Ellerman <michael@ellerman.id.au> wrote:
>
> +++ b/arch/powerpc/platforms/cell/axon_msi.c
> @@ -125,7 +125,7 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
> return NULL;
> }
>
> - for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) {
> + for (; dn; dn = of_get_next_parent(dn)) {
> ph = of_get_property(dn, "msi-translator", NULL);
> if (ph)
> break;
You no longer assign anything to tmp, but just below here, you may jump
to out_error: which will do an of_node_put(tmp). So you need to
initialise tmp or have another error goto label.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH 16/16] Use of_get_next_child() in EEH print_device_node_tree()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in print_device_node_tree() to safely
traverse the node's children.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/eeh_driver.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index abf1850..0a23bc4 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -44,6 +44,7 @@ static inline const char * pcid_name (struct pci_dev *pdev)
#ifdef DEBUG
static void print_device_node_tree (struct pci_dn *pdn, int dent)
{
+ struct device_node *pc;
int i;
if (!pdn) return;
for (i=0;i<dent; i++)
@@ -52,11 +53,8 @@ static void print_device_node_tree (struct pci_dn *pdn, int dent)
pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
pdn->eeh_pe_config_addr, pdn->node->full_name);
dent += 3;
- struct device_node *pc = pdn->node->child;
- while (pc) {
+ for (pc = NULL; (pc = of_get_next_child(pdn->node, pc));)
print_device_node_tree(PCI_DN(pc), dent);
- pc = pc->sibling;
- }
}
#endif
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 15/16] Use of_get_next_child() in eeh_reset_device()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in eeh_reset_device() to safely
traverse the node's children.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
Linas, I don't grok the logic in here, can you check it's OK. The old code
would potentially not walk through all siblings if pe_dn->node was not
equal to pe_dn->node->parent->child, but now it will regardless.
arch/powerpc/platforms/pseries/eeh_driver.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 15e015e..abf1850 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -249,7 +249,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
{
- struct device_node *dn;
+ struct device_node *dn, *parent;
int cnt, rc;
/* pcibios will clear the counter; save the value */
@@ -270,15 +270,16 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
dn = dn->parent->child;
- while (dn) {
+ parent = of_node_get(dn->parent);
+ for (dn = NULL; (dn = of_get_next_child(parent, dn));) {
struct pci_dn *ppe = PCI_DN(dn);
/* On Power4, always true because eeh_pe_config_addr=0 */
if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) {
rtas_configure_bridge(ppe);
eeh_restore_bars(ppe);
}
- dn = dn->sibling;
}
+ of_node_put(parent);
/* Give the system 5 seconds to finish running the user-space
* hotplug shutdown scripts, e.g. ifdown for ethernet. Yes,
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 14/16] Use of_get_next_child() in __eeh_clear_slot()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in __eeh_clear_slot() to safely
traverse the node's children.
To achieve this we need to change __eeh_clear_slot() to take the parent
node, not the child. This is also safer, as passing anything other than
node->child to the existing routine will not traverse all peers, only
those deeper in the sibling list.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/eeh.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index d06ab36..1537597 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -412,16 +412,17 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
__eeh_mark_slot(dn, mode_flag);
}
-static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
+static void __eeh_clear_slot(struct device_node *parent, int mode_flag)
{
- while (dn) {
+ struct device_node *dn;
+
+ for (dn = NULL; (dn = of_get_next_child(parent, dn));) {
if (PCI_DN(dn)) {
PCI_DN(dn)->eeh_mode &= ~mode_flag;
PCI_DN(dn)->eeh_check_count = 0;
if (dn->child)
- __eeh_clear_slot (dn->child, mode_flag);
+ __eeh_clear_slot(dn, mode_flag);
}
- dn = dn->sibling;
}
}
@@ -438,7 +439,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
PCI_DN(dn)->eeh_mode &= ~mode_flag;
PCI_DN(dn)->eeh_check_count = 0;
- __eeh_clear_slot (dn->child, mode_flag);
+ __eeh_clear_slot(dn, mode_flag);
spin_unlock_irqrestore(&confirm_error_lock, flags);
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 13/16] Use of_get_next_child() in __eeh_mark_slot()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in __eeh_mark_slot() to safely
traverse the node's children.
To achieve this we need to change __eeh_mark_slot() to take the parent
node, not the child. This is also safer, as passing anything other than
node->child to the existing routine will not traverse all peers, only
those deeper in the sibling list.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/eeh.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index d1d6d55..d06ab36 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -373,9 +373,11 @@ struct device_node * find_device_pe(struct device_node *dn)
* an interrupt context, which is bad.
*/
-static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
+static void __eeh_mark_slot(struct device_node *parent, int mode_flag)
{
- while (dn) {
+ struct device_node *dn;
+
+ for (dn = NULL; (dn = of_get_next_child(parent, dn));) {
if (PCI_DN(dn)) {
/* Mark the pci device driver too */
struct pci_dev *dev = PCI_DN(dn)->pcidev;
@@ -386,9 +388,8 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
dev->error_state = pci_channel_io_frozen;
if (dn->child)
- __eeh_mark_slot (dn->child, mode_flag);
+ __eeh_mark_slot(dn, mode_flag);
}
- dn = dn->sibling;
}
}
@@ -408,7 +409,7 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
if (dev)
dev->error_state = pci_channel_io_frozen;
- __eeh_mark_slot (dn->child, mode_flag);
+ __eeh_mark_slot(dn, mode_flag);
}
static void __eeh_clear_slot (struct device_node *dn, int mode_flag)
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 12/16] Use of_get_next_child() in eeh_add_device_tree_early()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in the eeh_add_device_tree_early()
routine to safely traverse the node's children.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/eeh.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index abe3de1..d1d6d55 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1120,7 +1120,7 @@ static void eeh_add_device_early(struct device_node *dn)
void eeh_add_device_tree_early(struct device_node *dn)
{
struct device_node *sib;
- for (sib = dn->child; sib; sib = sib->sibling)
+ for (sib = NULL; (sib = of_get_next_child(dn, sib));)
eeh_add_device_tree_early(sib);
eeh_add_device_early(dn);
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 11/16] Use of_get_next_child() in eeh_restore_bars()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in the eeh_restore_bars()
routine to safely traverse the node's children.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/eeh.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 7309caa..abe3de1 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -841,11 +841,8 @@ void eeh_restore_bars(struct pci_dn *pdn)
if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code))
__restore_bars (pdn);
- dn = pdn->node->child;
- while (dn) {
+ for (dn = NULL; (dn = of_get_next_child(pdn->node, dn));)
eeh_restore_bars (PCI_DN(dn));
- dn = dn->sibling;
- }
}
/**
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 10/16] Use of_get_next_child() in EEH gather_pci_data()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We should use of_get_next_child() in the EEH gather_pci_data()
routine to safely traverse the node's children.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/eeh.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 22322b3..7309caa 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -238,12 +238,10 @@ static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len)
/* Gather status on devices under the bridge */
if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) {
- dn = pdn->node->child;
- while (dn) {
+ for (dn = NULL; (dn = of_get_next_child(pdn->node, dn));) {
pdn = PCI_DN(dn);
if (pdn)
n += gather_pci_data(pdn, buf+n, len-n);
- dn = dn->sibling;
}
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 09/16] Use of_get_next_parent() in axon_msi.c
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
We can use of_get_next_parent() in two places in axon_msi.c to
simplify the looping logic.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/axon_msi.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 095988f..76870fe 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -125,7 +125,7 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
return NULL;
}
- for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) {
+ for (; dn; dn = of_get_next_parent(dn)) {
ph = of_get_property(dn, "msi-translator", NULL);
if (ph)
break;
@@ -171,7 +171,7 @@ static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type)
static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
{
- struct device_node *dn, *tmp;
+ struct device_node *dn;
struct msi_desc *entry;
int len;
const u32 *prop;
@@ -184,7 +184,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
- for (; dn; tmp = of_get_parent(dn), of_node_put(dn), dn = tmp) {
+ for (; dn; dn = of_get_next_parent(dn)) {
if (entry->msi_attrib.is_64) {
prop = of_get_property(dn, "msi-address-64", &len);
if (prop)
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 08/16] Use of_get_next_parent() in pseries_mpic_init_IRQ()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
Use of_get_next_parent() in pseries_mpic_init_IRQ() to simplify
the loop logic.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/setup.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index fdb9b1c..f08dfaf 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -129,7 +129,7 @@ void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
static void __init pseries_mpic_init_IRQ(void)
{
- struct device_node *np, *old, *cascade = NULL;
+ struct device_node *np, *cascade = NULL;
const unsigned int *addrp;
unsigned long intack = 0;
const unsigned int *opprop;
@@ -182,11 +182,8 @@ static void __init pseries_mpic_init_IRQ(void)
}
/* Check ACK type */
- for (old = of_node_get(cascade); old != NULL ; old = np) {
- np = of_get_parent(old);
- of_node_put(old);
- if (np == NULL)
- break;
+ np = of_node_get(cascade);
+ while ((np = of_get_next_parent(np))) {
if (strcmp(np->name, "pci") != 0)
continue;
addrp = of_get_property(np, "8259-interrupt-acknowledge",
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 07/16] Use of_get_next_parent() in xics_setup_8259_cascade()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
Use of_get_next_parent() in xics_setup_8259_cascade() to simplify
the loop logic.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/xics.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 66e7d68..58a3cc7 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -617,7 +617,7 @@ static void __init xics_init_one_node(struct device_node *np,
static void __init xics_setup_8259_cascade(void)
{
- struct device_node *np, *old, *found = NULL;
+ struct device_node *np, *found = NULL;
int cascade, naddr;
const u32 *addrp;
unsigned long intack = 0;
@@ -638,11 +638,8 @@ static void __init xics_setup_8259_cascade(void)
}
pr_debug("xics: cascade mapped to irq %d\n", cascade);
- for (old = of_node_get(found); old != NULL ; old = np) {
- np = of_get_parent(old);
- of_node_put(old);
- if (np == NULL)
- break;
+ np = of_node_get(found);
+ while ((np = of_get_next_parent(np))) {
if (strcmp(np->name, "pci") != 0)
continue;
addrp = of_get_property(np, "8259-interrupt-acknowledge", NULL);
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 06/16] Use of_get_next_child() in pci_dma_bus_setup_pSeries()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
pci_dma_bus_setup_pSeries() should use of_get_next_child() to safely
iterate through the nodes children.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/iommu.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index ef1aa8d..1a9e14f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -343,7 +343,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
of_node_put(isa_dn);
/* Count number of direct PCI children of the PHB. */
- for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
+ for (children = 0, tmp = NULL; (tmp = of_get_next_child(dn, tmp));)
children++;
DBG("Children: %d\n", children);
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 05/16] Use of_get_next_parent() in pci_dma_dev_setup_pSeriesLP()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
pci_dma_dev_setup_pSeriesLP() should use of_get_next_parent() to safely
iterate through the parent nodes.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/iommu.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 5e9430e..ef1aa8d 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -503,8 +503,9 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
dn = pci_device_to_OF_node(dev);
DBG(" node is %s\n", dn->full_name);
- for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
- pdn = pdn->parent) {
+ for (pdn = of_node_get(dn);
+ pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
+ pdn = of_get_next_parent(pdn)) {
dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
if (dma_window)
break;
@@ -514,7 +515,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: "
"no DMA window found for pci dev=%s dn=%s\n",
pci_name(dev), dn? dn->full_name : "<null>");
- return;
+ goto out_put;
}
DBG(" parent is %s\n", pdn->full_name);
@@ -524,7 +525,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
if (dma_window == NULL || pdn->parent == NULL) {
DBG(" no dma window for device, linking to parent\n");
dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table;
- return;
+ goto out_put;
}
pci = PCI_DN(pdn);
@@ -544,6 +545,9 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
}
dev->dev.archdata.dma_data = pci->iommu_table;
+
+out_put:
+ of_node_put(pdn);
}
#else /* CONFIG_PCI */
#define pci_dma_bus_setup_pSeries NULL
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 04/16] Use of_get_next_parent() in pci_dma_dev_setup_pSeries()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
pci_dma_dev_setup_pSeries() should use of_get_next_parent() to safely
iterate through the parent nodes.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/iommu.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index e2b325d..5e9430e 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -472,14 +472,17 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
* an already allocated iommu table is found and use that.
*/
+ dn = of_node_get(dn);
while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
- dn = dn->parent;
+ dn = of_get_next_parent(dn);
if (dn && PCI_DN(dn))
dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table;
else
printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
pci_name(dev));
+
+ of_node_put(dn);
}
static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 03/16] Use of_get_next_parent() in pci_dma_bus_setup_pSeriesLP()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
pci_dma_bus_setup_pSeriesLP() should use of_get_next_parent() to safely
iterate through the parent nodes.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/iommu.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 83c0e0f..e2b325d 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -403,7 +403,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name);
/* Find nearest ibm,dma-window, walking up the device tree */
- for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
+ for (pdn = of_node_get(dn); pdn; pdn = of_get_next_parent(pdn)) {
dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
if (dma_window != NULL)
break;
@@ -411,6 +411,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
if (dma_window == NULL) {
DBG(" no ibm,dma-window property !\n");
+ of_node_put(pdn);
return;
}
@@ -437,6 +438,8 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
if (pdn != dn)
PCI_DN(dn)->iommu_table = ppci->iommu_table;
+
+ of_node_put(pdn);
}
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 02/16] Use of_get_next_parent() in pci_dma_bus_setup_pSeries()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <80449d4682309dbf8cf80816be4f381fe875f3d1.1193381582.git.michael@ellerman.id.au>
pci_dma_bus_setup_pSeries() should use of_get_next_parent() to safely
iterate through the parent nodes.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/iommu.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index be17d23..83c0e0f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -314,7 +314,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
{
struct device_node *dn;
struct iommu_table *tbl;
- struct device_node *isa_dn, *isa_dn_orig;
+ struct device_node *isa_dn;
struct device_node *tmp;
struct pci_dn *pci;
int children;
@@ -334,13 +334,13 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
/* Check if the ISA bus on the system is under
* this PHB.
*/
- isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
+ isa_dn = of_find_node_by_type(NULL, "isa");
while (isa_dn && isa_dn != dn)
- isa_dn = isa_dn->parent;
+ isa_dn = of_get_next_parent(isa_dn);
- if (isa_dn_orig)
- of_node_put(isa_dn_orig);
+ /* Drop our reference, it's still safe to check the pointer below */
+ of_node_put(isa_dn);
/* Count number of direct PCI children of the PHB. */
for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [PATCH 01/16] Add of_get_next_parent()
From: Michael Ellerman @ 2007-10-26 6:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: davem
Iterating through a device node's parents is simple enough, but dealing
with the refcounts properly is a little ugly, and replicating that logic
is asking for someone to get it wrong or forget it all together, eg:
while (dn != NULL) {
/* loop body */
tmp = of_get_parent(dn);
of_node_put(dn);
dn = tmp;
}
So add of_get_next_parent(), inspired by of_get_next_child(). The contract
is that it returns the parent and drops the reference on the current node,
this makes the loop look like:
while (dn != NULL) {
/* loop body */
dn = of_get_next_parent(dn);
}
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
drivers/of/base.c | 25 +++++++++++++++++++++++++
include/linux/of.h | 1 +
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 9377f3b..e0db2b5 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -138,6 +138,31 @@ struct device_node *of_get_parent(const struct device_node *node)
EXPORT_SYMBOL(of_get_parent);
/**
+ * of_get_next_parent - Iterate to a node's parent
+ * @node: Node to get parent of
+ *
+ * This is like of_get_parent() except that it drops the
+ * refcount on the passed node, making it suitable for iterating
+ * through a node's parents.
+ *
+ * Returns a node pointer with refcount incremented, use
+ * of_node_put() on it when done.
+ */
+struct device_node *of_get_next_parent(struct device_node *node)
+{
+ struct device_node *parent;
+
+ if (!node)
+ return NULL;
+
+ read_lock(&devtree_lock);
+ parent = of_node_get(node->parent);
+ of_node_put(node);
+ read_unlock(&devtree_lock);
+ return parent;
+}
+
+/**
* of_get_next_child - Iterate a node childs
* @node: parent node
* @prev: previous child of the parent node, or NULL to get first
diff --git a/include/linux/of.h b/include/linux/of.h
index 5c39b92..3557d1e 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -44,6 +44,7 @@ extern struct device_node *of_find_compatible_node(struct device_node *from,
extern struct device_node *of_find_node_by_path(const char *path);
extern struct device_node *of_find_node_by_phandle(phandle handle);
extern struct device_node *of_get_parent(const struct device_node *node);
+extern struct device_node *of_get_next_parent(struct device_node *node);
extern struct device_node *of_get_next_child(const struct device_node *node,
struct device_node *prev);
extern struct property *of_find_property(const struct device_node *np,
--
1.5.2.rc1.1884.g59b20
^ permalink raw reply related
* [2/2] dtc: Switch dtc to C-style literals
From: David Gibson @ 2007-10-26 6:20 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
In-Reply-To: <20071026061718.GA6136@localhost.localdomain>
This patch introduces a new version of dts file, distinguished from
older files by starting with the special token /dts-v1/. dts files in
the new version take C-style literals instead of the old bare hex or
OF-style base notation. In addition, the "range" for of memreserve entries
(/memreserve/ f0000-fffff) is no longer recognized in the new format.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
dtc-lexer.l | 40 ++++++++++++++++++++++++++++++++--------
dtc-parser.y | 38 ++++++++++++++++++++++++++++++++++++--
tests/run_tests.sh | 4 ++++
tests/test_tree1.dts | 16 +++++++++-------
tests/test_tree1_dts0.dts | 27 +++++++++++++++++++++++++++
5 files changed, 108 insertions(+), 17 deletions(-)
Index: dtc/dtc-lexer.l
===================================================================
--- dtc.orig/dtc-lexer.l 2007-10-26 15:11:02.000000000 +1000
+++ dtc/dtc-lexer.l 2007-10-26 15:36:46.000000000 +1000
@@ -23,6 +23,7 @@
%x INCLUDE
%x BYTESTRING
%x PROPNODENAME
+%s V1
PROPCHAR [a-zA-Z0-9,._+*#?-]
UNITCHAR [0-9a-f,]
@@ -44,12 +45,18 @@
#define DPRINT(fmt, ...) do { } while (0)
#endif
+static int dts_version; /* = 0 */
-
+#define BEGIN_DEFAULT() if (dts_version == 0) { \
+ DPRINT("<INITIAL>\n"); \
+ BEGIN(INITIAL); \
+ } else { \
+ DPRINT("<V1>\n"); \
+ BEGIN(V1); \
+ }
%}
%%
-
<*>"/include/" BEGIN(INCLUDE);
<INCLUDE>\"[^"\n]*\" {
@@ -58,7 +65,7 @@
/* Some unrecoverable error.*/
exit(1);
}
- BEGIN(INITIAL);
+ BEGIN_DEFAULT();
}
@@ -78,11 +85,20 @@
return DT_STRING;
}
+<*>"/dts-v1/" {
+ yylloc.filenum = srcpos_filenum;
+ yylloc.first_line = yylineno;
+ DPRINT("Keyword: /dts-v1/\n");
+ dts_version = 1;
+ BEGIN_DEFAULT();
+ return DT_V1;
+ }
+
<*>"/memreserve/" {
yylloc.filenum = srcpos_filenum;
yylloc.first_line = yylineno;
DPRINT("Keyword: /memreserve/\n");
- BEGIN(INITIAL);
+ BEGIN_DEFAULT();
return DT_MEMRESERVE;
}
@@ -95,7 +111,7 @@
return DT_LABEL;
}
-[bodh]# {
+<INITIAL>[bodh]# {
yylloc.filenum = srcpos_filenum;
yylloc.first_line = yylineno;
if (*yytext == 'b')
@@ -110,7 +126,15 @@
return DT_BASE;
}
-[0-9a-fA-F]+ {
+<INITIAL>[0-9a-fA-F]+ {
+ yylloc.filenum = srcpos_filenum;
+ yylloc.first_line = yylineno;
+ yylval.literal = strdup(yytext);
+ DPRINT("Literal: '%s'\n", yylval.literal);
+ return DT_LEGACYLITERAL;
+ }
+
+<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
yylloc.filenum = srcpos_filenum;
yylloc.first_line = yylineno;
yylval.literal = strdup(yytext);
@@ -138,7 +162,7 @@
yylloc.filenum = srcpos_filenum;
yylloc.first_line = yylineno;
DPRINT("/BYTESTRING\n");
- BEGIN(INITIAL);
+ BEGIN_DEFAULT();
return ']';
}
@@ -147,7 +171,7 @@
yylloc.first_line = yylineno;
DPRINT("PropNodeName: %s\n", yytext);
yylval.propnodename = strdup(yytext);
- BEGIN(INITIAL);
+ BEGIN_DEFAULT();
return DT_PROPNODENAME;
}
Index: dtc/dtc-parser.y
===================================================================
--- dtc.orig/dtc-parser.y 2007-10-26 15:11:02.000000000 +1000
+++ dtc/dtc-parser.y 2007-10-26 15:49:05.000000000 +1000
@@ -48,9 +48,11 @@
struct reserve_info *re;
}
+%token DT_V1
%token DT_MEMRESERVE
%token <propnodename> DT_PROPNODENAME
%token <literal> DT_LITERAL
+%token <literal> DT_LEGACYLITERAL
%token <cbase> DT_BASE
%token <byte> DT_BYTE
%token <data> DT_STRING
@@ -61,6 +63,8 @@
%type <data> propdataprefix
%type <re> memreserve
%type <re> memreserves
+%type <re> v0_memreserve
+%type <re> v0_memreserves
%type <addr> addr
%type <data> celllist
%type <cbase> cellbase
@@ -78,7 +82,11 @@
%%
sourcefile:
- memreserves devicetree
+ DT_V1 ';' memreserves devicetree
+ {
+ the_boot_info = build_boot_info($3, $4);
+ }
+ | v0_memreserves devicetree
{
the_boot_info = build_boot_info($1, $2);
}
@@ -100,6 +108,24 @@
{
$$ = build_reserve_entry($3, $4, $1);
}
+ ;
+
+v0_memreserves:
+ /* empty */
+ {
+ $$ = NULL;
+ }
+ | v0_memreserve v0_memreserves
+ {
+ $$ = chain_reserve_entry($1, $2);
+ };
+ ;
+
+v0_memreserve:
+ memreserve
+ {
+ $$ = $1;
+ }
| label DT_MEMRESERVE addr '-' addr ';'
{
$$ = build_reserve_entry($3, $5 - $3 + 1, $1);
@@ -108,6 +134,10 @@
addr:
DT_LITERAL
+ {
+ $$ = eval_literal($1, 0, 64);
+ }
+ | DT_LEGACYLITERAL
{
$$ = eval_literal($1, 16, 64);
}
@@ -212,7 +242,11 @@
;
cellval:
- cellbase DT_LITERAL
+ DT_LITERAL
+ {
+ $$ = eval_literal($1, 0, 32);
+ }
+ | cellbase DT_LEGACYLITERAL
{
$$ = eval_literal($2, $1, 32);
}
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2007-10-26 15:11:02.000000000 +1000
+++ dtc/tests/run_tests.sh 2007-10-26 15:18:43.000000000 +1000
@@ -118,6 +118,10 @@
tree1_tests_rw dtc_tree1.test.dtb
run_test dtbs_equal_ordered dtc_tree1.test.dtb test_tree1.dtb
+ run_test dtc.sh -I dts -O dtb -o dtc_tree1_dts0.test.dtb test_tree1_dts0.dts
+ tree1_tests dtc_tree1_dts0.test.dtb
+ tree1_tests_rw dtc_tree1_dts0.test.dtb
+
run_test dtc.sh -I dts -O dtb -o dtc_escapes.test.dtb escapes.dts
run_test string_escapes dtc_escapes.test.dtb
}
Index: dtc/tests/test_tree1.dts
===================================================================
--- dtc.orig/tests/test_tree1.dts 2007-10-26 15:11:02.000000000 +1000
+++ dtc/tests/test_tree1.dts 2007-10-26 15:18:43.000000000 +1000
@@ -1,27 +1,29 @@
-/memreserve/ deadbeef00000000-deadbeef000fffff;
-/memreserve/ abcd1234 00001234;
+/dts-v1/;
+
+/memreserve/ 0xdeadbeef00000000 0x100000;
+/memreserve/ 0xabcd1234 0x00001234;
/ {
compatible = "test_tree1";
- prop-int = <deadbeef>;
+ prop-int = <0xdeadbeef>;
prop-str = "hello world";
subnode@1 {
compatible = "subnode1";
- prop-int = <deadbeef>;
+ prop-int = <0xdeadbeef>;
subsubnode {
compatible = "subsubnode1", "subsubnode";
- prop-int = <deadbeef>;
+ prop-int = <0xdeadbeef>;
};
};
subnode@2 {
- prop-int = <abcd1234>;
+ prop-int = <0xabcd1234>;
subsubnode@0 {
compatible = "subsubnode2", "subsubnode";
- prop-int = <abcd1234>;
+ prop-int = <0xabcd1234>;
};
};
};
Index: dtc/tests/test_tree1_dts0.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/test_tree1_dts0.dts 2007-10-26 15:18:43.000000000 +1000
@@ -0,0 +1,27 @@
+/memreserve/ deadbeef00000000-deadbeef000fffff;
+/memreserve/ abcd1234 00001234;
+
+/ {
+ compatible = "test_tree1";
+ prop-int = <deadbeef>;
+ prop-str = "hello world";
+
+ subnode@1 {
+ compatible = "subnode1";
+ prop-int = <deadbeef>;
+
+ subsubnode {
+ compatible = "subsubnode1", "subsubnode";
+ prop-int = <deadbeef>;
+ };
+ };
+
+ subnode@2 {
+ prop-int = <abcd1234>;
+
+ subsubnode@0 {
+ compatible = "subsubnode2", "subsubnode";
+ prop-int = <abcd1234>;
+ };
+ };
+};
--
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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox