LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH/RFC] Hookable IO operations
From: Segher Boessenkool @ 2006-11-04 22:33 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1162677911.28571.55.camel@localhost.localdomain>

>>> + * for the out_* accessors has the arguments in opposite order
>>> from the usual
>>> + * linux PCI accessors. Unlike those, they take the address first
>>> and the value
>>> + * next.
>>
>> Isn't that more confusing than useful?
>
> That's how they have been singe day 1. I'm not about to change that  
> and
> go fix every bit of ppc code that uses them. At least not with this
> patch.

Sure.  By just reading the patch I couldn't tell whether this was
new (or a new comment) or not, without cross-referencing stuff :-)

>> Drop the "inline" and you don't need any macro games anymore, and  
>> code
>> size drops, and it shouldn't be slower -- the I/O operation itself
>> dominates runtime (but testing is needed, of course).
>
> No, the low level accessors are staying inline and I don't see how  
> that
> would prevent macro games... Anyway that doesn't matter much at this
> point.

It would be nice if someone could measure the difference between
inlined and non-inlined though, both in code size and actual
performance.

> Note that I've posted a second version of the patch with simpler
> macros.

Your mails show up in my mailbox really late, I'll look at the
new version.

>> You can also drop the "volatile" -- it has no effect.
>
> Well, it's possible, but I've never quite understood when and when  
> not C
> compilers need/want volatile or not in the case of IO accessors :-)

"volatile" on a pointer only has effect at the point where that
pointer is dereferenced (at the C level, asm doesn't count).
"volatile" in a function prototype is meaningless; in a function
definition, it only does something _within_ that function, and
then only where the pointer is dereferenced.  It's preferable
for clarity to cast the pointer to the volatile version of its
type _right at the dereference itself_.

> It
> seems to be the rule accross linux that those functions take  
> volatile so
> I will continue following it.

... but then there's that, heh.  I don't feel up to a bad-use-of-
volatile-crusade right now, so I won't ask you to either :-)

>> "r"(addr) should probably be "b" (and you might want to lose the  
>> "m" --
>> it certainly won't have any bad effects if you decide to get rid  
>> of the
>> inline).
>
> In which case should "r" be "b" ? Those macros are directly equivalent
> to the previous code that was there and it didn't use "b". If you look
> closely, depending on the type of operations(lbz,lhz,lwz etc.. vs.
> lhbrz, lwbrx etc...), we use %1 or %2 for the address. In the former
> case, we get more efficient code by letting gcc generate the right  
> type
> of instruction (update form, indexed form, ... using %U and %X) by  
> using
> and "m" input. For the later, we use "r" and we use it for rB which  
> can
> safely be r0 afaik so we don't need "b".
>
>>> +#define DEF_MMIO_IN_BE(pfx, size, insn) \
>>> +	DEF_MMIO_IN(pfx##size, u##size, __stringify(insn)"%U2%X2 %0,%2")
>>> +#define DEF_MMIO_IN_LE(pfx, size, insn) \
>>> +	DEF_MMIO_IN(pfx##size, u##size, __stringify(insn)" %0,0,%1")
>>
>> ... "r" is okay actually, no "b" needed (would be needed if addr  
>> was the
>> first arg -- which is very much preferred on most CPUs for  
>> performance
>> reasons).
>
> Ah ? But how so ? I mean, there has to be a rB, there is no form of
> these instructions (the LE ones) with only one argument.

In load/store insns of the form

	op rD,rA,rB

the rA needs to be "b" (i.e., GPR0 is disallowed) and rB can be "r".

Some CPUs want rA to be a "real" address itself, probably because of
how they do the storage address translation.  I don't have details,
but see http://gcc.gnu.org/PR28690 .  I can speculate but let's do
that in private, not on this mailing list :-)

> Thus there is
> always a register specified as the second part of the address. So if I
> was using "b" with rA, I would have to spill another register for  
> rB and
> put 0 in it.

Quite true; just keep it as-is until you get complaints :-)

>>> +/* Enforce in-order execution of data I/O.
>>> + * No distinction between read/write on PPC; use eieio for all  
>>> three.
>>> + */
>>
>> It also prevents write gathering; if not, the _w version wouldn't
>> need eieio.
>
> That was there already, I haven't touched that comment. Maybe I
> should...

Yes exactly.

>>> +config PPC_INDIRECT_IO
>>
>> I find this name a little confusing, it sounds too much like the
>> "PCI indirect I/O".
>
> Any better idea ?

Not sure really...  PPC_HOOKED_IO?

>> Get rid of the caps in IoAddress too?
>
> As I said to Arnd, I will do that in a separate patch as I sanitize a
> bit the content of those functions.

Yeah I didn't see that reply yet.  Great to hear you'll do this
cleanup, thanks!

And now to review #2, or did you send #3 already :-)


Segher

^ permalink raw reply

* Re: [PATCH/RFC] Hookable IO operations #2
From: Segher Boessenkool @ 2006-11-04 22:50 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1162627290.28571.22.camel@localhost.localdomain>

Much nicer, great.  I said I'd comment though, so some
trivial nits :-)

> + * * __ioremap_explicit (and it's pending __iounmap_explicit) are  
> low level

s/it's/its/ .  Or "the", even.

> + * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap  
> implementation
> + * which needs some additional definitions here. They basically  
> allow PIO
> + * space overall to be 1Gb. This will work as long as we never try  
> to use
> + * iomap to map MMIO below 1Gb which should be fine on ppc64
> + */

1GB, not 1Gb.

> +#define HAVE_ARCH_PIO_SIZE	1
> +#define PIO_OFFSET		0x00000000UL
> +#define PIO_MASK		0x3fffffffUL
> +#define PIO_RESERVED		0x40000000UL


Segher

^ permalink raw reply

* Re: minor progress with plb_temac v3.00a, EDK 8.2, & 2.6.18.1
From: David H. Lynch Jr. @ 2006-11-04 23:20 UTC (permalink / raw)
  To: robert corley; +Cc: linux linuxppc-embedded
In-Reply-To: <20061104150210.7507.qmail@web56301.mail.re3.yahoo.com>

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

robert corley wrote:
> Pradeep;
>
> Booting with a ramdisk is a matter of putting the appropriate image in 
> the arch/ppc/boot/images directory (I obtained mine from the gsrd 
> design files), adding the root=/dev/ram rw on the command-line boot 
> options, making the .config changes for ram disk support and initrd 
> usage, and issuing a make zImage.initrd command.
>
> Beware when upgrading to 2.6.18.1 as you may have difficulties with 
> the adapter.c you obtained previously.  The adapter.c in EDK 8.2 is 
> not as easy to find.  Using the EDK to generate software components 
> for linux will not expose the proper adapter.c.  I had to use the path 
> that Rick Moleres posted earlier to retrieve the adapter.c which I 
> used for 2.6.18.1 and in my notes.
>
> -cy
>
    I am booting with a ramdisk using initramfs. Aside from its being 
somewhat harder to find documentation I beleive it is actually easier.
   
    In the simplest form, create a directory on your host that contains 
exactly what you want on the ramdisk.
    Enable CONFIG_INITRAMFS
    and point the CONFIG_INITRAMFS_SOURCE  to that directory.

    It is pretty much that simple. The linux build process creates a 
kernel - I use zImage.elf that has the ramdisk compressed and concatentated.
    Nothing except the Linux kernel itself has to make any accomidations 
for the ramdisk. The bootloader does not have to deal with another file, 
or pass pointers to it to Linux, ....
    It took some time to get it working - mostly because I did nto know 
what I was doing, but in hindsight it is really easy.



> ----- Original Message ----
> From: Pradeep Sampath <pradeepsampath@yahoo.com>
> To: robert corley <rdcorle@yahoo.com>
> Sent: Thursday, November 2, 2006 7:57:25 PM
> Subject: Re: minor progress with plb_temac v3.00a, EDK 8.2, & 2.6.18.1
>
> This is great! I played around for a while with the Sysace CF driver 
> patches and got it to work. Since you are booting with ramdisk image 
> would you be kind enough to add more text on how to do that? I see 
> that you are using UART Lite? Does it require any special setting for 
> the boot logs to show up on the standard hyperterminal.
>  
> I am planning on rebuilding the whole system using EDK 8.2 and linux 
> kernel 2.6.18.1.
>  
> -Pradeep
>
> */robert corley <rdcorle@yahoo.com>/* wrote:
>
>     For those interested, I have acheived some measure of success with
>     the plb_temac driver.
>
>     I have attached a txt file of what I had to do to get it working
>     under 2.6.18.1
>
>     I am using the plb_temac in DMA mode 3
>
>     Below you will see the boot dump.
>
>     For those able to help, can anyone provide insight as to the
>     failure of setting PHY link speed?
>
>     -cy
>
>
>
>     ====================
>     ----------------------------------------------------------------------
>     2.6.18.1 kernel with all patches
>     11/02/2006 15:30
>     plb_temac v3.00a
>     hard_temac v3.00b
>
>
>     loaded at: 00400000 009F1138
>     board data at: 009EF120 009EF138
>     relocated to: 004040B4 004040CC
>     zimage at: 00404EC7 0057C1F2
>     initrd at: 0057D000 009EE6FE
>     avail ram: 009F2000 04000000
>
>
>     Linux/PPC load: console=ttyUL0 single
>     ip=192.168.1.100:192.168.1.144:192.168.1.1:255.255.255.0:nab::
>     ramdisk_size=4660000 root=/dev/ram rw
>
>     Uncompressing Linux...done.
>
>     Now booting the kernel
>
>     [ 0.000000] Linux version 2.6.18.1 (rdcorle@athena) (gcc version
>     3.4.2) #2 Thu Nov 2 21:56:32 UTC 2006
>     [ 0.000000] Xilinx ML403 Reference System (Virtex-4 FX)
>     [ 0.000000] Built 1 zonelists. Total pages: 16384
>     [ 0.000000] Kernel command line: console=ttyUL0 single
>     ip=192.168.1.100:192.168.1.144:192.168.1.1:255.255.255.0:nab::
>     ramdisk_size=4660000 root=/dev/ram rw
>     [ 0.000000] Xilinx INTC #0 at 0xD1000FC0 mapped to 0xFDFFFFC0
>     [ 0.000000] PID hash table entries: 512 (order: 9, 2048 bytes)
>     [ 0.000158] Console: colour dummy device 80x25
>     [ 0.000568] Dentry cache hash table entries: 8192 (order: 3, 32768
>     bytes)
>     [ 0.001277] Inode-cache hash table entries: 4096 (order: 2, 16384
>     bytes)
>     [ 0.012895] Memory: 57060k available (2548k kernel code, 640k
>     data, 96k init, 0k highmem)
>     [ 0.104378] Mount-cache hash table entries: 512
>     [ 0.106721] checking if image is initramfs...it isn't (no cpio
>     magic); looks like an initrd
>     [ 2.414242] Freeing initrd memory: 4549k freed
>     [ 2.418712] NET: Registered protocol family 16
>     [ 2.427313] NET: Registered protocol family 2
>     [ 2.464244] IP route cache hash table entries: 512 (order: -1,
>     2048 bytes)
>     [ 2.465037] TCP established hash table entries: 2048 (order: 1,
>     8192 bytes)
>     [ 2.465205] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
>     [ 2.465296] TCP: Hash tables configured (established 2048 bind 1024)
>     [ 2.465324] TCP reno registered
>     [ 2.474633] NTFS driver 2.1.27 [Flags: R/O].
>     [ 2.475046] JFS: nTxBlock = 481, nTxLock = 3854
>     [ 2.477623] SGI XFS with no debug enabled
>     [ 2.479001] io scheduler noop registered
>     [ 2.479109] io scheduler anticipatory registered
>     [ 2.479197] io scheduler deadline registered
>     [ 2.479402] io scheduler cfq registered (default)
>     [ 2.517627] uartlite.0: ttyUL0 at MMIO 0xa0000000 (irq = 1) is a
>     uartlite
>     [ 2.691029] RAMDISK driver initialized: 16 RAM disks of 4660000K
>     size 1024 blocksize
>     [ 2.703933] loop: loaded (max 8 devices)
>     [ 2.709698] XTemac: using sgDMA mode.
>     [ 2.713493] XTemac: using TxDRE mode
>     [ 2.717081] XTemac: using RxDRE mode
>     [ 2.720678] XTemac: buffer descriptor size: 32768 (0x8000)
>     [ 2.726622] XTemac: (buffer_descriptor_init) phy: 0x580000, virt:
>     0xff100000, size: 0x8000
>     [ 2.741073] eth0: Xilinx TEMAC #0 at 0x60000000 mapped to
>     0xC5050000, irq=0
>     [ 2.748080] eth0: XTemac id 1.0f, block id 5, type 8
>     [ 2.753636] mice: PS/2 mouse device common for all mice
>     [ 2.759529] TCP bic registered
>     [ 3.264317] eth0: XTemac: Options: 0xb8f2
>     [ 15.227339] eth0: XTemac: Not able to set the speed to 1000
>     (status: 0x148)
>     [ 25.200394] eth0: XTemac: Not able to set the speed to 100
>     (status: 0x148)
>     [ 35.173357] eth0: XTemac: Not able to set the speed to 10
>     (status: 0x148)
>     [ 35.180122] eth0: XTemac: could not negotiate speed
>     [ 35.187740] eth0: XTemac: Send Threshold = 16, Receive Threshold = 2
>     [ 35.194116] eth0: XTemac: Send Wait bound = 1, Receive Wait bound = 1
>     [ 36.205399] IP-Config: Complete:
>     [ 36.208459] device=eth0, addr=192.168.1.100, mask=255.255.255.0,
>     gw=192.168.1.1,
>     [ 36.216339] host=nab, domain=, nis-domain=(none),
>     [ 36.221487] bootserver=192.168.1.144, rootserver=192.168.1.144,
>     rootpath=
>     [ 36.229826] RAMDISK: Compressed image found at block 0
>     [ 37.200498] eth0: XTemac: PHY Link carrier lost.
>     [ 39.097820] VFS: Mounted root (ext2 filesystem).
>     [ 39.102751] Freeing unused kernel memory: 96k init
>     [ 39.108356] ulite_startup: UART status = 0x0014
>     [ 39.124619] ulite_startup: UART status = 0x0014
>     [ 39.134313] ulite_startup: UART status = 0x0014
>
>
>     BusyBox v1.00-pre9 (2004.04.18-19:53+0000) Built-in shell (ash)
>     Enter 'help' for a list of built-in commands.
>
>     -sh: can't access tty; job control turned off
>
>
>     steps for plb_temac drivers under EDK 8.2.02i (w/SP2.4+0)
>     Using plb_temac v3.00a & hard_temac v3.00b
>
>     Generate s/w libraries
>
>     1. copy or ftp the following files from
>     C:\EDK\sw\ThirdParty\bsp\linux_2_6_v1_00_a\linux\
>     to the base directory of the linux source tree
>
>     USED:
>     arch\ppc\platforms\4xx\xparameters\xparameters.h
>
>     ** UNUSED
>     arch\ppc\platforms\4xx\virtex.c
>     arch\ppc\boot\simple\embed_config.c
>     include\linux\xilinx_devices.h
>
>     2. copy
>     C:\EDK\sw\ThirdParty\bsp\linux_2_6_v1_00_a\drivers\temac_linux_2_6_v2_00_b\src\adapter.c
>     to
>     ../drivers/net/xilinx_temac/adapter.c
>
>     3. copy or ftp ..\linux\arch\ppc\platforms\xilinx_ocp =>
>     drivers/xilinx_edk
>     Note: Remove all old files first *except* Kconfig, xio.h
>
>     4. modify drivers/xilinx_edk/Makefile with the following to look
>     like this:
>
>     # Linux file to EXPORT_SYMBOL all of the Xilinx entries.
>     obj-$(CONFIG_XILINX_EDK) += xilinx_syms.o
>     #
>     # # The Xilinx OS independent code.
>     xilinx_syms-objs := xbasic_types.o \
>     xdmav3.o xdmav3_intr.o xdmav3_selftest.o xdmav3_simple.o xdmav3_sg.o \
>     xipif_v1_23_b.o \
>     xpacket_fifo_l_v2_00_a.o xpacket_fifo_v2_00_a.o \
>     xversion.o
>
>     5. Modify your copied xparameters_ml403.h (see notes below) as
>     follows:
>     add these lines after #define XPAR_PLB_TEMAC_0_INCLUDE_RX_CSUM
>
>     #define XPAR_TEMAC_0_IPIF_RDFIFO_DEPTH XPAR_PLB_TEMAC_0_RXFIFO_DEPTH
>     #define XPAR_TEMAC_0_IPIF_WRFIFO_DEPTH XPAR_PLB_TEMAC_0_TXFIFO_DEPTH
>     #define XPAR_TEMAC_0_MAC_FIFO_DEPTH XPAR_PLB_TEMAC_0_MAC_FIFO_DEPTH
>     #define XPAR_TEMAC_0_TEMAC_DCR_HOST 0
>     #define XPAR_TEMAC_0_INCLUDE_DRE 1
>
>
>     6. (optional) modify arch/ppc/platforms/virtex.h to accomodate
>     RX_CSUM XPAR
>
>     struct xtemac_platform_data {
>     #ifdef XPAR_TEMAC_0_INCLUDE_RX_CSUM
>     u8 tx_dre;
>     u8 rx_dre;
>     u8 tx_csum;
>     u8 rx_csum;
>     u8 phy_type;
>     #endif
>     u8 dma_mode;
>     u32 rx_pkt_fifo_depth;
>     u32 tx_pkt_fifo_depth;
>     u16 mac_fifo_depth;
>     u8 dcr_host;
>     u8 dre;
>     u8 mac_addr[6];
>     };
>
>     7. Modify ../drivers/net/xilinx_temac/adapter.c to remove #include and
>     add #include
>     add #include
>
>     ____________________________________________________________________________________
>     NOTES:
>     1. Don't forget to copy EDK-generated xparameters.h to
>     ../arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h
>
>
>
>     =====================================================
>     Files in latest patch:
>     ../drivers/net/xilinx_temac =
>     Makefile
>     adapter.c
>     xtemac.c
>     xtemac_control.c
>     xtemac_fifo.c
>     xtemac_intr.c
>     xtemac_intr_fifo.c
>     xtemac_intr_sgdma.c
>     xtemac_l.c
>     xtemac_sgdma.c
>     xtemac.h
>     xtemac_i.h
>     xtemac_l.h
>
>     Files in ..\linux\drivers\net\xilinx_temac => (** = new files)
>
>     Makefile
>     adapter.c
>     xtemac.c
>     xtemac_control.c
>     xtemac_fifo.c
>     xtemac_g.c**
>     xtemac_intr.c
>     xtemac_intr_fifo.c
>     xtemac_intr_sgdma.c
>     xtemac_l.c
>     xtemac_selftest.c**
>     xtemac_sgdma.c
>     xtemac_sinit.c**
>     xtemac_stats.c**
>     xtemac.h
>     xtemac_i.h
>     xtemac_l.h
>
>     ============================================================
>     Files in ../drivers/xilinx_edk =>
>
>     Kconfig
>     Makefile
>     xbasic_types.c
>     xdmav2.c
>     xdmav2_intr.c
>     xdmav2_sg.c
>     xdmav2_simple.c
>     xilinx_syms.c
>     xpacket_fifo_l_v2_00_a.c
>     xpacket_fifo_v2_00_a.c
>     xbasic_types.h
>     xdmabdv2.h
>     xdmav2.h
>     xdmav2_l.h
>     xio.h
>     xpacket_fifo_l_v2_00_a.h
>     xpacket_fifo_v2_00_a.h
>     xstatus.h
>
>     Files in ..\linux\arch\ppc\platforms\xilinx_ocp=>
>     Makefile
>     xbasic_types.c
>     xutil_memtest.c
>     xpacket_fifo_v2_00_a.c
>     xdmav3.c
>     xpacket_fifo_l_v2_00_a.c
>     xdmav3_intr.c
>     xipif_v1_23_b.c
>     xdmav3_selftest.c
>     xdmav3_sg.c
>     xdmav3_simple.c
>     xversion.c
>     xenv.h
>     xenv_none.h
>     xenv_vxworks.h
>     xdmav3_l.h
>     xipif_v1_23_b.h
>     xdmav3.h
>     xpacket_fifo_l_v2_00_a.h
>     xdmabdv3.h
>     xpacket_fifo_v2_00_a.h
>     xparameters_ml300.h
>     xstatus.h
>     xutil.h
>     xbasic_types.h
>     xenv_linux.h
>     xversion.h
>     _______________________________________________
>     Linuxppc-embedded mailing list
>     Linuxppc-embedded@ozlabs.org
>     https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded


-- 
Dave Lynch 					  	    DLA Systems
Software Development:  				         Embedded Linux
717.627.3770 	       dhlii@dlasys.net 	  http://www.dlasys.net
fax: 1.253.369.9244 			           Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.

"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein


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

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Benjamin Herrenschmidt @ 2006-11-04 23:35 UTC (permalink / raw)
  To: Nicolas DET; +Cc: linuxppc-dev, Sylvain Munaut, sl, linuxppc-embedded
In-Reply-To: <454A5952.6090801@bplan-gmbh.de>

On Thu, 2006-11-02 at 21:47 +0100, Nicolas DET wrote:

> + *
> + * Programmable Interrupt Controller functions for the Freescale MPC52xx.
> + *
> + * Based on (well, mostly copied from) the code from the 2.4 kernel by
> + * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
> + * 
> + * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
> + * Copyright (C) 2003 Montavista Software, Inc

You did significant changes, you should add your (c) before the "Based
on..." line.

> +	switch (l1irq) {
> +	case MPC52xx_IRQ_L1_CRIT:
> +		pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
> +
> +		BUG_ON(l2irq != 0);
> +
> +		type = mpc52xx_irqx_gettype(l2irq);
> +		good_irqchip = &mpc52xx_extirq_irqchip;
> +		break;
> +
> +	case MPC52xx_IRQ_L1_MAIN:
> +		pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
> +
> +		if ((l2irq >= 1) && (l2irq <= 3)) {
> +			type = mpc52xx_irqx_gettype(l2irq);
> +			good_irqchip = &mpc52xx_extirq_irqchip;
> +		} else {
> +			good_irqchip = &mpc52xx_main_irqchip;
> +		}
> +		break;

You have changed the mapping of L1/L2 but not the device-tree
representation to match them. Which means that you need the ugly hack
above. That is not goot. Fix your device-tree instead and do the same
split in the tree for L1/L2 than you do in the code.

In fact, I'm wondering if it might not be worth going back to 2 cells
and have cell 0 just contain the HW number now that we have sanitized
those... In any way, the above special casing should go.

> +	picnode = find_mpc52xx_picnode();
> +	sdmanode = find_mpc52xx_sdmanode();

Any reason why you have those inline 1-line functions and just not put
the actual of_find_* call in here ?

You probably also need some of_node_put() in the error case. You are
doing a whole bunch of "return" that bypass them.

The rest looks ok.

Please submit the io.h patch separately. Also, you may need to fix the
default case (which is the one we are using) in there to work with
CONFIG_PCI not set (by defining PCI_DRAM_BASE to 0 among others).

> --- a/include/asm-ppc/io.h	2006-11-01 09:19:02.000000000 +0100
> +++ b/include/asm-ppc/io.h	2006-11-02 18:01:17.000000000 +0100
> @@ -26,7 +26,7 @@
>  
>  #if defined(CONFIG_4xx)
>  #include <asm/ibm4xx.h>
> -#elif defined(CONFIG_PPC_MPC52xx)
> +#elif defined(CONFIG_PPC_MPC52xx) && !defined(CONFIG_PPC_MERGE)
>  #include <asm/mpc52xx.h>
>  #elif defined(CONFIG_8xx)
>  #include <asm/mpc8xx.h>

Ben.

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: Add of_platform support for OHCI/Bigendian HC
From: Benjamin Herrenschmidt @ 2006-11-04 23:37 UTC (permalink / raw)
  To: Nicolas DET; +Cc: linuxppc-dev, sl, linuxppc-embedded
In-Reply-To: <454A59CC.6070902@bplan-gmbh.de>

On Thu, 2006-11-02 at 21:49 +0100, Nicolas DET wrote:

> fsoc-ppc. As I am not sure what it does exactly I 
> left it like this. This module performs well here so far.

Well, it cause the kernel to keep other interrupts disabled on that CPU
while you are handling yours. Should not be necessary and might cause
undue latencies. 

Regarding the rest of the patch, I don't understand why you are creating
duplicate match lists and probe/remove functions.

Just do a single of_platform_driver() that matches both and have it's
probe() function check the properties (device_is_compatible() would do
the trick, though a common thing in OF is to just have an empty property
"big-endian" in the node).

Ben.

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: Add Efika platform support
From: Benjamin Herrenschmidt @ 2006-11-04 23:45 UTC (permalink / raw)
  To: Nicolas DET; +Cc: linuxppc-dev, sl, linuxppc-embedded
In-Reply-To: <454A5A61.6080800@bplan-gmbh.de>

On Thu, 2006-11-02 at 21:52 +0100, Nicolas DET wrote:

> Well. there was other init done here before. However, I think it's good 
> to have this here, in case more code would be needed or in the 
> ppc_md.init_IRQ is changed. no ?

No. Hook it directly. Don't solve problems you don't have. If you ever
need to do other inits there, you can change it back.

> Well. It it doesn't hurt it can stay here. People are a little bit weird 
> today. Maybe they would try to solder a PCI southbridige to get a nice 
> PC speaker beep ;-)

Yeah, doesn't hurt.

On a general note about your patches: Don't reply and post a new patch
in the same email. Reply, then separately, post patches using the proper
format for patch submission. That is, a changelog comment, a
Signed-off-by: line followed by the patch.

If you want to have off-the-record comments, add "---" after the
Signed-off-by: line and insert your comments between that and the patch
itself, they will be stripped when commiting to git.

Ben.

> * Efika 5K2 platform setup
> + * Some code really inspired from the lite5200b platform.

No (c) ?

> + * 
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + *
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/sched.h>
> +#include <linux/kernel.h>
> +#include <linux/ptrace.h>
> +#include <linux/slab.h>
> +#include <linux/user.h>
> +#include <linux/interrupt.h>
> +#include <linux/reboot.h>
> +#include <linux/init.h>
> +#include <linux/utsrelease.h>
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +#include <linux/console.h>
> +#include <linux/seq_file.h>
> +#include <linux/root_dev.h>
> +#include <linux/initrd.h>
> +#include <linux/module.h>
> +#include <linux/timer.h>
> +
> +#include <asm/pgtable.h>
> +#include <asm/prom.h>
> +#include <asm/dma.h>
> +#include <asm/machdep.h>
> +#include <asm/irq.h>
> +#include <asm/sections.h>
> +#include <asm/time.h>
> +#include <asm/rtas.h>
> +#include <asm/of_device.h>
> +#include <asm/mpc52xx.h>
> +
> +#include "efika.h"

You probably don't need half of those includes :)

> +static void efika_show_cpuinfo(struct seq_file *m)
> +{
> +	struct device_node *root;
> +	const char *revision = NULL;
> +	const char *codegendescription = NULL;
> +	const char *codegenvendor = NULL;
> +
> +	root = of_find_node_by_path("/");
> +	if (root) {
> +		revision = get_property(root, "revision", NULL);
> +		codegendescription =
> +		    get_property(root, "CODEGEN,description", NULL);
> +		codegenvendor = get_property(root, "CODEGEN,vendor", NULL);
> +	}
> +
> +	of_node_put(root);

Move the above to after you are done with the results of get_property().

> +	if (codegendescription)
> +		seq_printf(m, "machine\t\t: %s\n", codegendescription);
> +	else
> +		seq_printf(m, "machine\t\t: Efika\n");
> +
> +	if (revision)
> +		seq_printf(m, "revision\t: %s\n", revision);
> +
> +	if (codegenvendor)
> +		seq_printf(m, "vendor\t\t: %s\n", codegenvendor);
> +}

> +static void __init efika_init_IRQ(void)
> +{
> +	mpc52xx_init_irq();
> +}

Just hook mpc52xx_init_irq() directly

> +static void __init efika_init(void)
> +{
> +	struct device_node *np;
> +	struct device_node *cnp = NULL;
> +	const u32 *base;
> +	char *name;
> +
> +	/* Find every child of the SOC node and add it to of_platform */
> +	np = of_find_node_by_name(NULL, "builtin");
> +	if (np) {
> +		while ((cnp = of_get_next_child(np, cnp))) {
> +			name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
> +			if (name == NULL)
> +				continue;

Why kmalloc ?

> +			strcpy(name, cnp->name);
> +
> +			base = get_property(cnp, "reg", NULL);
> +			if (base == NULL) {
> +				kfree(name);
> +				continue;
> +			}
> +
> +			sprintf(name+strlen(name), "@%x", *base);
> +			of_platform_device_create(cnp, name, NULL);

Just use a stack based buffer. Either that, or kfree(name) when you are
done. of_platform_device_create() will make a copy of the sting.

Rest looks good.

Ben.

^ permalink raw reply

* [PATCH] ppc/powerpc: Fix io.h for config with CONFIG_PCI not set
From: Sylvain Munaut @ 2006-11-05  0:17 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Sylvain Munaut, ML PPC Embedded, Sven

When CONFIG_PCI option is not set, the variables
pci_dram_offset, isa_io_base and isa_mem_base are not defined.

Currently, the test is handled in each platform header. This
patch moves the test in io.h once and for all.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
 include/asm-powerpc/mpc85xx.h |    8 --------
 include/asm-ppc/io.h          |    8 +-------
 include/asm-ppc/mpc52xx.h     |   11 -----------
 include/asm-ppc/mpc83xx.h     |    8 --------
 include/asm-ppc/mpc85xx.h     |    8 --------
 5 files changed, 1 insertions(+), 42 deletions(-)

diff --git a/include/asm-powerpc/mpc85xx.h b/include/asm-powerpc/mpc85xx.h
index ccdb8a2..5414299 100644
--- a/include/asm-powerpc/mpc85xx.h
+++ b/include/asm-powerpc/mpc85xx.h
@@ -31,14 +31,6 @@ #ifdef CONFIG_MPC85xx_CDS
 #include <platforms/85xx/mpc85xx_cds.h>
 #endif
 
-#define _IO_BASE        isa_io_base
-#define _ISA_MEM_BASE   isa_mem_base
-#ifdef CONFIG_PCI
-#define PCI_DRAM_OFFSET pci_dram_offset
-#else
-#define PCI_DRAM_OFFSET 0
-#endif
-
 /* Let modules/drivers get at CCSRBAR */
 extern phys_addr_t get_ccsrbar(void);
 
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index a4c411b..b744baf 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -26,17 +26,11 @@ #define PREP_PCI_DRAM_OFFSET 	0x80000000
 
 #if defined(CONFIG_4xx)
 #include <asm/ibm4xx.h>
-#elif defined(CONFIG_PPC_MPC52xx)
-#include <asm/mpc52xx.h>
 #elif defined(CONFIG_8xx)
 #include <asm/mpc8xx.h>
 #elif defined(CONFIG_8260)
 #include <asm/mpc8260.h>
-#elif defined(CONFIG_83xx)
-#include <asm/mpc83xx.h>
-#elif defined(CONFIG_85xx)
-#include <asm/mpc85xx.h>
-#elif defined(CONFIG_APUS)
+#elif defined(CONFIG_APUS) || !defined(CONFIG_PCI)
 #define _IO_BASE	0
 #define _ISA_MEM_BASE	0
 #define PCI_DRAM_OFFSET 0
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index 64c8874..d9d21aa 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -29,17 +29,6 @@ struct pt_regs;
 #endif /* __ASSEMBLY__ */
 
 
-#ifdef CONFIG_PCI
-#define _IO_BASE	isa_io_base
-#define _ISA_MEM_BASE	isa_mem_base
-#define PCI_DRAM_OFFSET	pci_dram_offset
-#else
-#define _IO_BASE	0
-#define _ISA_MEM_BASE	0
-#define PCI_DRAM_OFFSET	0
-#endif
-
-
 /* ======================================================================== */
 /* PPC Sys devices definition                                               */
 /* ======================================================================== */
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 02ed2c3..c306197 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -25,14 +25,6 @@ #ifdef CONFIG_MPC834x_SYS
 #include <platforms/83xx/mpc834x_sys.h>
 #endif
 
-#define _IO_BASE        isa_io_base
-#define _ISA_MEM_BASE   isa_mem_base
-#ifdef CONFIG_PCI
-#define PCI_DRAM_OFFSET pci_dram_offset
-#else
-#define PCI_DRAM_OFFSET 0
-#endif
-
 /*
  * The "residual" board information structure the boot loader passes
  * into the kernel.
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 9b48511..d7e4a79 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -44,14 +44,6 @@ #if defined(CONFIG_TQM8540) || defined(C
 #include <platforms/85xx/tqm85xx.h>
 #endif
 
-#define _IO_BASE        isa_io_base
-#define _ISA_MEM_BASE   isa_mem_base
-#ifdef CONFIG_PCI
-#define PCI_DRAM_OFFSET pci_dram_offset
-#else
-#define PCI_DRAM_OFFSET 0
-#endif
-
 /*
  * The "residual" board information structure the boot loader passes
  * into the kernel.
-- 
1.4.2

^ permalink raw reply related

* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Sylvain Munaut @ 2006-11-05  0:27 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linuxppc-embedded, sl
In-Reply-To: <1162683341.28571.82.camel@localhost.localdomain>


>> +	picnode = find_mpc52xx_picnode();
>> +	sdmanode = find_mpc52xx_sdmanode();
>>     
>
> Any reason why you have those inline 1-line functions and just not put
> the actual of_find_* call in here ?
>   
I think it might be worth creating a
arch/powerpc/sysdev/mpc52xx_common.c (we'll probably need it later on
anyway)
with a helper that would do
 - The find_node
 - get_address / translate /  get_size
 - ioremap

Something like :

intr = mpc52xx_find_and_map("mpc52xx-intr");
sdma = mpc52xx_find_and_map("mpc52xx-sdma");

would be more elegant. Especially since finding and mapping things like
intr/sdma/xlb/cdm ... will be done at several place. That would prevent
repeating all that code for nothing.




Also, in the Makefile, I would make the compilation conditionnal to
CONFIG_PPC_MPC52xx and not CONFIG_PPC_MPC52xx_PIC ...
If you're on a 52xx, you most likely want the interrupt controller ...

But the CONFIG_PPC_MPC52xx option should be in arch/powerpc/Kconfig
and not in the platform/embedded6xx/Kconfig


        Sylvain

^ permalink raw reply

* Re: [PATCH] ppc/powerpc: Fix io.h for config with CONFIG_PCI not set
From: Benjamin Herrenschmidt @ 2006-11-05  1:12 UTC (permalink / raw)
  To: Sylvain Munaut; +Cc: ML PPC Embedded, Sven
In-Reply-To: <11626858382465-git-send-email-tnt@246tNt.com>

On Sun, 2006-11-05 at 01:17 +0100, Sylvain Munaut wrote:
> When CONFIG_PCI option is not set, the variables
> pci_dram_offset, isa_io_base and isa_mem_base are not defined.
> 
> Currently, the test is handled in each platform header. This
> patch moves the test in io.h once and for all.

Be careful with _IO_BASE... I'm not 100% sure some platforms don't need
it set to something else even when PCI is not present.

Ben.

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Benjamin Herrenschmidt @ 2006-11-05  1:13 UTC (permalink / raw)
  To: Sylvain Munaut; +Cc: linuxppc-dev, linuxppc-embedded, sl
In-Reply-To: <454D2FEC.3050605@246tNt.com>

On Sun, 2006-11-05 at 01:27 +0100, Sylvain Munaut wrote:
> >> +	picnode = find_mpc52xx_picnode();
> >> +	sdmanode = find_mpc52xx_sdmanode();
> >>     
> >
> > Any reason why you have those inline 1-line functions and just not put
> > the actual of_find_* call in here ?
> >   
> I think it might be worth creating a
> arch/powerpc/sysdev/mpc52xx_common.c (we'll probably need it later on
> anyway)
> with a helper that would do

> - The find_node

I don't see why we need a helper for that at all in the first place :)

>  - get_address / translate /  get_size

That too

>  - ioremap
> 
> Something like :
> 
> intr = mpc52xx_find_and_map("mpc52xx-intr");
> sdma = mpc52xx_find_and_map("mpc52xx-sdma");

Hrm... I don't care that much but I also don't think we need that
helper. It's not saving much.

> would be more elegant. Especially since finding and mapping things like
> intr/sdma/xlb/cdm ... will be done at several place. That would prevent
> repeating all that code for nothing.

It's not much code to repeat ;) but if you want, I have no big problem
with that.

> Also, in the Makefile, I would make the compilation conditionnal to
> CONFIG_PPC_MPC52xx and not CONFIG_PPC_MPC52xx_PIC ...
> If you're on a 52xx, you most likely want the interrupt controller ...
> 
> But the CONFIG_PPC_MPC52xx option should be in arch/powerpc/Kconfig
> and not in the platform/embedded6xx/Kconfig

Ben.

^ permalink raw reply

* Re: [PATCH] Add MPC52xx PIO/ATA support for arch/powerpc
From: Benjamin Herrenschmidt @ 2006-11-05  1:27 UTC (permalink / raw)
  To: Nicolas DET; +Cc: akpm, linuxppc-dev list, sl, linuxppc-embedded
In-Reply-To: <200611041504.kA4F4Ll1029368@post.webmailer.de>

On Sat, 2006-11-04 at 16:04 +0100, Nicolas DET wrote:
> This patch add MPC52xx ATA/PIO support.
> 
> It's based on a previous patch:
> http://patchwork.ozlabs.org/linuxppc/patch?id=4364
> 
> But, it now use of_platform and a of_device_id to match the appropriate device.
> 
> Signed-off-by: Nicolas DET <nd@bplqn-gmbh.de>

Very quick look, seems good to me. (Well, the fact that I wrote the
original version of it might help ! hehehe...)

Could you post it to linux-ide though in case somebody else spots
something wrong ?

I think it can go in 2.6.20 along with the rest of your platform support
(once the later is finally ready to go, hopefully soon).

Ben.

^ permalink raw reply

* Re: Has anyone 2.6 kernel with Xenomai and MPC5200 Lite running?
From: Wolfgang Denk @ 2006-11-05  1:32 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20061104163119.GC69112@server.idefix.loc>

In message <20061104163119.GC69112@server.idefix.loc> you wrote:
> 
> I have here a MPC5200 Lite (IceCube/Freescale Lite 5200) and tried to
> get Xenomai running.
> 
> If I use the 2.6 kernel from denx the board boots fine but I am not

Note that we explicitely do NOT support the MPC5200 in this tree yet.

> able to patch the kernel with the adeos patch (adeos-patch is for
> kernel 2.6.18) and the kernel from denx is 2.6.19rc4. I checked the
> changes and they are to much for me to adapt it.

Then just check out the 2.6.18 version of the tree.  This  is  a  git
repo, so seeking to any version you like is a matter of seconds.

> What I need now is a patch for kernel 2.6.18 to get all the MPC5200
> stuff running (priority has the networkchip) or a adeos patch for the
> denx kernel 2.6.19-rc4.

You do not want this, if you're on a MPC5200. I repeat, this  is  not
supported.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
If I had to live my life again,  I'd  make  the  same  mistakes, only
sooner.                                          -- Tallulah Bankhead

^ permalink raw reply

* Re: [PATCH] ppc/powerpc: Fix io.h for config with CONFIG_PCI not set
From: Sylvain Munaut @ 2006-11-05  1:45 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: ML PPC Embedded, Sven
In-Reply-To: <1162689134.28571.120.camel@localhost.localdomain>

Benjamin Herrenschmidt wrote:
> On Sun, 2006-11-05 at 01:17 +0100, Sylvain Munaut wrote:
>   
>> When CONFIG_PCI option is not set, the variables
>> pci_dram_offset, isa_io_base and isa_mem_base are not defined.
>>
>> Currently, the test is handled in each platform header. This
>> patch moves the test in io.h once and for all.
>>     
>
> Be careful with _IO_BASE... I'm not 100% sure some platforms don't need
> it set to something else even when PCI is not present.
>   
When I saw in  mpc83xx.h and  mpc85xx.h that they still defined them, I
wondered.
But when looking at the code :
    unsigned long isa_io_base     = 0;
    unsigned long isa_mem_base    = 0;
are both defined in pci_{32/64}.c and won't be included if CONFIG_PCI is
not set.


    Sylvain

^ permalink raw reply

* Re: Has anyone 2.6 kernel with Xenomai and MPC5200 Lite running?
From: Grant Likely @ 2006-11-05  2:32 UTC (permalink / raw)
  To: linuxppc-embedded, Matthias Fechner
In-Reply-To: <20061104163119.GC69112@server.idefix.loc>

On 11/4/06, Matthias Fechner <idefix@fechner.net> wrote:
> Hi,
>
> I have here a MPC5200 Lite (IceCube/Freescale Lite 5200) and tried to
> get Xenomai running.
>
> If I use the 2.6 kernel from denx the board boots fine but I am not
> able to patch the kernel with the adeos patch (adeos-patch is for
> kernel 2.6.18) and the kernel from denx is 2.6.19rc4. I checked the
> changes and they are to much for me to adapt it.
>
> What I need now is a patch for kernel 2.6.18 to get all the MPC5200
> stuff running (priority has the networkchip) or a adeos patch for the
> denx kernel 2.6.19-rc4.
>
> Can anyone help me here, please?

Yup, there exists patches for all the functionality that you're
looking for.  You can find them if you search the list, but I'll send
you a link to a git tree with all those patches in it later tonight.

Cheers
g.


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

^ permalink raw reply

* hi, guy's Need help to jtag a PPC405D4
From: jhon scoot @ 2006-11-05  3:46 UTC (permalink / raw)
  To: linuxppc-embedded

hi,,

guy,,

I am trying to read my PPC405D4,, the problem is , my serial cable DB9 to 
RJ12 is missing , and I need
to configure my Riscwatch Probe setting up the IP/TCP ,, does some one have 
, a Riscwatch probe, and and check the serial cable how is configurated, for 
I can buil'it here.

Example: This is a example...
RJ12 to DB9 (DCE Male) converter:

		DCD	1  <--------  1	DCD
		RXD	2  <--------  2	RXD
	      DTR/RTS	3  -------->  4	DTR
          |_>  7	RTS
RJ12		GND	4  ----------  5	GND	DB9
		TXD	5  -------->  3	TXD
		CTS	6  <--------  8	CTS


thnkas

_________________________________________________________________
Get today's hot entertainment gossip  
http://movies.msn.com/movies/hotgossip?icid=T002MSN03A07001

^ permalink raw reply

* Re: [patch 01/16] remove inclusion of asm/processor.h for powerpc
From: Benjamin Herrenschmidt @ 2006-11-05  6:46 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linuxppc-dev
In-Reply-To: <20061103084237.GA22478@localhost.localdomain>

On Fri, 2006-11-03 at 09:42 +0100, Sascha Hauer wrote:
> On Fri, Nov 03, 2006 at 09:20:20AM +1100, Benjamin Herrenschmidt wrote:
> > On Thu, 2006-11-02 at 13:55 +0100, s.hauer@pengutronix.de wrote:
> > > plain text document attachment
> > > (drivers-ide-pci-via82xxx-remove-ppc-ifdef.diff)
> > > Remove inclusion of asm/processor.h for powerpc. It was used for
> > > some ppc specific hook in this file, but the hook is gone
> > 
> > It's not:
> > 
> > init_hwif_via82cxxx() contains:
> > 
> > #if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
> >         if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
> >                 hwif->irq = hwif->channel ? 15 : 14;
> >         }
> > #endif
> > 
> > Now you can replace CONFIG_PPC_MULTIPLATFORM with CONFIG_PPC_CHRP
> > 
> 
> Oops, missed that one. Here is an updated version:
> 
> Remove inclusion of asm/processor.h for powerpc. It was used for
> some ppc specific hook in this file, but the hook is gone
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

You should update the changelog comment :)

Ben.

^ permalink raw reply

* Re: [patch 04/16] powerpc: remove dead code in iommu.h
From: Benjamin Herrenschmidt @ 2006-11-05  6:47 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linuxppc-dev
In-Reply-To: <20061103084730.GB22478@localhost.localdomain>

On Fri, 2006-11-03 at 09:47 +0100, Sascha Hauer wrote:
> On Fri, Nov 03, 2006 at 09:21:53AM +1100, Benjamin Herrenschmidt wrote:
> > On Thu, 2006-11-02 at 13:55 +0100, s.hauer@pengutronix.de wrote:
> > > plain text document attachment
> > > (powerpc-include-asm-powerpc-iommu_h-remove-dead-code.diff)
> > > iommu_setup_pSeries() and iommu_setup_dart() are declared extern but are
> > > not implemented, so remove them. iommu_free_table() is pSeries specific,
> > > so #ifdef it with CONFIG_PPC_PSERIES and not CONFIG_PPC_MULTIPLATFORM
> > > 
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > 
> > There is no need to #ifdef an extern declaration. Just remove the
> > ifdef's and the two obsolete prototypes alltogether
> > 
> 
> Here we go:
> 
> iommu_setup_pSeries() and iommu_setup_dart() are declared extern but are
> not implemented, so remove them. iommu_free_table() is pSeries specific,
> so #ifdef it with CONFIG_PPC_PSERIES and not CONFIG_PPC_MULTIPLATFORM

Same here :-)

Ben.

> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> 
> Index: include/asm-powerpc/iommu.h
> ===================================================================
> --- a/include/asm-powerpc/iommu.h.orig
> +++ b/include/asm-powerpc/iommu.h
> @@ -70,17 +70,9 @@ struct iommu_table {
>  struct scatterlist;
>  struct device_node;
>  
> -#ifdef CONFIG_PPC_MULTIPLATFORM
> -
> -/* Walks all buses and creates iommu tables */
> -extern void iommu_setup_pSeries(void);
> -extern void iommu_setup_dart(void);
> -
>  /* Frees table for an individual device node */
>  extern void iommu_free_table(struct device_node *dn);
>  
> -#endif /* CONFIG_PPC_MULTIPLATFORM */
> -
>  /* Initializes an iommu_table based in values set in the passed-in
>   * structure
>   */
> 

^ permalink raw reply

* Re: [patch 01/16] remove inclusion of asm/processor.h for powerpc
From: Benjamin Herrenschmidt @ 2006-11-05  6:47 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linuxppc-dev
In-Reply-To: <20061103085249.GC22478@localhost.localdomain>

On Fri, 2006-11-03 at 09:52 +0100, Sascha Hauer wrote:
> I Sent a -p0 patch by accident, forget the last one.
> 
> There is some PPC_CHRP specific code in drivers/ide/pci/via82cxxx.c,
> so #ifdef on CONFIG_PPC_CHRP instead of CONFIG_PPC_MULTIPLATFORM.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

> Index: drivers/ide/pci/via82cxxx.c
> ===================================================================
> --- a/drivers/ide/pci/via82cxxx.c.orig
> +++ b/drivers/ide/pci/via82cxxx.c
> @@ -35,7 +35,7 @@
>  #include <linux/ide.h>
>  #include <asm/io.h>
>  
> -#ifdef CONFIG_PPC_MULTIPLATFORM
> +#ifdef CONFIG_PPC_CHRP
>  #include <asm/processor.h>
>  #endif
>  
> @@ -442,7 +442,7 @@ static void __devinit init_hwif_via82cxx
>  	hwif->speedproc = &via_set_drive;
>  
> 
> -#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
> +#ifdef CONFIG_PPC_CHRP
>  	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
>  		hwif->irq = hwif->channel ? 15 : 14;
>  	}
> 
> 
> 

^ permalink raw reply

* [PATCH/RFC] Hookable IO operations #3
From: Benjamin Herrenschmidt @ 2006-11-05  7:09 UTC (permalink / raw)
  To: linuxppc-dev list

[This is version 3 of the patch. It grew bigger as I added new
base operations in order to fully support the iomap API. It works
along with the patch from Linus:

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

To provide the working iomap via a modified generic one]

This patch reworks the way iSeries hooks on PCI IO operations (both MMIO
and PIO) and provides a generic way for other platforms to do so (we
have need to do that for various other platforms).

While reworking the IO ops, I ended up doing some spring cleaning in
io.h and eeh.h which I might want to split into 2 or 3 patches (among
others, eeh.h had a lot of useless stuff in it).

A side effect is that EEH for PIO should work now (it used to pass IO
ports down to the eeh address check functions which is bogus).

Also, new are MMIO "repeat" ops, which other archs like ARM already had,
and that we have too now: readsb, readsw, readsl, writesb, writesw,
writesl.

Since I need that to fix some issues with Cell fairly urgently, I plan
to push that to 2.6.20 when the merge window opens, so please comment
asap :)

Oh, also, in the long run, I might also make EEH use the hooks instead
of wrapping at the toplevel, which would make things even cleaner and
relegate EEH completely in platforms/iseries, but we have to measure the
performance impact there (though it's really only on MMIO reads)

Since I also need to hook on ioremap, I shuffled the functions a bit
there. I introduced ioremap_flags() to use by drivers who want to pass
explicit flags to ioremap (and it can be hooked). The old __ioremap() is
still there as a low level and cannot be hooked, thus drivers who use it
should migrate unless they know they want the low level version.

Diffstat is not as nice as the previous versions of the patch mostly due
to comments verbosity, the new accessors, and the iSeries implementation
of all the missing ones (for completeness).

 arch/powerpc/Kconfig                   |   10
 arch/powerpc/kernel/Makefile           |    6
 arch/powerpc/kernel/io.c               |   18
 arch/powerpc/kernel/pci_64.c           |    2
 arch/powerpc/kernel/setup_64.c         |    7
 arch/powerpc/mm/pgtable_64.c           |   46 +-
 arch/powerpc/platforms/iseries/pci.c   |  366 +++++++-----------
 arch/powerpc/platforms/iseries/setup.c |   12
 include/asm-powerpc/eeh.h              |  118 +-----
 include/asm-powerpc/io-defs.h          |   56 ++
 include/asm-powerpc/io.h               |  637
+++++++++++++++++++--------------
 include/asm-powerpc/machdep.h          |    4
 12 files changed, 680 insertions(+), 602 deletions(-)

Index: linux-cell/include/asm-powerpc/io.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/io.h	2006-11-04 15:24:57.000000000 +1100
+++ linux-cell/include/asm-powerpc/io.h	2006-11-05 16:22:43.000000000 +1100
@@ -31,57 +31,120 @@
 
 #define SLOW_DOWN_IO
 
+/*
+ *
+ * Low level MMIO accessors
+ *
+ * This provides the non-bus specific accessors to MMIO. Those are PowerPC
+ * specific and thus shouldn't be used in generic code. The accessors
+ * provided here are:
+ *
+ *	in_8, in_le16, in_be16, in_le32, in_be32, in_le64, in_be64
+ *	out_8, out_le16, out_be16, out_le32, out_be32, out_le64, out_be64
+ *	_insb, _insw_ns, _insl_ns, _outsb, _outsw_ns, _outsl_ns
+ *
+ * Those operate directly on a kernel virtual address. Note that the prototype
+ * for the out_* accessors has the arguments in opposite order from the usual
+ * linux PCI accessors. Unlike those, they take the address first and the value
+ * next.
+ *
+ * Note: I might drop the _ns suffix on the stream operations soon as it is
+ * simply normal for stream operations to not swap in the first place.
+ *
+ */
+
+#define DEF_MMIO_IN(name, type, insn)					\
+static inline type name(const volatile type __iomem *addr)		\
+{									\
+	type ret;							\
+	__asm__ __volatile__("sync;" insn ";twi 0,%0,0;isync"		\
+ 		: "=r" (ret) : "r" (addr), "m" (*addr));		\
+	return ret;							\
+}
+
+#define DEF_MMIO_OUT(name, type, insn)					\
+static inline void name(volatile type __iomem *addr, type val)		\
+{									\
+	__asm__ __volatile__("sync;" insn				\
+ 		: "=m" (*addr) : "r" (val), "r" (addr));		\
+	get_paca()->io_sync = 1;					\
+}
+
+
+#define DEF_MMIO_IN_BE(name, size, insn) \
+	DEF_MMIO_IN(name, u##size, __stringify(insn)"%U2%X2 %0,%2")
+#define DEF_MMIO_IN_LE(name, size, insn) \
+	DEF_MMIO_IN(name, u##size, __stringify(insn)" %0,0,%1")
+
+#define DEF_MMIO_OUT_BE(name, size, insn) \
+	DEF_MMIO_OUT(name, u##size, __stringify(insn)"%U0%X0 %1,%0")
+#define DEF_MMIO_OUT_LE(name, size, insn) \
+	DEF_MMIO_OUT(name, u##size, __stringify(insn)" %1,0,%2")
+
+DEF_MMIO_IN_BE(in_8,     8, lbz);
+DEF_MMIO_IN_BE(in_be16, 16, lhz);
+DEF_MMIO_IN_BE(in_be32, 32, lwz);
+DEF_MMIO_IN_BE(in_be64, 64, ld);
+DEF_MMIO_IN_LE(in_le16, 16, lhbrx);
+DEF_MMIO_IN_LE(in_le32, 32, lwbrx);
+
+DEF_MMIO_OUT_BE(out_8,     8, stb);
+DEF_MMIO_OUT_BE(out_be16, 16, sth);
+DEF_MMIO_OUT_BE(out_be32, 32, stw);
+DEF_MMIO_OUT_BE(out_be64, 64, std);
+DEF_MMIO_OUT_LE(out_le16, 16, sthbrx);
+DEF_MMIO_OUT_LE(out_le32, 32, stwbrx);
+
+/* There is no asm instructions for 64 bits reverse loads and stores */
+static inline u64 in_le64(const volatile u64 __iomem *addr)
+{
+	return le64_to_cpu(in_be64(addr));
+}
+
+static inline void out_le64(volatile u64 __iomem *addr, u64 val)
+{
+	out_be64(addr, cpu_to_le64(val));
+}
+
+/*
+ * Low level IO stream instructions are defined out of line for now
+ */
+extern void _insb(const volatile u8 __iomem *addr, void *buf, long count);
+extern void _outsb(volatile u8 __iomem *addr,const void *buf,long count);
+extern void _insw_ns(const volatile u16 __iomem *addr, void *buf, long count);
+extern void _outsw_ns(volatile u16 __iomem *addr, const void *buf, long count);
+extern void _insl_ns(const volatile u32 __iomem *addr, void *buf, long count);
+extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count);
+
+/* The _ns naming is historical and will be removed. For now, just #define
+ * the non _ns equivalent names
+ */
+#define _insw	_insw_ns
+#define _insl	_insl_ns
+#define _outsw	_outsw_ns
+#define _outsl	_outsl_ns
+
+/*
+ *
+ * PCI and standard ISA accessors
+ *
+ * Those are globally defined linux accessors for devices on PCI or ISA
+ * busses. They follow the Linux defined semantics. The current implementation
+ * for PowerPC is as close as possible to the x86 version of these, and thus
+ * provides fairly heavy weight barriers for the non-raw versions
+ *
+ * In addition, they support a hook mechanism when CONFIG_PPC_INDIRECT_IO
+ * allowing the platform to provide its own implementation of some or all
+ * of the accessors.
+ */
+
 extern unsigned long isa_io_base;
 extern unsigned long pci_io_base;
 
-#ifdef CONFIG_PPC_ISERIES
 
-extern int in_8(const volatile unsigned char __iomem *addr);
-extern void out_8(volatile unsigned char __iomem *addr, int val);
-extern int in_le16(const volatile unsigned short __iomem *addr);
-extern int in_be16(const volatile unsigned short __iomem *addr);
-extern void out_le16(volatile unsigned short __iomem *addr, int val);
-extern void out_be16(volatile unsigned short __iomem *addr, int val);
-extern unsigned in_le32(const volatile unsigned __iomem *addr);
-extern unsigned in_be32(const volatile unsigned __iomem *addr);
-extern void out_le32(volatile unsigned __iomem *addr, int val);
-extern void out_be32(volatile unsigned __iomem *addr, int val);
-extern unsigned long in_le64(const volatile unsigned long __iomem *addr);
-extern unsigned long in_be64(const volatile unsigned long __iomem *addr);
-extern void out_le64(volatile unsigned long __iomem *addr, unsigned long val);
-extern void out_be64(volatile unsigned long __iomem *addr, unsigned long val);
-
-extern unsigned char __raw_readb(const volatile void __iomem *addr);
-extern unsigned short __raw_readw(const volatile void __iomem *addr);
-extern unsigned int __raw_readl(const volatile void __iomem *addr);
-extern unsigned long __raw_readq(const volatile void __iomem *addr);
-extern void __raw_writeb(unsigned char v, volatile void __iomem *addr);
-extern void __raw_writew(unsigned short v, volatile void __iomem *addr);
-extern void __raw_writel(unsigned int v, volatile void __iomem *addr);
-extern void __raw_writeq(unsigned long v, volatile void __iomem *addr);
-
-extern void memset_io(volatile void __iomem *addr, int c, unsigned long n);
-extern void memcpy_fromio(void *dest, const volatile void __iomem *src,
-                                 unsigned long n);
-extern void memcpy_toio(volatile void __iomem *dest, const void *src,
-                                 unsigned long n);
-
-#else /* CONFIG_PPC_ISERIES */
-
-#define in_8(addr)		__in_8((addr))
-#define out_8(addr, val)	__out_8((addr), (val))
-#define in_le16(addr)		__in_le16((addr))
-#define in_be16(addr)		__in_be16((addr))
-#define out_le16(addr, val)	__out_le16((addr), (val))
-#define out_be16(addr, val)	__out_be16((addr), (val))
-#define in_le32(addr)		__in_le32((addr))
-#define in_be32(addr)		__in_be32((addr))
-#define out_le32(addr, val)	__out_le32((addr), (val))
-#define out_be32(addr, val)	__out_be32((addr), (val))
-#define in_le64(addr)		__in_le64((addr))
-#define in_be64(addr)		__in_be64((addr))
-#define out_le64(addr, val)	__out_le64((addr), (val))
-#define out_be64(addr, val)	__out_be64((addr), (val))
+/*
+ * Non ordered and non-swapping "raw" accessors
+ */
 
 static inline unsigned char __raw_readb(const volatile void __iomem *addr)
 {
@@ -115,52 +178,197 @@
 {
 	*(volatile unsigned long __force *)addr = v;
 }
-#define memset_io(a,b,c)	eeh_memset_io((a),(b),(c))
-#define memcpy_fromio(a,b,c)	eeh_memcpy_fromio((a),(b),(c))
-#define memcpy_toio(a,b,c)	eeh_memcpy_toio((a),(b),(c))
-
-#endif /* CONFIG_PPC_ISERIES */
-
-/*
- * The insw/outsw/insl/outsl macros don't do byte-swapping.
- * They are only used in practice for transferring buffers which
- * are arrays of bytes, and byte-swapping is not appropriate in
- * that case.  - paulus */
-#define insb(port, buf, ns)	eeh_insb((port), (buf), (ns))
-#define insw(port, buf, ns)	eeh_insw_ns((port), (buf), (ns))
-#define insl(port, buf, nl)	eeh_insl_ns((port), (buf), (nl))
-
-#define outsb(port, buf, ns)  _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
-#define outsw(port, buf, ns)  _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
-#define outsl(port, buf, nl)  _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
-
-#define readb(addr)		eeh_readb(addr)
-#define readw(addr)		eeh_readw(addr)
-#define readl(addr)		eeh_readl(addr)
-#define readq(addr)		eeh_readq(addr)
-#define writeb(data, addr)	eeh_writeb((data), (addr))
-#define writew(data, addr)	eeh_writew((data), (addr))
-#define writel(data, addr)	eeh_writel((data), (addr))
-#define writeq(data, addr)	eeh_writeq((data), (addr))
-#define inb(port)		eeh_inb((unsigned long)port)
-#define outb(val, port)		eeh_outb(val, (unsigned long)port)
-#define inw(port)		eeh_inw((unsigned long)port)
-#define outw(val, port)		eeh_outw(val, (unsigned long)port)
-#define inl(port)		eeh_inl((unsigned long)port)
-#define outl(val, port)		eeh_outl(val, (unsigned long)port)
 
+
+/*
+ *
+ * PCI PIO and MMIO accessors.
+ *
+ */
+
+#include <asm/eeh.h>
+
+/* Shortcut to the MMIO argument pointer */
+#define PCI_IO_ADDR	volatile void __iomem *
+
+/* Indirect IO address tokens:
+ *
+ * When CONFIG_PPC_INDIRECT_IO is set, the platform can provide hooks
+ * on all IOs.
+ *
+ * To help platforms who may need to differenciate MMIO addresses in
+ * their hooks, a bitfield is reserved for use by the platform near the
+ * top of MMIO addresses (not PIO, those have to cope the hard way).
+ *
+ * This bit field is 12 bits and is at the top of the IO virtual
+ * addresses PCI_IO_INDIRECT_TOKEN_MASK.
+ *
+ * The kernel virtual space is thus:
+ *
+ *  0xD000000000000000		: vmalloc
+ *  0xD000080000000000		: PCI PHB IO space
+ *  0xD000080080000000		: ioremap
+ *  0xD0000fffffffffff		: end of ioremap region
+ *
+ * Since the top 4 bits are reserved as the region ID, we use thus
+ * the next 12 bits and keep 4 bits available for the future if the
+ * virtual address space is ever to be extended.
+ *
+ * The direct IO mapping operations will then mask off those bits
+ * before doing the actual access, though that only happen when
+ * CONFIG_PPC_INDIRECT_IO is set, thus be careful when you use that
+ * mechanism
+ */
+
+#ifdef CONFIG_PPC_INDIRECT_IO
+#define PCI_IO_IND_TOKEN_MASK	0x0fff0000000000000ul
+#define PCI_IO_IND_TOKEN_SHIFT	48
+#define PCI_FIX_ADDR(addr)					\
+	((PCI_IO_ADDR)(((unsigned long)(addr)) & ~PCI_IO_IND_TOKEN_MASK))
+#define PCI_GET_ADDR_TOKEN(addr)				\
+	(((unsigned long)(addr) & PCI_IO_IND_TOKEN_MASK) >> 	\
+		PCI_IO_IND_TOKEN_SHIFT)
+#define PCI_SET_ADDR_TOKEN(addr, token) 			\
+do {								\
+	unsigned long __a = (unsigned long)(addr);		\
+	__a &= ~PCI_IO_IND_TOKEN_MASK;				\
+	__a |= (token) << PCI_IO_IND_TOKEN_SHIFT;		\
+	(addr) = (void __iomem *)__a;				\
+} while(0)
+#else
+#define PCI_FIX_ADDR(addr) (addr)
+#endif
+
+/* The "__do_*" operations below provide the actual "base" implementation
+ * for each of the defined acccessor. Some of them use the out_* functions
+ * directly, some of them still use EEH, though we might change that in the
+ * future. Those macros below provide the necessary argument swapping and
+ * handling of the IO base for PIO.
+ *
+ * They are themselves used by the macros that define the actual accessors
+ * and can be used by the hooks if any.
+ *
+ * Note that PIO operations are always defined in terms of their corresonding
+ * MMIO operations. That allows platforms like iSeries who want to modify the
+ * behaviour of both to only hook on the MMIO version and get both. It's also
+ * possible to hook directly at the toplevel PIO operation if they have to
+ * be handled differently
+ */
+#define __do_writeb(val, addr)	out_8(PCI_FIX_ADDR(addr), val)
+#define __do_writew(val, addr)	out_le16(PCI_FIX_ADDR(addr), val)
+#define __do_writel(val, addr)	out_le32(PCI_FIX_ADDR(addr), val)
+#define __do_writeq(val, addr)	out_le64(PCI_FIX_ADDR(addr), val)
+#define __do_writew_be(val, addr) out_be16(PCI_FIX_ADDR(addr), val)
+#define __do_writel_be(val, addr) out_be32(PCI_FIX_ADDR(addr), val)
+#define __do_writeq_be(val, addr) out_be64(PCI_FIX_ADDR(addr), val)
+#define __do_readb(addr)	eeh_readb(PCI_FIX_ADDR(addr))
+#define __do_readw(addr)	eeh_readw(PCI_FIX_ADDR(addr))
+#define __do_readl(addr)	eeh_readl(PCI_FIX_ADDR(addr))
+#define __do_readq(addr)	eeh_readq(PCI_FIX_ADDR(addr))
+#define __do_readw_be(addr)	eeh_readw_be(PCI_FIX_ADDR(addr))
+#define __do_readl_be(addr)	eeh_readl_be(PCI_FIX_ADDR(addr))
+#define __do_readq_be(addr)	eeh_readq_be(PCI_FIX_ADDR(addr))
+
+#define __do_outb(val, port)	writeb(val,(PCI_IO_ADDR)pci_io_base+port);
+#define __do_outw(val, port)	writew(val,(PCI_IO_ADDR)pci_io_base+port);
+#define __do_outl(val, port)	writel(val,(PCI_IO_ADDR)pci_io_base+port);
+#define __do_inb(port)		readb((PCI_IO_ADDR)pci_io_base + port);
+#define __do_inw(port)		readw((PCI_IO_ADDR)pci_io_base + port);
+#define __do_inl(port)		readl((PCI_IO_ADDR)pci_io_base + port);
+
+#define __do_readsb(a, b, n)	eeh_readsb((a), (b), (n))
+#define __do_readsw(a, b, n)	eeh_readsw((a), (b), (n))
+#define __do_readsl(a, b, n)	eeh_readsl((a), (b), (n))
+#define __do_writesb(a, b, n)	_outsb((a),(b),(n))
+#define __do_writesw(a, b, n)	_outsw((a),(b),(n))
+#define __do_writesl(a, b, n)	_outsl((a),(b),(n))
+
+#define __do_insb(p, b, n)	readsb((PCI_IO_ADDR)pci_io_base+(p), (b), (n))
+#define __do_insw(p, b, n)	readsw((PCI_IO_ADDR)pci_io_base+(p), (b), (n))
+#define __do_insl(p, b, n)	readsl((PCI_IO_ADDR)pci_io_base+(p), (b), (n))
+#define __do_outsb(p, b, n)	writesb((PCI_IO_ADDR)pci_io_base+(p),(b),(n))
+#define __do_outsw(p, b, n)	writesw((PCI_IO_ADDR)pci_io_base+(p),(b),(n))
+#define __do_outsl(p, b, n)	writesl((PCI_IO_ADDR)pci_io_base+(p),(b),(n))
+
+#define __do_memset_io(addr, c, n)	eeh_memset_io(PCI_FIX_ADDR(addr), c, n)
+#define __do_memcpy_fromio(dst, src, n)	eeh_memcpy_fromio(dst, \
+						PCI_FIX_ADDR(src), n)
+#define __do_memcpy_toio(dst, src, n)	eeh_memcpy_toio(PCI_FIX_ADDR(dst), \
+						src, n)
+
+#ifdef CONFIG_PPC_INDIRECT_IO
+#define DEF_PCI_HOOK(x)		x
+#else
+#define DEF_PCI_HOOK(x)		NULL
+#endif
+
+/* Structure containing all the hooks */
+extern struct ppc_pci_io {
+
+#define DEF_PCI_AC_RET(name, ret, at, al)	ret (*name) at;
+#define DEF_PCI_AC_NORET(name, at, al)		void (*name) at;
+
+#include <asm/io-defs.h>
+
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
+
+} ppc_pci_io;
+
+/* The inline wrappers */
+#define DEF_PCI_AC_RET(name, ret, at, al)			\
+static inline ret name at					\
+{								\
+	if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL)		\
+		return ppc_pci_io.name al;			\
+	return __do_##name al;					\
+}
+
+#define DEF_PCI_AC_NORET(name, at, al)				\
+static inline void name at					\
+{								\
+	if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL)		\
+		ppc_pci_io.name al;				\
+	else							\
+		__do_##name al;					\
+}
+
+#include <asm/io-defs.h>
+
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
+
+/* Nothing to do */
+
+#define dma_cache_inv(_start,_size)		do { } while (0)
+#define dma_cache_wback(_start,_size)		do { } while (0)
+#define dma_cache_wback_inv(_start,_size)	do { } while (0)
+
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p)	__va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p)	p
+
+/*
+ * We don't do relaxed operations yet, at least not with this semantic
+ */
 #define readb_relaxed(addr) readb(addr)
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
 #define readq_relaxed(addr) readq(addr)
 
-extern void _insb(volatile u8 __iomem *port, void *buf, long count);
-extern void _outsb(volatile u8 __iomem *port, const void *buf, long count);
-extern void _insw_ns(volatile u16 __iomem *port, void *buf, long count);
-extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count);
-extern void _insl_ns(volatile u32 __iomem *port, void *buf, long count);
-extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count);
-
+/*
+ * Enforce synchronisation of stores vs. spin_unlock
+ * (this does it explicitely, though our implementation of spin_unlock
+ * does it implicitely too)
+ */
 static inline void mmiowb(void)
 {
 	unsigned long tmp;
@@ -170,6 +378,23 @@
 	: "memory");
 }
 
+static inline void iosync(void)
+{
+        __asm__ __volatile__ ("sync" : : : "memory");
+}
+
+/* Enforce in-order execution of data I/O.
+ * No distinction between read/write on PPC; use eieio for all three.
+ * Those are fairly week though. They don't provide a barrier between
+ * MMIO and cacheable storage nor do they provide a barrier vs. locks,
+ * they only provide barriers between 2 __raw MMIO operations and
+ * possibly break write combining.
+ */
+#define iobarrier_rw() eieio()
+#define iobarrier_r()  eieio()
+#define iobarrier_w()  eieio()
+
+
 /*
  * output pause versions need a delay at least for the
  * w83c105 ide controller in a p610.
@@ -185,11 +410,6 @@
 #define IO_SPACE_LIMIT ~(0UL)
 
 
-extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr,
-		     	      unsigned long size, unsigned long flags);
-extern void __iomem *__ioremap(unsigned long address, unsigned long size,
-		       unsigned long flags);
-
 /**
  * ioremap     -   map bus memory into CPU space
  * @address:   bus address of the memory
@@ -200,14 +420,70 @@
  * writew/writel functions and the other mmio helpers. The returned
  * address is not guaranteed to be usable directly as a virtual
  * address.
+ *
+ * We provide a few variations of it:
+ *
+ * * ioremap is the standard one and provides non-cacheable guarded mappings
+ *   and can be hooked by the platform via ppc_md
+ *
+ * * ioremap_flags allows to specify the page flags as an argument and can
+ *   also be hooked by the platform via ppc_md
+ *
+ * * ioremap_nocache is identical to ioremap
+ *
+ * * iounmap undoes such a mapping and can be hooked
+ *
+ * * __ioremap_explicit (and the pending __iounmap_explicit) are low level
+ *   functions to create hand-made mappings for use only by the PCI code
+ *   and cannot currently be hooked.
+ *
+ * * __ioremap is the low level implementation used by ioremap and
+ *   ioremap_flags and cannot be hooked (but can be used by a hook on one
+ *   of the previous ones)
+ *
+ * * __iounmap, is the low level implementation used by iounmap and cannot
+ *   be hooked (but can be used by a hook on iounmap)
+ *
  */
 extern void __iomem *ioremap(unsigned long address, unsigned long size);
-
+extern void __iomem *ioremap_flags(unsigned long address, unsigned long size,
+				   unsigned long flags);
 #define ioremap_nocache(addr, size)	ioremap((addr), (size))
-extern int iounmap_explicit(volatile void __iomem *addr, unsigned long size);
-extern void iounmap(volatile void __iomem *addr);
+extern void iounmap(void __iomem *addr);
+
+extern void __iomem *__ioremap(unsigned long address, unsigned long size,
+			       unsigned long flags);
+extern void __iounmap(void __iomem *addr);
+
+extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr,
+		     	      unsigned long size, unsigned long flags);
+extern int __iounmap_explicit(void __iomem *start, unsigned long size);
+
 extern void __iomem * reserve_phb_iospace(unsigned long size);
 
+
+/*
+ * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap implementation
+ * which needs some additional definitions here. They basically allow PIO
+ * space overall to be 1GB. This will work as long as we never try to use
+ * iomap to map MMIO below 1GB which should be fine on ppc64
+ */
+#define HAVE_ARCH_PIO_SIZE		1
+#define PIO_OFFSET			0x00000000UL
+#define PIO_MASK			0x3fffffffUL
+#define PIO_RESERVED			0x40000000UL
+
+#define mmio_read16be(addr)		readw_be(addr)
+#define mmio_read32be(addr)		readl_be(addr)
+#define mmio_write16be(val, addr)	writew_be(val, addr)
+#define mmio_write32be(val, addr)	writel_be(val, addr)
+#define mmio_insb(addr, dst, count)	readsb(addr, dst, count)
+#define mmio_insw(addr, dst, count)	readsw(addr, dst, count)
+#define mmio_insl(addr, dst, count)	readsl(addr, dst, count)
+#define mmio_outsb(addr, src, count)	writesb(addr, src, count)
+#define mmio_outsw(addr, src, count)	writesw(addr, src, count)
+#define mmio_outsl(addr, src, count)	writesl(addr, src, count)
+
 /**
  *	virt_to_phys	-	map virtual addresses to physical
  *	@address: address to remap
@@ -254,177 +530,6 @@
  */
 #define BIO_VMERGE_BOUNDARY	0
 
-static inline void iosync(void)
-{
-        __asm__ __volatile__ ("sync" : : : "memory");
-}
-
-/* Enforce in-order execution of data I/O. 
- * No distinction between read/write on PPC; use eieio for all three.
- */
-#define iobarrier_rw() eieio()
-#define iobarrier_r()  eieio()
-#define iobarrier_w()  eieio()
-
-/*
- * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
- * These routines do not perform EEH-related I/O address translation,
- * and should not be used directly by device drivers.  Use inb/readb
- * instead.
- */
-static inline int __in_8(const volatile unsigned char __iomem *addr)
-{
-	int ret;
-
-	__asm__ __volatile__("sync; lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
-			     : "=r" (ret) : "m" (*addr));
-	return ret;
-}
-
-static inline void __out_8(volatile unsigned char __iomem *addr, int val)
-{
-	__asm__ __volatile__("sync; stb%U0%X0 %1,%0"
-			     : "=m" (*addr) : "r" (val));
-	get_paca()->io_sync = 1;
-}
-
-static inline int __in_le16(const volatile unsigned short __iomem *addr)
-{
-	int ret;
-
-	__asm__ __volatile__("sync; lhbrx %0,0,%1; twi 0,%0,0; isync"
-			     : "=r" (ret) : "r" (addr), "m" (*addr));
-	return ret;
-}
-
-static inline int __in_be16(const volatile unsigned short __iomem *addr)
-{
-	int ret;
-
-	__asm__ __volatile__("sync; lhz%U1%X1 %0,%1; twi 0,%0,0; isync"
-			     : "=r" (ret) : "m" (*addr));
-	return ret;
-}
-
-static inline void __out_le16(volatile unsigned short __iomem *addr, int val)
-{
-	__asm__ __volatile__("sync; sthbrx %1,0,%2"
-			     : "=m" (*addr) : "r" (val), "r" (addr));
-	get_paca()->io_sync = 1;
-}
-
-static inline void __out_be16(volatile unsigned short __iomem *addr, int val)
-{
-	__asm__ __volatile__("sync; sth%U0%X0 %1,%0"
-			     : "=m" (*addr) : "r" (val));
-	get_paca()->io_sync = 1;
-}
-
-static inline unsigned __in_le32(const volatile unsigned __iomem *addr)
-{
-	unsigned ret;
-
-	__asm__ __volatile__("sync; lwbrx %0,0,%1; twi 0,%0,0; isync"
-			     : "=r" (ret) : "r" (addr), "m" (*addr));
-	return ret;
-}
-
-static inline unsigned __in_be32(const volatile unsigned __iomem *addr)
-{
-	unsigned ret;
-
-	__asm__ __volatile__("sync; lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
-			     : "=r" (ret) : "m" (*addr));
-	return ret;
-}
-
-static inline void __out_le32(volatile unsigned __iomem *addr, int val)
-{
-	__asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr)
-			     : "r" (val), "r" (addr));
-	get_paca()->io_sync = 1;
-}
-
-static inline void __out_be32(volatile unsigned __iomem *addr, int val)
-{
-	__asm__ __volatile__("sync; stw%U0%X0 %1,%0"
-			     : "=m" (*addr) : "r" (val));
-	get_paca()->io_sync = 1;
-}
-
-static inline unsigned long __in_le64(const volatile unsigned long __iomem *addr)
-{
-	unsigned long tmp, ret;
-
-	__asm__ __volatile__(
-			     "sync\n"
-			     "ld %1,0(%2)\n"
-			     "twi 0,%1,0\n"
-			     "isync\n"
-			     "rldimi %0,%1,5*8,1*8\n"
-			     "rldimi %0,%1,3*8,2*8\n"
-			     "rldimi %0,%1,1*8,3*8\n"
-			     "rldimi %0,%1,7*8,4*8\n"
-			     "rldicl %1,%1,32,0\n"
-			     "rlwimi %0,%1,8,8,31\n"
-			     "rlwimi %0,%1,24,16,23\n"
-			     : "=r" (ret) , "=r" (tmp) : "b" (addr) , "m" (*addr));
-	return ret;
-}
-
-static inline unsigned long __in_be64(const volatile unsigned long __iomem *addr)
-{
-	unsigned long ret;
-
-	__asm__ __volatile__("sync; ld%U1%X1 %0,%1; twi 0,%0,0; isync"
-			     : "=r" (ret) : "m" (*addr));
-	return ret;
-}
-
-static inline void __out_le64(volatile unsigned long __iomem *addr, unsigned long val)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-			     "rldimi %0,%1,5*8,1*8\n"
-			     "rldimi %0,%1,3*8,2*8\n"
-			     "rldimi %0,%1,1*8,3*8\n"
-			     "rldimi %0,%1,7*8,4*8\n"
-			     "rldicl %1,%1,32,0\n"
-			     "rlwimi %0,%1,8,8,31\n"
-			     "rlwimi %0,%1,24,16,23\n"
-			     "sync\n"
-			     "std %0,0(%3)"
-			     : "=&r" (tmp) , "=&r" (val) : "1" (val) , "b" (addr) , "m" (*addr));
-	get_paca()->io_sync = 1;
-}
-
-static inline void __out_be64(volatile unsigned long __iomem *addr, unsigned long val)
-{
-	__asm__ __volatile__("sync; std%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
-	get_paca()->io_sync = 1;
-}
-
-#include <asm/eeh.h>
-
-/* Nothing to do */
-
-#define dma_cache_inv(_start,_size)		do { } while (0)
-#define dma_cache_wback(_start,_size)		do { } while (0)
-#define dma_cache_wback_inv(_start,_size)	do { } while (0)
-
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem
- * access
- */
-#define xlate_dev_mem_ptr(p)	__va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)	p
-
 #endif /* __KERNEL__ */
 
 #endif /* CONFIG_PPC64 */
Index: linux-cell/arch/powerpc/Kconfig
===================================================================
--- linux-cell.orig/arch/powerpc/Kconfig	2006-11-04 15:24:57.000000000 +1100
+++ linux-cell/arch/powerpc/Kconfig	2006-11-05 14:58:01.000000000 +1100
@@ -389,6 +389,7 @@
 config PPC_ISERIES
 	bool "IBM Legacy iSeries"
 	depends on PPC_MULTIPLATFORM && PPC64
+	select PPC_INDIRECT_IO
 
 config PPC_CHRP
 	bool "Common Hardware Reference Platform (CHRP) based machines"
@@ -534,6 +535,15 @@
 	bool
 	default n
 
+config PPC_INDIRECT_IO
+	bool
+	select GENERIC_IOMAP
+	default n
+
+config GENERIC_IOMAP
+	bool
+	default n
+
 source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_PMAC
Index: linux-cell/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/setup_64.c	2006-11-04 15:24:57.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/setup_64.c	2006-11-04 21:25:10.000000000 +1100
@@ -599,3 +599,10 @@
 	}
 }
 #endif
+
+
+#ifdef CONFIG_PPC_INDIRECT_IO
+struct ppc_pci_io ppc_pci_io;
+EXPORT_SYMBOL(ppc_pci_io);
+#endif /* CONFIG_PPC_INDIRECT_IO */
+
Index: linux-cell/arch/powerpc/platforms/iseries/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/iseries/pci.c	2006-11-04 15:24:57.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/iseries/pci.c	2006-11-05 14:37:22.000000000 +1100
@@ -156,53 +156,6 @@
 }
 
 /*
- * iSeries_pcibios_init
- *
- * Description:
- *   This function checks for all possible system PCI host bridges that connect
- *   PCI buses.  The system hypervisor is queried as to the guest partition
- *   ownership status.  A pci_controller is built for any bus which is partially
- *   owned or fully owned by this guest partition.
- */
-void iSeries_pcibios_init(void)
-{
-	struct pci_controller *phb;
-	struct device_node *root = of_find_node_by_path("/");
-	struct device_node *node = NULL;
-
-	if (root == NULL) {
-		printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
-				"of device tree\n");
-		return;
-	}
-	while ((node = of_get_next_child(root, node)) != NULL) {
-		HvBusNumber bus;
-		const u32 *busp;
-
-		if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
-			continue;
-
-		busp = get_property(node, "bus-range", NULL);
-		if (busp == NULL)
-			continue;
-		bus = *busp;
-		printk("bus %d appears to exist\n", bus);
-		phb = pcibios_alloc_controller(node);
-		if (phb == NULL)
-			continue;
-
-		phb->pci_mem_offset = phb->local_number = bus;
-		phb->first_busno = bus;
-		phb->last_busno = bus;
-		phb->ops = &iSeries_pci_ops;
-	}
-
-	of_node_put(root);
-
-	pci_devs_phb_init();
-}
-
-/*
  * iSeries_pci_final_fixup(void)
  */
 void __init iSeries_pci_final_fixup(void)
@@ -438,11 +391,7 @@
 /*
  * Read MM I/O Instructions for the iSeries
  * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
- * else, data is returned in big Endian format.
- *
- * iSeries_Read_Byte = Read Byte  ( 8 bit)
- * iSeries_Read_Word = Read Word  (16 bit)
- * iSeries_Read_Long = Read Long  (32 bit)
+ * else, data is returned in Big Endian format.
  */
 static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
 {
@@ -462,14 +411,15 @@
 			num_printed = 0;
 		}
 		if (num_printed++ < 10)
-			printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress);
+			printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n",
+			       IoAddress);
 		return 0xff;
 	}
 	do {
 		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
 	} while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
 
-	return (u8)ret.value;
+	return ret.value;
 }
 
 static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
@@ -490,7 +440,8 @@
 			num_printed = 0;
 		}
 		if (num_printed++ < 10)
-			printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress);
+			printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n",
+			       IoAddress);
 		return 0xffff;
 	}
 	do {
@@ -498,7 +449,7 @@
 				BarOffset, 0);
 	} while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
 
-	return swab16((u16)ret.value);
+	return ret.value;
 }
 
 static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
@@ -519,7 +470,8 @@
 			num_printed = 0;
 		}
 		if (num_printed++ < 10)
-			printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress);
+			printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n",
+			       IoAddress);
 		return 0xffffffff;
 	}
 	do {
@@ -527,15 +479,12 @@
 				BarOffset, 0);
 	} while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
 
-	return swab32((u32)ret.value);
+	return ret.value;
 }
 
 /*
  * Write MM I/O Instructions for the iSeries
  *
- * iSeries_Write_Byte = Write Byte (8 bit)
- * iSeries_Write_Word = Write Word(16 bit)
- * iSeries_Write_Long = Write Long(32 bit)
  */
 static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
 {
@@ -581,11 +530,12 @@
 			num_printed = 0;
 		}
 		if (num_printed++ < 10)
-			printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress);
+			printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n",
+			       IoAddress);
 		return;
 	}
 	do {
-		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
+		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0);
 	} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
 }
 
@@ -607,231 +557,221 @@
 			num_printed = 0;
 		}
 		if (num_printed++ < 10)
-			printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress);
+			printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n",
+			       IoAddress);
 		return;
 	}
 	do {
-		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
+		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0);
 	} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
 }
 
-extern unsigned char __raw_readb(const volatile void __iomem *addr)
-{
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	return *(volatile unsigned char __force *)addr;
-}
-EXPORT_SYMBOL(__raw_readb);
-
-extern unsigned short __raw_readw(const volatile void __iomem *addr)
+static u8 iseries_readb(const volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	return *(volatile unsigned short __force *)addr;
+	return iSeries_Read_Byte(addr);
 }
-EXPORT_SYMBOL(__raw_readw);
 
-extern unsigned int __raw_readl(const volatile void __iomem *addr)
+static u16 iseries_readw(const volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	return *(volatile unsigned int __force *)addr;
+	return le16_to_cpu(iSeries_Read_Word(addr));
 }
-EXPORT_SYMBOL(__raw_readl);
 
-extern unsigned long __raw_readq(const volatile void __iomem *addr)
+static u32 iseries_readl(const volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	return *(volatile unsigned long __force *)addr;
+	return le32_to_cpu(iSeries_Read_Long(addr));
 }
-EXPORT_SYMBOL(__raw_readq);
 
-extern void __raw_writeb(unsigned char v, volatile void __iomem *addr)
+static u16 iseries_readw_be(const volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	*(volatile unsigned char __force *)addr = v;
+	return iSeries_Read_Word(addr);
 }
-EXPORT_SYMBOL(__raw_writeb);
 
-extern void __raw_writew(unsigned short v, volatile void __iomem *addr)
+static u32 iseries_readl_be(const volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	*(volatile unsigned short __force *)addr = v;
+	return iSeries_Read_Long(addr);
 }
-EXPORT_SYMBOL(__raw_writew);
 
-extern void __raw_writel(unsigned int v, volatile void __iomem *addr)
+static void iseries_writeb(u8 data, volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	*(volatile unsigned int __force *)addr = v;
+	iSeries_Write_Byte(data, addr);
 }
-EXPORT_SYMBOL(__raw_writel);
 
-extern void __raw_writeq(unsigned long v, volatile void __iomem *addr)
+static void iseries_writew(u16 data, volatile void __iomem *addr)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	*(volatile unsigned long __force *)addr = v;
+	iSeries_Write_Word(cpu_to_le16(data), addr);
 }
-EXPORT_SYMBOL(__raw_writeq);
 
-int in_8(const volatile unsigned char __iomem *addr)
+static void iseries_writel(u32 data, volatile void __iomem *addr)
 {
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		return iSeries_Read_Byte(addr);
-	return __in_8(addr);
+	iSeries_Write_Long(cpu_to_le32(data), addr);
 }
-EXPORT_SYMBOL(in_8);
 
-void out_8(volatile unsigned char __iomem *addr, int val)
+static void iseries_writew_be(u16 data, volatile void __iomem *addr)
 {
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		iSeries_Write_Byte(val, addr);
-	else
-		__out_8(addr, val);
+	iSeries_Write_Word(data, addr);
 }
-EXPORT_SYMBOL(out_8);
 
-int in_le16(const volatile unsigned short __iomem *addr)
+static void iseries_writel_be(u32 data, volatile void __iomem *addr)
 {
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		return iSeries_Read_Word(addr);
-	return __in_le16(addr);
+	iSeries_Write_Long(data, addr);
 }
-EXPORT_SYMBOL(in_le16);
 
-int in_be16(const volatile unsigned short __iomem *addr)
+static void iseries_readsb(const volatile void __iomem *addr, void *buf,
+			   unsigned long count)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	return __in_be16(addr);
+	u8 *dst = buf;
+	while(count-- > 0)
+		*(dst++) = iSeries_Read_Byte(addr);
 }
-EXPORT_SYMBOL(in_be16);
 
-void out_le16(volatile unsigned short __iomem *addr, int val)
+static void iseries_readsw(const volatile void __iomem *addr, void *buf,
+			   unsigned long count)
 {
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		iSeries_Write_Word(val, addr);
-	else
-		__out_le16(addr, val);
+	u16 *dst = buf;
+	while(count-- > 0)
+		*(dst++) = iSeries_Read_Word(addr);
 }
-EXPORT_SYMBOL(out_le16);
 
-void out_be16(volatile unsigned short __iomem *addr, int val)
+static void iseries_readsl(const volatile void __iomem *addr, void *buf,
+			   unsigned long count)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	__out_be16(addr, val);
+	u32 *dst = buf;
+	while(count-- > 0)
+		*(dst++) = iSeries_Read_Long(addr);
 }
-EXPORT_SYMBOL(out_be16);
 
-unsigned in_le32(const volatile unsigned __iomem *addr)
+static void iseries_writesb(volatile void __iomem *addr, const void *buf,
+			    unsigned long count)
 {
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		return iSeries_Read_Long(addr);
-	return __in_le32(addr);
+	const u8 *src = buf;
+	while(count-- > 0)
+		iSeries_Write_Byte(*(src++), addr);
 }
-EXPORT_SYMBOL(in_le32);
 
-unsigned in_be32(const volatile unsigned __iomem *addr)
+static void iseries_writesw(volatile void __iomem *addr, const void *buf,
+			    unsigned long count)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	return __in_be32(addr);
+	const u16 *src = buf;
+	while(count-- > 0)
+		iSeries_Write_Word(*(src++), addr);
 }
-EXPORT_SYMBOL(in_be32);
 
-void out_le32(volatile unsigned __iomem *addr, int val)
+static void iseries_writesl(volatile void __iomem *addr, const void *buf,
+			    unsigned long count)
 {
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		iSeries_Write_Long(val, addr);
-	else
-		__out_le32(addr, val);
+	const u32 *src = buf;
+	while(count-- > 0)
+		iSeries_Write_Long(*(src++), addr);
 }
-EXPORT_SYMBOL(out_le32);
 
-void out_be32(volatile unsigned __iomem *addr, int val)
+static void iseries_memset_io(volatile void __iomem *addr, int c,
+			      unsigned long n)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+	volatile char __iomem *d = addr;
 
-	__out_be32(addr, val);
+	while (n-- > 0)
+		iSeries_Write_Byte(c, d++);
 }
-EXPORT_SYMBOL(out_be32);
 
-unsigned long in_le64(const volatile unsigned long __iomem *addr)
+static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
+				  unsigned long n)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+	char *d = dest;
+	const volatile char __iomem *s = src;
 
-	return __in_le64(addr);
+	while (n-- > 0)
+		*d++ = iSeries_Read_Byte(s++);
 }
-EXPORT_SYMBOL(in_le64);
 
-unsigned long in_be64(const volatile unsigned long __iomem *addr)
+static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
+				unsigned long n)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+	const char *s = src;
+	volatile char __iomem *d = dest;
 
-	return __in_be64(addr);
+	while (n-- > 0)
+		iSeries_Write_Byte(*s++, d++);
 }
-EXPORT_SYMBOL(in_be64);
 
-void out_le64(volatile unsigned long __iomem *addr, unsigned long val)
+static void __init iseries_setup_io_access(void)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
-	__out_le64(addr, val);
+	/* We only set MMIO ops. The default PIO ops will be default
+	 * to the MMIO ops + pci_io_base which is 0 on iSeries as
+	 * expected so both should work.
+	 *
+	 * Note that we don't implement the readq/writeq versions as
+	 * I don't know of an HV call for doing so. Thus, the default
+	 * operation will be used instead, which will fault a the value
+	 * return by iSeries for MMIO addresses always hits a non mapped
+	 * area. This is as good as the BUG() we used to have there.
+	 */
+	ppc_pci_io.readb = iseries_readb;
+	ppc_pci_io.readw = iseries_readw;
+	ppc_pci_io.readl = iseries_readl;
+	ppc_pci_io.readw_be = iseries_readw_be;
+	ppc_pci_io.readl_be = iseries_readl_be;
+	ppc_pci_io.writeb = iseries_writeb;
+	ppc_pci_io.writew = iseries_writew;
+	ppc_pci_io.writel = iseries_writel;
+	ppc_pci_io.writew_be = iseries_writew_be;
+	ppc_pci_io.writel_be = iseries_writel_be;
+	ppc_pci_io.readsb = iseries_readsb;
+	ppc_pci_io.readsw = iseries_readsw;
+	ppc_pci_io.readsl = iseries_readsl;
+	ppc_pci_io.writesb = iseries_writesb;
+	ppc_pci_io.writesw = iseries_writesw;
+	ppc_pci_io.writesl = iseries_writesl;
+	ppc_pci_io.memset_io = iseries_memset_io;
+	ppc_pci_io.memcpy_fromio = iseries_memcpy_fromio;
+	ppc_pci_io.memcpy_toio = iseries_memcpy_toio;
 }
-EXPORT_SYMBOL(out_le64);
 
-void out_be64(volatile unsigned long __iomem *addr, unsigned long val)
+/*
+ * iSeries_pcibios_init
+ *
+ * Description:
+ *   This function checks for all possible system PCI host bridges that connect
+ *   PCI buses.  The system hypervisor is queried as to the guest partition
+ *   ownership status.  A pci_controller is built for any bus which is partially
+ *   owned or fully owned by this guest partition.
+ */
+void __init iSeries_pcibios_init(void)
 {
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
+	struct pci_controller *phb;
+	struct device_node *root = of_find_node_by_path("/");
+	struct device_node *node = NULL;
 
-	__out_be64(addr, val);
-}
-EXPORT_SYMBOL(out_be64);
+	iseries_setup_io_access();
 
-void memset_io(volatile void __iomem *addr, int c, unsigned long n)
-{
-	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		volatile char __iomem *d = addr;
+	if (root == NULL) {
+		printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
+				"of device tree\n");
+		return;
+	}
+	while ((node = of_get_next_child(root, node)) != NULL) {
+		HvBusNumber bus;
+		const u32 *busp;
 
-		while (n-- > 0) {
-			iSeries_Write_Byte(c, d++);
-		}
-	} else
-		eeh_memset_io(addr, c, n);
-}
-EXPORT_SYMBOL(memset_io);
+		if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
+			continue;
 
-void memcpy_fromio(void *dest, const volatile void __iomem *src,
-                                 unsigned long n)
-{
-	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		char *d = dest;
-		const volatile char __iomem *s = src;
+		busp = get_property(node, "bus-range", NULL);
+		if (busp == NULL)
+			continue;
+		bus = *busp;
+		printk("bus %d appears to exist\n", bus);
+		phb = pcibios_alloc_controller(node);
+		if (phb == NULL)
+			continue;
 
-		while (n-- > 0) {
-			*d++ = iSeries_Read_Byte(s++);
-		}
-	} else
-		eeh_memcpy_fromio(dest, src, n);
-}
-EXPORT_SYMBOL(memcpy_fromio);
+		phb->pci_mem_offset = phb->local_number = bus;
+		phb->first_busno = bus;
+		phb->last_busno = bus;
+		phb->ops = &iSeries_pci_ops;
+	}
 
-void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
-{
-	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		const char *s = src;
-		volatile char __iomem *d = dest;
+	of_node_put(root);
 
-		while (n-- > 0) {
-			iSeries_Write_Byte(*s++, d++);
-		}
-	} else
-		eeh_memcpy_toio(dest, src, n);
+	pci_devs_phb_init();
 }
-EXPORT_SYMBOL(memcpy_toio);
+
Index: linux-cell/include/asm-powerpc/eeh.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/eeh.h	2006-11-04 15:24:57.000000000 +1100
+++ linux-cell/include/asm-powerpc/eeh.h	2006-11-05 14:23:07.000000000 +1100
@@ -120,10 +120,6 @@
 		return eeh_check_failure(addr, val);
 	return val;
 }
-static inline void eeh_writeb(u8 val, volatile void __iomem *addr)
-{
-	out_8(addr, val);
-}
 
 static inline u16 eeh_readw(const volatile void __iomem *addr)
 {
@@ -132,21 +128,6 @@
 		return eeh_check_failure(addr, val);
 	return val;
 }
-static inline void eeh_writew(u16 val, volatile void __iomem *addr)
-{
-	out_le16(addr, val);
-}
-static inline u16 eeh_raw_readw(const volatile void __iomem *addr)
-{
-	u16 val = in_be16(addr);
-	if (EEH_POSSIBLE_ERROR(val, u16))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) {
-	volatile u16 __iomem *vaddr = (volatile u16 __iomem *) addr;
-	out_be16(vaddr, val);
-}
 
 static inline u32 eeh_readl(const volatile void __iomem *addr)
 {
@@ -155,44 +136,38 @@
 		return eeh_check_failure(addr, val);
 	return val;
 }
-static inline void eeh_writel(u32 val, volatile void __iomem *addr)
-{
-	out_le32(addr, val);
-}
-static inline u32 eeh_raw_readl(const volatile void __iomem *addr)
+
+static inline u64 eeh_readq(const volatile void __iomem *addr)
 {
-	u32 val = in_be32(addr);
-	if (EEH_POSSIBLE_ERROR(val, u32))
+	u64 val = in_le64(addr);
+	if (EEH_POSSIBLE_ERROR(val, u64))
 		return eeh_check_failure(addr, val);
 	return val;
 }
-static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr)
-{
-	out_be32(addr, val);
-}
 
-static inline u64 eeh_readq(const volatile void __iomem *addr)
+static inline u16 eeh_readw_be(const volatile void __iomem *addr)
 {
-	u64 val = in_le64(addr);
-	if (EEH_POSSIBLE_ERROR(val, u64))
+	u16 val = in_be16(addr);
+	if (EEH_POSSIBLE_ERROR(val, u16))
 		return eeh_check_failure(addr, val);
 	return val;
 }
-static inline void eeh_writeq(u64 val, volatile void __iomem *addr)
+
+static inline u32 eeh_readl_be(const volatile void __iomem *addr)
 {
-	out_le64(addr, val);
+	u32 val = in_be32(addr);
+	if (EEH_POSSIBLE_ERROR(val, u32))
+		return eeh_check_failure(addr, val);
+	return val;
 }
-static inline u64 eeh_raw_readq(const volatile void __iomem *addr)
+
+static inline u64 eeh_readq_be(const volatile void __iomem *addr)
 {
 	u64 val = in_be64(addr);
 	if (EEH_POSSIBLE_ERROR(val, u64))
 		return eeh_check_failure(addr, val);
 	return val;
 }
-static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
-{
-	out_be64(addr, val);
-}
 
 #define EEH_CHECK_ALIGN(v,a) \
 	((((unsigned long)(v)) & ((a) - 1)) == 0)
@@ -292,68 +267,29 @@
 
 #undef EEH_CHECK_ALIGN
 
-static inline u8 eeh_inb(unsigned long port)
-{
-	u8 val;
-	val = in_8((u8 __iomem *)(port+pci_io_base));
-	if (EEH_POSSIBLE_ERROR(val, u8))
-		return eeh_check_failure((void __iomem *)(port), val);
-	return val;
-}
-
-static inline void eeh_outb(u8 val, unsigned long port)
-{
-	out_8((u8 __iomem *)(port+pci_io_base), val);
-}
-
-static inline u16 eeh_inw(unsigned long port)
-{
-	u16 val;
-	val = in_le16((u16 __iomem *)(port+pci_io_base));
-	if (EEH_POSSIBLE_ERROR(val, u16))
-		return eeh_check_failure((void __iomem *)(port), val);
-	return val;
-}
-
-static inline void eeh_outw(u16 val, unsigned long port)
-{
-	out_le16((u16 __iomem *)(port+pci_io_base), val);
-}
-
-static inline u32 eeh_inl(unsigned long port)
-{
-	u32 val;
-	val = in_le32((u32 __iomem *)(port+pci_io_base));
-	if (EEH_POSSIBLE_ERROR(val, u32))
-		return eeh_check_failure((void __iomem *)(port), val);
-	return val;
-}
-
-static inline void eeh_outl(u32 val, unsigned long port)
-{
-	out_le32((u32 __iomem *)(port+pci_io_base), val);
-}
-
 /* in-string eeh macros */
-static inline void eeh_insb(unsigned long port, void * buf, int ns)
+static inline void eeh_readsb(const volatile void __iomem *addr, void * buf,
+			      int ns)
 {
-	_insb((u8 __iomem *)(port+pci_io_base), buf, ns);
+	_insb(addr, buf, ns);
 	if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8))
-		eeh_check_failure((void __iomem *)(port), *(u8*)buf);
+		eeh_check_failure(addr, *(u8*)buf);
 }
 
-static inline void eeh_insw_ns(unsigned long port, void * buf, int ns)
+static inline void eeh_readsw(const volatile void __iomem *addr, void * buf,
+			      int ns)
 {
-	_insw_ns((u16 __iomem *)(port+pci_io_base), buf, ns);
+	_insw(addr, buf, ns);
 	if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16))
-		eeh_check_failure((void __iomem *)(port), *(u16*)buf);
+		eeh_check_failure(addr, *(u16*)buf);
 }
 
-static inline void eeh_insl_ns(unsigned long port, void * buf, int nl)
+static inline void eeh_readsl(const volatile void __iomem *addr, void * buf,
+			      int nl)
 {
-	_insl_ns((u32 __iomem *)(port+pci_io_base), buf, nl);
+	_insl(addr, buf, nl);
 	if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32))
-		eeh_check_failure((void __iomem *)(port), *(u32*)buf);
+		eeh_check_failure(addr, *(u32*)buf);
 }
 
 #endif /* __KERNEL__ */
Index: linux-cell/arch/powerpc/kernel/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/Makefile	2006-11-04 18:03:56.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/Makefile	2006-11-04 18:05:27.000000000 +1100
@@ -63,7 +63,7 @@
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
 
-pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o iomap.o
+pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o
 pci32-$(CONFIG_PPC32)		:= pci_32.o
 obj-$(CONFIG_PCI)		+= $(pci64-y) $(pci32-y)
 kexec-$(CONFIG_PPC64)		:= machine_kexec_64.o
@@ -72,6 +72,10 @@
 obj-$(CONFIG_AUDIT)		+= audit.o
 obj64-$(CONFIG_AUDIT)		+= compat_audit.o
 
+ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
+pci64-$(CONFIG_PPC64)		+= iomap.o
+endif
+
 ifeq ($(CONFIG_PPC_ISERIES),y)
 $(obj)/head_64.o: $(obj)/lparmap.s
 AFLAGS_head_64.o += -I$(obj)
Index: linux-cell/arch/powerpc/mm/pgtable_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/mm/pgtable_64.c	2006-11-04 17:47:01.000000000 +1100
+++ linux-cell/arch/powerpc/mm/pgtable_64.c	2006-11-04 18:24:49.000000000 +1100
@@ -129,22 +129,12 @@
 	return (void __iomem *) (ea + (addr & ~PAGE_MASK));
 }
 
-
-void __iomem *
-ioremap(unsigned long addr, unsigned long size)
-{
-	return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
-}
-
 void __iomem * __ioremap(unsigned long addr, unsigned long size,
 			 unsigned long flags)
 {
 	unsigned long pa, ea;
 	void __iomem *ret;
 
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		return (void __iomem *)addr;
-
 	/*
 	 * Choose an address to map it to.
 	 * Once the imalloc system is running, we use it.
@@ -178,6 +168,25 @@
 	return ret;
 }
 
+
+void __iomem * ioremap(unsigned long addr, unsigned long size)
+{
+	unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+	if (ppc_md.ioremap)
+		return ppc_md.ioremap(addr, size, flags);
+	return __ioremap(addr, size, flags);
+}
+
+void __iomem * ioremap_flags(unsigned long addr, unsigned long size,
+			     unsigned long flags)
+{
+	if (ppc_md.ioremap)
+		return ppc_md.ioremap(addr, size, flags);
+	return __ioremap(addr, size, flags);
+}
+
+
 #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
 
 int __ioremap_explicit(unsigned long pa, unsigned long ea,
@@ -235,13 +244,10 @@
  *
  * XXX	what about calls before mem_init_done (ie python_countermeasures())
  */
-void iounmap(volatile void __iomem *token)
+void __iounmap(void __iomem *token)
 {
 	void *addr;
 
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		return;
-
 	if (!mem_init_done)
 		return;
 	
@@ -250,6 +256,14 @@
 	im_free(addr);
 }
 
+void iounmap(void __iomem *token)
+{
+	if (ppc_md.iounmap)
+		ppc_md.iounmap(token);
+	else
+		__iounmap(token);
+}
+
 static int iounmap_subset_regions(unsigned long addr, unsigned long size)
 {
 	struct vm_struct *area;
@@ -268,7 +282,7 @@
 	return 0;
 }
 
-int iounmap_explicit(volatile void __iomem *start, unsigned long size)
+int __iounmap_explicit(void __iomem *start, unsigned long size)
 {
 	struct vm_struct *area;
 	unsigned long addr;
@@ -303,8 +317,10 @@
 }
 
 EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(ioremap_flags);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(__iounmap);
 
 void __iomem * reserve_phb_iospace(unsigned long size)
 {
Index: linux-cell/arch/powerpc/platforms/iseries/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/iseries/setup.c	2006-11-04 17:54:18.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/iseries/setup.c	2006-11-04 18:10:36.000000000 +1100
@@ -649,6 +649,16 @@
 void __init iSeries_init_IRQ(void) { }
 #endif
 
+static void __iomem *iseries_ioremap(unsigned long address, unsigned long size,
+				     unsigned long flags)
+{
+	return (void __iomem *)address;
+}
+
+static void iseries_iounmap(void __iomem *token)
+{
+}
+
 /*
  * iSeries has no legacy IO, anything calling this function has to
  * fail or bad things will happen
@@ -687,6 +697,8 @@
 	.progress	= iSeries_progress,
 	.probe		= iseries_probe,
 	.check_legacy_ioport	= iseries_check_legacy_ioport,
+	.ioremap	= iseries_ioremap,
+	.iounmap	= iseries_iounmap,
 	/* XXX Implement enable_pmcs for iSeries */
 };
 
Index: linux-cell/include/asm-powerpc/io-defs.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/io-defs.h	2006-11-05 14:24:30.000000000 +1100
@@ -0,0 +1,56 @@
+/* This file is meant to be include multiple times by other headers */
+
+DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr))
+DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr))
+
+DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port))
+DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port))
+DEF_PCI_AC_RET(inl, u32, (unsigned long port), (port))
+DEF_PCI_AC_NORET(outb, (u8 val, unsigned long port), (val, port))
+DEF_PCI_AC_NORET(outw, (u16 val, unsigned long port), (val, port))
+DEF_PCI_AC_NORET(outl, (u32 val, unsigned long port), (val, port))
+
+DEF_PCI_AC_NORET(readsb, (const PCI_IO_ADDR a, void *b, unsigned long c), \
+		 (a, b, c))
+DEF_PCI_AC_NORET(readsw, (const PCI_IO_ADDR a, void *b, unsigned long c), \
+		 (a, b, c))
+DEF_PCI_AC_NORET(readsl, (const PCI_IO_ADDR a, void *b, unsigned long c), \
+		 (a, b, c))
+DEF_PCI_AC_NORET(writesb, (PCI_IO_ADDR a, const void *b, unsigned long c), \
+		 (a, b, c))
+DEF_PCI_AC_NORET(writesw, (PCI_IO_ADDR a, const void *b, unsigned long c), \
+		 (a, b, c))
+DEF_PCI_AC_NORET(writesl, (PCI_IO_ADDR a, const void *b, unsigned long c), \
+		 (a, b, c))
+
+DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c), \
+		 (p, b, c))
+DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c), \
+		 (p, b, c))
+DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c), \
+		 (p, b, c))
+DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c), \
+		 (p, b, c))
+DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c), \
+		 (p, b, c))
+DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c), \
+		 (p, b, c))
+
+DEF_PCI_AC_NORET(memset_io, (PCI_IO_ADDR a, int c, unsigned long n),	   \
+		 (a, c, n))
+DEF_PCI_AC_NORET(memcpy_fromio,(void *d,const PCI_IO_ADDR s,unsigned long n), \
+		 (d, s, n))
+DEF_PCI_AC_NORET(memcpy_toio,(PCI_IO_ADDR d,const void *s,unsigned long n),   \
+		 (d, s, n))
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h	2006-11-04 17:43:47.000000000 +1100
+++ linux-cell/include/asm-powerpc/machdep.h	2006-11-04 17:57:24.000000000 +1100
@@ -87,6 +87,10 @@
 	void		(*tce_flush)(struct iommu_table *tbl);
 	void		(*pci_dma_dev_setup)(struct pci_dev *dev);
 	void		(*pci_dma_bus_setup)(struct pci_bus *bus);
+
+	void __iomem *	(*ioremap)(unsigned long addr, unsigned long size,
+				   unsigned long flags);
+	void		(*iounmap)(void __iomem *token);
 #endif /* CONFIG_PPC64 */
 
 	int		(*probe)(void);
Index: linux-cell/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_64.c	2006-11-04 18:25:17.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/pci_64.c	2006-11-04 18:25:19.000000000 +1100
@@ -1172,7 +1172,7 @@
 	
 	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
 		return 1;
-	if (iounmap_explicit((void __iomem *) start_virt, size))
+	if (__iounmap_explicit((void __iomem *) start_virt, size))
 		return 1;
 
 	return 0;
Index: linux-cell/arch/powerpc/kernel/io.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/io.c	2006-11-05 13:38:08.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/io.c	2006-11-05 13:55:50.000000000 +1100
@@ -25,13 +25,11 @@
 #include <asm/firmware.h>
 #include <asm/bug.h>
 
-void _insb(volatile u8 __iomem *port, void *buf, long count)
+void _insb(const volatile u8 __iomem *port, void *buf, long count)
 {
 	u8 *tbuf = buf;
 	u8 tmp;
 
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
 	if (unlikely(count <= 0))
 		return;
 	asm volatile("sync");
@@ -48,8 +46,6 @@
 {
 	const u8 *tbuf = buf;
 
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
 	if (unlikely(count <= 0))
 		return;
 	asm volatile("sync");
@@ -60,13 +56,11 @@
 }
 EXPORT_SYMBOL(_outsb);
 
-void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
+void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
 {
 	u16 *tbuf = buf;
 	u16 tmp;
 
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
 	if (unlikely(count <= 0))
 		return;
 	asm volatile("sync");
@@ -83,8 +77,6 @@
 {
 	const u16 *tbuf = buf;
 
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
 	if (unlikely(count <= 0))
 		return;
 	asm volatile("sync");
@@ -95,13 +87,11 @@
 }
 EXPORT_SYMBOL(_outsw_ns);
 
-void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
+void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
 {
 	u32 *tbuf = buf;
 	u32 tmp;
 
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
 	if (unlikely(count <= 0))
 		return;
 	asm volatile("sync");
@@ -118,8 +108,6 @@
 {
 	const u32 *tbuf = buf;
 
-	BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
-
 	if (unlikely(count <= 0))
 		return;
 	asm volatile("sync");

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Nicolas DET @ 2006-11-05 10:17 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, Sylvain Munaut, sl, linuxppc-embedded
In-Reply-To: <1162683341.28571.82.camel@localhost.localdomain>

On Sun, 05 Nov 2006 10:35:40 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Thu, 2006-11-02 at 21:47 +0100, Nicolas DET wrote:
> 
> > + *
> > + * Programmable Interrupt Controller functions for the Freescale MPC52xx.
> > + *
> > + * Based on (well, mostly copied from) the code from the 2.4 kernel by
> > + * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
> > + * 
> > + * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
> > + * Copyright (C) 2003 Montavista Software, Inc
> 
> You did significant changes, you should add your (c) before the "Based
> on..." line.

Ok. It now looks likes this:

+/*
+ *
+ * Programmable Interrupt Controller functions for the Freescale MPC52xx.
+ *
+ * Copyright (C) 2006 bplan GmbH
+ *
+ * Based on (well, mostly copied from) the code from the 2.4 kernel by
+ * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
+ * 
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Montavista Software, Inc
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */


> 
> > +	switch (l1irq) {
> > +	case MPC52xx_IRQ_L1_CRIT:
> > +		pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
> > +
> > +		BUG_ON(l2irq != 0);
> > +
> > +		type = mpc52xx_irqx_gettype(l2irq);
> > +		good_irqchip = &mpc52xx_extirq_irqchip;
> > +		break;
> > +
> > +	case MPC52xx_IRQ_L1_MAIN:
> > +		pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
> > +
> > +		if ((l2irq >= 1) && (l2irq <= 3)) {
> > +			type = mpc52xx_irqx_gettype(l2irq);
> > +			good_irqchip = &mpc52xx_extirq_irqchip;
> > +		} else {
> > +			good_irqchip = &mpc52xx_main_irqchip;
> > +		}
> > +		break;
> 
> You have changed the mapping of L1/L2 but not the device-tree
> representation to match them. Which means that you need the ugly hack
> above. That is not goot. Fix your device-tree instead and do the same
> split in the tree for L1/L2 than you do in the code.

There is no option here.

> > +	picnode = find_mpc52xx_picnode();
> > +	sdmanode = find_mpc52xx_sdmanode();
> 
> Any reason why you have those inline 1-line functions and just not put
> the actual of_find_* call in here ?
> 
> You probably also need some of_node_put() in the error case. You are
> doing a whole bunch of "return" that bypass them.

I have done it because other platform may add their how type/compatible/way to find the node. For example, I did not find any bestcomm node in the recent lite5200 device-tree.

http://ozlabs.org/pipermail/linuxppc-embedded/2006-November/024970.html

> The rest looks ok.
> 

;-)

> Please submit the io.h patch separately. Also, you may need to fix the
> default case (which is the one we are using) in there to work with
> CONFIG_PCI not set (by defining PCI_DRAM_BASE to 0 among others).
>

Sylvain was faster than me. :-)

Regards

^ permalink raw reply

* Re: Has anyone 2.6 kernel with Xenomai and MPC5200 Lite running?
From: Matthias Fechner @ 2006-11-05 10:21 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20061105013258.9B7DC352638@atlas.denx.de>

Hello Wolfgang,

* Wolfgang Denk <wd@denx.de> [05-11-06 02:32]:
> Then just check out the 2.6.18 version of the tree.  This  is  a  git
> repo, so seeking to any version you like is a matter of seconds.

hm, I did it but was not successfully. What I did was:
git clone git://www.denx.de/git/linux-2.6-denx.git linux-2.6-denx
cd linux-2.6-denx
git checkout -b private2.6.18 v2.6.18

Now I had kernel 2.6.18 but without network :(

Is that wrong? Sry but git is completely new for me.

> You do not want this, if you're on a MPC5200. I repeat, this  is  not
> supported.

ok, that is clear but if the kernel boots fine on the board with
network and I am able to patch it with Xenomai I can live with it.


Best regards,
Matthias

-- 

"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the universe trying to
produce bigger and better idiots. So far, the universe is winning." --
Rich Cook

^ permalink raw reply

* Re: Has anyone 2.6 kernel with Xenomai and MPC5200 Lite running?
From: Matthias Fechner @ 2006-11-05 10:23 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <528646bc0611041832j327c8391i9d3401782529073d@mail.gmail.com>

Hello Grant,

* Grant Likely <grant.likely@secretlab.ca> [04-11-06 20:32]:
> Yup, there exists patches for all the functionality that you're
> looking for.  You can find them if you search the list, but I'll send
> you a link to a git tree with all those patches in it later tonight.

you maybe mean:
http://gitbits.246tNt.com/gitbits/linux-2.6-mpc52xx.git

I tried that repository but here I was not able to patch the tree with
Xenomai.
But if you have another link it would be a pleasure for me to receive
the link :)


Best regards,
Matthias

-- 

"Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the universe trying to
produce bigger and better idiots. So far, the universe is winning." --
Rich Cook

^ permalink raw reply

* Re: Has anyone 2.6 kernel with Xenomai and MPC5200 Lite running?
From: Sylvain Munaut @ 2006-11-05 10:34 UTC (permalink / raw)
  To: linuxppc-embedded, idefix
In-Reply-To: <20061105102328.GH79990@server.idefix.loc>

Matthias Fechner wrote:
> Hello Grant,
>
> * Grant Likely <grant.likely@secretlab.ca> [04-11-06 20:32]:
>   
>> Yup, there exists patches for all the functionality that you're
>> looking for.  You can find them if you search the list, but I'll send
>> you a link to a git tree with all those patches in it later tonight.
>>     
>
> you maybe mean:
> http://gitbits.246tNt.com/gitbits/linux-2.6-mpc52xx.git
>
> I tried that repository but here I was not able to patch the tree with
> Xenomai.
> But if you have another link it would be a pleasure for me to receive
> the link :)
>   
Take the patchs off that link (bestcomm branch), and apply them on a
fresh/recent
tree, that should work. (that is, clone a official tree, then pull from
the above link
and merge the two).

There is work in progress for the arch/powerpc port but it's not done yet.


    Sylvain

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Benjamin Herrenschmidt @ 2006-11-05 10:37 UTC (permalink / raw)
  To: Nicolas DET; +Cc: linuxppc-dev, Sylvain Munaut, sl, linuxppc-embedded
In-Reply-To: <20061105111753.3e41f6b7.nd@bplan-gmbh.de>


> > You have changed the mapping of L1/L2 but not the device-tree
> > representation to match them. Which means that you need the ugly hack
> > above. That is not goot. Fix your device-tree instead and do the same
> > split in the tree for L1/L2 than you do in the code.
> 
> There is no option here.

I don't agree. Your firmware can always be upgraded. There is no way you
will impose a broken format on everybody else. Unfortunately, being the
first implementation, that's just what you are doing...

At worst, you'll have to do a fixup pass in prom_init.c

> I have done it because other platform may add their how type/compatible/way to find the node.
> For example, I did not find any bestcomm node in the recent lite5200 device-tree.
> 
> http://ozlabs.org/pipermail/linuxppc-embedded/2006-November/024970.html

They should get there ultimately.

Ben.

^ permalink raw reply

* [Fwd: [Bug 7431] New: ohci1394 Oops after a rmmod/modprobe cycle]
From: Stefan Richter @ 2006-11-05 10:41 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gioele Barabucci

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

Hi list,
there was a bug report on ohci1394 which seems to be related to the
platform-specific code in the driver. Additional details were posted on
linux1394-user:
http://thread.gmane.org/gmane.linux.kernel.firewire.user/focus=2120
Subject: "strange interaction: ohci1394 and backlight on iBook"
Any ideas? Thanks,
-- 
Stefan Richter
-=====-=-==- =-== --=-=
http://arcgraph.de/sr/

[-- Attachment #2: [Bug 7431] New: ohci1394 Oops after a rmmod/modprobe cycle --]
[-- Type: message/rfc822, Size: 4665 bytes --]

From: bugme-daemon@bugzilla.kernel.org
To: stefan-r-bz@s5r6.in-berlin.de
Subject: [Bug 7431] New: ohci1394 Oops after a rmmod/modprobe cycle
Date: Sun, 29 Oct 2006 17:24:53 -0800
Message-ID: <200610300124.k9U1Orae030173@fire-2.osdl.org>

http://bugzilla.kernel.org/show_bug.cgi?id=7431

           Summary: ohci1394 Oops after a rmmod/modprobe cycle
    Kernel Version: 2.6.18 (gentoo-sources-2.6.18)
            Status: NEW
          Severity: normal
             Owner: drivers_ieee1394@kernel-bugs.osdl.org
         Submitter: dev@gioelebarabucci.com


Distribution: Gentoo
Hardware Environment: PPC iBook G3 (PowerBook4,3)
Problem Description:

When I 'rmmod ohci1394' and then 'modprobe ohci1394', I get a "Bus error" 
message from modprobe and my backlight is set to full brightness.
dmesg reveals that an oops occurred. Here is the dmesg output after 'modprobe 
ohci1394':

| Machine check in kernel mode.
| Caused by (from SRR1=49030): Transfer error ack signal
| Oops: Machine check, sig: 7 [#1]
|
| Modules linked in: ohci1394 ipv6 af_packet radeon drm snd_seq snd_seq_device 
snd_powermac ide_cd cdrom snd_aoa_i2sbus snd_pcm airport snd_timer 
snd_page_alloc snd orinoco soundcore hermes snd_aoa_soundbus sungem ieee1394 
ohci_hcd usbcore uninorth_agp sungem_phy agpgart evdev unix
| NIP: EA08D29C LR: EA091618 CTR: C002CCB0
| REGS: cd533c80 TRAP: 0200   Not tainted  (2.6.18-gentoo)
| MSR: 00049030 <EE,ME,IR,DR>  CR: 24004482  XER: 00000000
| TASK = cd947850[8127] 'modprobe' THREAD: cd532000
| GPR00: FFFFFFFF CD533D30 CD947850 CB2B9E68 EA08E094 CB2B9F44 CC1BD7FC 
00000000
| GPR08: 0000001F EA084000 000007C0 EA084000 84004488 1001F288 0000001D 
EA08B13C
| GPR16: E7454AE0 EA0886D4 00000124 00000000 C0045298 EA088148 EA088724 
EA090000
| GPR24: CB2B8000 CB2B9EE8 CB2B9FA0 CB2B9E8C CB2B9F44 C79BA000 CB2B9E68 
00000000
| NIP [EA08D29C] ohci_soft_reset+0x50/0x78 [ohci1394]
| LR [EA091618] ohci1394_pci_probe+0x2f4/0xb90 [ohci1394]
| Call Trace:
| [CD533D30] [C79BA000] 0xc79ba000 (unreliable)
| [CD533D40] [EA091618] ohci1394_pci_probe+0x2f4/0xb90 [ohci1394]
| [CD533DA0] [C00F755C] pci_device_probe+0x84/0xa4
| [CD533DC0] [C014EE88] driver_probe_device+0x60/0x118
| [CD533DE0] [C014F0C0] __driver_attach+0xcc/0xf8
| [CD533E00] [C014E764] bus_for_each_dev+0x58/0x94
| [CD533E30] [C014ED9C] driver_attach+0x24/0x34
| [CD533E40] [C014E2CC] bus_add_driver+0x88/0x164
| [CD533E60] [C014F36C] driver_register+0x70/0xb8
| [CD533E70] [C00F7378] __pci_register_driver+0x4c/0x8c
| [CD533E80] [E900D020] ohci1394_init+0x20/0x60 [ohci1394]
| [CD533E90] [C0046214] sys_init_module+0x170/0x1544
| [CD533F40] [C000F2FC] ret_from_syscall+0x0/0x38
| --- Exception: c01 at 0xff3caac
|    LR = 0x10002e84
| Instruction dump:
| 7c0004ac 7d20052c 3be00000 48000014 4800570d 2f9f0063 3bff0001 419e0028
| 813e0008 38090050 7c0004ac 7c00042c <0c000000> 4c00012c 74090001 386003e8

Steps to reproduce:
* rmmod ohci1394
* modprobe ohci1394

In addition, it is impossible now to remove the ohci1394 module:
| # rmmod ohci1394
| ERROR: Module ohci1394 is in use

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

^ permalink raw reply


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