File: /usr/src/linux/include/asm-arm/arch-shark/io.h

1     /*
2      * linux/include/asm-arm/arch-shark/io.h
3      *
4      * by Alexander Schulz <aschulz@netwinder.org>
5      *
6      * derived from:
7      * linux/include/asm-arm/arch-ebsa110/io.h
8      * Copyright (C) 1997,1998 Russell King
9      */
10     
11     #ifndef __ASM_ARM_ARCH_IO_H
12     #define __ASM_ARM_ARCH_IO_H
13     
14     #define iomem_valid_addr(off,sz)	(1)
15     #define iomem_to_phys(off)		(off)
16     
17     #define IO_SPACE_LIMIT 0xffffffff
18     
19     /*
20      * We use two different types of addressing - PC style addresses, and ARM
21      * addresses.  PC style accesses the PC hardware with the normal PC IO
22      * addresses, eg 0x3f8 for serial#1.  ARM addresses are 0x80000000+
23      * and are translated to the start of IO.
24      */
25     #define __PORT_PCIO(x)	(!((x) & 0x80000000))
26     
27     /*
28      * Dynamic IO functions - let the compiler
29      * optimize the expressions
30      */
31     #define DECLARE_DYN_OUT(fnsuffix,instr)						\
32     static inline void __out##fnsuffix (unsigned int value, unsigned int port)	\
33     {										\
34     	unsigned long temp;							\
35     	__asm__ __volatile__(							\
36     	"tst	%2, #0x80000000\n\t"						\
37     	"mov	%0, %4\n\t"							\
38     	"addeq	%0, %0, %3\n\t"							\
39     	"str" instr "	%1, [%0, %2]	@ out" #fnsuffix			\
40     	: "=&r" (temp)								\
41     	: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)	\
42     	: "cc");								\
43     }
44     
45     #define DECLARE_DYN_IN(sz,fnsuffix,instr)					\
46     static inline unsigned sz __in##fnsuffix (unsigned int port)		\
47     {										\
48     	unsigned long temp, value;						\
49     	__asm__ __volatile__(							\
50     	"tst	%2, #0x80000000\n\t"						\
51     	"mov	%0, %4\n\t"							\
52     	"addeq	%0, %0, %3\n\t"							\
53     	"ldr" instr "	%1, [%0, %2]	@ in" #fnsuffix				\
54     	: "=&r" (temp), "=r" (value)						\
55     	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
56     	: "cc");								\
57     	return (unsigned sz)value;						\
58     }
59     
60     static inline unsigned int __ioaddr (unsigned int port)			
61     {										
62     	if (__PORT_PCIO(port))							
63     		return (unsigned int)(PCIO_BASE + (port));			
64     	else									
65     		return (unsigned int)(IO_BASE + (port));			
66     }
67     
68     #define DECLARE_IO(sz,fnsuffix,instr)	\
69     	DECLARE_DYN_OUT(fnsuffix,instr)	\
70     	DECLARE_DYN_IN(sz,fnsuffix,instr)
71     
72     DECLARE_IO(char,b,"b")
73     DECLARE_IO(short,w,"h")
74     DECLARE_IO(long,l,"")
75     
76     #undef DECLARE_IO
77     #undef DECLARE_DYN_OUT
78     #undef DECLARE_DYN_IN
79     
80     /*
81      * Constant address IO functions
82      *
83      * These have to be macros for the 'J' constraint to work -
84      * +/-4096 immediate operand.
85      */
86     #define __outbc(value,port)							\
87     ({										\
88     	if (__PORT_PCIO((port)))						\
89     		__asm__ __volatile__(						\
90     		"strb	%0, [%1, %2]		@ outbc"			\
91     		: : "r" (value), "r" (PCIO_BASE), "Jr" (port));		\
92     	else									\
93     		__asm__ __volatile__(						\
94     		"strb	%0, [%1, %2]		@ outbc"			\
95     		: : "r" (value), "r" (IO_BASE), "r" (port));		\
96     })
97     
98     #define __inbc(port)								\
99     ({										\
100     	unsigned char result;                                                   \
101     	if (__PORT_PCIO((port)))						\
102     		__asm__ __volatile__(						\
103     		"ldrb	%0, [%1, %2]		@ inbc"				\
104     		: "=r" (result) : "r" (PCIO_BASE), "Jr" (port));		\
105     	else									\
106     		__asm__ __volatile__(						\
107     		"ldrb	%0, [%1, %2]		@ inbc"				\
108     		: "=r" (result) : "r" (IO_BASE), "r" (port));		\
109     	result;									\
110     })
111     
112     #define __outwc(value,port)							\
113     ({										\
114     	unsigned long v = value;						\
115     	if (__PORT_PCIO((port)))						\
116     		__asm__ __volatile__(						\
117     		"strh	%0, [%1, %2]		@ outwc"			\
118     		: : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" (port));	\
119     	else									\
120     		__asm__ __volatile__(						\
121     		"strh	%0, [%1, %2]		@ outwc"			\
122     		: : "r" (v|v<<16), "r" (IO_BASE), "r" (port));		\
123     })
124     
125     #define __inwc(port)								\
126     ({										\
127     	unsigned short result;							\
128     	if (__PORT_PCIO((port)))						\
129     		__asm__ __volatile__(						\
130     		"ldrh	%0, [%1, %2]		@ inwc"				\
131     		: "=r" (result) : "r" (PCIO_BASE), "Jr" (port));		\
132     	else									\
133     		__asm__ __volatile__(						\
134     		"ldrh	%0, [%1, %2]		@ inwc"				\
135     		: "=r" (result) : "r" (IO_BASE), "r" (port));		\
136     	result & 0xffff;							\
137     })
138     
139     #define __outlc(value,port)								\
140     ({										\
141     	unsigned long v = value;						\
142     	if (__PORT_PCIO((port)))						\
143     		__asm__ __volatile__(						\
144     		"str	%0, [%1, %2]		@ outlc"			\
145     		: : "r" (v), "r" (PCIO_BASE), "Jr" (port));		\
146     	else									\
147     		__asm__ __volatile__(						\
148     		"str	%0, [%1, %2]		@ outlc"			\
149     		: : "r" (v), "r" (IO_BASE), "r" (port));			\
150     })
151     
152     #define __inlc(port)								\
153     ({										\
154     	unsigned long result;							\
155     	if (__PORT_PCIO((port)))						\
156     		__asm__ __volatile__(						\
157     		"ldr	%0, [%1, %2]		@ inlc"				\
158     		: "=r" (result) : "r" (PCIO_BASE), "Jr" (port));		\
159     	else									\
160     		__asm__ __volatile__(						\
161     		"ldr	%0, [%1, %2]		@ inlc"				\
162     		: "=r" (result) : "r" (IO_BASE), "r" (port));		\
163     	result;									\
164     })
165     
166     #define __ioaddrc(port)								\
167     ({										\
168     	unsigned long addr;							\
169     	if (__PORT_PCIO((port)))						\
170     		addr = PCIO_BASE + (port);				\
171     	else									\
172     		addr = IO_BASE + (port);					\
173     	addr;									\
174     })
175     
176     #define __mem_pci(addr) addr
177     
178     #define inb(p)	 	(__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
179     #define inw(p)	 	(__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
180     #define inl(p)	 	(__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
181     #define outb(v,p)	(__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
182     #define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
183     #define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
184     
185     #define __arch_getw(addr)	(*(volatile unsigned short *)(addr))
186     #define __arch_putw(b,addr)	(*(volatile unsigned short *)(addr) = (b))
187     
188     /*
189      * Translated address IO functions
190      *
191      * IO address has already been translated to a virtual address
192      */
193     #define outb_t(v,p)								\
194     	(*(volatile unsigned char *)(p) = (v))
195     
196     #define inb_t(p)								\
197     	(*(volatile unsigned char *)(p))
198     
199     #define outl_t(v,p)								\
200     	(*(volatile unsigned long *)(p) = (v))
201     
202     #define inl_t(p)								\
203     	(*(volatile unsigned long *)(p))
204     
205     #endif
206