io.h 8.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* Generic I/O port emulation, based on MN10300 code
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#ifndef __ASM_GENERIC_IO_H
#define __ASM_GENERIC_IO_H

#include <asm/page.h> /* I/O is all done through memory accesses */
#include <asm/cacheflush.h>
#include <linux/types.h>

#ifdef CONFIG_GENERIC_IOMAP
#include <asm-generic/iomap.h>
#endif

22
#ifndef mmiowb
23
#define mmiowb() do {} while (0)
24
#endif
25 26 27 28 29 30 31 32

/*****************************************************************************/
/*
 * readX/writeX() are used to access memory mapped devices. On some
 * architectures the memory mapped IO stuff needs to be accessed
 * differently. On the simple architectures, we just read/write the
 * memory location directly.
 */
33
#ifndef __raw_readb
34 35 36 37
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
	return *(const volatile u8 __force *) addr;
}
38
#endif
39

40
#ifndef __raw_readw
41 42 43 44
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
	return *(const volatile u16 __force *) addr;
}
45
#endif
46

47
#ifndef __raw_readl
48 49 50 51
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
	return *(const volatile u32 __force *) addr;
}
52
#endif
53 54 55 56 57

#define readb __raw_readb
#define readw(addr) __le16_to_cpu(__raw_readw(addr))
#define readl(addr) __le32_to_cpu(__raw_readl(addr))

58
#ifndef __raw_writeb
59 60 61 62
static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
{
	*(volatile u8 __force *) addr = b;
}
63
#endif
64

65
#ifndef __raw_writew
66 67 68 69
static inline void __raw_writew(u16 b, volatile void __iomem *addr)
{
	*(volatile u16 __force *) addr = b;
}
70
#endif
71

72
#ifndef __raw_writel
73 74 75 76
static inline void __raw_writel(u32 b, volatile void __iomem *addr)
{
	*(volatile u32 __force *) addr = b;
}
77
#endif
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

#define writeb __raw_writeb
#define writew(b,addr) __raw_writew(__cpu_to_le16(b),addr)
#define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr)

#ifdef CONFIG_64BIT
static inline u64 __raw_readq(const volatile void __iomem *addr)
{
	return *(const volatile u64 __force *) addr;
}
#define readq(addr) __le64_to_cpu(__raw_readq(addr))

static inline void __raw_writeq(u64 b, volatile void __iomem *addr)
{
	*(volatile u64 __force *) addr = b;
}
#define writeq(b,addr) __raw_writeq(__cpu_to_le64(b),addr)
#endif

97 98 99 100
#ifndef PCI_IOBASE
#define PCI_IOBASE ((void __iomem *) 0)
#endif

101 102 103 104 105 106 107
/*****************************************************************************/
/*
 * traditional input/output functions
 */

static inline u8 inb(unsigned long addr)
{
108
	return readb(addr + PCI_IOBASE);
109 110 111 112
}

static inline u16 inw(unsigned long addr)
{
113
	return readw(addr + PCI_IOBASE);
114 115 116 117
}

static inline u32 inl(unsigned long addr)
{
118
	return readl(addr + PCI_IOBASE);
119 120 121 122
}

static inline void outb(u8 b, unsigned long addr)
{
123
	writeb(b, addr + PCI_IOBASE);
124 125 126 127
}

static inline void outw(u16 b, unsigned long addr)
{
128
	writew(b, addr + PCI_IOBASE);
129 130 131 132
}

static inline void outl(u32 b, unsigned long addr)
{
133
	writel(b, addr + PCI_IOBASE);
134 135 136 137 138 139 140 141 142
}

#define inb_p(addr)	inb(addr)
#define inw_p(addr)	inw(addr)
#define inl_p(addr)	inl(addr)
#define outb_p(x, addr)	outb((x), (addr))
#define outw_p(x, addr)	outw((x), (addr))
#define outl_p(x, addr)	outl((x), (addr))

143
#ifndef insb
144 145 146 147 148 149 150 151 152 153
static inline void insb(unsigned long addr, void *buffer, int count)
{
	if (count) {
		u8 *buf = buffer;
		do {
			u8 x = inb(addr);
			*buf++ = x;
		} while (--count);
	}
}
154
#endif
155

156
#ifndef insw
157 158 159 160 161 162 163 164 165 166
static inline void insw(unsigned long addr, void *buffer, int count)
{
	if (count) {
		u16 *buf = buffer;
		do {
			u16 x = inw(addr);
			*buf++ = x;
		} while (--count);
	}
}
167
#endif
168

169
#ifndef insl
170 171 172 173 174 175 176 177 178 179
static inline void insl(unsigned long addr, void *buffer, int count)
{
	if (count) {
		u32 *buf = buffer;
		do {
			u32 x = inl(addr);
			*buf++ = x;
		} while (--count);
	}
}
180
#endif
181

182
#ifndef outsb
183 184 185 186 187 188 189 190 191
static inline void outsb(unsigned long addr, const void *buffer, int count)
{
	if (count) {
		const u8 *buf = buffer;
		do {
			outb(*buf++, addr);
		} while (--count);
	}
}
192
#endif
193

194
#ifndef outsw
195 196 197 198 199 200 201 202 203
static inline void outsw(unsigned long addr, const void *buffer, int count)
{
	if (count) {
		const u16 *buf = buffer;
		do {
			outw(*buf++, addr);
		} while (--count);
	}
}
204
#endif
205

206
#ifndef outsl
207 208 209 210 211 212 213 214 215
static inline void outsl(unsigned long addr, const void *buffer, int count)
{
	if (count) {
		const u32 *buf = buffer;
		do {
			outl(*buf++, addr);
		} while (--count);
	}
}
216
#endif
217

218 219
static inline void readsl(const void __iomem *addr, void *buf, int len)
{
220
	insl(addr - PCI_IOBASE, buf, len);
221 222 223 224
}

static inline void readsw(const void __iomem *addr, void *buf, int len)
{
225
	insw(addr - PCI_IOBASE, buf, len);
226 227 228 229
}

static inline void readsb(const void __iomem *addr, void *buf, int len)
{
230
	insb(addr - PCI_IOBASE, buf, len);
231 232 233 234
}

static inline void writesl(const void __iomem *addr, const void *buf, int len)
{
235
	outsl(addr - PCI_IOBASE, buf, len);
236 237 238 239
}

static inline void writesw(const void __iomem *addr, const void *buf, int len)
{
240
	outsw(addr - PCI_IOBASE, buf, len);
241 242 243 244
}

static inline void writesb(const void __iomem *addr, const void *buf, int len)
{
245
	outsb(addr - PCI_IOBASE, buf, len);
246 247
}

248 249 250
#ifndef CONFIG_GENERIC_IOMAP
#define ioread8(addr)		readb(addr)
#define ioread16(addr)		readw(addr)
251
#define ioread16be(addr)	be16_to_cpu(ioread16(addr))
252
#define ioread32(addr)		readl(addr)
253
#define ioread32be(addr)	be32_to_cpu(ioread32(addr))
254 255 256

#define iowrite8(v, addr)	writeb((v), (addr))
#define iowrite16(v, addr)	writew((v), (addr))
257
#define iowrite16be(v, addr)	iowrite16(be16_to_cpu(v), (addr))
258
#define iowrite32(v, addr)	writel((v), (addr))
259
#define iowrite32be(v, addr)	iowrite32(be32_to_cpu(v), (addr))
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275

#define ioread8_rep(p, dst, count) \
	insb((unsigned long) (p), (dst), (count))
#define ioread16_rep(p, dst, count) \
	insw((unsigned long) (p), (dst), (count))
#define ioread32_rep(p, dst, count) \
	insl((unsigned long) (p), (dst), (count))

#define iowrite8_rep(p, src, count) \
	outsb((unsigned long) (p), (src), (count))
#define iowrite16_rep(p, src, count) \
	outsw((unsigned long) (p), (src), (count))
#define iowrite32_rep(p, src, count) \
	outsl((unsigned long) (p), (src), (count))
#endif /* CONFIG_GENERIC_IOMAP */

276 277 278
#ifndef IO_SPACE_LIMIT
#define IO_SPACE_LIMIT 0xffff
#endif
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309

#ifdef __KERNEL__

#include <linux/vmalloc.h>
#define __io_virt(x) ((void __force *) (x))

#ifndef CONFIG_GENERIC_IOMAP
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
{
}
#endif /* CONFIG_GENERIC_IOMAP */

/*
 * Change virtual addresses to physical addresses and vv.
 * These are pretty trivial
 */
static inline unsigned long virt_to_phys(volatile void *address)
{
	return __pa((unsigned long)address);
}

static inline void *phys_to_virt(unsigned long address)
{
	return __va(address);
}

/*
 * Change "struct page" to physical address.
310 311 312
 *
 * This implementation is for the no-MMU case only... if you have an MMU
 * you'll need to provide your own definitions.
313
 */
314
#ifndef CONFIG_MMU
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
{
	return (void __iomem*) (unsigned long)offset;
}

#define __ioremap(offset, size, flags)	ioremap(offset, size)

#ifndef ioremap_nocache
#define ioremap_nocache ioremap
#endif

#ifndef ioremap_wc
#define ioremap_wc ioremap_nocache
#endif

static inline void iounmap(void *addr)
{
}
333
#endif /* CONFIG_MMU */
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349

#ifndef CONFIG_GENERIC_IOMAP
static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
	return (void __iomem *) port;
}

static inline void ioport_unmap(void __iomem *p)
{
}
#else /* CONFIG_GENERIC_IOMAP */
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
extern void ioport_unmap(void __iomem *p);
#endif /* CONFIG_GENERIC_IOMAP */

#define xlate_dev_kmem_ptr(p)	p
350
#define xlate_dev_mem_ptr(p)	__va(p)
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370

#ifndef virt_to_bus
static inline unsigned long virt_to_bus(volatile void *address)
{
	return ((unsigned long) address);
}

static inline void *bus_to_virt(unsigned long address)
{
	return (void *) address;
}
#endif

#define memset_io(a, b, c)	memset(__io_virt(a), (b), (c))
#define memcpy_fromio(a, b, c)	memcpy((a), __io_virt(b), (c))
#define memcpy_toio(a, b, c)	memcpy(__io_virt(a), (b), (c))

#endif /* __KERNEL__ */

#endif /* __ASM_GENERIC_IO_H */