From: Haavard Skinnemoen This adds definitions of inb, outb and friends to include/asm-avr32/io.h I'm still not sure about the best way to emulate I/O port access on AVR32, but we should be able to override the __io() macro from platform-specific headers in the future when we know better what the requirements really are. Signed-off-by: Haavard Skinnemoen Signed-off-by: Andrew Morton --- include/asm-avr32/io.h | 88 ++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff -puN include/asm-avr32/io.h~avr32-add-i-o-port-access-primitives include/asm-avr32/io.h --- a/include/asm-avr32/io.h~avr32-add-i-o-port-access-primitives +++ a/include/asm-avr32/io.h @@ -5,6 +5,24 @@ #ifdef __KERNEL__ +#include + +/* virt_to_phys will only work when address is in P1 or P2 */ +static __inline__ unsigned long virt_to_phys(volatile void *address) +{ + return PHYSADDR(address); +} + +static __inline__ void * phys_to_virt(unsigned long address) +{ + return (void *)P1SEGADDR(address); +} + +#define cached_to_phys(addr) ((unsigned long)PHYSADDR(addr)) +#define uncached_to_phys(addr) ((unsigned long)PHYSADDR(addr)) +#define phys_to_cached(addr) ((void *)P1SEGADDR(addr)) +#define phys_to_uncached(addr) ((void *)P2SEGADDR(addr)) + /* * Generic IO read/write. These perform native-endian accesses. Note * that some architectures will want to re-define __raw_{read,write}w. @@ -17,17 +35,6 @@ extern void __raw_readsb(unsigned int ad extern void __raw_readsw(unsigned int addr, void *data, int wordlen); extern void __raw_readsl(unsigned int addr, void *data, int longlen); -#ifdef PCMCIA_HSMC_IO_HACK -#error Needs updating -/* The HMATRIX tries to byteswap the address for us, so we have to swap it back. */ -#define __raw_writeb(v,a) (*(volatile unsigned char *)((unsigned long)(a) ^ 3UL) = (v)) -#define __raw_writew(v,a) (*(volatile unsigned short *)((unsigned long)(a) ^ 2UL) = (v)) -#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v)) - -#define __raw_readb(a) (*(volatile unsigned char *)((unsigned long)(a) ^ 3UL)) -#define __raw_readw(a) (*(volatile unsigned short *)((unsigned long)(a) ^ 2UL)) -#define __raw_readl(a) (*(volatile unsigned int *)(a)) -#else static inline void writeb(unsigned char b, volatile void __iomem *addr) { *(volatile unsigned char __force *)addr = b; @@ -59,7 +66,6 @@ static inline unsigned int readl(const v #define __raw_readb readb #define __raw_readw readw #define __raw_readl readl -#endif #define writesb(p, d, l) __raw_writesb((unsigned int)p, d, l) #define writesw(p, d, l) __raw_writesw((unsigned int)p, d, l) @@ -109,18 +115,36 @@ extern void __readwrite_bug(const char * #define IO_SPACE_LIMIT 0xffffffff +/* Convert I/O port address to virtual address */ +#define __io(p) ((void __iomem *)phys_to_uncached(p)) + /* - * All I/O is memory mapped, so these macros don't make very much - * sense. They are needed for PCMCIA support, however, so we'll have - * to implement them somehow. For now, they will cause linker errors. - */ -extern void outb(unsigned char value, unsigned long port); -extern void outw(unsigned short value, unsigned long port); -extern void outl(unsigned long value, unsigned long port); - -extern unsigned char inb(unsigned long port); -extern unsigned short inw(unsigned long port); -extern unsigned long inl(unsigned long port); + * IO port access primitives + * ------------------------- + * + * The AVR32 doesn't have special IO access instructions; all IO is memory + * mapped. Note that these are defined to perform little endian accesses + * only. Their primary purpose is to access PCI and ISA peripherals. + * + * Note that for a big endian machine, this implies that the following + * big endian mode connectivity is in place. + * + * The machine specific io.h include defines __io to translate an "IO" + * address to a memory address. + * + * Note that we prevent GCC re-ordering or caching values in expressions + * by introducing sequence points into the in*() definitions. Note that + * __raw_* do not guarantee this behaviour. + * + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. + */ +#define outb(v, p) __raw_writeb(v, __io(p)) +#define outw(v, p) __raw_writew(cpu_to_le16(v), __io(p)) +#define outl(v, p) __raw_writel(cpu_to_le32(v), __io(p)) + +#define inb(p) __raw_readb(__io(p)) +#define inw(p) le16_to_cpu(__raw_readw(__io(p))) +#define inl(p) le32_to_cpu(__raw_readl(__io(p))) static inline void __outsb(unsigned long port, void *addr, unsigned int count) { @@ -197,24 +221,6 @@ extern void __iounmap(void __iomem *addr #define iounmap(addr) \ __iounmap(addr) -#include - -/* virt_to_phys will only work when address is in P1 or P2 */ -static __inline__ unsigned long virt_to_phys(volatile void *address) -{ - return PHYSADDR(address); -} - -static __inline__ void * phys_to_virt(unsigned long address) -{ - return (void *)P1SEGADDR(address); -} - -#define cached_to_phys(addr) ((unsigned long)PHYSADDR(addr)) -#define uncached_to_phys(addr) ((unsigned long)PHYSADDR(addr)) -#define phys_to_cached(addr) ((void *)P1SEGADDR(addr)) -#define phys_to_uncached(addr) ((void *)P2SEGADDR(addr)) - #define cached(addr) P1SEGADDR(addr) #define uncached(addr) P2SEGADDR(addr) _