Path: blob/master/arch/arm/mach-rpc/include/mach/io.h
15162 views
/*1* arch/arm/mach-rpc/include/mach/io.h2*3* Copyright (C) 1997 Russell King4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License version 2 as7* published by the Free Software Foundation.8*9* Modifications:10* 06-Dec-1997 RMK Created.11*/12#ifndef __ASM_ARM_ARCH_IO_H13#define __ASM_ARM_ARCH_IO_H1415#include <mach/hardware.h>1617#define IO_SPACE_LIMIT 0xffffffff1819/*20* We use two different types of addressing - PC style addresses, and ARM21* addresses. PC style accesses the PC hardware with the normal PC IO22* addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+23* and are translated to the start of IO. Note that all addresses are24* shifted left!25*/26#define __PORT_PCIO(x) (!((x) & 0x80000000))2728/*29* Dynamic IO functions.30*/31static inline void __outb (unsigned int value, unsigned int port)32{33unsigned long temp;34__asm__ __volatile__(35"tst %2, #0x80000000\n\t"36"mov %0, %4\n\t"37"addeq %0, %0, %3\n\t"38"strb %1, [%0, %2, lsl #2] @ outb"39: "=&r" (temp)40: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)41: "cc");42}4344static inline void __outw (unsigned int value, unsigned int port)45{46unsigned long temp;47__asm__ __volatile__(48"tst %2, #0x80000000\n\t"49"mov %0, %4\n\t"50"addeq %0, %0, %3\n\t"51"str %1, [%0, %2, lsl #2] @ outw"52: "=&r" (temp)53: "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)54: "cc");55}5657static inline void __outl (unsigned int value, unsigned int port)58{59unsigned long temp;60__asm__ __volatile__(61"tst %2, #0x80000000\n\t"62"mov %0, %4\n\t"63"addeq %0, %0, %3\n\t"64"str %1, [%0, %2, lsl #2] @ outl"65: "=&r" (temp)66: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)67: "cc");68}6970#define DECLARE_DYN_IN(sz,fnsuffix,instr) \71static inline unsigned sz __in##fnsuffix (unsigned int port) \72{ \73unsigned long temp, value; \74__asm__ __volatile__( \75"tst %2, #0x80000000\n\t" \76"mov %0, %4\n\t" \77"addeq %0, %0, %3\n\t" \78"ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \79: "=&r" (temp), "=r" (value) \80: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \81: "cc"); \82return (unsigned sz)value; \83}8485static inline void __iomem *__deprecated __ioaddr(unsigned int port)86{87void __iomem *ret;88if (__PORT_PCIO(port))89ret = PCIO_BASE;90else91ret = IO_BASE;92return ret + (port << 2);93}9495#define DECLARE_IO(sz,fnsuffix,instr) \96DECLARE_DYN_IN(sz,fnsuffix,instr)9798DECLARE_IO(char,b,"b")99DECLARE_IO(short,w,"")100DECLARE_IO(int,l,"")101102#undef DECLARE_IO103#undef DECLARE_DYN_IN104105/*106* Constant address IO functions107*108* These have to be macros for the 'J' constraint to work -109* +/-4096 immediate operand.110*/111#define __outbc(value,port) \112({ \113if (__PORT_PCIO((port))) \114__asm__ __volatile__( \115"strb %0, [%1, %2] @ outbc" \116: : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \117else \118__asm__ __volatile__( \119"strb %0, [%1, %2] @ outbc" \120: : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \121})122123#define __inbc(port) \124({ \125unsigned char result; \126if (__PORT_PCIO((port))) \127__asm__ __volatile__( \128"ldrb %0, [%1, %2] @ inbc" \129: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \130else \131__asm__ __volatile__( \132"ldrb %0, [%1, %2] @ inbc" \133: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \134result; \135})136137#define __outwc(value,port) \138({ \139unsigned long __v = value; \140if (__PORT_PCIO((port))) \141__asm__ __volatile__( \142"str %0, [%1, %2] @ outwc" \143: : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \144else \145__asm__ __volatile__( \146"str %0, [%1, %2] @ outwc" \147: : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2)); \148})149150#define __inwc(port) \151({ \152unsigned short result; \153if (__PORT_PCIO((port))) \154__asm__ __volatile__( \155"ldr %0, [%1, %2] @ inwc" \156: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \157else \158__asm__ __volatile__( \159"ldr %0, [%1, %2] @ inwc" \160: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \161result & 0xffff; \162})163164#define __outlc(value,port) \165({ \166unsigned long __v = value; \167if (__PORT_PCIO((port))) \168__asm__ __volatile__( \169"str %0, [%1, %2] @ outlc" \170: : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \171else \172__asm__ __volatile__( \173"str %0, [%1, %2] @ outlc" \174: : "r" (__v), "r" (IO_BASE), "r" ((port) << 2)); \175})176177#define __inlc(port) \178({ \179unsigned long result; \180if (__PORT_PCIO((port))) \181__asm__ __volatile__( \182"ldr %0, [%1, %2] @ inlc" \183: "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \184else \185__asm__ __volatile__( \186"ldr %0, [%1, %2] @ inlc" \187: "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \188result; \189})190191#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))192#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))193#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))194#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))195#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))196#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))197198/* the following macro is deprecated */199#define ioaddr(port) ((unsigned long)__ioaddr((port)))200201#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)202#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)203204#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l)205#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)206207/*208* 1:1 mapping for ioremapped regions.209*/210#define __mem_pci(x) (x)211212#endif213214215