X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-parisc%2Fio.h;h=c421ac18495ab697e5ed230472c87f4b59498bdd;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=714db8ebf31cebfe5da44675daddfc51d8705e34;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h index 714db8ebf..c421ac184 100644 --- a/include/asm-parisc/io.h +++ b/include/asm-parisc/io.h @@ -1,14 +1,6 @@ #ifndef _ASM_IO_H #define _ASM_IO_H -/* USE_HPPA_IOREMAP IS THE MAGIC FLAG TO ENABLE OR DISABLE REAL IOREMAP() FUNCTIONALITY */ -/* FOR 712 or 715 MACHINES THIS SHOULD BE ENABLED, - NEWER MACHINES STILL HAVE SOME ISSUES IN THE SCSI AND/OR NETWORK DRIVERS AND - BECAUSE OF THAT I WILL LEAVE IT DISABLED FOR NOW */ -/* WHEN THOSE ISSUES ARE SOLVED, USE_HPPA_IOREMAP WILL GO AWAY */ -#define USE_HPPA_IOREMAP 0 - - #include #include #include @@ -25,42 +17,43 @@ extern unsigned long parisc_vmerge_max_size; #define bus_to_virt phys_to_virt /* - * Change "struct page" to physical address. - */ -#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) - -/* Memory mapped IO */ - -extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); - -extern inline void * ioremap(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, 0); -} - -/* - * This one maps high address device memory and turns off caching for that area. - * it's useful if some control registers are in such an area and write combining - * or read caching is not desirable: + * Memory mapped I/O + * + * readX()/writeX() do byteswapping and take an ioremapped address + * __raw_readX()/__raw_writeX() don't byteswap and take an ioremapped address. + * gsc_*() don't byteswap and operate on physical addresses; + * eg dev->hpa or 0xfee00000. */ -extern inline void * ioremap_nocache(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */); -} -extern void iounmap(void *addr); +#ifdef CONFIG_DEBUG_IOREMAP +#ifdef CONFIG_64BIT +#define NYBBLE_SHIFT 60 +#else +#define NYBBLE_SHIFT 28 +#endif +extern void gsc_bad_addr(unsigned long addr); +extern void __raw_bad_addr(const volatile void __iomem *addr); +#define gsc_check_addr(addr) \ + if ((addr >> NYBBLE_SHIFT) != 0xf) { \ + gsc_bad_addr(addr); \ + addr |= 0xfUL << NYBBLE_SHIFT; \ + } +#define __raw_check_addr(addr) \ + if (((unsigned long)addr >> NYBBLE_SHIFT) != 0xe) \ + __raw_bad_addr(addr); \ + addr = (void *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT)); +#else +#define gsc_check_addr(addr) +#define __raw_check_addr(addr) +#endif -/* - * __raw_ variants have no defined meaning. on hppa, it means `i was - * too lazy to ioremap first'. kind of like isa_, except that there's - * no additional base address to add on. - */ -#define __raw_readb(a) ___raw_readb((unsigned long)(a)) -extern __inline__ unsigned char ___raw_readb(unsigned long addr) +static inline unsigned char gsc_readb(unsigned long addr) { long flags; unsigned char ret; + gsc_check_addr(addr); + __asm__ __volatile__( " rsm 2,%0\n" " ldbx 0(%2),%1\n" @@ -70,12 +63,13 @@ extern __inline__ unsigned char ___raw_readb(unsigned long addr) return ret; } -#define __raw_readw(a) ___raw_readw((unsigned long)(a)) -extern __inline__ unsigned short ___raw_readw(unsigned long addr) +static inline unsigned short gsc_readw(unsigned long addr) { long flags; unsigned short ret; + gsc_check_addr(addr); + __asm__ __volatile__( " rsm 2,%0\n" " ldhx 0(%2),%1\n" @@ -85,11 +79,12 @@ extern __inline__ unsigned short ___raw_readw(unsigned long addr) return ret; } -#define __raw_readl(a) ___raw_readl((unsigned long)(a)) -extern __inline__ unsigned int ___raw_readl(unsigned long addr) +static inline unsigned int gsc_readl(unsigned long addr) { u32 ret; + gsc_check_addr(addr); + __asm__ __volatile__( " ldwax 0(%1),%0\n" : "=r" (ret) : "r" (addr) ); @@ -97,26 +92,28 @@ extern __inline__ unsigned int ___raw_readl(unsigned long addr) return ret; } -#define __raw_readq(a) ___raw_readq((unsigned long)(a)) -extern __inline__ unsigned long long ___raw_readq(unsigned long addr) +static inline unsigned long long gsc_readq(unsigned long addr) { unsigned long long ret; + gsc_check_addr(addr); + #ifdef __LP64__ __asm__ __volatile__( " ldda 0(%1),%0\n" : "=r" (ret) : "r" (addr) ); #else /* two reads may have side effects.. */ - ret = ((u64) __raw_readl(addr)) << 32; - ret |= __raw_readl(addr+4); + ret = ((u64) gsc_readl(addr)) << 32; + ret |= gsc_readl(addr+4); #endif return ret; } -#define __raw_writeb(a,b) ___raw_writeb(a, (unsigned long)(b)) -extern __inline__ void ___raw_writeb(unsigned char val, unsigned long addr) +static inline void gsc_writeb(unsigned char val, unsigned long addr) { long flags; + gsc_check_addr(addr); + __asm__ __volatile__( " rsm 2,%0\n" " stbs %1,0(%2)\n" @@ -124,10 +121,11 @@ extern __inline__ void ___raw_writeb(unsigned char val, unsigned long addr) : "=&r" (flags) : "r" (val), "r" (addr) ); } -#define __raw_writew(a,b) ___raw_writew(a, (unsigned long)(b)) -extern __inline__ void ___raw_writew(unsigned short val, unsigned long addr) +static inline void gsc_writew(unsigned short val, unsigned long addr) { long flags; + gsc_check_addr(addr); + __asm__ __volatile__( " rsm 2,%0\n" " sths %1,0(%2)\n" @@ -135,86 +133,180 @@ extern __inline__ void ___raw_writew(unsigned short val, unsigned long addr) : "=&r" (flags) : "r" (val), "r" (addr) ); } -#define __raw_writel(a,b) ___raw_writel(a, (unsigned long)(b)) -extern __inline__ void ___raw_writel(unsigned int val, unsigned long addr) +static inline void gsc_writel(unsigned int val, unsigned long addr) { + gsc_check_addr(addr); + __asm__ __volatile__( " stwas %0,0(%1)\n" : : "r" (val), "r" (addr) ); } -#define __raw_writeq(a,b) ___raw_writeq(a, (unsigned long)(b)) -extern __inline__ void ___raw_writeq(unsigned long long val, unsigned long addr) +static inline void gsc_writeq(unsigned long long val, unsigned long addr) { + gsc_check_addr(addr); + #ifdef __LP64__ __asm__ __volatile__( " stda %0,0(%1)\n" : : "r" (val), "r" (addr) ); #else /* two writes may have side effects.. */ - __raw_writel(val >> 32, addr); - __raw_writel(val, addr+4); + gsc_writel(val >> 32, addr); + gsc_writel(val, addr+4); #endif } +/* + * The standard PCI ioremap interfaces + */ + +extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); + +extern inline void __iomem * ioremap(unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, 0); +} + +/* + * This one maps high address device memory and turns off caching for that area. + * it's useful if some control registers are in such an area and write combining + * or read caching is not desirable: + */ +extern inline void * ioremap_nocache(unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */); +} + +extern void iounmap(void __iomem *addr); + +/* + * USE_HPPA_IOREMAP is the magic flag to enable or disable real ioremap() + * functionality. It's currently disabled because it may not work on some + * machines. + */ +#define USE_HPPA_IOREMAP 0 + #if USE_HPPA_IOREMAP -#define readb(addr) (*(volatile unsigned char *) (addr)) -#define readw(addr) (*(volatile unsigned short *) (addr)) -#define readl(addr) (*(volatile unsigned int *) (addr)) -#define readq(addr) (*(volatile u64 *) (addr)) -#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b)) -#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b)) -#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b)) -#define writeq(b,addr) (*(volatile u64 *) (addr) = (b)) +static inline unsigned char __raw_readb(const volatile void __iomem *addr) +{ + return (*(volatile unsigned char __force *) (addr)); +} +static inline unsigned short __raw_readw(const volatile void __iomem *addr) +{ + return *(volatile unsigned short __force *) addr; +} +static inline unsigned int __raw_readl(const volatile void __iomem *addr) +{ + return *(volatile unsigned int __force *) addr; +} +static inline unsigned long long __raw_readq(const volatile void __iomem *addr) +{ + return *(volatile unsigned long long __force *) addr; +} + +static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr) +{ + *(volatile unsigned char __force *) addr = b; +} +static inline void __raw_writew(unsigned short b, volatile void __iomem *addr) +{ + *(volatile unsigned short __force *) addr = b; +} +static inline void __raw_writel(unsigned int b, volatile void __iomem *addr) +{ + *(volatile unsigned int __force *) addr = b; +} +static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr) +{ + *(volatile unsigned long long __force *) addr = b; +} #else /* !USE_HPPA_IOREMAP */ +static inline unsigned char __raw_readb(const volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + return gsc_readb((unsigned long) addr); +} +static inline unsigned short __raw_readw(const volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + return gsc_readw((unsigned long) addr); +} +static inline unsigned int __raw_readl(const volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + return gsc_readl((unsigned long) addr); +} +static inline unsigned long long __raw_readq(const volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + return gsc_readq((unsigned long) addr); +} + +static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + gsc_writeb(b, (unsigned long) addr); +} +static inline void __raw_writew(unsigned short b, volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + gsc_writew(b, (unsigned long) addr); +} +static inline void __raw_writel(unsigned int b, volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + gsc_writel(b, (unsigned long) addr); +} +static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr) +{ + __raw_check_addr(addr); + + gsc_writeq(b, (unsigned long) addr); +} +#endif /* !USE_HPPA_IOREMAP */ + #define readb(addr) __raw_readb(addr) #define readw(addr) le16_to_cpu(__raw_readw(addr)) #define readl(addr) le32_to_cpu(__raw_readl(addr)) #define readq(addr) le64_to_cpu(__raw_readq(addr)) -#define writeb(b,addr) __raw_writeb(b,addr) -#define writew(b,addr) __raw_writew(cpu_to_le16(b),addr) -#define writel(b,addr) __raw_writel(cpu_to_le32(b),addr) -#define writeq(b,addr) __raw_writeq(cpu_to_le64(b),addr) -#endif /* !USE_HPPA_IOREMAP */ +#define writeb(b, addr) __raw_writeb(b, addr) +#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr) +#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr) +#define writeq(b, addr) __raw_writeq(cpu_to_le64(b), addr) #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 __memcpy_fromio(unsigned long dest, unsigned long src, int count); -extern void __memcpy_toio(unsigned long dest, unsigned long src, int count); -extern void __memset_io(unsigned long dest, char fill, int count); +#define mmiowb() do { } while (0) -#define memcpy_fromio(a,b,c) __memcpy_fromio((unsigned long)(a), (unsigned long)(b), (c)) -#define memcpy_toio(a,b,c) __memcpy_toio((unsigned long)(a), (unsigned long)(b), (c)) -#define memset_io(a,b,c) __memset_io((unsigned long)(a), (b), (c)) +void memset_io(volatile void __iomem *addr, unsigned char val, int count); +void memcpy_fromio(void *dst, const volatile void __iomem *src, int count); +void memcpy_toio(volatile void __iomem *dst, const void *src, int count); /* Support old drivers which don't ioremap. * NB this interface is scheduled to disappear in 2.5 */ -#define EISA_BASE 0xfffffffffc000000UL -#define isa_readb(a) readb(EISA_BASE | (a)) -#define isa_readw(a) readw(EISA_BASE | (a)) -#define isa_readl(a) readl(EISA_BASE | (a)) -#define isa_writeb(b,a) writeb((b), EISA_BASE | (a)) -#define isa_writew(b,a) writew((b), EISA_BASE | (a)) -#define isa_writel(b,a) writel((b), EISA_BASE | (a)) -#define isa_memset_io(a,b,c) memset_io(EISA_BASE | (a), (b), (c)) -#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), EISA_BASE | (b), (c)) -#define isa_memcpy_toio(a,b,c) memcpy_toio(EISA_BASE | (a), (b), (c)) - -/* - * These functions support PA-RISC drivers which don't yet call ioremap(). - * They will disappear once the last of these drivers is gone. - */ -#define gsc_readb(x) __raw_readb(x) -#define gsc_readw(x) __raw_readw(x) -#define gsc_readl(x) __raw_readl(x) -#define gsc_writeb(x, y) __raw_writeb(x, y) -#define gsc_writew(x, y) __raw_writew(x, y) -#define gsc_writel(x, y) __raw_writel(x, y) +#define __isa_addr(x) (void __iomem *)(F_EXTEND(0xfc000000) | (x)) +#define isa_readb(a) readb(__isa_addr(a)) +#define isa_readw(a) readw(__isa_addr(a)) +#define isa_readl(a) readl(__isa_addr(a)) +#define isa_writeb(b,a) writeb((b), __isa_addr(a)) +#define isa_writew(b,a) writew((b), __isa_addr(a)) +#define isa_writel(b,a) writel((b), __isa_addr(a)) +#define isa_memset_io(a,b,c) memset_io(__isa_addr(a), (b), (c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a), __isa_addr(b), (c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__isa_addr(a), (b), (c)) /* @@ -309,4 +401,6 @@ extern void outsl (unsigned long port, const void *src, unsigned long count); * value for either 32 or 64 bit mode */ #define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL))) +#include + #endif