blob: ac9da00e9f2c66b104029aa7b89253802708a322 [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
Heiko Carstens7292e7e2013-01-07 14:17:23 +010056
57#define readw readw
58static inline u16 readw(const volatile void __iomem *addr)
59{
60 return __le16_to_cpu(__raw_readw(addr));
61}
62
63#define readl readl
64static inline u32 readl(const volatile void __iomem *addr)
65{
66 return __le32_to_cpu(__raw_readl(addr));
67}
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000068
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040069#ifndef __raw_writeb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000070static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
71{
72 *(volatile u8 __force *) addr = b;
73}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040074#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000075
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040076#ifndef __raw_writew
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000077static inline void __raw_writew(u16 b, volatile void __iomem *addr)
78{
79 *(volatile u16 __force *) addr = b;
80}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040081#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000082
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040083#ifndef __raw_writel
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000084static inline void __raw_writel(u32 b, volatile void __iomem *addr)
85{
86 *(volatile u32 __force *) addr = b;
87}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -040088#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000089
90#define writeb __raw_writeb
91#define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
92#define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)
93
94#ifdef CONFIG_64BIT
Jan Glaubercd248342012-11-29 12:50:30 +010095#ifndef __raw_readq
Arnd Bergmann3f7e2122009-05-13 22:56:35 +000096static inline u64 __raw_readq(const volatile void __iomem *addr)
97{
98 return *(const volatile u64 __force *) addr;
99}
Jan Glaubercd248342012-11-29 12:50:30 +0100100#endif
101
Heiko Carstens7292e7e2013-01-07 14:17:23 +0100102#define readq readq
103static inline u64 readq(const volatile void __iomem *addr)
104{
105 return __le64_to_cpu(__raw_readq(addr));
106}
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000107
Jan Glaubercd248342012-11-29 12:50:30 +0100108#ifndef __raw_writeq
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000109static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
110{
111 *(volatile u64 __force *) addr = b;
112}
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000113#endif
114
Jan Glaubercd248342012-11-29 12:50:30 +0100115#define writeq(b, addr) __raw_writeq(__cpu_to_le64(b), addr)
116#endif /* CONFIG_64BIT */
117
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800118#ifndef PCI_IOBASE
119#define PCI_IOBASE ((void __iomem *) 0)
120#endif
121
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000122/*****************************************************************************/
123/*
124 * traditional input/output functions
125 */
126
127static inline u8 inb(unsigned long addr)
128{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800129 return readb(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000130}
131
132static inline u16 inw(unsigned long addr)
133{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800134 return readw(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000135}
136
137static inline u32 inl(unsigned long addr)
138{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800139 return readl(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000140}
141
142static inline void outb(u8 b, unsigned long addr)
143{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800144 writeb(b, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000145}
146
147static inline void outw(u16 b, unsigned long addr)
148{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800149 writew(b, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000150}
151
152static inline void outl(u32 b, unsigned long addr)
153{
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800154 writel(b, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000155}
156
157#define inb_p(addr) inb(addr)
158#define inw_p(addr) inw(addr)
159#define inl_p(addr) inl(addr)
160#define outb_p(x, addr) outb((x), (addr))
161#define outw_p(x, addr) outw((x), (addr))
162#define outl_p(x, addr) outl((x), (addr))
163
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400164#ifndef insb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000165static inline void insb(unsigned long addr, void *buffer, int count)
166{
167 if (count) {
168 u8 *buf = buffer;
169 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800170 u8 x = __raw_readb(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000171 *buf++ = x;
172 } while (--count);
173 }
174}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400175#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000176
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400177#ifndef insw
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000178static inline void insw(unsigned long addr, void *buffer, int count)
179{
180 if (count) {
181 u16 *buf = buffer;
182 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800183 u16 x = __raw_readw(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000184 *buf++ = x;
185 } while (--count);
186 }
187}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400188#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000189
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400190#ifndef insl
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000191static inline void insl(unsigned long addr, void *buffer, int count)
192{
193 if (count) {
194 u32 *buf = buffer;
195 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800196 u32 x = __raw_readl(addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000197 *buf++ = x;
198 } while (--count);
199 }
200}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400201#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000202
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400203#ifndef outsb
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000204static inline void outsb(unsigned long addr, const void *buffer, int count)
205{
206 if (count) {
207 const u8 *buf = buffer;
208 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800209 __raw_writeb(*buf++, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000210 } while (--count);
211 }
212}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400213#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000214
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400215#ifndef outsw
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000216static inline void outsw(unsigned long addr, const void *buffer, int count)
217{
218 if (count) {
219 const u16 *buf = buffer;
220 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800221 __raw_writew(*buf++, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000222 } while (--count);
223 }
224}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400225#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000226
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400227#ifndef outsl
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000228static inline void outsl(unsigned long addr, const void *buffer, int count)
229{
230 if (count) {
231 const u32 *buf = buffer;
232 do {
Will Deacon41739ee2012-12-17 15:59:42 -0800233 __raw_writel(*buf++, addr + PCI_IOBASE);
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000234 } while (--count);
235 }
236}
Mike Frysinger35dbc0e2010-10-18 03:09:39 -0400237#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000238
239#ifndef CONFIG_GENERIC_IOMAP
240#define ioread8(addr) readb(addr)
241#define ioread16(addr) readw(addr)
Michal Simek711e5b42013-02-07 14:58:35 +0100242#define ioread16be(addr) __be16_to_cpu(__raw_readw(addr))
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000243#define ioread32(addr) readl(addr)
Michal Simek711e5b42013-02-07 14:58:35 +0100244#define ioread32be(addr) __be32_to_cpu(__raw_readl(addr))
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000245
246#define iowrite8(v, addr) writeb((v), (addr))
247#define iowrite16(v, addr) writew((v), (addr))
Michal Simek711e5b42013-02-07 14:58:35 +0100248#define iowrite16be(v, addr) __raw_writew(__cpu_to_be16(v), addr)
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000249#define iowrite32(v, addr) writel((v), (addr))
Michal Simek711e5b42013-02-07 14:58:35 +0100250#define iowrite32be(v, addr) __raw_writel(__cpu_to_be32(v), addr)
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000251
252#define ioread8_rep(p, dst, count) \
253 insb((unsigned long) (p), (dst), (count))
254#define ioread16_rep(p, dst, count) \
255 insw((unsigned long) (p), (dst), (count))
256#define ioread32_rep(p, dst, count) \
257 insl((unsigned long) (p), (dst), (count))
258
259#define iowrite8_rep(p, src, count) \
260 outsb((unsigned long) (p), (src), (count))
261#define iowrite16_rep(p, src, count) \
262 outsw((unsigned long) (p), (src), (count))
263#define iowrite32_rep(p, src, count) \
264 outsl((unsigned long) (p), (src), (count))
265#endif /* CONFIG_GENERIC_IOMAP */
266
GuanXuetao7dc59bd2011-02-22 19:06:43 +0800267#ifndef IO_SPACE_LIMIT
268#define IO_SPACE_LIMIT 0xffff
269#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000270
271#ifdef __KERNEL__
272
273#include <linux/vmalloc.h>
274#define __io_virt(x) ((void __force *) (x))
275
276#ifndef CONFIG_GENERIC_IOMAP
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000277struct pci_dev;
Jan Glaubercd248342012-11-29 12:50:30 +0100278extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
279
280#ifndef pci_iounmap
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000281static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
282{
283}
Jan Glaubercd248342012-11-29 12:50:30 +0100284#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000285#endif /* CONFIG_GENERIC_IOMAP */
286
287/*
288 * Change virtual addresses to physical addresses and vv.
289 * These are pretty trivial
290 */
Jan Glaubercd248342012-11-29 12:50:30 +0100291#ifndef virt_to_phys
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000292static inline unsigned long virt_to_phys(volatile void *address)
293{
294 return __pa((unsigned long)address);
295}
296
297static inline void *phys_to_virt(unsigned long address)
298{
299 return __va(address);
300}
Jan Glaubercd248342012-11-29 12:50:30 +0100301#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000302
303/*
304 * Change "struct page" to physical address.
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200305 *
306 * This implementation is for the no-MMU case only... if you have an MMU
307 * you'll need to provide your own definitions.
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000308 */
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200309#ifndef CONFIG_MMU
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000310static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
311{
312 return (void __iomem*) (unsigned long)offset;
313}
314
315#define __ioremap(offset, size, flags) ioremap(offset, size)
316
317#ifndef ioremap_nocache
318#define ioremap_nocache ioremap
319#endif
320
321#ifndef ioremap_wc
322#define ioremap_wc ioremap_nocache
323#endif
324
Mark Saltere66d3c42011-10-04 09:25:56 -0400325static inline void iounmap(void __iomem *addr)
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000326{
327}
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200328#endif /* CONFIG_MMU */
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000329
Jonas Bonn82ed2232011-07-02 17:23:29 +0200330#ifdef CONFIG_HAS_IOPORT
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000331#ifndef CONFIG_GENERIC_IOMAP
332static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
333{
334 return (void __iomem *) port;
335}
336
337static inline void ioport_unmap(void __iomem *p)
338{
339}
340#else /* CONFIG_GENERIC_IOMAP */
341extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
342extern void ioport_unmap(void __iomem *p);
343#endif /* CONFIG_GENERIC_IOMAP */
Jonas Bonn82ed2232011-07-02 17:23:29 +0200344#endif /* CONFIG_HAS_IOPORT */
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000345
346#define xlate_dev_kmem_ptr(p) p
Jonas Bonnf1ecc692011-07-02 17:17:35 +0200347#define xlate_dev_mem_ptr(p) __va(p)
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000348
James Hoganc93d0312012-11-23 16:13:05 +0000349#ifdef CONFIG_VIRT_TO_BUS
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000350#ifndef virt_to_bus
351static inline unsigned long virt_to_bus(volatile void *address)
352{
353 return ((unsigned long) address);
354}
355
356static inline void *bus_to_virt(unsigned long address)
357{
358 return (void *) address;
359}
360#endif
James Hoganc93d0312012-11-23 16:13:05 +0000361#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000362
Jan Glaubercd248342012-11-29 12:50:30 +0100363#ifndef memset_io
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000364#define memset_io(a, b, c) memset(__io_virt(a), (b), (c))
Jan Glaubercd248342012-11-29 12:50:30 +0100365#endif
366
367#ifndef memcpy_fromio
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000368#define memcpy_fromio(a, b, c) memcpy((a), __io_virt(b), (c))
Jan Glaubercd248342012-11-29 12:50:30 +0100369#endif
370#ifndef memcpy_toio
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000371#define memcpy_toio(a, b, c) memcpy(__io_virt(a), (b), (c))
Jan Glaubercd248342012-11-29 12:50:30 +0100372#endif
Arnd Bergmann3f7e2122009-05-13 22:56:35 +0000373
374#endif /* __KERNEL__ */
375
376#endif /* __ASM_GENERIC_IO_H */