2 * linux/include/asm-arm/arch-ebsa285/io.h
4 * Copyright (C) 1997,1998 Russell King
7 * 06-Dec-1997 RMK Created.
9 #ifndef __ASM_ARM_ARCH_IO_H
10 #define __ASM_ARM_ARCH_IO_H
12 #include <asm/dec21285.h>
15 * This architecture does not require any delayed IO, and
16 * has the constant-optimised IO
21 * Dynamic IO functions - let the compiler
22 * optimize the expressions
24 #define DECLARE_DYN_OUT(fnsuffix,instr,typ) \
25 extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \
27 __asm__ __volatile__( \
28 "str%?" ##instr## " %0, [%1, %2] @ out"###fnsuffix \
30 : "r" (value), "r" (PCIO_BASE), typ (port)); \
33 #define DECLARE_DYN_IN(sz,fnsuffix,instr,typ) \
34 extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \
36 unsigned long value; \
37 __asm__ __volatile__( \
38 "ldr%?" ##instr## " %0, [%1, %2] @ in"###fnsuffix \
40 : "r" (PCIO_BASE), typ (port)); \
41 return (unsigned sz)value; \
44 extern __inline__
unsigned int __ioaddr (unsigned int port
) \
46 return (unsigned int)(PCIO_BASE
+ port
); \
49 #define DECLARE_IO(sz,fnsuffix,instr,typ) \
50 DECLARE_DYN_OUT(fnsuffix,instr,typ) \
51 DECLARE_DYN_IN(sz,fnsuffix,instr,typ)
53 DECLARE_IO(char,b
,"b","Jr")
54 DECLARE_IO(short,w
,"h","r")
55 DECLARE_IO(long,l
,"","Jr")
58 #undef DECLARE_DYN_OUT
62 * Constant address IO functions
64 * These have to be macros for the 'J' constraint to work -
65 * +/-4096 immediate operand.
67 #define __outbc(value,port) \
69 __asm__ __volatile__( \
70 "str%?b %0, [%1, %2] @ outbc" \
72 : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \
75 #define __inbc(port) \
77 unsigned char result; \
78 __asm__ __volatile__( \
79 "ldr%?b %0, [%1, %2] @ inbc" \
81 : "r" (PCIO_BASE), "Jr" (port)); \
85 #define __outwc(value,port) \
87 __asm__ __volatile__( \
88 "str%?h %0, [%1, %2] @ outwc" \
90 : "r" (value), "r" (PCIO_BASE), "r" (port)); \
93 #define __inwc(port) \
95 unsigned short result; \
96 __asm__ __volatile__( \
97 "ldr%?h %0, [%1, %2] @ inwc" \
99 : "r" (PCIO_BASE), "r" (port)); \
103 #define __outlc(value,port) \
105 __asm__ __volatile__( \
106 "str%? %0, [%1, %2] @ outlc" \
108 : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \
111 #define __inlc(port) \
113 unsigned long result; \
114 __asm__ __volatile__( \
115 "ldr%? %0, [%1, %2] @ inlc" \
117 : "r" (PCIO_BASE), "Jr" (port)); \
121 #define __ioaddrc(port) \
123 unsigned long addr; \
124 addr = PCIO_BASE + port; \
129 * Translated address IO functions
131 * IO address has already been translated to a virtual address
133 #define outb_t(v,p) \
134 (*(volatile unsigned char *)(p) = (v))
137 (*(volatile unsigned char *)(p))
139 #define outl_t(v,p) \
140 (*(volatile unsigned long *)(p) = (v))
143 (*(volatile unsigned long *)(p))
148 #define valid_ioaddr(iomem,size) ((iomem) < 0x80000000 && (iomem) + (size) <= 0x80000000)
149 #define io_to_phys(iomem) ((iomem) + DC21285_PCI_MEM)
152 * Fudge up IO addresses by this much. Once we're confident that nobody
153 * is using read*() and so on with addresses they didn't get from ioremap
156 #define IO_FUDGE_FACTOR 0xe0000000
158 extern inline void *ioremap(unsigned long iomem_addr
, unsigned long size
)
160 unsigned long phys_addr
;
162 if (!valid_ioaddr(iomem_addr
, size
))
165 phys_addr
= io_to_phys(iomem_addr
& PAGE_MASK
);
167 return (void *)((unsigned long)__ioremap(phys_addr
, size
, 0)
171 #define ioremap_nocache(iomem_addr,size) ioremap((iomem_addr),(size))
173 extern void iounmap(void *addr
);
176 * We'd probably be better off with these as macros rather than functions.
177 * Firstly that would be more efficient and secondly we could do with the
178 * ability to stop GCC whinging about type conversions. --philb
180 static inline void writeb(unsigned char b
, unsigned int addr
)
182 *(volatile unsigned char *)(IO_FUDGE_FACTOR
+ (addr
)) = b
;
185 static inline unsigned char readb(unsigned int addr
)
187 return *(volatile unsigned char *)(IO_FUDGE_FACTOR
+ (addr
));
190 static inline void writew(unsigned short b
, unsigned int addr
)
192 *(volatile unsigned short *)(IO_FUDGE_FACTOR
+ (addr
)) = b
;
195 static inline unsigned short readw(unsigned int addr
)
197 return *(volatile unsigned short *)(IO_FUDGE_FACTOR
+ (addr
));
200 static inline void writel(unsigned long b
, unsigned int addr
)
202 *(volatile unsigned long *)(IO_FUDGE_FACTOR
+ (addr
)) = b
;
205 static inline unsigned short readl(unsigned int addr
)
207 return *(volatile unsigned long *)(IO_FUDGE_FACTOR
+ (addr
));