1/* 2 * linux/arch/m32r/platforms/oaks32r/io.c 3 * 4 * Typical I/O routines for OAKS32R board. 5 * 6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, 7 * Hitoshi Yamamoto, Mamoru Sakugawa 8 */ 9 10#include <asm/m32r.h> 11#include <asm/page.h> 12#include <asm/io.h> 13 14#define PORT2ADDR(port) _port2addr(port) 15 16static inline void *_port2addr(unsigned long port) 17{ 18 return (void *)(port | NONCACHE_OFFSET); 19} 20 21static inline void *_port2addr_ne(unsigned long port) 22{ 23 return (void *)((port<<1) + NONCACHE_OFFSET + 0x02000000); 24} 25 26static inline void delay(void) 27{ 28 __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); 29} 30 31/* 32 * NIC I/O function 33 */ 34 35#define PORT2ADDR_NE(port) _port2addr_ne(port) 36 37static inline unsigned char _ne_inb(void *portp) 38{ 39 return *(volatile unsigned char *)(portp+1); 40} 41 42static inline unsigned short _ne_inw(void *portp) 43{ 44 unsigned short tmp; 45 46 tmp = *(unsigned short *)(portp) & 0xff; 47 tmp |= *(unsigned short *)(portp+2) << 8; 48 return tmp; 49} 50 51static inline void _ne_insb(void *portp, void *addr, unsigned long count) 52{ 53 unsigned char *buf = addr; 54 while (count--) 55 *buf++ = *(volatile unsigned char *)(portp+1); 56} 57 58static inline void _ne_outb(unsigned char b, void *portp) 59{ 60 *(volatile unsigned char *)(portp+1) = b; 61} 62 63static inline void _ne_outw(unsigned short w, void *portp) 64{ 65 *(volatile unsigned short *)portp = (w >> 8); 66 *(volatile unsigned short *)(portp+2) = (w & 0xff); 67} 68 69unsigned char _inb(unsigned long port) 70{ 71 if (port >= 0x300 && port < 0x320) 72 return _ne_inb(PORT2ADDR_NE(port)); 73 74 return *(volatile unsigned char *)PORT2ADDR(port); 75} 76 77unsigned short _inw(unsigned long port) 78{ 79 if (port >= 0x300 && port < 0x320) 80 return _ne_inw(PORT2ADDR_NE(port)); 81 82 return *(volatile unsigned short *)PORT2ADDR(port); 83} 84 85unsigned long _inl(unsigned long port) 86{ 87 return *(volatile unsigned long *)PORT2ADDR(port); 88} 89 90unsigned char _inb_p(unsigned long port) 91{ 92 unsigned char v = _inb(port); 93 delay(); 94 return (v); 95} 96 97unsigned short _inw_p(unsigned long port) 98{ 99 unsigned short v = _inw(port); 100 delay(); 101 return (v); 102} 103 104unsigned long _inl_p(unsigned long port) 105{ 106 unsigned long v = _inl(port); 107 delay(); 108 return (v); 109} 110 111void _outb(unsigned char b, unsigned long port) 112{ 113 if (port >= 0x300 && port < 0x320) 114 _ne_outb(b, PORT2ADDR_NE(port)); 115 else 116 *(volatile unsigned char *)PORT2ADDR(port) = b; 117} 118 119void _outw(unsigned short w, unsigned long port) 120{ 121 if (port >= 0x300 && port < 0x320) 122 _ne_outw(w, PORT2ADDR_NE(port)); 123 else 124 *(volatile unsigned short *)PORT2ADDR(port) = w; 125} 126 127void _outl(unsigned long l, unsigned long port) 128{ 129 *(volatile unsigned long *)PORT2ADDR(port) = l; 130} 131 132void _outb_p(unsigned char b, unsigned long port) 133{ 134 _outb(b, port); 135 delay(); 136} 137 138void _outw_p(unsigned short w, unsigned long port) 139{ 140 _outw(w, port); 141 delay(); 142} 143 144void _outl_p(unsigned long l, unsigned long port) 145{ 146 _outl(l, port); 147 delay(); 148} 149 150void _insb(unsigned int port, void *addr, unsigned long count) 151{ 152 if (port >= 0x300 && port < 0x320) 153 _ne_insb(PORT2ADDR_NE(port), addr, count); 154 else { 155 unsigned char *buf = addr; 156 unsigned char *portp = PORT2ADDR(port); 157 while (count--) 158 *buf++ = *(volatile unsigned char *)portp; 159 } 160} 161 162void _insw(unsigned int port, void *addr, unsigned long count) 163{ 164 unsigned short *buf = addr; 165 unsigned short *portp; 166 167 if (port >= 0x300 && port < 0x320) { 168 portp = PORT2ADDR_NE(port); 169 while (count--) 170 *buf++ = _ne_inw(portp); 171 } else { 172 portp = PORT2ADDR(port); 173 while (count--) 174 *buf++ = *(volatile unsigned short *)portp; 175 } 176} 177 178void _insl(unsigned int port, void *addr, unsigned long count) 179{ 180 unsigned long *buf = addr; 181 unsigned long *portp; 182 183 portp = PORT2ADDR(port); 184 while (count--) 185 *buf++ = *(volatile unsigned long *)portp; 186} 187 188void _outsb(unsigned int port, const void *addr, unsigned long count) 189{ 190 const unsigned char *buf = addr; 191 unsigned char *portp; 192 193 if (port >= 0x300 && port < 0x320) { 194 portp = PORT2ADDR_NE(port); 195 while (count--) 196 _ne_outb(*buf++, portp); 197 } else { 198 portp = PORT2ADDR(port); 199 while (count--) 200 *(volatile unsigned char *)portp = *buf++; 201 } 202} 203 204void _outsw(unsigned int port, const void *addr, unsigned long count) 205{ 206 const unsigned short *buf = addr; 207 unsigned short *portp; 208 209 if (port >= 0x300 && port < 0x320) { 210 portp = PORT2ADDR_NE(port); 211 while (count--) 212 _ne_outw(*buf++, portp); 213 } else { 214 portp = PORT2ADDR(port); 215 while (count--) 216 *(volatile unsigned short *)portp = *buf++; 217 } 218} 219 220void _outsl(unsigned int port, const void *addr, unsigned long count) 221{ 222 const unsigned long *buf = addr; 223 unsigned char *portp; 224 225 portp = PORT2ADDR(port); 226 while (count--) 227 *(volatile unsigned long *)portp = *buf++; 228} 229