985 lines · 19.6 KB · C
RawDownload
/* 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 <linux/string.h> /* for memset() and memcpy() */#include <linux/types.h> #ifdef CONFIG_GENERIC_IOMAP#include <asm-generic/iomap.h>#endif #include <asm-generic/pci_iomap.h> #ifndef mmiowb#define mmiowb() do {} while (0)#endif /* * __raw_{read,write}{b,w,l,q}() access memory in native endianness. * * On some architectures memory mapped IO needs to be accessed differently. * On the simple architectures, we just read/write the memory location * directly. */ #ifndef __raw_readb#define __raw_readb __raw_readbstatic inline u8 __raw_readb(const volatile void __iomem *addr){	return *(const volatile u8 __force *)addr;}#endif #ifndef __raw_readw#define __raw_readw __raw_readwstatic inline u16 __raw_readw(const volatile void __iomem *addr){	return *(const volatile u16 __force *)addr;}#endif #ifndef __raw_readl#define __raw_readl __raw_readlstatic inline u32 __raw_readl(const volatile void __iomem *addr){	return *(const volatile u32 __force *)addr;}#endif #ifdef CONFIG_64BIT#ifndef __raw_readq#define __raw_readq __raw_readqstatic inline u64 __raw_readq(const volatile void __iomem *addr){	return *(const volatile u64 __force *)addr;}#endif#endif /* CONFIG_64BIT */ #ifndef __raw_writeb#define __raw_writeb __raw_writebstatic inline void __raw_writeb(u8 value, volatile void __iomem *addr){	*(volatile u8 __force *)addr = value;}#endif #ifndef __raw_writew#define __raw_writew __raw_writewstatic inline void __raw_writew(u16 value, volatile void __iomem *addr){	*(volatile u16 __force *)addr = value;}#endif #ifndef __raw_writel#define __raw_writel __raw_writelstatic inline void __raw_writel(u32 value, volatile void __iomem *addr){	*(volatile u32 __force *)addr = value;}#endif #ifdef CONFIG_64BIT#ifndef __raw_writeq#define __raw_writeq __raw_writeqstatic inline void __raw_writeq(u64 value, volatile void __iomem *addr){	*(volatile u64 __force *)addr = value;}#endif#endif /* CONFIG_64BIT */ /* * {read,write}{b,w,l,q}() access little endian memory and return result in * native endianness. */ #ifndef readb#define readb readbstatic inline u8 readb(const volatile void __iomem *addr){	return __raw_readb(addr);}#endif #ifndef readw#define readw readwstatic inline u16 readw(const volatile void __iomem *addr){	return __le16_to_cpu(__raw_readw(addr));}#endif #ifndef readl#define readl readlstatic inline u32 readl(const volatile void __iomem *addr){	return __le32_to_cpu(__raw_readl(addr));}#endif #ifdef CONFIG_64BIT#ifndef readq#define readq readqstatic inline u64 readq(const volatile void __iomem *addr){	return __le64_to_cpu(__raw_readq(addr));}#endif#endif /* CONFIG_64BIT */ #ifndef writeb#define writeb writebstatic inline void writeb(u8 value, volatile void __iomem *addr){	__raw_writeb(value, addr);}#endif #ifndef writew#define writew writewstatic inline void writew(u16 value, volatile void __iomem *addr){	__raw_writew(cpu_to_le16(value), addr);}#endif #ifndef writel#define writel writelstatic inline void writel(u32 value, volatile void __iomem *addr){	__raw_writel(__cpu_to_le32(value), addr);}#endif #ifdef CONFIG_64BIT#ifndef writeq#define writeq writeqstatic inline void writeq(u64 value, volatile void __iomem *addr){	__raw_writeq(__cpu_to_le64(value), addr);}#endif#endif /* CONFIG_64BIT */ /* * {read,write}{b,w,l,q}_relaxed() are like the regular version, but * are not guaranteed to provide ordering against spinlocks or memory * accesses. */#ifndef readb_relaxed#define readb_relaxed readb#endif #ifndef readw_relaxed#define readw_relaxed readw#endif #ifndef readl_relaxed#define readl_relaxed readl#endif #if defined(readq) && !defined(readq_relaxed)#define readq_relaxed readq#endif #ifndef writeb_relaxed#define writeb_relaxed writeb#endif #ifndef writew_relaxed#define writew_relaxed writew#endif #ifndef writel_relaxed#define writel_relaxed writel#endif #if defined(writeq) && !defined(writeq_relaxed)#define writeq_relaxed writeq#endif /* * {read,write}s{b,w,l,q}() repeatedly access the same memory address in * native endianness in 8-, 16-, 32- or 64-bit chunks (@count times). */#ifndef readsb#define readsb readsbstatic inline void readsb(const volatile void __iomem *addr, void *buffer,			  unsigned int count){	if (count) {		u8 *buf = buffer; 		do {			u8 x = __raw_readb(addr);			*buf++ = x;		} while (--count);	}}#endif #ifndef readsw#define readsw readswstatic inline void readsw(const volatile void __iomem *addr, void *buffer,			  unsigned int count){	if (count) {		u16 *buf = buffer; 		do {			u16 x = __raw_readw(addr);			*buf++ = x;		} while (--count);	}}#endif #ifndef readsl#define readsl readslstatic inline void readsl(const volatile void __iomem *addr, void *buffer,			  unsigned int count){	if (count) {		u32 *buf = buffer; 		do {			u32 x = __raw_readl(addr);			*buf++ = x;		} while (--count);	}}#endif #ifdef CONFIG_64BIT#ifndef readsq#define readsq readsqstatic inline void readsq(const volatile void __iomem *addr, void *buffer,			  unsigned int count){	if (count) {		u64 *buf = buffer; 		do {			u64 x = __raw_readq(addr);			*buf++ = x;		} while (--count);	}}#endif#endif /* CONFIG_64BIT */ #ifndef writesb#define writesb writesbstatic inline void writesb(volatile void __iomem *addr, const void *buffer,			   unsigned int count){	if (count) {		const u8 *buf = buffer; 		do {			__raw_writeb(*buf++, addr);		} while (--count);	}}#endif #ifndef writesw#define writesw writeswstatic inline void writesw(volatile void __iomem *addr, const void *buffer,			   unsigned int count){	if (count) {		const u16 *buf = buffer; 		do {			__raw_writew(*buf++, addr);		} while (--count);	}}#endif #ifndef writesl#define writesl writeslstatic inline void writesl(volatile void __iomem *addr, const void *buffer,			   unsigned int count){	if (count) {		const u32 *buf = buffer; 		do {			__raw_writel(*buf++, addr);		} while (--count);	}}#endif #ifdef CONFIG_64BIT#ifndef writesq#define writesq writesqstatic inline void writesq(volatile void __iomem *addr, const void *buffer,			   unsigned int count){	if (count) {		const u64 *buf = buffer; 		do {			__raw_writeq(*buf++, addr);		} while (--count);	}}#endif#endif /* CONFIG_64BIT */ #ifndef PCI_IOBASE#define PCI_IOBASE ((void __iomem *)0)#endif #ifndef IO_SPACE_LIMIT#define IO_SPACE_LIMIT 0xffff#endif /* * {in,out}{b,w,l}() access little endian I/O. {in,out}{b,w,l}_p() can be * implemented on hardware that needs an additional delay for I/O accesses to * take effect. */ #ifndef inb#define inb inbstatic inline u8 inb(unsigned long addr){	return readb(PCI_IOBASE + addr);}#endif #ifndef inw#define inw inwstatic inline u16 inw(unsigned long addr){	return readw(PCI_IOBASE + addr);}#endif #ifndef inl#define inl inlstatic inline u32 inl(unsigned long addr){	return readl(PCI_IOBASE + addr);}#endif #ifndef outb#define outb outbstatic inline void outb(u8 value, unsigned long addr){	writeb(value, PCI_IOBASE + addr);}#endif #ifndef outw#define outw outwstatic inline void outw(u16 value, unsigned long addr){	writew(value, PCI_IOBASE + addr);}#endif #ifndef outl#define outl outlstatic inline void outl(u32 value, unsigned long addr){	writel(value, PCI_IOBASE + addr);}#endif #ifndef inb_p#define inb_p inb_pstatic inline u8 inb_p(unsigned long addr){	return inb(addr);}#endif #ifndef inw_p#define inw_p inw_pstatic inline u16 inw_p(unsigned long addr){	return inw(addr);}#endif #ifndef inl_p#define inl_p inl_pstatic inline u32 inl_p(unsigned long addr){	return inl(addr);}#endif #ifndef outb_p#define outb_p outb_pstatic inline void outb_p(u8 value, unsigned long addr){	outb(value, addr);}#endif #ifndef outw_p#define outw_p outw_pstatic inline void outw_p(u16 value, unsigned long addr){	outw(value, addr);}#endif #ifndef outl_p#define outl_p outl_pstatic inline void outl_p(u32 value, unsigned long addr){	outl(value, addr);}#endif /* * {in,out}s{b,w,l}{,_p}() are variants of the above that repeatedly access a * single I/O port multiple times. */ #ifndef insb#define insb insbstatic inline void insb(unsigned long addr, void *buffer, unsigned int count){	readsb(PCI_IOBASE + addr, buffer, count);}#endif #ifndef insw#define insw inswstatic inline void insw(unsigned long addr, void *buffer, unsigned int count){	readsw(PCI_IOBASE + addr, buffer, count);}#endif #ifndef insl#define insl inslstatic inline void insl(unsigned long addr, void *buffer, unsigned int count){	readsl(PCI_IOBASE + addr, buffer, count);}#endif #ifndef outsb#define outsb outsbstatic inline void outsb(unsigned long addr, const void *buffer,			 unsigned int count){	writesb(PCI_IOBASE + addr, buffer, count);}#endif #ifndef outsw#define outsw outswstatic inline void outsw(unsigned long addr, const void *buffer,			 unsigned int count){	writesw(PCI_IOBASE + addr, buffer, count);}

Lines 1–500 of 985.