xref: /openbmc/linux/arch/alpha/include/asm/io.h (revision 4bdc0d67)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2024b246eSLinus Torvalds #ifndef __ALPHA_IO_H
3024b246eSLinus Torvalds #define __ALPHA_IO_H
4024b246eSLinus Torvalds 
5024b246eSLinus Torvalds #ifdef __KERNEL__
6024b246eSLinus Torvalds 
7024b246eSLinus Torvalds #include <linux/kernel.h>
8024b246eSLinus Torvalds #include <linux/mm.h>
9024b246eSLinus Torvalds #include <asm/compiler.h>
10024b246eSLinus Torvalds #include <asm/pgtable.h>
11024b246eSLinus Torvalds #include <asm/machvec.h>
12024b246eSLinus Torvalds #include <asm/hwrpb.h>
13024b246eSLinus Torvalds 
14024b246eSLinus Torvalds /* The generic header contains only prototypes.  Including it ensures that
15024b246eSLinus Torvalds    the implementation we have here matches that interface.  */
16024b246eSLinus Torvalds #include <asm-generic/iomap.h>
17024b246eSLinus Torvalds 
18024b246eSLinus Torvalds /* We don't use IO slowdowns on the Alpha, but.. */
19024b246eSLinus Torvalds #define __SLOW_DOWN_IO	do { } while (0)
20024b246eSLinus Torvalds #define SLOW_DOWN_IO	do { } while (0)
21024b246eSLinus Torvalds 
22024b246eSLinus Torvalds /*
23024b246eSLinus Torvalds  * Virtual -> physical identity mapping starts at this offset
24024b246eSLinus Torvalds  */
25024b246eSLinus Torvalds #ifdef USE_48_BIT_KSEG
26024b246eSLinus Torvalds #define IDENT_ADDR     0xffff800000000000UL
27024b246eSLinus Torvalds #else
28024b246eSLinus Torvalds #define IDENT_ADDR     0xfffffc0000000000UL
29024b246eSLinus Torvalds #endif
30024b246eSLinus Torvalds 
31024b246eSLinus Torvalds /*
32024b246eSLinus Torvalds  * We try to avoid hae updates (thus the cache), but when we
33024b246eSLinus Torvalds  * do need to update the hae, we need to do it atomically, so
34024b246eSLinus Torvalds  * that any interrupts wouldn't get confused with the hae
35024b246eSLinus Torvalds  * register not being up-to-date with respect to the hardware
36024b246eSLinus Torvalds  * value.
37024b246eSLinus Torvalds  */
38024b246eSLinus Torvalds extern inline void __set_hae(unsigned long new_hae)
39024b246eSLinus Torvalds {
40e2609f6aSIvan Kokshaysky 	unsigned long flags = swpipl(IPL_MAX);
41e2609f6aSIvan Kokshaysky 
42e2609f6aSIvan Kokshaysky 	barrier();
43024b246eSLinus Torvalds 
44024b246eSLinus Torvalds 	alpha_mv.hae_cache = new_hae;
45024b246eSLinus Torvalds 	*alpha_mv.hae_register = new_hae;
46024b246eSLinus Torvalds 	mb();
47024b246eSLinus Torvalds 	/* Re-read to make sure it was written.  */
48024b246eSLinus Torvalds 	new_hae = *alpha_mv.hae_register;
49024b246eSLinus Torvalds 
50e2609f6aSIvan Kokshaysky 	setipl(flags);
51e2609f6aSIvan Kokshaysky 	barrier();
52024b246eSLinus Torvalds }
53024b246eSLinus Torvalds 
54024b246eSLinus Torvalds extern inline void set_hae(unsigned long new_hae)
55024b246eSLinus Torvalds {
56024b246eSLinus Torvalds 	if (new_hae != alpha_mv.hae_cache)
57024b246eSLinus Torvalds 		__set_hae(new_hae);
58024b246eSLinus Torvalds }
59024b246eSLinus Torvalds 
60024b246eSLinus Torvalds /*
61024b246eSLinus Torvalds  * Change virtual addresses to physical addresses and vv.
62024b246eSLinus Torvalds  */
63024b246eSLinus Torvalds #ifdef USE_48_BIT_KSEG
64024b246eSLinus Torvalds static inline unsigned long virt_to_phys(void *address)
65024b246eSLinus Torvalds {
66024b246eSLinus Torvalds 	return (unsigned long)address - IDENT_ADDR;
67024b246eSLinus Torvalds }
68024b246eSLinus Torvalds 
69024b246eSLinus Torvalds static inline void * phys_to_virt(unsigned long address)
70024b246eSLinus Torvalds {
71024b246eSLinus Torvalds 	return (void *) (address + IDENT_ADDR);
72024b246eSLinus Torvalds }
73024b246eSLinus Torvalds #else
74024b246eSLinus Torvalds static inline unsigned long virt_to_phys(void *address)
75024b246eSLinus Torvalds {
76024b246eSLinus Torvalds         unsigned long phys = (unsigned long)address;
77024b246eSLinus Torvalds 
78024b246eSLinus Torvalds 	/* Sign-extend from bit 41.  */
79024b246eSLinus Torvalds 	phys <<= (64 - 41);
80024b246eSLinus Torvalds 	phys = (long)phys >> (64 - 41);
81024b246eSLinus Torvalds 
82024b246eSLinus Torvalds 	/* Crop to the physical address width of the processor.  */
83024b246eSLinus Torvalds         phys &= (1ul << hwrpb->pa_bits) - 1;
84024b246eSLinus Torvalds 
85024b246eSLinus Torvalds         return phys;
86024b246eSLinus Torvalds }
87024b246eSLinus Torvalds 
88024b246eSLinus Torvalds static inline void * phys_to_virt(unsigned long address)
89024b246eSLinus Torvalds {
90024b246eSLinus Torvalds         return (void *)(IDENT_ADDR + (address & ((1ul << 41) - 1)));
91024b246eSLinus Torvalds }
92024b246eSLinus Torvalds #endif
93024b246eSLinus Torvalds 
94024b246eSLinus Torvalds #define page_to_phys(page)	page_to_pa(page)
95024b246eSLinus Torvalds 
96024b246eSLinus Torvalds /* Maximum PIO space address supported?  */
97024b246eSLinus Torvalds #define IO_SPACE_LIMIT 0xffff
98024b246eSLinus Torvalds 
99024b246eSLinus Torvalds /*
100024b246eSLinus Torvalds  * Change addresses as seen by the kernel (virtual) to addresses as
101024b246eSLinus Torvalds  * seen by a device (bus), and vice versa.
102024b246eSLinus Torvalds  *
103024b246eSLinus Torvalds  * Note that this only works for a limited range of kernel addresses,
104024b246eSLinus Torvalds  * and very well may not span all memory.  Consider this interface
105024b246eSLinus Torvalds  * deprecated in favour of the DMA-mapping API.
106024b246eSLinus Torvalds  */
107024b246eSLinus Torvalds extern unsigned long __direct_map_base;
108024b246eSLinus Torvalds extern unsigned long __direct_map_size;
109024b246eSLinus Torvalds 
110024b246eSLinus Torvalds static inline unsigned long __deprecated virt_to_bus(void *address)
111024b246eSLinus Torvalds {
112024b246eSLinus Torvalds 	unsigned long phys = virt_to_phys(address);
113024b246eSLinus Torvalds 	unsigned long bus = phys + __direct_map_base;
114024b246eSLinus Torvalds 	return phys <= __direct_map_size ? bus : 0;
115024b246eSLinus Torvalds }
116024b246eSLinus Torvalds #define isa_virt_to_bus virt_to_bus
117024b246eSLinus Torvalds 
118024b246eSLinus Torvalds static inline void * __deprecated bus_to_virt(unsigned long address)
119024b246eSLinus Torvalds {
120024b246eSLinus Torvalds 	void *virt;
121024b246eSLinus Torvalds 
122024b246eSLinus Torvalds 	/* This check is a sanity check but also ensures that bus address 0
123024b246eSLinus Torvalds 	   maps to virtual address 0 which is useful to detect null pointers
124024b246eSLinus Torvalds 	   (the NCR driver is much simpler if NULL pointers are preserved).  */
125024b246eSLinus Torvalds 	address -= __direct_map_base;
126024b246eSLinus Torvalds 	virt = phys_to_virt(address);
127024b246eSLinus Torvalds 	return (long)address <= 0 ? NULL : virt;
128024b246eSLinus Torvalds }
129024b246eSLinus Torvalds #define isa_bus_to_virt bus_to_virt
130024b246eSLinus Torvalds 
131024b246eSLinus Torvalds /*
132024b246eSLinus Torvalds  * There are different chipsets to interface the Alpha CPUs to the world.
133024b246eSLinus Torvalds  */
134024b246eSLinus Torvalds 
135024b246eSLinus Torvalds #define IO_CONCAT(a,b)	_IO_CONCAT(a,b)
136024b246eSLinus Torvalds #define _IO_CONCAT(a,b)	a ## _ ## b
137024b246eSLinus Torvalds 
138024b246eSLinus Torvalds #ifdef CONFIG_ALPHA_GENERIC
139024b246eSLinus Torvalds 
140024b246eSLinus Torvalds /* In a generic kernel, we always go through the machine vector.  */
141024b246eSLinus Torvalds 
142024b246eSLinus Torvalds #define REMAP1(TYPE, NAME, QUAL)					\
143024b246eSLinus Torvalds static inline TYPE generic_##NAME(QUAL void __iomem *addr)		\
144024b246eSLinus Torvalds {									\
145024b246eSLinus Torvalds 	return alpha_mv.mv_##NAME(addr);				\
146024b246eSLinus Torvalds }
147024b246eSLinus Torvalds 
148024b246eSLinus Torvalds #define REMAP2(TYPE, NAME, QUAL)					\
149024b246eSLinus Torvalds static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr)	\
150024b246eSLinus Torvalds {									\
151024b246eSLinus Torvalds 	alpha_mv.mv_##NAME(b, addr);					\
152024b246eSLinus Torvalds }
153024b246eSLinus Torvalds 
154024b246eSLinus Torvalds REMAP1(unsigned int, ioread8, /**/)
155024b246eSLinus Torvalds REMAP1(unsigned int, ioread16, /**/)
156024b246eSLinus Torvalds REMAP1(unsigned int, ioread32, /**/)
157024b246eSLinus Torvalds REMAP1(u8, readb, const volatile)
158024b246eSLinus Torvalds REMAP1(u16, readw, const volatile)
159024b246eSLinus Torvalds REMAP1(u32, readl, const volatile)
160024b246eSLinus Torvalds REMAP1(u64, readq, const volatile)
161024b246eSLinus Torvalds 
162024b246eSLinus Torvalds REMAP2(u8, iowrite8, /**/)
163024b246eSLinus Torvalds REMAP2(u16, iowrite16, /**/)
164024b246eSLinus Torvalds REMAP2(u32, iowrite32, /**/)
165024b246eSLinus Torvalds REMAP2(u8, writeb, volatile)
166024b246eSLinus Torvalds REMAP2(u16, writew, volatile)
167024b246eSLinus Torvalds REMAP2(u32, writel, volatile)
168024b246eSLinus Torvalds REMAP2(u64, writeq, volatile)
169024b246eSLinus Torvalds 
170024b246eSLinus Torvalds #undef REMAP1
171024b246eSLinus Torvalds #undef REMAP2
172024b246eSLinus Torvalds 
173024b246eSLinus Torvalds extern inline void __iomem *generic_ioportmap(unsigned long a)
174024b246eSLinus Torvalds {
175024b246eSLinus Torvalds 	return alpha_mv.mv_ioportmap(a);
176024b246eSLinus Torvalds }
177024b246eSLinus Torvalds 
178024b246eSLinus Torvalds static inline void __iomem *generic_ioremap(unsigned long a, unsigned long s)
179024b246eSLinus Torvalds {
180024b246eSLinus Torvalds 	return alpha_mv.mv_ioremap(a, s);
181024b246eSLinus Torvalds }
182024b246eSLinus Torvalds 
183024b246eSLinus Torvalds static inline void generic_iounmap(volatile void __iomem *a)
184024b246eSLinus Torvalds {
185024b246eSLinus Torvalds 	return alpha_mv.mv_iounmap(a);
186024b246eSLinus Torvalds }
187024b246eSLinus Torvalds 
188024b246eSLinus Torvalds static inline int generic_is_ioaddr(unsigned long a)
189024b246eSLinus Torvalds {
190024b246eSLinus Torvalds 	return alpha_mv.mv_is_ioaddr(a);
191024b246eSLinus Torvalds }
192024b246eSLinus Torvalds 
193024b246eSLinus Torvalds static inline int generic_is_mmio(const volatile void __iomem *a)
194024b246eSLinus Torvalds {
195024b246eSLinus Torvalds 	return alpha_mv.mv_is_mmio(a);
196024b246eSLinus Torvalds }
197024b246eSLinus Torvalds 
198024b246eSLinus Torvalds #define __IO_PREFIX		generic
199024b246eSLinus Torvalds #define generic_trivial_rw_bw	0
200024b246eSLinus Torvalds #define generic_trivial_rw_lq	0
201024b246eSLinus Torvalds #define generic_trivial_io_bw	0
202024b246eSLinus Torvalds #define generic_trivial_io_lq	0
203024b246eSLinus Torvalds #define generic_trivial_iounmap	0
204024b246eSLinus Torvalds 
205024b246eSLinus Torvalds #else
206024b246eSLinus Torvalds 
207024b246eSLinus Torvalds #if defined(CONFIG_ALPHA_APECS)
208024b246eSLinus Torvalds # include <asm/core_apecs.h>
209024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_CIA)
210024b246eSLinus Torvalds # include <asm/core_cia.h>
211024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_IRONGATE)
212024b246eSLinus Torvalds # include <asm/core_irongate.h>
213024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_JENSEN)
214024b246eSLinus Torvalds # include <asm/jensen.h>
215024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_LCA)
216024b246eSLinus Torvalds # include <asm/core_lca.h>
217024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_MARVEL)
218024b246eSLinus Torvalds # include <asm/core_marvel.h>
219024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_MCPCIA)
220024b246eSLinus Torvalds # include <asm/core_mcpcia.h>
221024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_POLARIS)
222024b246eSLinus Torvalds # include <asm/core_polaris.h>
223024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_T2)
224024b246eSLinus Torvalds # include <asm/core_t2.h>
225024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_TSUNAMI)
226024b246eSLinus Torvalds # include <asm/core_tsunami.h>
227024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_TITAN)
228024b246eSLinus Torvalds # include <asm/core_titan.h>
229024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_WILDFIRE)
230024b246eSLinus Torvalds # include <asm/core_wildfire.h>
231024b246eSLinus Torvalds #else
232024b246eSLinus Torvalds #error "What system is this?"
233024b246eSLinus Torvalds #endif
234024b246eSLinus Torvalds 
235024b246eSLinus Torvalds #endif /* GENERIC */
236024b246eSLinus Torvalds 
237024b246eSLinus Torvalds /*
238024b246eSLinus Torvalds  * We always have external versions of these routines.
239024b246eSLinus Torvalds  */
240024b246eSLinus Torvalds extern u8		inb(unsigned long port);
241024b246eSLinus Torvalds extern u16		inw(unsigned long port);
242024b246eSLinus Torvalds extern u32		inl(unsigned long port);
243024b246eSLinus Torvalds extern void		outb(u8 b, unsigned long port);
244024b246eSLinus Torvalds extern void		outw(u16 b, unsigned long port);
245024b246eSLinus Torvalds extern void		outl(u32 b, unsigned long port);
246024b246eSLinus Torvalds 
247024b246eSLinus Torvalds extern u8		readb(const volatile void __iomem *addr);
248024b246eSLinus Torvalds extern u16		readw(const volatile void __iomem *addr);
249024b246eSLinus Torvalds extern u32		readl(const volatile void __iomem *addr);
250024b246eSLinus Torvalds extern u64		readq(const volatile void __iomem *addr);
251024b246eSLinus Torvalds extern void		writeb(u8 b, volatile void __iomem *addr);
252024b246eSLinus Torvalds extern void		writew(u16 b, volatile void __iomem *addr);
253024b246eSLinus Torvalds extern void		writel(u32 b, volatile void __iomem *addr);
254024b246eSLinus Torvalds extern void		writeq(u64 b, volatile void __iomem *addr);
255024b246eSLinus Torvalds 
256024b246eSLinus Torvalds extern u8		__raw_readb(const volatile void __iomem *addr);
257024b246eSLinus Torvalds extern u16		__raw_readw(const volatile void __iomem *addr);
258024b246eSLinus Torvalds extern u32		__raw_readl(const volatile void __iomem *addr);
259024b246eSLinus Torvalds extern u64		__raw_readq(const volatile void __iomem *addr);
260024b246eSLinus Torvalds extern void		__raw_writeb(u8 b, volatile void __iomem *addr);
261024b246eSLinus Torvalds extern void		__raw_writew(u16 b, volatile void __iomem *addr);
262024b246eSLinus Torvalds extern void		__raw_writel(u32 b, volatile void __iomem *addr);
263024b246eSLinus Torvalds extern void		__raw_writeq(u64 b, volatile void __iomem *addr);
264024b246eSLinus Torvalds 
265024b246eSLinus Torvalds /*
266024b246eSLinus Torvalds  * Mapping from port numbers to __iomem space is pretty easy.
267024b246eSLinus Torvalds  */
268024b246eSLinus Torvalds 
269024b246eSLinus Torvalds /* These two have to be extern inline because of the extern prototype from
270024b246eSLinus Torvalds    <asm-generic/iomap.h>.  It is not legal to mix "extern" and "static" for
271024b246eSLinus Torvalds    the same declaration.  */
272024b246eSLinus Torvalds extern inline void __iomem *ioport_map(unsigned long port, unsigned int size)
273024b246eSLinus Torvalds {
274024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,ioportmap) (port);
275024b246eSLinus Torvalds }
276024b246eSLinus Torvalds 
277024b246eSLinus Torvalds extern inline void ioport_unmap(void __iomem *addr)
278024b246eSLinus Torvalds {
279024b246eSLinus Torvalds }
280024b246eSLinus Torvalds 
281024b246eSLinus Torvalds static inline void __iomem *ioremap(unsigned long port, unsigned long size)
282024b246eSLinus Torvalds {
283024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,ioremap) (port, size);
284024b246eSLinus Torvalds }
285024b246eSLinus Torvalds 
2864bdc0d67SChristoph Hellwig #define ioremap_wc ioremap
2874bdc0d67SChristoph Hellwig #define ioremap_uc ioremap
288024b246eSLinus Torvalds 
289024b246eSLinus Torvalds static inline void iounmap(volatile void __iomem *addr)
290024b246eSLinus Torvalds {
291024b246eSLinus Torvalds 	IO_CONCAT(__IO_PREFIX,iounmap)(addr);
292024b246eSLinus Torvalds }
293024b246eSLinus Torvalds 
294024b246eSLinus Torvalds static inline int __is_ioaddr(unsigned long addr)
295024b246eSLinus Torvalds {
296024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,is_ioaddr)(addr);
297024b246eSLinus Torvalds }
298024b246eSLinus Torvalds #define __is_ioaddr(a)		__is_ioaddr((unsigned long)(a))
299024b246eSLinus Torvalds 
300024b246eSLinus Torvalds static inline int __is_mmio(const volatile void __iomem *addr)
301024b246eSLinus Torvalds {
302024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,is_mmio)(addr);
303024b246eSLinus Torvalds }
304024b246eSLinus Torvalds 
305024b246eSLinus Torvalds 
306024b246eSLinus Torvalds /*
307024b246eSLinus Torvalds  * If the actual I/O bits are sufficiently trivial, then expand inline.
308024b246eSLinus Torvalds  */
309024b246eSLinus Torvalds 
310024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
311024b246eSLinus Torvalds extern inline unsigned int ioread8(void __iomem *addr)
312024b246eSLinus Torvalds {
313024b246eSLinus Torvalds 	unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr);
314024b246eSLinus Torvalds 	mb();
315024b246eSLinus Torvalds 	return ret;
316024b246eSLinus Torvalds }
317024b246eSLinus Torvalds 
318024b246eSLinus Torvalds extern inline unsigned int ioread16(void __iomem *addr)
319024b246eSLinus Torvalds {
320024b246eSLinus Torvalds 	unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr);
321024b246eSLinus Torvalds 	mb();
322024b246eSLinus Torvalds 	return ret;
323024b246eSLinus Torvalds }
324024b246eSLinus Torvalds 
325024b246eSLinus Torvalds extern inline void iowrite8(u8 b, void __iomem *addr)
326024b246eSLinus Torvalds {
327024b246eSLinus Torvalds 	mb();
328cd0e00c1SSinan Kaya 	IO_CONCAT(__IO_PREFIX, iowrite8)(b, addr);
329024b246eSLinus Torvalds }
330024b246eSLinus Torvalds 
331024b246eSLinus Torvalds extern inline void iowrite16(u16 b, void __iomem *addr)
332024b246eSLinus Torvalds {
333024b246eSLinus Torvalds 	mb();
334cd0e00c1SSinan Kaya 	IO_CONCAT(__IO_PREFIX, iowrite16)(b, addr);
335024b246eSLinus Torvalds }
336024b246eSLinus Torvalds 
337024b246eSLinus Torvalds extern inline u8 inb(unsigned long port)
338024b246eSLinus Torvalds {
339024b246eSLinus Torvalds 	return ioread8(ioport_map(port, 1));
340024b246eSLinus Torvalds }
341024b246eSLinus Torvalds 
342024b246eSLinus Torvalds extern inline u16 inw(unsigned long port)
343024b246eSLinus Torvalds {
344024b246eSLinus Torvalds 	return ioread16(ioport_map(port, 2));
345024b246eSLinus Torvalds }
346024b246eSLinus Torvalds 
347024b246eSLinus Torvalds extern inline void outb(u8 b, unsigned long port)
348024b246eSLinus Torvalds {
349024b246eSLinus Torvalds 	iowrite8(b, ioport_map(port, 1));
350024b246eSLinus Torvalds }
351024b246eSLinus Torvalds 
352024b246eSLinus Torvalds extern inline void outw(u16 b, unsigned long port)
353024b246eSLinus Torvalds {
354024b246eSLinus Torvalds 	iowrite16(b, ioport_map(port, 2));
355024b246eSLinus Torvalds }
356024b246eSLinus Torvalds #endif
357024b246eSLinus Torvalds 
358024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
359024b246eSLinus Torvalds extern inline unsigned int ioread32(void __iomem *addr)
360024b246eSLinus Torvalds {
361024b246eSLinus Torvalds 	unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr);
362024b246eSLinus Torvalds 	mb();
363024b246eSLinus Torvalds 	return ret;
364024b246eSLinus Torvalds }
365024b246eSLinus Torvalds 
366024b246eSLinus Torvalds extern inline void iowrite32(u32 b, void __iomem *addr)
367024b246eSLinus Torvalds {
368024b246eSLinus Torvalds 	mb();
369cd0e00c1SSinan Kaya 	IO_CONCAT(__IO_PREFIX, iowrite32)(b, addr);
370024b246eSLinus Torvalds }
371024b246eSLinus Torvalds 
372024b246eSLinus Torvalds extern inline u32 inl(unsigned long port)
373024b246eSLinus Torvalds {
374024b246eSLinus Torvalds 	return ioread32(ioport_map(port, 4));
375024b246eSLinus Torvalds }
376024b246eSLinus Torvalds 
377024b246eSLinus Torvalds extern inline void outl(u32 b, unsigned long port)
378024b246eSLinus Torvalds {
379024b246eSLinus Torvalds 	iowrite32(b, ioport_map(port, 4));
380024b246eSLinus Torvalds }
381024b246eSLinus Torvalds #endif
382024b246eSLinus Torvalds 
383024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1
384024b246eSLinus Torvalds extern inline u8 __raw_readb(const volatile void __iomem *addr)
385024b246eSLinus Torvalds {
386024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,readb)(addr);
387024b246eSLinus Torvalds }
388024b246eSLinus Torvalds 
389024b246eSLinus Torvalds extern inline u16 __raw_readw(const volatile void __iomem *addr)
390024b246eSLinus Torvalds {
391024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,readw)(addr);
392024b246eSLinus Torvalds }
393024b246eSLinus Torvalds 
394024b246eSLinus Torvalds extern inline void __raw_writeb(u8 b, volatile void __iomem *addr)
395024b246eSLinus Torvalds {
396024b246eSLinus Torvalds 	IO_CONCAT(__IO_PREFIX,writeb)(b, addr);
397024b246eSLinus Torvalds }
398024b246eSLinus Torvalds 
399024b246eSLinus Torvalds extern inline void __raw_writew(u16 b, volatile void __iomem *addr)
400024b246eSLinus Torvalds {
401024b246eSLinus Torvalds 	IO_CONCAT(__IO_PREFIX,writew)(b, addr);
402024b246eSLinus Torvalds }
403024b246eSLinus Torvalds 
404024b246eSLinus Torvalds extern inline u8 readb(const volatile void __iomem *addr)
405024b246eSLinus Torvalds {
406024b246eSLinus Torvalds 	u8 ret = __raw_readb(addr);
407024b246eSLinus Torvalds 	mb();
408024b246eSLinus Torvalds 	return ret;
409024b246eSLinus Torvalds }
410024b246eSLinus Torvalds 
411024b246eSLinus Torvalds extern inline u16 readw(const volatile void __iomem *addr)
412024b246eSLinus Torvalds {
413024b246eSLinus Torvalds 	u16 ret = __raw_readw(addr);
414024b246eSLinus Torvalds 	mb();
415024b246eSLinus Torvalds 	return ret;
416024b246eSLinus Torvalds }
417024b246eSLinus Torvalds 
418024b246eSLinus Torvalds extern inline void writeb(u8 b, volatile void __iomem *addr)
419024b246eSLinus Torvalds {
420024b246eSLinus Torvalds 	mb();
421cd0e00c1SSinan Kaya 	__raw_writeb(b, addr);
422024b246eSLinus Torvalds }
423024b246eSLinus Torvalds 
424024b246eSLinus Torvalds extern inline void writew(u16 b, volatile void __iomem *addr)
425024b246eSLinus Torvalds {
426024b246eSLinus Torvalds 	mb();
427cd0e00c1SSinan Kaya 	__raw_writew(b, addr);
428024b246eSLinus Torvalds }
429024b246eSLinus Torvalds #endif
430024b246eSLinus Torvalds 
431024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_rw_lq) == 1
432024b246eSLinus Torvalds extern inline u32 __raw_readl(const volatile void __iomem *addr)
433024b246eSLinus Torvalds {
434024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,readl)(addr);
435024b246eSLinus Torvalds }
436024b246eSLinus Torvalds 
437024b246eSLinus Torvalds extern inline u64 __raw_readq(const volatile void __iomem *addr)
438024b246eSLinus Torvalds {
439024b246eSLinus Torvalds 	return IO_CONCAT(__IO_PREFIX,readq)(addr);
440024b246eSLinus Torvalds }
441024b246eSLinus Torvalds 
442024b246eSLinus Torvalds extern inline void __raw_writel(u32 b, volatile void __iomem *addr)
443024b246eSLinus Torvalds {
444024b246eSLinus Torvalds 	IO_CONCAT(__IO_PREFIX,writel)(b, addr);
445024b246eSLinus Torvalds }
446024b246eSLinus Torvalds 
447024b246eSLinus Torvalds extern inline void __raw_writeq(u64 b, volatile void __iomem *addr)
448024b246eSLinus Torvalds {
449024b246eSLinus Torvalds 	IO_CONCAT(__IO_PREFIX,writeq)(b, addr);
450024b246eSLinus Torvalds }
451024b246eSLinus Torvalds 
452024b246eSLinus Torvalds extern inline u32 readl(const volatile void __iomem *addr)
453024b246eSLinus Torvalds {
454024b246eSLinus Torvalds 	u32 ret = __raw_readl(addr);
455024b246eSLinus Torvalds 	mb();
456024b246eSLinus Torvalds 	return ret;
457024b246eSLinus Torvalds }
458024b246eSLinus Torvalds 
459024b246eSLinus Torvalds extern inline u64 readq(const volatile void __iomem *addr)
460024b246eSLinus Torvalds {
461024b246eSLinus Torvalds 	u64 ret = __raw_readq(addr);
462024b246eSLinus Torvalds 	mb();
463024b246eSLinus Torvalds 	return ret;
464024b246eSLinus Torvalds }
465024b246eSLinus Torvalds 
466024b246eSLinus Torvalds extern inline void writel(u32 b, volatile void __iomem *addr)
467024b246eSLinus Torvalds {
468024b246eSLinus Torvalds 	mb();
469cd0e00c1SSinan Kaya 	__raw_writel(b, addr);
470024b246eSLinus Torvalds }
471024b246eSLinus Torvalds 
472024b246eSLinus Torvalds extern inline void writeq(u64 b, volatile void __iomem *addr)
473024b246eSLinus Torvalds {
474024b246eSLinus Torvalds 	mb();
475cd0e00c1SSinan Kaya 	__raw_writeq(b, addr);
476024b246eSLinus Torvalds }
477024b246eSLinus Torvalds #endif
478024b246eSLinus Torvalds 
47925534eb7SMichael Cree #define ioread16be(p) be16_to_cpu(ioread16(p))
48025534eb7SMichael Cree #define ioread32be(p) be32_to_cpu(ioread32(p))
48125534eb7SMichael Cree #define iowrite16be(v,p) iowrite16(cpu_to_be16(v), (p))
48225534eb7SMichael Cree #define iowrite32be(v,p) iowrite32(cpu_to_be32(v), (p))
48325534eb7SMichael Cree 
484024b246eSLinus Torvalds #define inb_p		inb
485024b246eSLinus Torvalds #define inw_p		inw
486024b246eSLinus Torvalds #define inl_p		inl
487024b246eSLinus Torvalds #define outb_p		outb
488024b246eSLinus Torvalds #define outw_p		outw
489024b246eSLinus Torvalds #define outl_p		outl
490024b246eSLinus Torvalds #define readb_relaxed(addr)	__raw_readb(addr)
491024b246eSLinus Torvalds #define readw_relaxed(addr)	__raw_readw(addr)
492024b246eSLinus Torvalds #define readl_relaxed(addr)	__raw_readl(addr)
493024b246eSLinus Torvalds #define readq_relaxed(addr)	__raw_readq(addr)
4949e36c633SWill Deacon #define writeb_relaxed(b, addr)	__raw_writeb(b, addr)
4959e36c633SWill Deacon #define writew_relaxed(b, addr)	__raw_writew(b, addr)
4969e36c633SWill Deacon #define writel_relaxed(b, addr)	__raw_writel(b, addr)
4979e36c633SWill Deacon #define writeq_relaxed(b, addr)	__raw_writeq(b, addr)
498024b246eSLinus Torvalds 
499024b246eSLinus Torvalds /*
500024b246eSLinus Torvalds  * String version of IO memory access ops:
501024b246eSLinus Torvalds  */
502024b246eSLinus Torvalds extern void memcpy_fromio(void *, const volatile void __iomem *, long);
503024b246eSLinus Torvalds extern void memcpy_toio(volatile void __iomem *, const void *, long);
504024b246eSLinus Torvalds extern void _memset_c_io(volatile void __iomem *, unsigned long, long);
505024b246eSLinus Torvalds 
506024b246eSLinus Torvalds static inline void memset_io(volatile void __iomem *addr, u8 c, long len)
507024b246eSLinus Torvalds {
508024b246eSLinus Torvalds 	_memset_c_io(addr, 0x0101010101010101UL * c, len);
509024b246eSLinus Torvalds }
510024b246eSLinus Torvalds 
511024b246eSLinus Torvalds #define __HAVE_ARCH_MEMSETW_IO
512024b246eSLinus Torvalds static inline void memsetw_io(volatile void __iomem *addr, u16 c, long len)
513024b246eSLinus Torvalds {
514024b246eSLinus Torvalds 	_memset_c_io(addr, 0x0001000100010001UL * c, len);
515024b246eSLinus Torvalds }
516024b246eSLinus Torvalds 
517024b246eSLinus Torvalds /*
518024b246eSLinus Torvalds  * String versions of in/out ops:
519024b246eSLinus Torvalds  */
520024b246eSLinus Torvalds extern void insb (unsigned long port, void *dst, unsigned long count);
521024b246eSLinus Torvalds extern void insw (unsigned long port, void *dst, unsigned long count);
522024b246eSLinus Torvalds extern void insl (unsigned long port, void *dst, unsigned long count);
523024b246eSLinus Torvalds extern void outsb (unsigned long port, const void *src, unsigned long count);
524024b246eSLinus Torvalds extern void outsw (unsigned long port, const void *src, unsigned long count);
525024b246eSLinus Torvalds extern void outsl (unsigned long port, const void *src, unsigned long count);
526024b246eSLinus Torvalds 
527024b246eSLinus Torvalds /*
528024b246eSLinus Torvalds  * The Alpha Jensen hardware for some rather strange reason puts
529024b246eSLinus Torvalds  * the RTC clock at 0x170 instead of 0x70. Probably due to some
530024b246eSLinus Torvalds  * misguided idea about using 0x70 for NMI stuff.
531024b246eSLinus Torvalds  *
532024b246eSLinus Torvalds  * These defines will override the defaults when doing RTC queries
533024b246eSLinus Torvalds  */
534024b246eSLinus Torvalds 
535024b246eSLinus Torvalds #ifdef CONFIG_ALPHA_GENERIC
536024b246eSLinus Torvalds # define RTC_PORT(x)	((x) + alpha_mv.rtc_port)
537024b246eSLinus Torvalds #else
538024b246eSLinus Torvalds # ifdef CONFIG_ALPHA_JENSEN
539024b246eSLinus Torvalds #  define RTC_PORT(x)	(0x170+(x))
540024b246eSLinus Torvalds # else
541024b246eSLinus Torvalds #  define RTC_PORT(x)	(0x70 + (x))
542024b246eSLinus Torvalds # endif
543024b246eSLinus Torvalds #endif
544024b246eSLinus Torvalds #define RTC_ALWAYS_BCD	0
545024b246eSLinus Torvalds 
546024b246eSLinus Torvalds /*
547024b246eSLinus Torvalds  * Some mucking forons use if[n]def writeq to check if platform has it.
548024b246eSLinus Torvalds  * It's a bloody bad idea and we probably want ARCH_HAS_WRITEQ for them
549024b246eSLinus Torvalds  * to play with; for now just use cpp anti-recursion logics and make sure
550024b246eSLinus Torvalds  * that damn thing is defined and expands to itself.
551024b246eSLinus Torvalds  */
552024b246eSLinus Torvalds 
553024b246eSLinus Torvalds #define writeq writeq
554024b246eSLinus Torvalds #define readq readq
555024b246eSLinus Torvalds 
556024b246eSLinus Torvalds /*
557024b246eSLinus Torvalds  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
558024b246eSLinus Torvalds  * access
559024b246eSLinus Torvalds  */
560024b246eSLinus Torvalds #define xlate_dev_mem_ptr(p)	__va(p)
561024b246eSLinus Torvalds 
562024b246eSLinus Torvalds /*
563024b246eSLinus Torvalds  * Convert a virtual cached pointer to an uncached pointer
564024b246eSLinus Torvalds  */
565024b246eSLinus Torvalds #define xlate_dev_kmem_ptr(p)	p
566024b246eSLinus Torvalds 
567024b246eSLinus Torvalds #endif /* __KERNEL__ */
568024b246eSLinus Torvalds 
569024b246eSLinus Torvalds #endif /* __ALPHA_IO_H */
570