* OProfile callgraph support not working correctly on PPC processors
From: Bob Nelson @ 2007-12-21 17:15 UTC (permalink / raw)
To: linuxppc
I have been investigating why I have not been able to get callgraph code fo=
r=20
OProfile on Cell to work correctly and I am pretty sure that I have run int=
o=20
a problem that is common across all the Power platforms. (At least the oth=
er=20
ones I have looked at.) I have a simple test program that is attached=20
below. =A0It has a main, that calls function1, which calls function2. =A0Ea=
ch of=20
the functions has some type of loop in it so that I can catch it spending=20
some CPU time with OProfile. =A0I have also attached the objdump -d output =
for=20
the program cut down to the three pertinent functions that shows what is=20
happening. =A0In a nutshell when a terminal function (calls no other functi=
on)=20
is called the compiler is making an optimization that seems to break the AB=
I=20
convention as far as I can tell. =A0It does not store the Link Register on =
the=20
stack like any other function. It just leaves the return address in LR,=20
knowing that nothing should change it. =A0(You can see at the top of both m=
ain=20
and function1 the first thing it does is "mflr =A0r0" to copy the link regi=
ster=20
to R0 to be saved. It does not do that in function2.) =A0 When OProfile tak=
es=20
an interrupt and needs to gather the callgraph information it does so by=20
grabbing the process' stack pointer (R1) and follows the chain back up the=
=20
stack to gather all the caller's addresses. =A0This works for most function=
s,=20
except for terminal functions for the reason noted above.
Looking at the assembly listing I drew myself a diagram of the stack while=
=20
function2 is active to convince myself of what was wrong and here is what I=
=20
see it as... =A0When the interrupt is handled OProfile grabs a copy of R1, =
it=20
ignores the first frame on the stack because there should be no address=20
stored. =A0In the second frame it expects to find function2's caller but si=
nce=20
function2 doesn't store it, it grabs some random data and proceeds. The sta=
ck=20
chain is all ok so it doesn't go off into neverland trying to follow a bad=
=20
chain, but it grabs an invalid address for the caller. =A0And that is why=20
OProfile thinks terminal functions have no callers on PPC...
Any suggestions on how this can be fixed? =A0I am guessing that changing th=
e=20
compiler and recompiling every program is probably not the answer. I assum=
e=20
the link register has to be saved in the interrupt routine when it runs, or=
=20
else it couldn't call anything else without crashing the program that was=20
interrupted. Is there a safe place to find it?
Thanks, Bob Nelson
top of stack =A0 ------------------------------
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0|
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| <------------------------------
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0R0 (link register) =A0 =A0 =A0| =A0=
=2D-> main's caller =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0flags (unused) =A0 =A0 =A0 =A0 =A0|=
=A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------|=A0 =A0 =A0 =
=A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0R1 (previous frame) |>---------=
=2D---------------------
R1 main =A0 =A0 -> |----------------------------| 0 (Offset from R1 <----=
=2D-----
=A0 =A0(entry) =A0 =A0=A0| =A0 =A0R31 save =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|=
=A0 at entry to main) =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 |----------------------------| -8 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0|=A0 =A0 =A0 =A0 =A0 =A0 |=20
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0|
=A0 =A0 =A0 =A0 =A0 =A0 =A0 |----------------------------| =A0 =A0 =A0 =A0=
=A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0R0 (link register) =A0 =A0 =A0| =A0--=
>function1's caller (main) |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 |----------------------------| =A0 =A0 =
=A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0flags (not stored)=A0 =A0 =A0 |=A0 =
=A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 |----------------------------| =A0 =A0 =A0 =A0=
=A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0R1 (previous frame) |>-----------=
=2D-------------------
R1 function1-->|----------------------------| -144 <-----------------------=
=2D-
=A0 =A0(entry) =A0 =A0 | =A0 =A0R31 save =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =
=A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------|=A0 =A0 =A0 =
=A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0nothing stored =A0 =A0 =A0 =A0 =A0|=
(should be function2's caller |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0function1)=
=A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0flags (not stored) =A0 =A0 =A0| =A0=
=A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0R1 (previous frame) |>---------=
=2D---------------------
R1 function2-->|----------------------------| -288 <-----------------------=
=2D-
=A0 =A0(entry) =A0 =A0 | =A0 =A0R31 save =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =
=A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0nothing stored =A0 =A0 =A0 =A0 =A0|=
=A0would be used if function2 =A0|
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0called any=
thing |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0flags (not stored) =A0 =A0 =A0| =A0=
=A0 =A0 =A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|----------------------------| =A0 =A0 =A0 =
=A0 =A0 =A0 |
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0R1 (previous frame) |>---------=
=2D---------------------
R1 function2-->|----------------------------| -368=A0 =A0(running)
| =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0 =A0 . =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0|
=A0 =A0 =A0 =A0 =A0 =A0 =A0 | =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0|
/* loop.c - nonsense code for testing OProfile */
#include <stdio.h>
int function2( int count )
{
int i, j, k;
for ( i=3D0; i<count; i++ )
{
k =3D k + j * i;
}
return k;
}
int function1( int count )
{
int i, j;
i =3D function2( count );
for ( j=3D0; j<1000; j++ ) i++;
return i;
}
int main( int argc, char *argv[] )
{
int count, i, j, k;
if ( argc > 0 )
count =3D atoi( argv[1] );
else
count =3D 10000;
for ( i=3D0; i<count; i++ )
{
j =3D function1( 10000 );
for( j=3D0; j<10000; j++ ) k =3D k + j;
}
return 0;
}
loop.64: file format elf64-powerpc
=2E.. deleted ...
00000000100005b0 <.function2>:
100005b0: fb e1 ff f8 std r31,-8(r1)
100005b4: f8 21 ff b1 stdu r1,-80(r1)
100005b8: 7c 3f 0b 78 mr r31,r1
100005bc: 7c 60 1b 78 mr r0,r3
100005c0: 90 1f 00 80 stw r0,128(r31)
100005c4: 38 00 00 00 li r0,0
100005c8: 90 1f 00 38 stw r0,56(r31)
100005cc: 48 00 00 2c b 100005f8 <.function2+0x48>
100005d0: 81 3f 00 34 lwz r9,52(r31)
100005d4: 80 1f 00 38 lwz r0,56(r31)
100005d8: 7c 09 01 d6 mullw r0,r9,r0
100005dc: 7c 09 07 b4 extsw r9,r0
100005e0: 80 1f 00 30 lwz r0,48(r31)
100005e4: 7c 00 4a 14 add r0,r0,r9
100005e8: 90 1f 00 30 stw r0,48(r31)
100005ec: 81 3f 00 38 lwz r9,56(r31)
100005f0: 38 09 00 01 addi r0,r9,1
100005f4: 90 1f 00 38 stw r0,56(r31)
100005f8: 80 1f 00 38 lwz r0,56(r31)
100005fc: 81 3f 00 80 lwz r9,128(r31)
10000600: 7f 80 48 00 cmpw cr7,r0,r9
10000604: 41 9c ff cc blt+ cr7,100005d0 <.function2+0x20>
10000608: 80 1f 00 30 lwz r0,48(r31)
1000060c: 7c 00 07 b4 extsw r0,r0
10000610: 7c 03 03 78 mr r3,r0
10000614: e8 21 00 00 ld r1,0(r1)
10000618: eb e1 ff f8 ld r31,-8(r1)
1000061c: 4e 80 00 20 blr
...
10000628: 80 01 00 01 lwz r0,1(r1)
000000001000062c <.function1>:
1000062c: 7c 08 02 a6 mflr r0
10000630: fb e1 ff f8 std r31,-8(r1)
10000634: f8 01 00 10 std r0,16(r1)
10000638: f8 21 ff 71 stdu r1,-144(r1)
1000063c: 7c 3f 0b 78 mr r31,r1
10000640: 7c 60 1b 78 mr r0,r3
10000644: 90 1f 00 c0 stw r0,192(r31)
10000648: 80 1f 00 c0 lwz r0,192(r31)
1000064c: 7c 00 07 b4 extsw r0,r0
10000650: 7c 03 03 78 mr r3,r0
10000654: 4b ff ff 5d bl 100005b0 <.function2>
10000658: 7c 60 1b 78 mr r0,r3
1000065c: 90 1f 00 74 stw r0,116(r31)
10000660: 38 00 00 00 li r0,0
10000664: 90 1f 00 70 stw r0,112(r31)
10000668: 48 00 00 1c b 10000684 <.function1+0x58>
1000066c: 81 3f 00 74 lwz r9,116(r31)
10000670: 38 09 00 01 addi r0,r9,1
10000674: 90 1f 00 74 stw r0,116(r31)
10000678: 81 3f 00 70 lwz r9,112(r31)
1000067c: 38 09 00 01 addi r0,r9,1
10000680: 90 1f 00 70 stw r0,112(r31)
10000684: 80 1f 00 70 lwz r0,112(r31)
10000688: 2f 80 03 e7 cmpwi cr7,r0,999
1000068c: 40 9d ff e0 ble+ cr7,1000066c <.function1+0x40>
10000690: 80 1f 00 74 lwz r0,116(r31)
10000694: 7c 00 07 b4 extsw r0,r0
10000698: 7c 03 03 78 mr r3,r0
1000069c: e8 21 00 00 ld r1,0(r1)
100006a0: e8 01 00 10 ld r0,16(r1)
100006a4: 7c 08 03 a6 mtlr r0
100006a8: eb e1 ff f8 ld r31,-8(r1)
100006ac: 4e 80 00 20 blr
100006b0: 00 00 00 00 .long 0x0
100006b4: 00 00 00 01 .long 0x1
100006b8: 80 01 00 01 lwz r0,1(r1)
00000000100006bc <.main>:
100006bc: 7c 08 02 a6 mflr r0
100006c0: fb e1 ff f8 std r31,-8(r1)
100006c4: f8 01 00 10 std r0,16(r1)
100006c8: f8 21 ff 71 stdu r1,-144(r1)
100006cc: 7c 3f 0b 78 mr r31,r1
100006d0: 7c 60 1b 78 mr r0,r3
100006d4: f8 9f 00 c8 std r4,200(r31)
100006d8: 90 1f 00 c0 stw r0,192(r31)
100006dc: 80 1f 00 c0 lwz r0,192(r31)
100006e0: 2f 80 00 00 cmpwi cr7,r0,0
100006e4: 40 9d 00 28 ble- cr7,1000070c <.main+0x50>
100006e8: e9 3f 00 c8 ld r9,200(r31)
100006ec: 39 29 00 08 addi r9,r9,8
100006f0: e8 09 00 00 ld r0,0(r9)
100006f4: 7c 03 03 78 mr r3,r0
100006f8: 4b ff fc f9 bl 100003f0 <._init+0x38>
100006fc: e8 41 00 28 ld r2,40(r1)
10000700: 7c 60 1b 78 mr r0,r3
10000704: 90 1f 00 7c stw r0,124(r31)
10000708: 48 00 00 0c b 10000714 <.main+0x58>
1000070c: 38 00 27 10 li r0,10000
10000710: 90 1f 00 7c stw r0,124(r31)
10000714: 38 00 00 00 li r0,0
10000718: 90 1f 00 78 stw r0,120(r31)
1000071c: 48 00 00 54 b 10000770 <.main+0xb4>
10000720: 38 60 27 10 li r3,10000
10000724: 4b ff ff 09 bl 1000062c <.function1>
10000728: 7c 60 1b 78 mr r0,r3
1000072c: 90 1f 00 74 stw r0,116(r31)
10000730: 38 00 00 00 li r0,0
10000734: 90 1f 00 74 stw r0,116(r31)
10000738: 48 00 00 20 b 10000758 <.main+0x9c>
1000073c: 81 3f 00 70 lwz r9,112(r31)
10000740: 80 1f 00 74 lwz r0,116(r31)
10000744: 7c 09 02 14 add r0,r9,r0
10000748: 90 1f 00 70 stw r0,112(r31)
1000074c: 81 3f 00 74 lwz r9,116(r31)
10000750: 38 09 00 01 addi r0,r9,1
10000754: 90 1f 00 74 stw r0,116(r31)
10000758: 80 1f 00 74 lwz r0,116(r31)
1000075c: 2f 80 27 0f cmpwi cr7,r0,9999
10000760: 40 9d ff dc ble+ cr7,1000073c <.main+0x80>
10000764: 81 3f 00 78 lwz r9,120(r31)
10000768: 38 09 00 01 addi r0,r9,1
1000076c: 90 1f 00 78 stw r0,120(r31)
10000770: 80 1f 00 78 lwz r0,120(r31)
10000774: 81 3f 00 7c lwz r9,124(r31)
10000778: 7f 80 48 00 cmpw cr7,r0,r9
1000077c: 41 9c ff a4 blt+ cr7,10000720 <.main+0x64>
10000780: 38 00 00 00 li r0,0
10000784: 7c 03 03 78 mr r3,r0
10000788: e8 21 00 00 ld r1,0(r1)
1000078c: e8 01 00 10 ld r0,16(r1)
10000790: 7c 08 03 a6 mtlr r0
10000794: eb e1 ff f8 ld r31,-8(r1)
10000798: 4e 80 00 20 blr
1000079c: 00 00 00 00 .long 0x0
100007a0: 00 00 00 01 .long 0x1
100007a4: 80 01 00 01 lwz r0,1(r1)
100007a8: 60 00 00 00 nop
100007ac: 60 00 00 00 nop
=2E.. deleted ...
^ permalink raw reply
* Re: [PATCH 2/3] sbc8548: Add device tree source for Wind River SBC8548 board
From: Paul Gortmaker @ 2007-12-21 17:20 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <1ED67FCC-132F-4E9A-BDC9-41BF557FF0D6@kernel.crashing.org>
In message: Re: [PATCH 2/3] sbc8548: Add device tree source for Wind River SBC8548 board
on 21/12/2007 Kumar Gala wrote:
>
> On Dec 21, 2007, at 12:43 AM, Paul Gortmaker wrote:
>
>> This adds the device tree source for the Wind River SBC8548 board.
[...]
> mind looking at converting this to a dts-v1 format?
>
> - k
I figured there might be value in having it as a separate commit, seeing
as there aren't that many other dts-v1 as a reference (yet). Not sure
if I've got all the v1 type changes in that you had in mind, but I fed
it through the latest dtc from git and fed it to the board and it still
seems happy with it.
I'll probably be away from e-mail after this afternoon for the holiday
period -- so thanks (everyone) for the feedback and whatever I don't
get to today, or any additional recommended changes I'll pick up in Jan.
P.
---
>From: Paul Gortmaker <paul.gortmaker@windriver.com>
>Date: Fri, 21 Dec 2007 12:11:17 -0500
>Subject: [PATCH] sbc8548: Convert device tree to be dts-v1 compatible
This converts the sbc8548 dts to be dts-v1 compatible. Tested with the
latest git pull of dtc (Dec 21/07).
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
arch/powerpc/boot/dts/sbc8548.dts | 122 +++++++++++++++++++------------------
1 files changed, 62 insertions(+), 60 deletions(-)
diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts
index e63ed20..14be38a 100644
--- a/arch/powerpc/boot/dts/sbc8548.dts
+++ b/arch/powerpc/boot/dts/sbc8548.dts
@@ -12,6 +12,8 @@
*/
+/dts-v1/;
+
/ {
model = "SBC8548";
compatible = "SBC8548";
@@ -35,10 +37,10 @@
PowerPC,8548@0 {
device_type = "cpu";
reg = <0>;
- d-cache-line-size = <20>; // 32 bytes
- i-cache-line-size = <20>; // 32 bytes
- d-cache-size = <8000>; // L1, 32K
- i-cache-size = <8000>; // L1, 32K
+ d-cache-line-size = <0x20>; // 32 bytes
+ i-cache-line-size = <0x20>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>; // From uboot
bus-frequency = <0>;
clock-frequency = <0>;
@@ -47,31 +49,31 @@
memory {
device_type = "memory";
- reg = <00000000 10000000>;
+ reg = <0x00000000 0x10000000>;
};
soc8548@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
device_type = "soc";
- ranges = <00000000 e0000000 00100000>;
- reg = <e0000000 00001000>; // CCSRBAR
+ ranges = <0x00000000 0xe0000000 0x00100000>;
+ reg = <0xe0000000 0x00001000>; // CCSRBAR
bus-frequency = <0>;
memory-controller@2000 {
compatible = "fsl,8548-memory-controller";
- reg = <2000 1000>;
+ reg = <0x2000 0x1000>;
interrupt-parent = <&mpic>;
- interrupts = <12 2>;
+ interrupts = <0x12 0x2>;
};
l2-cache-controller@20000 {
compatible = "fsl,8548-l2-cache-controller";
- reg = <20000 1000>;
- cache-line-size = <20>; // 32 bytes
- cache-size = <80000>; // L2, 512K
+ reg = <0x20000 0x1000>;
+ cache-line-size = <0x20>; // 32 bytes
+ cache-size = <0x80000>; // L2, 512K
interrupt-parent = <&mpic>;
- interrupts = <10 2>;
+ interrupts = <0x10 0x2>;
};
i2c@3000 {
@@ -79,8 +81,8 @@
#size-cells = <0>;
cell-index = <0>;
compatible = "fsl-i2c";
- reg = <3000 100>;
- interrupts = <2b 2>;
+ reg = <0x3000 0x100>;
+ interrupts = <0x2b 0x2>;
interrupt-parent = <&mpic>;
dfsrr;
};
@@ -90,8 +92,8 @@
#size-cells = <0>;
cell-index = <1>;
compatible = "fsl-i2c";
- reg = <3100 100>;
- interrupts = <2b 2>;
+ reg = <0x3100 0x100>;
+ interrupts = <0x2b 0x2>;
interrupt-parent = <&mpic>;
dfsrr;
};
@@ -100,18 +102,18 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-mdio";
- reg = <24520 20>;
+ reg = <0x24520 0x20>;
phy0: ethernet-phy@19 {
interrupt-parent = <&mpic>;
- interrupts = <6 1>;
- reg = <19>;
+ interrupts = <0x6 0x1>;
+ reg = <0x19>;
device_type = "ethernet-phy";
};
phy1: ethernet-phy@1a {
interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <1a>;
+ interrupts = <0x7 0x1>;
+ reg = <0x1a>;
device_type = "ethernet-phy";
};
};
@@ -121,9 +123,9 @@
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
- reg = <24000 1000>;
+ reg = <0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <1d 2 1e 2 22 2>;
+ interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy0>;
};
@@ -133,9 +135,9 @@
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
- reg = <25000 1000>;
+ reg = <0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
- interrupts = <23 2 24 2 28 2>;
+ interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy1>;
};
@@ -144,9 +146,9 @@
cell-index = <0>;
device_type = "serial";
compatible = "ns16550";
- reg = <4500 100>; // reg base, size
+ reg = <0x4500 0x100>; // reg base, size
clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <2a 2>;
+ interrupts = <0x2a 0x2>;
interrupt-parent = <&mpic>;
};
@@ -154,15 +156,15 @@
cell-index = <1>;
device_type = "serial";
compatible = "ns16550";
- reg = <4600 100>; // reg base, size
+ reg = <0x4600 0x100>; // reg base, size
clock-frequency = <0>; // should we fill in in uboot?
- interrupts = <2a 2>;
+ interrupts = <0x2a 0x2>;
interrupt-parent = <&mpic>;
};
global-utilities@e0000 { //global utilities reg
compatible = "fsl,mpc8548-guts";
- reg = <e0000 1000>;
+ reg = <0xe0000 0x1000>;
fsl,has-rstcr;
};
@@ -171,7 +173,7 @@
#address-cells = <0>;
#size-cells = <0>;
#interrupt-cells = <2>;
- reg = <40000 40000>;
+ reg = <0x40000 0x40000>;
compatible = "chrp,open-pic";
device_type = "open-pic";
big-endian;
@@ -180,63 +182,63 @@
pci0: pci@e0008000 {
cell-index = <0>;
- interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x01 (PCI-X slot) */
- 00800 0 0 1 &mpic 0 1
- 00800 0 0 2 &mpic 1 1
- 00800 0 0 3 &mpic 2 1
- 00800 0 0 4 &mpic 3 1>;
+ 0x0800 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x0800 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x0800 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x0800 0x0 0x0 0x4 &mpic 0x3 0x1>;
interrupt-parent = <&mpic>;
- interrupts = <18 2>;
+ interrupts = <0x18 0x2>;
bus-range = <0 0>;
- ranges = <02000000 0 80000000 80000000 0 10000000
- 01000000 0 00000000 e2000000 0 00800000>;
- clock-frequency = <3f940aa>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00800000>;
+ clock-frequency = <66666666>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
- reg = <e0008000 1000>;
+ reg = <0xe0008000 0x1000>;
compatible = "fsl,mpc8540-pcix", "fsl,mpc8540-pci";
device_type = "pci";
};
pci2: pcie@e000a000 {
cell-index = <2>;
- interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
/* IDSEL 0x0 (PEX) */
- 00000 0 0 1 &mpic 0 1
- 00000 0 0 2 &mpic 1 1
- 00000 0 0 3 &mpic 2 1
- 00000 0 0 4 &mpic 3 1>;
+ 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1>;
interrupt-parent = <&mpic>;
- interrupts = <1a 2>;
- bus-range = <0 ff>;
- ranges = <02000000 0 a0000000 a0000000 0 20000000
- 01000000 0 00000000 e3000000 0 08000000>;
- clock-frequency = <1fca055>;
+ interrupts = <0x1a 0x2>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x08000000>;
+ clock-frequency = <33333333>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
- reg = <e000a000 1000>;
+ reg = <0xe000a000 0x1000>;
compatible = "fsl,mpc8548-pcie";
device_type = "pci";
pcie@0 {
- reg = <0 0 0 0 0>;
+ reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
#address-cells = <3>;
device_type = "pci";
- ranges = <02000000 0 a0000000
- 02000000 0 a0000000
- 0 20000000
+ ranges = <0x02000000 0x0 0xa0000000
+ 0x02000000 0x0 0xa0000000
+ 0x0 0x20000000
- 01000000 0 00000000
- 01000000 0 00000000
- 0 08000000>;
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x08000000>;
};
};
};
--
1.5.0.rc1.gf4b6c
^ permalink raw reply related
* Re: [PATCH 4/4] PowerPC: Add PCI node to 440GRx Rainier DTS.
From: Valentine Barshak @ 2007-12-21 17:19 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20071221162708.GA1724@ru.mvista.com>
> + reg = <1 eec00000 8 /* Config space access */
> + 1 eed80000 4 /* IACK */
> + 1 eed80000 4 /* Special cycle */
Please, discard this one, since it contains the typos pasted from
previous bamboo dts, which have been fixed :).
I'll send the corrected patch right away.
Thanks,
Valentine.
^ permalink raw reply
* Re: Time for cell code reshuffle?
From: Geoff Levand @ 2007-12-21 17:23 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Jeremy Kerr
In-Reply-To: <200712211522.03841.arnd@arndb.de>
Arnd Bergmann wrote:
> We've been discussing in the past a few times where we should best put
> the spufs code, and when to do it. Since Jeremy and I now have all the
> current patches in powerpc.git, maybe we should do it now.
>
> To the question, where what it should go, I'd leave the decision to
> Jeremy, but my current idea would be:
>
> arch/powerpc/platforms/cell/spufs -> arch/powerpc/spufs
> arch/powerpc/platforms/cell/spu_{callbacks,base,syscalls,fault,notify}.[co]
> -> arch/powerpc/spufs/{callbacks,base,syscalls,fault,notify}.[co]
I think we should consider support for SpursEngine. At the moment I have no
idea of what it needs, and if no one else does we need to find out.
> If we do it in git now, that should result in a minimal breakage of patches.
>
> A related question is what to do about the location of the other cell
> related files. platforms/ps3 is already pretty self-contained once we have
> spufs outside of platforms/cell, but there is still some code shared between
> platforms/cell and platforms/celleb, and each of these directories also contains
> code that is only relevant for a subset of the platforms.
It seems platforms/cell should have the shared and/or generic code, and the other
stuff moved into a new platform directory, but is it worth the effort?
-Geoff
^ permalink raw reply
* Re: [PATCH 0/4] arch/powerpc support for SBC8560 board
From: Scott Wood @ 2007-12-21 17:31 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: linuxppc-dev, david
In-Reply-To: <20071221033815.GA13921@windriver.com>
On Thu, Dec 20, 2007 at 10:38:15PM -0500, Paul Gortmaker wrote:
> Here is my interpretation of what is happening here -- we come in via
> find_legacy_serial_ports() to pick a console port. It grabs "chosen"
> to get np stdout, and then checks the parent of the 16550 compat ports
> against the following, requiring at least one of them to match:
>
> parent->type == "soc" ? add_legacy_soc_port()
>
> parent->type == "isa" ? add_legacy_isa_port()
>
> parent->type == "tsi-bridge" ? add_legacy_soc_port()
>
> parent->type == "opb" ? add_legacy_soc_port()
We should probably add a parent-is-compatible-with-"simple-bus" check, to
avoid needing to extend this hack even further.
> > Out of interest how exactly are the duart's wired on the 8560. Are they
> > off localbus?
>
> The board has a bunch of stuff hanging off of CS5 -- an RTC, a 7 segment
> display, an EEPROM, some BCSR-like registers, and of course the two
> UARTs which are supposed to be 16C2550. According to TFM, an EPM7128
> PLD is responsible for mashing/sub-decoding this all onto/off of CS5.
> CS3 and CS4 are the LB-SDRAM.
I'd put these devices under a /localbus node.
-Scott
^ permalink raw reply
* Re: Yet more patches added to for-2.6.25/master branches
From: Grant Likely @ 2007-12-21 17:34 UTC (permalink / raw)
To: Marian Balakowicz; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <476BCA09.3070104@semihalf.com>
[-- Attachment #1: Type: text/plain, Size: 1236 bytes --]
On 12/21/07, Marian Balakowicz <m8@semihalf.com> wrote:
>
>
> Any changes to add new 52xx targets:
>
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14661
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14662
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14663
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14743
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14665
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14666
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14667
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14668
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14669
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14670
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14671
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14672
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14673
>
> Those did not make it to 2.6.24, Grant Likely suggested to wait until
> 2.6.25 window opens.
I'll be picking these up next week. I haven't had time to do it earlier.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
[-- Attachment #2: Type: text/html, Size: 2744 bytes --]
^ permalink raw reply
* Re: [PATCH 3/4] sbc8560: Add device tree source for Wind River SBC8560 board
From: Scott Wood @ 2007-12-21 17:40 UTC (permalink / raw)
To: Paul Gortmaker, linuxppc-dev
In-Reply-To: <20071220235724.GA2665@localhost.localdomain>
On Fri, Dec 21, 2007 at 10:57:24AM +1100, David Gibson wrote:
> > + mpic: pic@40000 {
> > + clock-frequency = <0>;
>
> The mpic has a clock-frequency??
Yes, there's a timer on the PIC.
> > + interrupt-controller;
> > + #address-cells = <0>;
>
> Should have #size-cells = <0> too.
This is debatable. :-)
-Scott
^ permalink raw reply
* Re: [PATCH -mm 18/43] powerpc compat_binfmt_elf
From: Kyle McMartin @ 2007-12-21 17:51 UTC (permalink / raw)
To: Roland McGrath
Cc: linux-arch, linux-kernel, Christoph Hellwig, linuxppc-dev,
Paul Mackerras, Andrew Morton, Linus Torvalds
In-Reply-To: <20071221085609.4D53B26F98A@magilla.localdomain>
On Fri, Dec 21, 2007 at 12:56:09AM -0800, Roland McGrath wrote:
> > On Thu, Dec 20, 2007 at 03:58:16AM -0800, Roland McGrath wrote:
> > > +obj-$(CONFIG_PPC64) += ../../../fs/compat_binfmt_elf.o
> >
> > Building files from another directory is nasty. Please add a
> > CONFIG_BINFMT_COMPAT_ELF so we can simply build it in fs/
>
> If that's better, please post the precise Kconfig magic you have in mind to
> have it set when it should be.
>
Just taking a stab that hch means,
config BINFMT_COMPAT_ELF
def_bool n
depends on 64BIT
and then in arch/powerpc/Kconfig
config COMPAT
bool
default y if PPC64
select BINFMT_COMPAT_ELF
or somesuch.
Regards, Kyle
^ permalink raw reply
* [PATCH 4/4] PowerPC: Add PCI entry to 440GRx Rainier DTS.
From: Valentine Barshak @ 2007-12-21 17:22 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <476BF5B7.3030201@ru.mvista.com>
This adds PCI entry to PowerPC 440GRx Rainier DTS.
Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
---
arch/powerpc/boot/dts/rainier.dts | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+)
--- linux-2.6.orig/arch/powerpc/boot/dts/rainier.dts 2007-12-19 16:00:01.000000000 +0300
+++ linux-2.6/arch/powerpc/boot/dts/rainier.dts 2007-12-20 21:59:42.000000000 +0300
@@ -317,6 +317,33 @@
has-new-stacr-staopc;
};
};
+
+ PCI0: pci@1ec000000 {
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "ibm,plb440grx-pci", "ibm,plb-pci";
+ primary;
+ reg = <1 eec00000 8 /* Config space access */
+ 1 eed00000 4 /* IACK */
+ 1 eed00000 4 /* Special cycle */
+ 1 ef400000 40>; /* Internal registers */
+
+ /* Outbound ranges, one memory and one IO,
+ * later cannot be changed. Chip supports a second
+ * IO range but we don't use it for now
+ */
+ ranges = <02000000 0 80000000 1 80000000 0 10000000
+ 01000000 0 00000000 1 e8000000 0 00100000>;
+
+ /* Inbound 2GB range starting at 0 */
+ dma-ranges = <42000000 0 0 0 0 0 80000000>;
+
+ /* All PCI interrupts are routed to IRQ 67 */
+ interrupt-map-mask = <0000 0 0 0>;
+ interrupt-map = < 0000 0 0 0 &UIC2 3 8 >;
+ };
};
chosen {
^ permalink raw reply
* Re: Yet more patches added to for-2.6.25/master branches
From: Marian Balakowicz @ 2007-12-21 18:07 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <fa686aa40712210934s607ab3c3x6374d2850b9e987a@mail.gmail.com>
Grant Likely wrote:
>
> On 12/21/07, *Marian Balakowicz* <m8@semihalf.com
>
> Any changes to add new 52xx targets:
>
> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14661
[...]
>
> Those did not make it to 2.6.24, Grant Likely suggested to wait until
> 2.6.25 window opens.
>
>
> I'll be picking these up next week. I haven't had time to do it earlier.
Great, I'll retest the set with the latest vanilla next week.
Thanks,
Marian
^ permalink raw reply
* Re: Yet more patches added to for-2.6.25/master branches
From: Grant Likely @ 2007-12-21 18:13 UTC (permalink / raw)
To: Marian Balakowicz; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <476C00C9.8080107@semihalf.com>
On 12/21/07, Marian Balakowicz <m8@semihalf.com> wrote:
> Grant Likely wrote:
> >
> > On 12/21/07, *Marian Balakowicz* <m8@semihalf.com
> >
> > Any changes to add new 52xx targets:
> >
> > http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14661
> [...]
> >
> > Those did not make it to 2.6.24, Grant Likely suggested to wait until
> > 2.6.25 window opens.
> >
> >
> > I'll be picking these up next week. I haven't had time to do it earlier.
>
> Great, I'll retest the set with the latest vanilla next week.
Actually, you should retest against Paulus' latest tree instead
because that is what it will be merged against.
Cheers,
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: Yet more patches added to for-2.6.25/master branches
From: Marian Balakowicz @ 2007-12-21 18:25 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <fa686aa40712211013o21ae44d2s95b9b1abb44e661d@mail.gmail.com>
Grant Likely wrote:
> On 12/21/07, Marian Balakowicz <m8@semihalf.com> wrote:
>> Grant Likely wrote:
>>> On 12/21/07, *Marian Balakowicz* <m8@semihalf.com
>>>
>>> Any changes to add new 52xx targets:
>>>
>>> http://patchwork.ozlabs.org/linuxppc/patch?person=988&id=14661
>> [...]
>>> Those did not make it to 2.6.24, Grant Likely suggested to wait until
>>> 2.6.25 window opens.
>>>
>>>
>>> I'll be picking these up next week. I haven't had time to do it earlier.
>> Great, I'll retest the set with the latest vanilla next week.
>
> Actually, you should retest against Paulus' latest tree instead
> because that is what it will be merged against.
OK, got it.
Cheers,
Marian
^ permalink raw reply
* Re: Time for cell code reshuffle?
From: Arnd Bergmann @ 2007-12-21 19:15 UTC (permalink / raw)
To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Jeremy Kerr
In-Reply-To: <476BF67C.2030405@am.sony.com>
On Friday 21 December 2007, Geoff Levand wrote:
> Arnd Bergmann wrote:
>
> > arch/powerpc/platforms/cell/spufs -> arch/powerpc/spufs
> > arch/powerpc/platforms/cell/spu_{callbacks,base,syscalls,fault,notify}.[co]
> > -> arch/powerpc/spufs/{callbacks,base,syscalls,fault,notify}.[co]
>
>
> I think we should consider support for SpursEngine. At the moment I have no
> idea of what it needs, and if no one else does we need to find out.
Hmm, since there is not much documentation available for SpursEngine, it's
rather hard to tell what needs to be done for it.
If we think that it will hit the kernel anytime soon, we could use fs/spufs
instead of arch/powerpc/spufs right away. Interestingly, this is where it was
initially, but got moved to arch/powerpc/platforms/cell/spufs after a lot
of discussion ;-).
> It seems platforms/cell should have the shared and/or generic code, and the other
> stuff moved into a new platform directory, but is it worth the effort?
There is very little code in platforms/cell that can not be generic, so I think
it's not worth splitting it. The only IBM blade specific files are
cbe_cpufreq_pmi.c and parts of setup.c and pervasive.c. Everything else could
be shared by about any generic implementation without a hypervisor.
Arnd <><
^ permalink raw reply
* [PATCH POWERPC] i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers
From: Jochen Friedrich @ 2007-12-21 19:36 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, linux-kernel, i2c
Using the port of 2.4 code from Vitaly Bordug <vitb@kernel.crashing.org>
and the actual algorithm used by the i2c driver of the DBox code on
cvs.tuxboc.org from Tmbinc, Gillem (htoa@gmx.net). Renamed i2c-rpx.c and
i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an
of_platform_driver.
Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
arch/powerpc/boot/dts/mpc866ads.dts | 10 +
arch/powerpc/boot/dts/mpc885ads.dts | 10 +
arch/powerpc/platforms/8xx/mpc885ads_setup.c | 5 +
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-cpm.c | 776 ++++++++++++++++++++++++++
6 files changed, 812 insertions(+), 0 deletions(-)
create mode 100644 drivers/i2c/busses/i2c-cpm.c
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index 90f2293..c79cac1 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -141,6 +141,16 @@
interrupts = <1e 3>;
interrupt-parent = <&Cpm_pic>;
};
+
+ i2c@860 {
+ compatible = "fsl,mpc866-i2c",
+ "fsl,cpm1-i2c",
+ "fsl,cpm-i2c";
+ reg = <860 20 3c80 30>;
+ interrupts = <10 3>;
+ interrupt-parent = <&Cpm_pic>;
+ fsl,cpm-command = <0010>;
+ };
};
};
};
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e63..fd9c9d7 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -213,6 +213,16 @@
fsl,cpm-command = <0080>;
linux,network-index = <2>;
};
+
+ i2c@860 {
+ compatible = "fsl,mpc885-i2c",
+ "fsl,cpm1-i2c",
+ "fsl,cpm-i2c";
+ reg = <860 20 3c80 30>;
+ interrupts = <10>;
+ interrupt-parent = <&CPM_PIC>;
+ fsl,cpm-command = <0010>;
+ };
};
};
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2cf1b6a..4377521 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -157,6 +157,11 @@ static struct cpm_pin mpc885ads_pins[] = {
{CPM_PORTE, 28, CPM_PIN_OUTPUT},
{CPM_PORTE, 29, CPM_PIN_OUTPUT},
#endif
+ /* I2C */
+#ifdef CONFIG_I2C_8XX
+ {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+ {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+#endif
};
static void __init init_ioports(void)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index c466c6c..5950172 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
help
The unit of the TWI clock is kHz.
+config I2C_CPM
+ tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+ depends on (CPM1 || CPM2) && I2C && PPC_OF
+ help
+ This supports the use of the I2C interface on Freescale
+ processors with CPM1 or CPM2.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-cpm.
+
config I2C_DAVINCI
tristate "DaVinci I2C driver"
depends on ARCH_DAVINCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 81d43c2..a395555 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_AT91) += i2c-at91.o
obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644
index 0000000..c3714f6
--- /dev/null
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -0,0 +1,776 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update: There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any CPM board. The console messages have been
+ * changed to eliminate RPXLite references.
+ *
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * moved into proper i2c interface; separated out platform specific
+ * parts into i2c-8xx.c
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Tmbinc, Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007 Jochen Friedrich <jochen@scram.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/ */
+#undef I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ 513
+#define CPM_MAXBD 4
+
+/* Buffer descriptors used by many of the CPM protocols. */
+typedef struct cpm_buf_desc {
+ ushort cbd_sc; /* Status and Control */
+ ushort cbd_datlen; /* Data length in buffer */
+ uint cbd_bufaddr; /* Buffer address in host memory */
+} cbd_t;
+
+#define BD_I2C_EMPTY (0x8000) /* Receive is empty */
+#define BD_I2C_READY (0x8000) /* Transmit is ready */
+#define BD_I2C_WRAP (0x2000) /* Last buffer descriptor */
+#define BD_I2C_INTRPT (0x1000) /* Interrupt on change */
+#define BD_I2C_LAST (0x0800) /* Last buffer in frame */
+#define BD_I2C_START (0x0400) /* Send start condition */
+#define BD_I2C_NAK (0x0004) /* NAK - did not respond */
+#define BD_I2C_OV (0x0002) /* OV - receive overrun */
+#define BD_I2C_UN (0x0002) /* UN - transmit underrun */
+#define BD_I2C_CL (0x0001) /* Collision */
+
+#define CPM_CR_INIT_TRX (0x00)
+#define CPM_CR_CLOSE_RXBD (0x07)
+
+#define I2C_EB (0x10) /* Big endian mode */
+
+/* I2C parameter RAM. */
+typedef struct i2c_ram {
+ ushort rbase; /* Rx Buffer descriptor base address */
+ ushort tbase; /* Tx Buffer descriptor base address */
+ u_char rfcr; /* Rx function code */
+ u_char tfcr; /* Tx function code */
+ ushort mrblr; /* Max receive buffer length */
+ uint rstate; /* Internal */
+ uint rdp; /* Internal */
+ ushort rbptr; /* Rx Buffer descriptor pointer */
+ ushort rbc; /* Internal */
+ uint rxtmp; /* Internal */
+ uint tstate; /* Internal */
+ uint tdp; /* Internal */
+ ushort tbptr; /* Tx Buffer descriptor pointer */
+ ushort tbc; /* Internal */
+ uint txtmp; /* Internal */
+ char res1[4]; /* Reserved */
+ ushort rpbase; /* Relocation pointer */
+} i2c_ram_t;
+
+/* I2C Registers */
+typedef struct i2c_reg {
+ u8 i2mod;
+ u8 res1[3];
+ u8 i2add;
+ u8 res2[3];
+ u8 i2brg;
+ u8 res3[3];
+ u8 i2com;
+ u8 res4[3];
+ u8 i2cer;
+ u8 res5[3];
+ u8 i2cmr;
+} i2c_reg_t;
+
+struct cpm_i2c {
+ char *base;
+ struct of_device *ofdev;
+ struct i2c_adapter adap;
+ uint dp_addr;
+ int reloc;
+ int version; /* CPM1=1, CPM2=2 */
+ int irq;
+ int cp_command;
+ i2c_reg_t __iomem *i2c_reg;
+ i2c_ram_t __iomem *i2c_ram;
+ u16 i2c_addr;
+ wait_queue_head_t i2c_wait;
+ struct mutex i2c_mutex; /* Protects I2C CPM */
+ u_char *txbuf[CPM_MAXBD];
+ u_char *rxbuf[CPM_MAXBD];
+ u32 txdma[CPM_MAXBD];
+ u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+ struct i2c_adapter *adap;
+ struct cpm_i2c *cpm;
+ i2c_reg_t __iomem *i2c_reg;
+ int i;
+
+ adap = (struct i2c_adapter *) dev_id;
+ cpm = i2c_get_adapdata(adap);
+ i2c_reg = cpm->i2c_reg;
+
+ /* Clear interrupt.
+ */
+ i = in_8(&i2c_reg->i2cer);
+ out_8(&i2c_reg->i2cer, i);
+
+ dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+ /* Get 'me going again.
+ */
+ wake_up_interruptible(&cpm->i2c_wait);
+
+ return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+ i2c_ram_t __iomem *i2c_ram = cpm->i2c_ram;
+
+ /* Set up the IIC parameters in the parameter ram.
+ */
+ out_be16(&i2c_ram->tbase, cpm->dp_addr);
+ out_be16(&i2c_ram->rbase, cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+ out_8(&i2c_ram->tfcr, I2C_EB);
+ out_8(&i2c_ram->rfcr, I2C_EB);
+
+ out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+ out_be32(&i2c_ram->rstate, 0);
+ out_be32(&i2c_ram->rdp, 0);
+ out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+ out_be16(&i2c_ram->rbc, 0);
+ out_be32(&i2c_ram->rxtmp, 0);
+ out_be32(&i2c_ram->tstate, 0);
+ out_be32(&i2c_ram->tdp, 0);
+ out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+ out_be16(&i2c_ram->tbc, 0);
+ out_be32(&i2c_ram->txtmp, 0);
+}
+
+static int cpm_i2c_init(struct i2c_adapter *adap)
+{
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ i2c_ram_t __iomem *i2c_ram = cpm->i2c_ram;
+ i2c_reg_t __iomem *i2c_reg = cpm->i2c_reg;
+ unsigned char brg;
+ int ret, i;
+
+ pr_debug("i2c-cpm: cpm_i2c_init()\n");
+
+ ret = 0;
+ init_waitqueue_head(&cpm->i2c_wait);
+ mutex_init(&cpm->i2c_mutex);
+
+ /* Initialize Tx/Rx parameters. */
+
+ cpm_reset_i2c_params(cpm);
+
+ pr_debug("i2c-cpm: i2c_ram %x, dp_addr 0x%x\n", (uint) cpm->i2c_ram,
+ cpm->dp_addr);
+ pr_debug("i2c-cpm: tbase %d, rbase %d\n",
+ in_be16(&i2c_ram->tbase), in_be16(&i2c_ram->rbase));
+
+ cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+ /* Select an invalid address. Just make sure we don't use loopback mode
+ */
+ out_8(&i2c_reg->i2add, 0xfe);
+
+ /* Make clock run at 60 kHz. */
+
+ brg = get_brgfreq() / (32 * 2 * 60000) - 3;
+ out_8(&i2c_reg->i2brg, brg);
+
+ out_8(&i2c_reg->i2mod, 0x00);
+ out_8(&i2c_reg->i2com, 0x01); /* Master mode */
+
+ /* Disable interrupts. */
+ out_8(&i2c_reg->i2cmr, 0);
+ out_8(&i2c_reg->i2cer, 0xff);
+
+ /* Allocate TX and RX buffers */
+ for (i = 0; i < CPM_MAXBD; i++) {
+ cpm->rxbuf[i] = dma_alloc_coherent(
+ NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+ if (!cpm->rxbuf[i]) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+ NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+ if (!cpm->txbuf[i]) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ }
+
+ /* Install interrupt handler.
+ */
+ ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c", adap);
+ if (ret)
+ goto out;
+
+ return 0;
+
+out:
+ for (i = 0; i < CPM_MAXBD; i++) {
+ if (cpm->rxbuf[i])
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->rxbuf[i], cpm->rxdma[i]);
+ if (cpm->txbuf[i])
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->txbuf[i], cpm->txdma[i]);
+ }
+ return ret;
+}
+
+static int cpm_i2c_shutdown(struct i2c_adapter *adap)
+{
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ int i;
+
+ i2c_reg_t __iomem *i2c_reg = cpm->i2c_reg;
+
+ /* Shut down IIC. */
+ out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+ out_8(&i2c_reg->i2cmr, 0);
+ out_8(&i2c_reg->i2cer, 0xff);
+
+ for (i = 0; i < CPM_MAXBD; i++) {
+ if (cpm->rxbuf[i])
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->rxbuf[i], cpm->rxdma[i]);
+ if (cpm->txbuf[i])
+ dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ cpm->txbuf[i], cpm->txdma[i]);
+ }
+
+ free_irq(cpm->irq, adap);
+
+ return 0;
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ i2c_reg_t __iomem *i2c_reg = cpm->i2c_reg;
+
+ dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+ cpm_command(cpm->cp_command, CPM_CR_CLOSE_RXBD);
+
+ out_8(&i2c_reg->i2cmr, 0x00); /* Disable all interrupts */
+ out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+ struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+ cbd_t *tbdf, *rbdf;
+ u_char addr;
+ u_char *tb;
+ u_char *rb;
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ i2c_ram_t __iomem *i2c_ram = cpm->i2c_ram;
+ int i, dscan;
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+ /* This chip can't do zero length writes. However, the i2c core uses
+ them to scan for devices. The best we can do is to convert them
+ into 1 byte reads */
+
+ dscan = ((pmsg->len == 0) && (num == 1));
+
+ addr = pmsg->addr << 1;
+ if ((pmsg->flags & I2C_M_RD) || dscan)
+ addr |= 1;
+
+ tb = cpm->txbuf[tx];
+ rb = cpm->rxbuf[rx];
+
+ /* Align read buffer */
+ rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+ if ((pmsg->flags & I2C_M_RD) || dscan) {
+ /* To read, we need an empty buffer of the proper length.
+ * All that is used is the first byte for address, the remainder
+ * is just used for timing (and doesn't really have to exist).
+ */
+ tb[0] = addr; /* Device address byte w/rw flag */
+
+ dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+ tbdf[tx].cbd_bufaddr = cpm->txdma[tx];
+
+ if (dscan)
+ tbdf[tx].cbd_datlen = 2;
+ else
+ tbdf[tx].cbd_datlen = pmsg->len + 1;
+
+ tbdf[tx].cbd_sc = 0;
+
+ if (!(pmsg->flags & I2C_M_NOSTART))
+ tbdf[tx].cbd_sc |= BD_I2C_START;
+ if (tx + 1 == num)
+ tbdf[tx].cbd_sc |= BD_I2C_LAST | BD_I2C_WRAP;
+
+ rbdf[rx].cbd_datlen = 0;
+ rbdf[rx].cbd_bufaddr = ((cpm->rxdma[rx] + 1) & ~1);
+ rbdf[rx].cbd_sc = BD_I2C_EMPTY | BD_I2C_INTRPT;
+
+ if (rx + 1 == CPM_MAXBD)
+ tbdf[rx].cbd_sc |= BD_I2C_WRAP;
+
+ eieio();
+ tbdf[tx].cbd_sc |= BD_I2C_READY;
+ } else {
+ tb[0] = addr; /* Device address byte w/rw flag */
+ for (i = 0; i < pmsg->len; i++)
+ tb[i+1] = pmsg->buf[i];
+
+ dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr);
+
+ tbdf[tx].cbd_bufaddr = cpm->txdma[tx];
+ tbdf[tx].cbd_datlen = pmsg->len + 1;
+ tbdf[tx].cbd_sc = 0;
+
+ if (!(pmsg->flags & I2C_M_NOSTART))
+ tbdf[tx].cbd_sc |= BD_I2C_START;
+
+ if (tx + 1 == num)
+ tbdf[tx].cbd_sc |= BD_I2C_LAST | BD_I2C_WRAP;
+
+ eieio();
+ tbdf[tx].cbd_sc |= BD_I2C_READY | BD_I2C_INTRPT;
+
+ dev_dbg(&adap->dev, "tx sc %d %04x\n",
+ tx, tbdf[tx].cbd_sc);
+ }
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+ struct i2c_msg *pmsg, int tx, int rx)
+{
+ cbd_t *tbdf, *rbdf;
+ u_char *tb;
+ u_char *rb;
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ i2c_ram_t __iomem *i2c_ram = cpm->i2c_ram;
+ int i;
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+ tb = cpm->txbuf[tx];
+ rb = cpm->rxbuf[rx];
+
+ /* Align read buffer */
+ rb = (u_char *) (((uint) rb + 1) & ~1);
+
+ if (pmsg->flags & I2C_M_RD) {
+ dev_dbg(&adap->dev, "rx sc %04x, rx sc %04x\n",
+ tbdf[tx].cbd_sc, rbdf[rx].cbd_sc);
+
+ if (tbdf[tx].cbd_sc & BD_I2C_NAK) {
+ dev_dbg(&adap->dev, "IIC read; No ack\n");
+
+ if (pmsg->flags & I2C_M_IGNORE_NAK)
+ return 0;
+ else
+ return -EIO;
+ }
+ if (rbdf[rx].cbd_sc & BD_I2C_EMPTY) {
+ dev_dbg(&adap->dev,
+ "IIC read; complete but rbuf empty\n");
+ return -EREMOTEIO;
+ }
+ if (rbdf[rx].cbd_sc & BD_I2C_OV) {
+ dev_dbg(&adap->dev, "IIC read; Overrun\n");
+ return -EREMOTEIO;
+ }
+ for (i = 0; i < pmsg->len; i++)
+ pmsg->buf[i] = rb[i];
+ } else {
+ dev_dbg(&adap->dev, "tx sc %d %04x\n", tx, tbdf[tx].cbd_sc);
+
+ if (tbdf[tx].cbd_sc & BD_I2C_NAK) {
+ dev_dbg(&adap->dev, "IIC write; No ack\n");
+
+ if (pmsg->flags & I2C_M_IGNORE_NAK)
+ return 0;
+ else
+ return -EIO;
+ }
+ if (tbdf[tx].cbd_sc & BD_I2C_UN) {
+ dev_dbg(&adap->dev, "IIC write; Underrun\n");
+ return -EIO;
+ }
+ if (tbdf[tx].cbd_sc & BD_I2C_CL) {
+ dev_dbg(&adap->dev, "IIC write; Collision\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+ i2c_reg_t __iomem *i2c_reg = cpm->i2c_reg;
+ i2c_ram_t __iomem *i2c_ram = cpm->i2c_ram;
+ struct i2c_msg *pmsg, *rmsg;
+ int ret, i;
+ int tptr;
+ int rptr;
+ cbd_t *tbdf, *rbdf;
+
+ if (num > CPM_MAXBD)
+ return -EINVAL;
+
+ /* Check if we have any oversized READ requests */
+ for (i = 0; i < num; i++) {
+ pmsg = &msgs[i];
+ if (pmsg->len >= CPM_MAX_READ)
+ return -EINVAL;
+ }
+
+ mutex_lock(&cpm->i2c_mutex);
+
+ /* Reset to use first buffer */
+ out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+ out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+ tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+ rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+ tptr = 0;
+ rptr = 0;
+
+ while (tptr < num) {
+ pmsg = &msgs[tptr];
+ dev_dbg(&adap->dev, "i2c-algo-cpm.o: " "R: %d T: %d\n",
+ rptr, tptr);
+
+ cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+ if (pmsg->flags & I2C_M_RD)
+ rptr++;
+ tptr++;
+ }
+ /* Start transfer now */
+ /* Chip bug, set enable here */
+ out_8(&i2c_reg->i2cmr, 0x13); /* Enable some interupts */
+ out_8(&i2c_reg->i2cer, 0xff);
+ out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | 1); /* Enable */
+ /* Begin transmission */
+ out_8(&i2c_reg->i2com, in_8(&i2c_reg->i2com) | 0x80);
+
+ tptr = 0;
+ rptr = 0;
+
+ while (tptr < num) {
+ /* Check for outstanding messages */
+ dev_dbg(&adap->dev, "test ready.\n");
+ if (!(tbdf[tptr].cbd_sc & BD_I2C_READY)) {
+ dev_dbg(&adap->dev, "ready.\n");
+ rmsg = &msgs[tptr];
+ ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+ tptr++;
+ if (rmsg->flags & I2C_M_RD)
+ rptr++;
+ if (ret) {
+ cpm_i2c_force_close(adap);
+ mutex_unlock(&cpm->i2c_mutex);
+ return ret;
+ }
+ } else {
+ dev_dbg(&adap->dev, "not ready.\n");
+ ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+ !(tbdf[tptr].cbd_sc & BD_I2C_READY), 1 * HZ);
+ if (ret == 0) {
+ cpm_i2c_force_close(adap);
+ dev_dbg(&adap->dev, "I2C read: timeout!\n");
+ mutex_unlock(&cpm->i2c_mutex);
+ return -EREMOTEIO;
+ }
+ }
+ }
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+ mutex_unlock(&cpm->i2c_mutex);
+ return (num);
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* -----exported algorithm data: ------------------------------------- */
+
+static struct i2c_algorithm cpm_i2c_algo = {
+ .master_xfer = cpm_i2c_xfer,
+ .functionality = cpm_i2c_func,
+};
+
+/*
+ * registering functions to load algorithms at runtime
+ */
+int i2c_cpm_add_bus(struct i2c_adapter *adap)
+{
+ int res;
+
+ pr_debug("i2c-cpm: hw routines for %s registered.\n", adap->name);
+
+ /* register new adapter to i2c module... */
+
+ adap->algo = &cpm_i2c_algo;
+
+ res = cpm_i2c_init(adap);
+
+ if (res)
+ return res;
+
+ return i2c_add_adapter(adap);
+}
+
+int i2c_cpm_del_bus(struct i2c_adapter *adap)
+{
+ i2c_del_adapter(adap);
+
+ return cpm_i2c_shutdown(adap);
+}
+
+static const struct i2c_adapter cpm_ops = {
+ .owner = THIS_MODULE,
+ .name = "i2c-cpm",
+ .id = I2C_HW_MPC8XX_EPON,
+ .class = I2C_CLASS_HWMON,
+};
+
+static int i2c_cpm_setup(struct cpm_i2c *i2c)
+{
+ struct of_device *ofdev = i2c->ofdev;
+ const u32 *data;
+ int len, ret;
+ void __iomem *i2c_base;
+
+ /* Pointer to Communication Processor
+ */
+ i2c->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+ if (i2c->irq == NO_IRQ)
+ return -EINVAL;
+
+ if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+ /* IIC parameter RAM */
+ i2c->i2c_ram = of_iomap(ofdev->node, 1);
+ if (i2c->i2c_ram == NULL)
+ return -EINVAL;
+
+ /* Check for and use a microcode relocation patch.
+ */
+ i2c->reloc = i2c->i2c_ram->rpbase;
+
+ /* Maybe should use cpm_muram_alloc instead of hardcoding
+ * this in micropatch.c */
+ if (i2c->reloc) {
+ iounmap(i2c->i2c_ram);
+ i2c->i2c_ram = cpm_muram_addr(i2c->i2c_ram->rpbase);
+ }
+ i2c->version = 1;
+ } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+ i2c_base = of_iomap(ofdev->node, 1);
+ if (i2c_base == NULL)
+ return -EINVAL;
+ i2c->i2c_addr = cpm_muram_alloc(0x30, 64);
+ i2c->i2c_ram = cpm_muram_addr(i2c->i2c_addr);
+ out_be16(i2c_base, i2c->i2c_addr);
+ iounmap(i2c_base);
+ i2c->version = 2;
+ } else
+ return -EINVAL;
+
+ /* I2C control/status registers */
+ i2c->i2c_reg = of_iomap(ofdev->node, 0);
+ if (i2c->i2c_reg == NULL) {
+ ret = -EINVAL;
+ goto out_ram;
+ }
+
+ /* Allocate space for two transmit and two receive buffer
+ * descriptors in the DP ram.
+ */
+ i2c->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 4, 8);
+ if (!i2c->dp_addr) {
+ ret = -ENOMEM;
+ goto out_reg;
+ }
+
+ data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+ if (!data || len != 4) {
+ ret = -EINVAL;
+ goto out_muram;
+ }
+
+ i2c->cp_command = *data;
+ return 0;
+
+out_muram:
+ cpm_muram_free(i2c->dp_addr);
+out_reg:
+ iounmap(i2c->i2c_reg);
+out_ram:
+ if ((i2c->version == 1) && (!i2c->reloc))
+ iounmap(i2c->i2c_ram);
+ if (i2c->version == 2)
+ cpm_muram_free(i2c->i2c_addr);
+ return ret;
+}
+
+static void i2c_cpm_release(struct cpm_i2c *i2c)
+{
+ cpm_muram_free(i2c->dp_addr);
+ iounmap(i2c->i2c_reg);
+
+ if ((i2c->version == 1) && (!i2c->reloc))
+ iounmap(i2c->i2c_ram);
+ if (i2c->version == 2)
+ cpm_muram_free(i2c->i2c_addr);
+
+ return;
+}
+
+static int i2c_cpm_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ int result;
+ struct cpm_i2c *i2c;
+
+ i2c = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+ i2c->ofdev = ofdev;
+
+ result = i2c_cpm_setup(i2c);
+ if (result) {
+ printk(KERN_ERR "i2c-cpm: Unable to register resources\n");
+ goto out;
+ }
+
+ dev_set_drvdata(&ofdev->dev, i2c);
+
+ i2c->adap = cpm_ops;
+ i2c_set_adapdata(&i2c->adap, i2c);
+ i2c->adap.dev.parent = &ofdev->dev;
+
+ result = i2c_cpm_add_bus(&i2c->adap);
+ if (result < 0) {
+ printk(KERN_ERR "i2c-cpm: Unable to register with I2C\n");
+ goto out;
+ }
+ return 0;
+
+out:
+ kfree(i2c);
+ return result;
+}
+
+static int i2c_cpm_remove(struct of_device *ofdev)
+{
+ struct cpm_i2c *i2c = dev_get_drvdata(&ofdev->dev);
+
+ i2c_cpm_del_bus(&i2c->adap);
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ i2c_cpm_release(i2c);
+ kfree(i2c);
+ return 0;
+}
+
+static struct of_device_id i2c_cpm_match[] = {
+ {
+ .compatible = "fsl,cpm-i2c",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, i2c_cpm_match);
+
+static struct of_platform_driver i2c_cpm_driver = {
+ .name = "fsl-i2c-cpm",
+ .match_table = i2c_cpm_match,
+ .probe = i2c_cpm_probe,
+ .remove = i2c_cpm_remove,
+};
+
+static int __init i2c_cpm_init(void)
+{
+ return of_register_platform_driver(&i2c_cpm_driver);
+}
+
+static void __exit i2c_cpm_exit(void)
+{
+ of_unregister_platform_driver(&i2c_cpm_driver);
+}
+
+module_init(i2c_cpm_init);
+module_exit(i2c_cpm_exit);
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
--
1.5.3.7
^ permalink raw reply related
* Re: [PATCH -mm 18/43] powerpc compat_binfmt_elf
From: Arnd Bergmann @ 2007-12-21 19:36 UTC (permalink / raw)
To: linuxppc-dev
Cc: linux-arch, Christoph Hellwig, linux-kernel, Kyle McMartin,
Paul Mackerras, Andrew Morton, Linus Torvalds, Roland McGrath
In-Reply-To: <20071221175106.GB17656@fattire.cabal.ca>
On Friday 21 December 2007, Kyle McMartin wrote:
> Just taking a stab that hch means,
>=20
> config BINFMT_COMPAT_ELF
> =A0=A0=A0=A0=A0=A0=A0=A0def_bool n
> =A0=A0=A0=A0=A0=A0=A0=A0depends on 64BIT
>=20
I'd call it COMPAT_BINFMT_ELF, for consistency with the file name.
Also, the definition and the depends are redundant if you expect the
option to be autoselected. You can do either of
config COMPAT_BINFMT_ELF
bool
or=20
config COMPAT_BINFMT_ELF
def_bool y
depends on COMPAT
The second option makes sense at the point where all architectures with
compat code are using the same compat_binfmt_elf code.
Arnd <><
^ permalink raw reply
* Re: [PATCH 2/4] PowerPC: update 440EP(x)/440GR(x) identical PVR issue workaround
From: Valentine Barshak @ 2007-12-21 19:47 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev, Stefan Roese
In-Reply-To: <20071221104347.54cd2ad5@zod.rchland.ibm.com>
Josh Boyer wrote:
> On Fri, 21 Dec 2007 19:24:02 +0300
> Valentine Barshak <vbarshak@ru.mvista.com> wrote:
>
>> Commit 3ee133269861dc449ad5be761aa8570b1b05571f introduced
>> a CPU "model" property and thus broke PowerPC 440EP(x)/440GR(x)
>> identical PVR workaround. The patch updates it to use the new
>> model property for CPU identification.
>
> Good catch. I'll have to look more closely to see if anything else
> would be broken by changing the cpu node name from "PowerPC,xxxx@0" to
> "cpu@0".
>
> josh
Looks like we need a u-boot update for 405Ex Kilauea board.
Mine (U-Boot 1.3.0-rc3-gccc2fe86-dirty (Oct 25 2007 - 12:18:41))
fails to boot with new cpu node changes:
Uncompressing Kernel Image ... OK
Booting using the fdt at 0x400000
le to update property /cpus/PowerPC,405EX@0:timebase-frequency,
err=FDT_ERR_NOTFOUND
Unable to update property /cpus/PowerPC,405EX@0:clock-frequency,
err=FDT_ERR_NOTFOUND
Thanks,
Valentine.
^ permalink raw reply
* Re: [PATCH 2/4] PowerPC: update 440EP(x)/440GR(x) identical PVR issue workaround
From: Stefan Roese @ 2007-12-21 19:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <476C1862.8080603@ru.mvista.com>
Hi Valentine,
On Friday 21 December 2007, Valentine Barshak wrote:
> > Good catch. I'll have to look more closely to see if anything else
> > would be broken by changing the cpu node name from "PowerPC,xxxx@0" to
> > "cpu@0".
> >
> > josh
>
> Looks like we need a u-boot update for 405Ex Kilauea board.
> Mine (U-Boot 1.3.0-rc3-gccc2fe86-dirty (Oct 25 2007 - 12:18:41))
> fails to boot with new cpu node changes:
>
> Uncompressing Kernel Image ... OK
> Booting using the fdt at 0x400000
> le to update property /cpus/PowerPC,405EX@0:timebase-frequency,
> err=FDT_ERR_NOTFOUND
> Unable to update property /cpus/PowerPC,405EX@0:clock-frequency,
> err=FDT_ERR_NOTFOUND
Already done. :) Please take a look at the current implementation in the
for-1.3.2 branch of the u-boot-ppc4xx custodian repo:
http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot/u-boot-ppc4xx.git;a=shortlog;h=for-1.3.2
This works for both cpu node names.
Best regards,
Stefan
^ permalink raw reply
* [PATCH v3 0/4] device_type/compatible cleanups
From: Anton Vorontsov @ 2007-12-21 20:18 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
Hi all,
Here is the third version (let's hope the last :-).
Changes since v2:
- SPI conversion fixed and actually tested on MPC8323E-RDB to not
break anything;
- Few more users of device_type = "qe" converted to
compatible = "fsl,qe";
- Got Ack on SPI part from David.
Changes since v1:
- Device tree lookup changes should be backward compatible with
older dtbs;
- Few of_put_node() cleanups;
- cell-index property added to spi nodes;
- cpm-muram{,-data} added as an addition to qe-muram{,-data}.
Thanks,
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2
^ permalink raw reply
* [PATCH 1/4] [POWERPC] qe_lib and users: get rid of device_type and model
From: Anton Vorontsov @ 2007-12-21 20:20 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>
Now we're searching for "fsl,qe", "fsl,qe-muram", "fsl,qe-muram-data".
Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/boot/dts/mpc832x_mds.dts | 7 ++++---
arch/powerpc/boot/dts/mpc832x_rdb.dts | 7 ++++---
arch/powerpc/boot/dts/mpc836x_mds.dts | 7 ++++---
arch/powerpc/boot/dts/mpc8568mds.dts | 7 ++++---
arch/powerpc/platforms/83xx/mpc832x_mds.c | 1 +
arch/powerpc/platforms/83xx/mpc832x_rdb.c | 1 +
arch/powerpc/platforms/83xx/mpc836x_mds.c | 1 +
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 4 +++-
arch/powerpc/sysdev/fsl_soc.c | 5 ++++-
arch/powerpc/sysdev/qe_lib/qe.c | 16 +++++++++++++---
10 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 26ac467..588d658 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -175,18 +175,19 @@
qe@e0100000 {
#address-cells = <1>;
#size-cells = <1>;
- device_type = "qe";
- model = "QE";
+ compatible = "fsl,qe";
ranges = <0 e0100000 00100000>;
reg = <e0100000 480>;
brg-frequency = <0>;
bus-frequency = <BCD3D80>;
muram@10000 {
- device_type = "muram";
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
ranges = <0 00010000 00004000>;
data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
reg = <0 4000>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 10ff7aa..719f375 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -165,18 +165,19 @@
qe@e0100000 {
#address-cells = <1>;
#size-cells = <1>;
- device_type = "qe";
- model = "QE";
+ compatible = "fsl,qe";
ranges = <0 e0100000 00100000>;
reg = <e0100000 480>;
brg-frequency = <0>;
bus-frequency = <BCD3D80>;
muram@10000 {
- device_type = "muram";
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
ranges = <0 00010000 00004000>;
data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
reg = <0 4000>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index fd841b2..8d7124e 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -206,18 +206,19 @@
qe@e0100000 {
#address-cells = <1>;
#size-cells = <1>;
- device_type = "qe";
- model = "QE";
+ compatible = "fsl,qe";
ranges = <0 e0100000 00100000>;
reg = <e0100000 480>;
brg-frequency = <0>;
bus-frequency = <179A7B00>;
muram@10000 {
- device_type = "muram";
+ device_type = "fsl,qe-muram", "fsl,cpm-muram";
ranges = <0 00010000 0000c000>;
data-only@0{
+ device_type = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
reg = <0 c000>;
};
};
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 5818a7c..89add8d 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -283,18 +283,19 @@
qe@e0080000 {
#address-cells = <1>;
#size-cells = <1>;
- device_type = "qe";
- model = "QE";
+ compatible = "fsl,qe";
ranges = <0 e0080000 00040000>;
reg = <e0080000 480>;
brg-frequency = <0>;
bus-frequency = <179A7B00>;
muram@10000 {
- device_type = "muram";
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
ranges = <0 00010000 0000c000>;
data-only@0{
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
reg = <0 c000>;
};
};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 1e570bb..516715e 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -105,6 +105,7 @@ static struct of_device_id mpc832x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .compatible = "fsl,qe", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index ffb2e93..a603def 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -118,6 +118,7 @@ static struct of_device_id mpc832x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .compatible = "fsl,qe", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 2ac9890..eb64cba 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -136,6 +136,7 @@ static struct of_device_id mpc836x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .compatible = "fsl,qe", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e6c63a5..a152bf8 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -94,7 +94,8 @@ static void __init mpc85xx_mds_setup_arch(void)
#endif
#ifdef CONFIG_QUICC_ENGINE
- if ((np = of_find_node_by_name(NULL, "qe")) != NULL) {
+ np = of_find_node_by_name(NULL, "fsl,qe");
+ if (np) {
qe_reset();
of_node_put(np);
}
@@ -139,6 +140,7 @@ static struct of_device_id mpc85xx_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
+ { .compatible = "fsl,qe", },
{},
};
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 4baad80..60d9c4e 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1226,7 +1226,10 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
const u32 *sysclk;
/* SPI controller is either clocked from QE or SoC clock */
- np = of_find_node_by_type(NULL, "qe");
+ np = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!np)
+ np = of_find_node_by_type(NULL, "qe");
+
if (!np)
np = of_find_node_by_type(NULL, "soc");
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 21e0106..cd6cee3 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -68,7 +68,10 @@ phys_addr_t get_qe_base(void)
if (qebase != -1)
return qebase;
- qe = of_find_node_by_type(NULL, "qe");
+ qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!qe)
+ qe = of_find_node_by_type(NULL, "qe");
+
if (qe) {
unsigned int size;
const void *prop = of_get_property(qe, "reg", &size);
@@ -155,7 +158,10 @@ unsigned int get_brg_clk(void)
if (brg_clk)
return brg_clk;
- qe = of_find_node_by_type(NULL, "qe");
+ qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!qe)
+ qe = of_find_node_by_type(NULL, "qe");
+
if (qe) {
unsigned int size;
const u32 *prop = of_get_property(qe, "brg-frequency", &size);
@@ -334,7 +340,11 @@ static void qe_muram_init(void)
/* XXX: This is a subset of the available muram. It
* varies with the processor and the microcode patches activated.
*/
- if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) {
+ np = of_find_compatible_node(NULL, NULL, "fsl,qe-muram-data");
+ if (!np)
+ np = of_find_node_by_name(NULL, "data-only");
+
+ if (np) {
address = *of_get_address(np, 0, &size, &flags);
of_node_put(np);
rh_attach_region(&qe_muram_info, address, (int) size);
--
1.5.2.2
^ permalink raw reply related
* [PATCH 2/4] [POWERPC][NET] ucc_geth_mii and users: get rid of device_type
From: Anton Vorontsov @ 2007-12-21 20:20 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>
device_type property is bogus, thus use proper compatible.
Also change compatible property to "fsl,ucc-mdio".
Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/boot/dts/mpc832x_mds.dts | 3 +--
arch/powerpc/boot/dts/mpc832x_rdb.dts | 3 +--
arch/powerpc/boot/dts/mpc836x_mds.dts | 3 +--
arch/powerpc/boot/dts/mpc8568mds.dts | 2 +-
drivers/net/ucc_geth_mii.c | 3 +++
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 588d658..8844d30 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -255,8 +255,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <2320 18>;
- device_type = "mdio";
- compatible = "ucc_geth_phy";
+ compatible = "fsl,ucc-mdio";
phy3: ethernet-phy@03 {
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 719f375..a7a2e45 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -236,8 +236,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <3120 18>;
- device_type = "mdio";
- compatible = "ucc_geth_phy";
+ compatible = "fsl,ucc-mdio";
phy00:ethernet-phy@00 {
interrupt-parent = <&pic>;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 8d7124e..5f0b427 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -288,8 +288,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <2120 18>;
- device_type = "mdio";
- compatible = "ucc_geth_phy";
+ compatible = "fsl,ucc-mdio";
phy0: ethernet-phy@00 {
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 89add8d..ea70010 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -356,7 +356,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <2120 18>;
- compatible = "ucc_geth_phy";
+ compatible = "fsl,ucc-mdio";
/* These are the same PHYs as on
* gianfar's MDIO bus */
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index df884f0..e3ba14a 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -256,6 +256,9 @@ static struct of_device_id uec_mdio_match[] = {
.type = "mdio",
.compatible = "ucc_geth_phy",
},
+ {
+ .compatible = "fsl,ucc-mdio",
+ },
{},
};
--
1.5.2.2
^ permalink raw reply related
* [PATCH 3/4] [POWERPC][SPI] use brg-frequency for SPI in QE
From: Anton Vorontsov @ 2007-12-21 20:21 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>
In case of QE we can use brg-frequency (which is qeclk/2).
Thus no need to divide sysclk in the spi_mpc83xx.
This patch also adds code to use get_brgfreq() on QE chips.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
---
arch/powerpc/sysdev/fsl_soc.c | 39 +++++++++++++++++++++++++++------------
drivers/spi/spi_mpc83xx.c | 6 +-----
2 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 60d9c4e..746f4c5 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -66,7 +66,7 @@ phys_addr_t get_immrbase(void)
EXPORT_SYMBOL(get_immrbase);
-#if defined(CONFIG_CPM2) || defined(CONFIG_8xx)
+#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
static u32 brgfreq = -1;
@@ -91,11 +91,21 @@ u32 get_brgfreq(void)
/* Legacy device binding -- will go away when no users are left. */
node = of_find_node_by_type(NULL, "cpm");
+ if (!node)
+ node = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!node)
+ node = of_find_node_by_type(NULL, "qe");
+
if (node) {
prop = of_get_property(node, "brg-frequency", &size);
if (prop && size == 4)
brgfreq = *prop;
+ if (brgfreq == -1 || brgfreq == 0) {
+ prop = of_get_property(node, "bus-frequency", &size);
+ if (prop && size == 4)
+ brgfreq = *prop / 2;
+ }
of_node_put(node);
}
@@ -1223,22 +1233,27 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
{
struct device_node *np;
unsigned int i;
- const u32 *sysclk;
+ u32 sysclk;
/* SPI controller is either clocked from QE or SoC clock */
- np = of_find_compatible_node(NULL, NULL, "fsl,qe");
- if (!np)
- np = of_find_node_by_type(NULL, "qe");
+ sysclk = get_brgfreq();
+ if (sysclk == -1) {
+ const u32 *freq;
+ int size;
- if (!np)
np = of_find_node_by_type(NULL, "soc");
+ if (!np)
+ return -ENODEV;
- if (!np)
- return -ENODEV;
+ freq = of_get_property(np, "bus-frequency", &size);
+ if (!freq || size != sizeof(*freq)) {
+ of_node_put(np);
+ return -ENODEV;
+ }
- sysclk = of_get_property(np, "bus-frequency", NULL);
- if (!sysclk)
- return -ENODEV;
+ sysclk = *freq;
+ of_node_put(np);
+ }
for (np = NULL, i = 1;
(np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
@@ -1255,7 +1270,7 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
memset(res, 0, sizeof(res));
- pdata.sysclk = *sysclk;
+ pdata.sysclk = sysclk;
prop = of_get_property(np, "reg", NULL);
if (!prop)
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 4580b9c..04f7cd9 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -436,11 +436,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
mpc83xx_spi->qe_mode = pdata->qe_mode;
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
-
- if (mpc83xx_spi->qe_mode)
- mpc83xx_spi->spibrg = pdata->sysclk / 2;
- else
- mpc83xx_spi->spibrg = pdata->sysclk;
+ mpc83xx_spi->spibrg = pdata->sysclk;
mpc83xx_spi->rx_shift = 0;
mpc83xx_spi->tx_shift = 0;
--
1.5.2.2
^ permalink raw reply related
* [PATCH 4/4] [POWERPC] fsl_spi_init and users: stop using device_type = "spi"
From: Anton Vorontsov @ 2007-12-21 20:21 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>
Also:
- rename "fsl_spi" to "fsl,spi";
- add and use cell-index property, if found;
- split probing code out of fsl_spi_init, thus we can call
it for legacy device_type probing and new "compatible" probing.
Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/boot/dts/mpc8313erdb.dts | 4 +-
arch/powerpc/boot/dts/mpc832x_mds.dts | 8 ++--
arch/powerpc/boot/dts/mpc832x_rdb.dts | 8 ++--
arch/powerpc/boot/dts/mpc8349emitx.dts | 4 +-
arch/powerpc/boot/dts/mpc8349emitxgp.dts | 4 +-
arch/powerpc/boot/dts/mpc834x_mds.dts | 4 +-
arch/powerpc/boot/dts/mpc836x_mds.dts | 8 ++--
arch/powerpc/boot/dts/mpc8568mds.dts | 8 ++--
arch/powerpc/sysdev/fsl_soc.c | 87 ++++++++++++++++++-----------
9 files changed, 78 insertions(+), 57 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index c5b6665..a0492b6 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -82,8 +82,8 @@
};
spi@7000 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <7000 1000>;
interrupts = <10 8>;
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 8844d30..36ecd39 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -193,8 +193,8 @@
};
spi@4c0 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <4c0 40>;
interrupts = <2>;
interrupt-parent = < &qeic >;
@@ -202,8 +202,8 @@
};
spi@500 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <1>;
+ compatible = "fsl,spi";
reg = <500 40>;
interrupts = <1>;
interrupt-parent = < &qeic >;
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index a7a2e45..ce63b13 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -183,8 +183,8 @@
};
spi@4c0 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <4c0 40>;
interrupts = <2>;
interrupt-parent = <&qeic>;
@@ -192,8 +192,8 @@
};
spi@500 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <1>;
+ compatible = "fsl,spi";
reg = <500 40>;
interrupts = <1>;
interrupt-parent = <&qeic>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index e354f26..f8fc5f6 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -82,8 +82,8 @@
};
spi@7000 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <7000 1000>;
interrupts = <10 8>;
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index ebdf0b7..666650c 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -80,8 +80,8 @@
};
spi@7000 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <7000 1000>;
interrupts = <10 8>;
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index 0ba13eb..6ed36a1 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -93,8 +93,8 @@
};
spi@7000 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <7000 1000>;
interrupts = <10 8>;
interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 5f0b427..7801e66 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -224,8 +224,8 @@
};
spi@4c0 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <4c0 40>;
interrupts = <2>;
interrupt-parent = < &qeic >;
@@ -233,8 +233,8 @@
};
spi@500 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <1>;
+ compatible = "fsl,spi";
reg = <500 40>;
interrupts = <1>;
interrupt-parent = < &qeic >;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index ea70010..2a0ba5f 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -301,8 +301,8 @@
};
spi@4c0 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <0>;
+ compatible = "fsl,spi";
reg = <4c0 40>;
interrupts = <2>;
interrupt-parent = <&qeic>;
@@ -310,8 +310,8 @@
};
spi@500 {
- device_type = "spi";
- compatible = "fsl_spi";
+ cell-index = <1>;
+ compatible = "fsl,spi";
reg = <500 40>;
interrupts = <1>;
interrupt-parent = <&qeic>;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 746f4c5..5676a8a 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1226,39 +1226,17 @@ arch_initcall(cpm_smc_uart_of_init);
#endif /* CONFIG_8xx */
#endif /* CONFIG_PPC_CPM_NEW_BINDING */
-int __init fsl_spi_init(struct spi_board_info *board_infos,
- unsigned int num_board_infos,
- void (*activate_cs)(u8 cs, u8 polarity),
- void (*deactivate_cs)(u8 cs, u8 polarity))
+static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+ struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*activate_cs)(u8 cs, u8 polarity),
+ void (*deactivate_cs)(u8 cs, u8 polarity))
{
struct device_node *np;
- unsigned int i;
- u32 sysclk;
-
- /* SPI controller is either clocked from QE or SoC clock */
- sysclk = get_brgfreq();
- if (sysclk == -1) {
- const u32 *freq;
- int size;
-
- np = of_find_node_by_type(NULL, "soc");
- if (!np)
- return -ENODEV;
-
- freq = of_get_property(np, "bus-frequency", &size);
- if (!freq || size != sizeof(*freq)) {
- of_node_put(np);
- return -ENODEV;
- }
-
- sysclk = *freq;
- of_node_put(np);
- }
+ unsigned int i = 0;
- for (np = NULL, i = 1;
- (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
- i++) {
- int ret = 0;
+ for_each_compatible_node(np, type, compatible) {
+ int ret;
unsigned int j;
const void *prop;
struct resource res[2];
@@ -1277,6 +1255,10 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
goto err;
pdata.bus_num = *(u32 *)prop;
+ prop = of_get_property(np, "cell-index", NULL);
+ if (prop)
+ i = *(u32 *)prop;
+
prop = of_get_property(np, "mode", NULL);
if (prop && !strcmp(prop, "cpu-qe"))
pdata.qe_mode = 1;
@@ -1287,7 +1269,7 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
}
if (!pdata.max_chipselect)
- goto err;
+ continue;
ret = of_address_to_resource(np, 0, &res[0]);
if (ret)
@@ -1314,13 +1296,52 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
if (ret)
goto unreg;
- continue;
+ goto next;
unreg:
platform_device_del(pdev);
err:
- continue;
+ pr_err("%s: registration failed\n", np->full_name);
+next:
+ i++;
}
+ return i;
+}
+
+int __init fsl_spi_init(struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*activate_cs)(u8 cs, u8 polarity),
+ void (*deactivate_cs)(u8 cs, u8 polarity))
+{
+ u32 sysclk;
+ int ret;
+
+ /* SPI controller is either clocked from QE or SoC clock */
+ sysclk = get_brgfreq();
+ if (sysclk == -1) {
+ struct device_node *np;
+ const u32 *prop;
+
+ np = of_find_node_by_type(NULL, "soc");
+ if (!np)
+ return -ENODEV;
+
+ prop = of_get_property(np, "bus-frequency", NULL);
+ if (!prop) {
+ of_node_put(np);
+ return -ENODEV;
+ }
+
+ sysclk = *prop;
+ of_node_put(np);
+ }
+
+ ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
+ num_board_infos, activate_cs, deactivate_cs);
+ if (!ret)
+ of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
+ num_board_infos, activate_cs, deactivate_cs);
+
return spi_register_board_info(board_infos, num_board_infos);
}
--
1.5.2.2
^ permalink raw reply related
* [PATCH] [POWERPC] MPC8360E-RDK: Device tree and board file
From: Anton Vorontsov @ 2007-12-21 20:23 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
This is new board made by Freescale Semiconductor Inc. and
Logic Product Development.
Currently supported:
1. UEC1,2,7,4
2. I2C
3. SPI
4. NS16550 serial
5. PCI and miniPCI
6. Intel NOR StrataFlash X16 64Mbit PC28F640P30T85
Not supported so far:
1. StMICRO NAND512W3A2BN6E, 512 Mbit (supported with FSL UPM patches)
2. QE SCCs (slow UCCs, used as an UARTs)
3. ADC AD7843
4. FHCI USB
5. Graphics controller, Fujitsu MB86277
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/boot/dts/mpc836x_rdk.dts | 331 +++++++++++++++++++++++++++++
arch/powerpc/platforms/83xx/Kconfig | 11 +-
arch/powerpc/platforms/83xx/Makefile | 1 +
arch/powerpc/platforms/83xx/mpc836x_rdk.c | 118 ++++++++++
4 files changed, 460 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/boot/dts/mpc836x_rdk.dts
create mode 100644 arch/powerpc/platforms/83xx/mpc836x_rdk.c
diff --git a/arch/powerpc/boot/dts/mpc836x_rdk.dts b/arch/powerpc/boot/dts/mpc836x_rdk.dts
new file mode 100644
index 0000000..3f8d2b0
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc836x_rdk.dts
@@ -0,0 +1,331 @@
+/*
+ * MPC8360E RDK Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ * Copyright 2007 MontaVista Software, Inc.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "MPC8360ERDK", "MPC836xRDK", "MPC83xxRDK";
+ model = "MPC8360RDK";
+
+ aliases {
+ serial0 = &serial0;
+ serial1 = &serial1;
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8360@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <32768>;
+ i-cache-size = <32768>;
+ /* filled by u-boot */
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ };
+ };
+
+ soc8360@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ ranges = <0 0xe0000000 0x00100000>;
+ reg = <0xe0000000 0x00000200>;
+ /* filled by u-boot */
+ bus-frequency = <0>;
+
+ wdt@200 {
+ compatible = "mpc83xx_wdt";
+ reg = <0x200 0x100>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <16 8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+ };
+
+ serial0: serial@4500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ interrupts = <9 8>;
+ interrupt-parent = <&ipic>;
+ /* filled by u-boot */
+ clock-frequency = <0>;
+ };
+
+ serial1: serial@4600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ interrupts = <10 8>;
+ interrupt-parent = <&ipic>;
+ /* filled by u-boot */
+ clock-frequency = <0>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec2-crypto";
+ reg = <0x30000 0x10000>;
+ interrupts = <11 8>;
+ interrupt-parent = <&ipic>;
+ num-channels = <4>;
+ channel-fifo-len = <24>;
+ exec-units-mask = <0x0000007e>;
+ /*
+ * desc mask is for rev1.x, we need runtime fixup
+ * for >=2.x
+ */
+ descriptor-types-mask = <0x01010ebf>;
+ };
+
+ ipic: interrupt-controller@700 {
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "fsl,pq2pro-pic", "fsl,ipic";
+ interrupt-controller;
+ reg = <0x700 0x100>;
+ };
+
+ par_io@1400 {
+ compatible = "fsl,qe-pario";
+ reg = <0x1400 0x100>;
+ num-ports = <7>;
+ };
+ };
+
+ qe@e0100000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,qe";
+ ranges = <0 0xe0100000 0x00100000>;
+ reg = <0xe0100000 0x480>;
+ /* filled by u-boot */
+ brg-frequency = <0>;
+
+ muram@10000 {
+ compatible = "fsl,qe-muram", "fsl,cpm-muram";
+ ranges = <0 0x00010000 0x0000c000>;
+
+ data-only@0 {
+ compatible = "fsl,qe-muram-data",
+ "fsl,cpm-muram-data";
+ reg = <0 0xc000>;
+ };
+ };
+
+ spi@4c0 {
+ cell-index = <0>;
+ compatible = "fsl,spi";
+ reg = <0x4c0 0x40>;
+ interrupts = <2>;
+ interrupt-parent = <&qeic>;
+ mode = "cpu-qe";
+ };
+
+ spi@500 {
+ cell-index = <1>;
+ compatible = "fsl,spi";
+ reg = <0x500 0x40>;
+ interrupts = <1>;
+ interrupt-parent = <&qeic>;
+ mode = "cpu-qe";
+ };
+
+ usb@6c0 {
+ compatible = "qe_udc";
+ reg = <0x6c0 0x40 0x8b00 0x100>;
+ interrupts = <11>;
+ interrupt-parent = <&qeic>;
+ mode = "slave";
+ };
+
+ enet0: ucc@2000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ model = "UCC";
+ device-id = <1>;
+ reg = <0x2000 0x200>;
+ interrupts = <32>;
+ interrupt-parent = <&qeic>;
+ rx-clock = <0>;
+ tx-clock = <25>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+ /* filled by u-boot */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ enet1: ucc@3000 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ model = "UCC";
+ device-id = <2>;
+ reg = <0x3000 0x200>;
+ interrupts = <33>;
+ interrupt-parent = <&qeic>;
+ rx-clock = <0>;
+ tx-clock = <20>;
+ phy-handle = <&phy4>;
+ phy-connection-type = "rgmii-id";
+ /* filled by u-boot */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ enet2: ucc@2600 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ model = "UCC";
+ device-id = <7>;
+ reg = <0x2600 0x200>;
+ interrupts = <34>;
+ interrupt-parent = <&qeic>;
+ rx-clock = <36>;
+ tx-clock = <35>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "mii";
+ /* filled by u-boot */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ enet3: ucc@3200 {
+ device_type = "network";
+ compatible = "ucc_geth";
+ model = "UCC";
+ device-id = <4>;
+ reg = <0x3200 0x200>;
+ interrupts = <35>;
+ interrupt-parent = <&qeic>;
+ rx-clock = <24>;
+ tx-clock = <23>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "mii";
+ /* filled by u-boot */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+
+ mdio@2120 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2120 0x18>;
+ compatible = "fsl,ucc-mdio";
+
+ phy1: ethernet-phy@1 {
+ compatible = "national,DP83848VV";
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+
+ phy2: ethernet-phy@2 {
+ compatible = "broadcom,BCM5481UA2KMLG";
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+
+ phy3: ethernet-phy@3 {
+ compatible = "national,DP83848VV";
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+
+ phy4: ethernet-phy@4 {
+ compatible = "broadcom,BCM5481UA2KMLG";
+ reg = <4>;
+ device_type = "ethernet-phy";
+ };
+ };
+
+ qeic: interrupt-controller@80 {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ compatible = "fsl,qe-pic";
+ interrupt-controller;
+ reg = <0x80 0x80>;
+ big-endian;
+ interrupts = <32 8 33 8>;
+ interrupt-parent = <&ipic>;
+ };
+ };
+
+ localbus@e0005000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8360-localbus",
+ "fsl,pq2pro-localbus";
+ reg = <0xe0005000 0xd8>;
+ ranges = <0 0 0xff800000 0x800000>;
+
+ nor-flash@0,0 {
+ compatible = "intel,PC28F640P30T85", "cfi-flash";
+ reg = <0 0 0x800000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+ };
+
+ pci0: pci@e0008500 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci";
+ reg = <0xe0008500 0x100>;
+ ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000
+ 0x42000000 0 0x80000000 0x80000000 0 0x10000000
+ 0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>;
+ interrupts = <66 8>;
+ interrupt-parent = <&ipic>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = </* miniPCI0 IDSEL 0x14 AD20 */
+ 0xa000 0 0 1 &ipic 18 8
+ 0xa000 0 0 2 &ipic 19 8
+
+ /* PCI1 IDSEL 0x15 AD21 */
+ 0xa800 0 0 1 &ipic 19 8
+ 0xa800 0 0 2 &ipic 20 8
+ 0xa800 0 0 3 &ipic 21 8
+ 0xa800 0 0 4 &ipic 18 8>;
+ /* filled by u-boot */
+ bus-range = <0 0>;
+ clock-frequency = <0>;
+ };
+};
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 2430ac8..0d5a87c 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -55,6 +55,15 @@ config MPC837x_MDS
select DEFAULT_UIMAGE
help
This option enables support for the MPC837x MDS Processor Board.
+
+config MPC836x_RDK
+ bool "Freescale/Logic MPC836x RDK"
+ select DEFAULT_UIMAGE
+ select QUICC_ENGINE
+ help
+ This option enables support for the MPC836x RDK Processor Board,
+ also known as ZOOM PowerQUICC Kit.
+
endchoice
config PPC_MPC831x
@@ -79,7 +88,7 @@ config PPC_MPC836x
bool
select PPC_UDBG_16550
select PPC_INDIRECT_PCI
- default y if MPC836x_MDS
+ default y if MPC836x_MDS || MPC836x_RDK
config PPC_MPC837x
bool
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index df46629..bf1b799 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o
obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o
obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
+obj-$(CONFIG_MPC836x_RDK) += mpc836x_rdk.o
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
new file mode 100644
index 0000000..999cfa2
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
@@ -0,0 +1,118 @@
+/*
+ * MPC8360E-RDK board file.
+ *
+ * Copyright (c) 2006 Freescale Semicondutor, Inc.
+ * Copyright (c) 2007 MontaVista Software, Inc.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/ipic.h>
+#include <asm/udbg.h>
+#include <asm/io.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc83xx.h"
+
+static struct of_device_id mpc836x_rdk_ids[] = {
+ { .compatible = "soc", },
+ { .compatible = "fsl,qe", },
+ { .compatible = "fsl,pq2pro-localbus", },
+ {},
+};
+
+static int __init mpc836x_rdk_declare_of_platform_devices(void)
+{
+ if (!machine_is(mpc836x_rdk))
+ return 0;
+
+ of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL);
+
+ return 0;
+}
+device_initcall(mpc836x_rdk_declare_of_platform_devices);
+
+static void __init mpc836x_rdk_setup_arch(void)
+{
+ struct device_node *np;
+
+ if (ppc_md.progress)
+ ppc_md.progress("mpc836x_rdk_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+ for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
+ mpc83xx_add_bridge(np);
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+ qe_reset();
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,qe-pario");
+ if (np) {
+ par_io_init(np);
+ of_node_put(np);
+ } else {
+ pr_warning("QE PIO not initialized!\n");
+ }
+#endif
+}
+
+static void __init mpc836x_rdk_init_IRQ(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
+ if (!np)
+ return;
+
+ ipic_init(np, 0);
+
+ /*
+ * Initialize the default interrupt mapping priorities,
+ * in case the boot rom changed something on us.
+ */
+ ipic_set_default_priority();
+ of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+ np = of_find_compatible_node(NULL, NULL, "fsl,qe-pic");
+ if (!np)
+ return;
+
+ qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic);
+ of_node_put(np);
+#endif
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened.
+ */
+static int __init mpc836x_rdk_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "MPC836xRDK");
+}
+
+define_machine(mpc836x_rdk) {
+ .name = "MPC836x RDK",
+ .probe = mpc836x_rdk_probe,
+ .setup_arch = mpc836x_rdk_setup_arch,
+ .init_IRQ = mpc836x_rdk_init_IRQ,
+ .get_irq = ipic_get_irq,
+ .restart = mpc83xx_restart,
+ .time_init = mpc83xx_time_init,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
--
1.5.2.2
^ permalink raw reply related
* [PATCH 0/4] PowerPC: implement GPIO API
From: Anton Vorontsov @ 2007-12-21 20:28 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
Hi all,
OF device tree GPIOs bindings are similar to IRQs:
pario0: gpio-controller@0 {
#gpio-cells = <2>;
num-ports = <7>;
};
device@0 {
gpios = <bank pin bank pin bank pin>;
gpio-parent = <&pario0>;
};
"bank pin" scheme is controller specific, so controllers that want
to implement flat mappings or any other could do so.
So far I implemented GPIO API for QE and CPM2 chips. GPIO API for
CPM1 implemented by Jochen Friedrich <jochen@scram.de>, included in
this patchset.
- QE GPIO API tested to work with FSL UPM NAND driver and
MPC8360E-RDK (STMicro NAND512W3A2BN6E);
- CPM2 GPIO API tested to work with MPC8555E+Samsung HY27UF081G6 (LP);
- CPM1 GPIO API untested.
GPIO API is described in Documentation/gpio.txt, and these
patches are tend to support most of it.
As an additional bonus, PowerPC now gets access to few pleasing
drivers:
- drivers/leds/leds-gpio.c (we could use it to play with
on-board LEDs);
- drivers/i2c/busses/i2c-gpio.c (generic I2C bit-banging driver);
- drivers/input/keyboard/gpio_keys.c - gpio keys (requires
gpio_to_irq, so far not implemented);
- Could be more (I named the ones I knew about).
Also, in the upcoming kernels, there will be GPIOLIB[1] addition to
the generic GPIO API, to support off-chip GPIO expanders (like MFDs
on I2C/LBC). But so far we support on-chip GPIOs only, with single
controller built-in.
Changes since RFC:
- Implemented #gpio-cells handling;
- Per-bank spinlocks removed;
- Added a patch which implements GPIO API for CPM1;
- Few minor fixes.
Thanks,
[1] http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.24-rc4/2.6.24-rc4-mm1/broken-out/generic-gpio-gpio_chip-support.patch
--
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH -mm 18/43] powerpc compat_binfmt_elf
From: Sam Ravnborg @ 2007-12-21 20:00 UTC (permalink / raw)
To: Kyle McMartin
Cc: linux-arch, linux-kernel, Christoph Hellwig, linuxppc-dev,
Paul Mackerras, Andrew Morton, Linus Torvalds, Roland McGrath
In-Reply-To: <20071221175106.GB17656@fattire.cabal.ca>
On Fri, Dec 21, 2007 at 12:51:06PM -0500, Kyle McMartin wrote:
> On Fri, Dec 21, 2007 at 12:56:09AM -0800, Roland McGrath wrote:
> > > On Thu, Dec 20, 2007 at 03:58:16AM -0800, Roland McGrath wrote:
> > > > +obj-$(CONFIG_PPC64) += ../../../fs/compat_binfmt_elf.o
> > >
> > > Building files from another directory is nasty. Please add a
> > > CONFIG_BINFMT_COMPAT_ELF so we can simply build it in fs/
> >
> > If that's better, please post the precise Kconfig magic you have in mind to
> > have it set when it should be.
Kyle made a proposal but I like to get in to the party too...
> >
>
> Just taking a stab that hch means,
>
> config BINFMT_COMPAT_ELF
> def_bool n
> depends on 64BIT
>
> and then in arch/powerpc/Kconfig
>
> config COMPAT
> bool
> default y if PPC64
> select BINFMT_COMPAT_ELF
>
> or somesuch.
We recently discussed a common prefix for the selctable symbols
and consensus pointed out "HAVE_" so let us try to use it.
I did not quite understand the "depends on 64BIT" in Kyles example.
Does we really want to use compat_binfmt_elf for all archs that
define 64BIT? Anyway I added this in the example below.
fs/Makefile:
obj-$(COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
fs/Kconfig:
config COMPAT_BINFMT_ELF
depends on HAVE_COMPAT_BINFMT_ELF || 64BIT
# COMPAT_BINFMT_ELF must be selected when an
# architecture supoorts ...
config HAVE_COMPAT_BINFMT_ELF
arch/powerpc/Kconfig:
config COMPAT
bool
default PPC64
select HAVE_COMPAT_BINFMT_ELF
In the example above the extra indirection:
HAVE_COMPAT_BINFMT_ELF => COMPAT_BNFMT_ELF is not really needed
but tomorrow when we add another "depends on" to COMPAT_INFMT_ELF
it is needed to avoid the misbehaving select that just ignore the
dependencies and select the symbol anyway.
Sam
^ 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