blob: 33bbbae4ddc699ba84b5ae657594c35bfa61cb22 [file] [log] [blame]
Arnd Bergmann3f7e2122009-05-13 22:56:35 +00001/* Generic I/O port emulation, based on MN10300 code
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#ifndef __ASM_GENERIC_IO_H
12#define __ASM_GENERIC_IO_H
13
14#include <asm/page.h> /* I/O is all done through memory accesses */
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000015#include <linux/types.h>
16
17#ifdef CONFIG_GENERIC_IOMAP
18#include <asm-generic/iomap.h>
19#endif
20
Michael S. Tsirkin66eab4d2011-11-24 20:45:20 +020021#include <asm-generic/pci_iomap.h>
22
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040023#ifndef mmiowb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000024#define mmiowb() do {} while (0)
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040025#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000026
27/*****************************************************************************/
28/*
29 * readX/writeX() are used to access memory mapped devices. On some
30 * architectures the memory mapped IO stuff needs to be accessed
31 * differently. On the simple architectures, we just read/write the
32 * memory location directly.
33 */
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040034#ifndef __raw_readb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000035static inline u8 __raw_readb(const volatile void __iomem *addr)
36{
37 return *(const volatile u8 __force *) addr;
38}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040039#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000040
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040041#ifndef __raw_readw
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000042static inline u16 __raw_readw(const volatile void __iomem *addr)
43{
44 return *(const volatile u16 __force *) addr;
45}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040046#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000047
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040048#ifndef __raw_readl
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000049static inline u32 __raw_readl(const volatile void __iomem *addr)
50{
51 return *(const volatile u32 __force *) addr;
52}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040053#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000054
55#define readb __raw_readb
56#define readw(addr) __le16_to_cpu(__raw_readw(addr))
57#define readl(addr) __le32_to_cpu(__raw_readl(addr))
58
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040059#ifndef __raw_writeb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000060static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
61{
62 *(volatile u8 __force *) addr = b;
63}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040064#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000065
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040066#ifndef __raw_writew
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000067static inline void __raw_writew(u16 b, volatile void __iomem *addr)
68{
69 *(volatile u16 __force *) addr = b;
70}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040071#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000072
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040073#ifndef __raw_writel
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000074static inline void __raw_writel(u32 b, volatile void __iomem *addr)
75{
76 *(volatile u32 __force *) addr = b;
77}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040078#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000079
80#define writeb __raw_writeb
81#define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
82#define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)
83
84#ifdef CONFIG_64BIT
Jan Glaubercd248342012-11-29 12:50:30 +010085#ifndef __raw_readq
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000086static inline u64 __raw_readq(const volatile void __iomem *addr)
87{
88 return *(const volatile u64 __force *) addr;
89}
Jan Glaubercd248342012-11-29 12:50:30 +010090#endif
91
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000092#define readq(addr) __le64_to_cpu(__raw_readq(addr))
93
Jan Glaubercd248342012-11-29 12:50:30 +010094#ifndef __raw_writeq
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000095static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
96{
97 *(volatile u64 __force *) addr = b;
98}
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000099#endif
100
Jan Glaubercd248342012-11-29 12:50:30 +0100101#define writeq(b, addr) __raw_writeq(__cpu_to_le64(b), addr)
102#endif /* CONFIG_64BIT */
103
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800104#ifndef PCI_IOBASE
105#define PCI_IOBASE ((void __iomem *) 0)
106#endif
107
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000108/*****************************************************************************/
109/*
110 * traditional input/output functions
111 */
112
113static inline u8 inb(unsigned long addr)
114{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800115 return readb(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000116}
117
118static inline u16 inw(unsigned long addr)
119{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800120 return readw(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000121}
122
123static inline u32 inl(unsigned long addr)
124{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800125 return readl(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000126}
127
128static inline void outb(u8 b, unsigned long addr)
129{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800130 writeb(b, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000131}
132
133static inline void outw(u16 b, unsigned long addr)
134{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800135 writew(b, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000136}
137
138static inline void outl(u32 b, unsigned long addr)
139{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800140 writel(b, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000141}
142
143#define inb_p(addr) inb(addr)
144#define inw_p(addr) inw(addr)
145#define inl_p(addr) inl(addr)
146#define outb_p(x, addr) outb((x), (addr))
147#define outw_p(x, addr) outw((x), (addr))
148#define outl_p(x, addr) outl((x), (addr))
149
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400150#ifndef insb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000151static inline void insb(unsigned long addr, void *buffer, int count)
152{
153 if (count) {
154 u8 *buf = buffer;
155 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800156 u8 x = __raw_readb(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000157 *buf++ = x;
158 } while (--count);
159 }
160}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400161#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000162
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400163#ifndef insw
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000164static inline void insw(unsigned long addr, void *buffer, int count)
165{
166 if (count) {
167 u16 *buf = buffer;
168 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800169 u16 x = __raw_readw(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000170 *buf++ = x;
171 } while (--count);
172 }
173}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400174#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000175
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400176#ifndef insl
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000177static inline void insl(unsigned long addr, void *buffer, int count)
178{
179 if (count) {
180 u32 *buf = buffer;
181 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800182 u32 x = __raw_readl(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000183 *buf++ = x;
184 } while (--count);
185 }
186}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400187#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000188
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400189#ifndef outsb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000190static inline void outsb(unsigned long addr, const void *buffer, int count)
191{
192 if (count) {
193 const u8 *buf = buffer;
194 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800195 __raw_writeb(*buf++, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000196 } while (--count);
197 }
198}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400199#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000200
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400201#ifndef outsw
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000202static inline void outsw(unsigned long addr, const void *buffer, int count)
203{
204 if (count) {
205 const u16 *buf = buffer;
206 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800207 __raw_writew(*buf++, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000208 } while (--count);
209 }
210}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400211#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000212
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400213#ifndef outsl
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000214static inline void outsl(unsigned long addr, const void *buffer, int count)
215{
216 if (count) {
217 const u32 *buf = buffer;
218 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800219 __raw_writel(*buf++, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000220 } while (--count);
221 }
222}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400223#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000224
225#ifndef CONFIG_GENERIC_IOMAP
226#define ioread8(addr) readb(addr)
227#define ioread16(addr) readw(addr)
Mike Frysinger7387be32010-08-09 17:20:17 -0700228#define ioread16be(addr) be16_to_cpu(ioread16(addr))
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000229#define ioread32(addr) readl(addr)
Mike Frysinger7387be32010-08-09 17:20:17 -0700230#define ioread32be(addr) be32_to_cpu(ioread32(addr))
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000231
232#define iowrite8(v, addr) writeb((v), (addr))
233#define iowrite16(v, addr) writew((v), (addr))
Mike Frysinger7387be32010-08-09 17:20:17 -0700234#define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr))
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000235#define iowrite32(v, addr) writel((v), (addr))
Mike Frysinger7387be32010-08-09 17:20:17 -0700236#define iowrite32be(v, addr) iowrite32(be32_to_cpu(v), (addr))
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000237
238#define ioread8_rep(p, dst, count) \
239 insb((unsigned long) (p), (dst), (count))
240#define ioread16_rep(p, dst, count) \
241 insw((unsigned long) (p), (dst), (count))
242#define ioread32_rep(p, dst, count) \
243 insl((unsigned long) (p), (dst), (count))
244
245#define iowrite8_rep(p, src, count) \
246 outsb((unsigned long) (p), (src), (count))
247#define iowrite16_rep(p, src, count) \
248 outsw((unsigned long) (p), (src), (count))
249#define iowrite32_rep(p, src, count) \
250 outsl((unsigned long) (p), (src), (count))
251#endif /* CONFIG_GENERIC_IOMAP */
252
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800253#ifndef IO_SPACE_LIMIT
254#define IO_SPACE_LIMIT 0xffff
255#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000256
257#ifdef __KERNEL__
258
259#include <linux/vmalloc.h>
260#define __io_virt(x) ((void __force *) (x))
261
262#ifndef CONFIG_GENERIC_IOMAP
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000263struct pci_dev;
Jan Glaubercd248342012-11-29 12:50:30 +0100264extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
265
266#ifndef pci_iounmap
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000267static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
268{
269}
Jan Glaubercd248342012-11-29 12:50:30 +0100270#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000271#endif /* CONFIG_GENERIC_IOMAP */
272
273/*
274 * Change virtual addresses to physical addresses and vv.
275 * These are pretty trivial
276 */
Jan Glaubercd248342012-11-29 12:50:30 +0100277#ifndef virt_to_phys
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000278static inline unsigned long virt_to_phys(volatile void *address)
279{
280 return __pa((unsigned long)address);
281}
282
283static inline void *phys_to_virt(unsigned long address)
284{
285 return __va(address);
286}
Jan Glaubercd248342012-11-29 12:50:30 +0100287#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000288
289/*
290 * Change "struct page" to physical address.
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200291 *
292 * This implementation is for the no-MMU case only... if you have an MMU
293 * you'll need to provide your own definitions.
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000294 */
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200295#ifndef CONFIG_MMU
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000296static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
297{
298 return (void __iomem*) (unsigned long)offset;
299}
300
301#define __ioremap(offset, size, flags) ioremap(offset, size)
302
303#ifndef ioremap_nocache
304#define ioremap_nocache ioremap
305#endif
306
307#ifndef ioremap_wc
308#define ioremap_wc ioremap_nocache
309#endif
310
Mark Saltere66d3c42011-10-04 09:25:56 -0400311static inline void iounmap(void __iomem *addr)
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000312{
313}
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200314#endif /* CONFIG_MMU */
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000315
Jonas Bonn82ed2232011-07-02 17:23:29 +0200316#ifdef CONFIG_HAS_IOPORT
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000317#ifndef CONFIG_GENERIC_IOMAP
318static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
319{
320 return (void __iomem *) port;
321}
322
323static inline void ioport_unmap(void __iomem *p)
324{
325}
326#else /* CONFIG_GENERIC_IOMAP */
327extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
328extern void ioport_unmap(void __iomem *p);
329#endif /* CONFIG_GENERIC_IOMAP */
Jonas Bonn82ed2232011-07-02 17:23:29 +0200330#endif /* CONFIG_HAS_IOPORT */
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000331
332#define xlate_dev_kmem_ptr(p) p
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200333#define xlate_dev_mem_ptr(p) __va(p)
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000334
335#ifndef virt_to_bus
336static inline unsigned long virt_to_bus(volatile void *address)
337{
338 return ((unsigned long) address);
339}
340
341static inline void *bus_to_virt(unsigned long address)
342{
343 return (void *) address;
344}
345#endif
346
Jan Glaubercd248342012-11-29 12:50:30 +0100347#ifndef memset_io
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000348#define memset_io(a, b, c) memset(__io_virt(a), (b), (c))
Jan Glaubercd248342012-11-29 12:50:30 +0100349#endif
350
351#ifndef memcpy_fromio
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000352#define memcpy_fromio(a, b, c) memcpy((a), __io_virt(b), (c))
Jan Glaubercd248342012-11-29 12:50:30 +0100353#endif
354#ifndef memcpy_toio
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000355#define memcpy_toio(a, b, c) memcpy(__io_virt(a), (b), (c))
Jan Glaubercd248342012-11-29 12:50:30 +0100356#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000357
358#endif /* __KERNEL__ */
359
360#endif /* __ASM_GENERIC_IO_H */