
Hi Graeme,
[...]
+#ifdef CONFIG_X86 +#define uart_writeb(x,y) outb(x,(ulong)y) +#define uart_readb(y) inb((ulong)y) +#else +#define uart_writeb(x,y) writeb(x,y) +#define uart_readb(y) readb(y) +#endif
Why do you need a specific variant for X86 instead of implementing writeb and readb correctly in the first place?
For x86 readb and writeb provide volatile accessors to memory - These are used for memory-mapped devices (i.e. devices which are attached directly to the memory bus such as PCI devices etc). inb and outb provide access to I/O Ports. For example:
writeb(0x12, 0x00001000) will generate something like: movb $0x12, al movl $0x00001000, ebx movb al, ebx
outb(0x12, 0x00001000) will generate something like: movb $0x12, al movl $0x00001000, ebx outb al, ebx
Looking at include/asm/asm-ppc/io.h it seems to me that, for PPC, there is no differentiation between readb/writeb and inb/outb other than that the user may define an optional IOBASE for inb/outb which shifts where in memory inb/outb accesses, but they are still memory accesses. So, for PPC, if IOBASE is 0, the above two examples will compile to identical code.
(Having a look at the other arches, it appears that x86 is very unique in that inb/outb do not access memory)
Ok, I remember this icky in/out stuff from x86 now that you come to mention it.
So it seems we have to keep the distinction somehow. Looking at drivers/serial/8250.c to see what Linux does, we could start including something like the "port.iotype" layer from there, although I feel this is somewhat too heavy currently. So in the meantime, I'd suggest that we at least start using the Linux convention and turn all the register accesses into "serial_{in,out}" and define these for X86 and !X86 like you did.
This way should be somewhat clearer than defining a "writeb" not to be a writeb after all, which I find confusing.
What do you think?
Cheers Detlev