1/* 2 * linux/arch/m32r/platforms/usrv/io.c 3 * 4 * Typical I/O routines for uServer board. 5 * 6 * Copyright (c) 2001-2005 Hiroyuki Kondo, Hirokazu Takata, 7 * Hitoshi Yamamoto, Takeo Takahashi 8 * 9 * This file is subject to the terms and conditions of the GNU General 10 * Public License. See the file "COPYING" in the main directory of this 11 * archive for more details. 12 * 13 */ 14 15#include <asm/m32r.h> 16#include <asm/page.h> 17#include <asm/io.h> 18 19#include <linux/types.h> 20#include "../../../../drivers/pcmcia/m32r_cfc.h" 21 22extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int); 23extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int); 24extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); 25extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); 26#define CFC_IOSTART CFC_IOPORT_BASE 27#define CFC_IOEND (CFC_IOSTART + (M32R_PCC_MAPSIZE * M32R_MAX_PCC) - 1) 28 29#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) 30#define UART0_REGSTART 0x04c20000 31#define UART1_REGSTART 0x04c20100 32#define UART_IOMAP_SIZE 8 33#define UART0_IOSTART 0x3f8 34#define UART0_IOEND (UART0_IOSTART + UART_IOMAP_SIZE - 1) 35#define UART1_IOSTART 0x2f8 36#define UART1_IOEND (UART1_IOSTART + UART_IOMAP_SIZE - 1) 37#endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */ 38 39#define PORT2ADDR(port) _port2addr(port) 40 41static inline void *_port2addr(unsigned long port) 42{ 43#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) 44 if (port >= UART0_IOSTART && port <= UART0_IOEND) 45 port = ((port - UART0_IOSTART) << 1) + UART0_REGSTART; 46 else if (port >= UART1_IOSTART && port <= UART1_IOEND) 47 port = ((port - UART1_IOSTART) << 1) + UART1_REGSTART; 48#endif /* CONFIG_SERIAL_8250 || CONFIG_SERIAL_8250_MODULE */ 49 return (void *)(port | (NONCACHE_OFFSET)); 50} 51 52static inline void delay(void) 53{ 54 __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory"); 55} 56 57unsigned char _inb(unsigned long port) 58{ 59 if (port >= CFC_IOSTART && port <= CFC_IOEND) { 60 unsigned char b; 61 pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0); 62 return b; 63 } else 64 return *(volatile unsigned char *)PORT2ADDR(port); 65} 66 67unsigned short _inw(unsigned long port) 68{ 69 if (port >= CFC_IOSTART && port <= CFC_IOEND) { 70 unsigned short w; 71 pcc_ioread_word(0, port, &w, sizeof(w), 1, 0); 72 return w; 73 } else 74 return *(volatile unsigned short *)PORT2ADDR(port); 75} 76 77unsigned long _inl(unsigned long port) 78{ 79 if (port >= CFC_IOSTART && port <= CFC_IOEND) { 80 unsigned long l; 81 pcc_ioread_word(0, port, &l, sizeof(l), 1, 0); 82 return l; 83 } else 84 return *(volatile unsigned long *)PORT2ADDR(port); 85} 86 87unsigned char _inb_p(unsigned long port) 88{ 89 unsigned char v = _inb(port); 90 delay(); 91 return v; 92} 93 94unsigned short _inw_p(unsigned long port) 95{ 96 unsigned short v = _inw(port); 97 delay(); 98 return v; 99} 100 101unsigned long _inl_p(unsigned long port) 102{ 103 unsigned long v = _inl(port); 104 delay(); 105 return v; 106} 107 108void _outb(unsigned char b, unsigned long port) 109{ 110 if (port >= CFC_IOSTART && port <= CFC_IOEND) 111 pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); 112 else 113 *(volatile unsigned char *)PORT2ADDR(port) = b; 114} 115 116void _outw(unsigned short w, unsigned long port) 117{ 118 if (port >= CFC_IOSTART && port <= CFC_IOEND) 119 pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0); 120 else 121 *(volatile unsigned short *)PORT2ADDR(port) = w; 122} 123 124void _outl(unsigned long l, unsigned long port) 125{ 126 if (port >= CFC_IOSTART && port <= CFC_IOEND) 127 pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0); 128 else 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 >= CFC_IOSTART && port <= CFC_IOEND) 153 pcc_ioread_byte(0, port, addr, sizeof(unsigned char), count, 1); 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 >= CFC_IOSTART && port <= CFC_IOEND) 168 pcc_ioread_word(0, port, addr, sizeof(unsigned short), count, 169 1); 170 else { 171 portp = PORT2ADDR(port); 172 while (count--) 173 *buf++ = *(volatile unsigned short *)portp; 174 } 175} 176 177void _insl(unsigned int port, void * addr, unsigned long count) 178{ 179 unsigned long *buf = addr; 180 unsigned long *portp; 181 182 portp = PORT2ADDR(port); 183 while (count--) 184 *buf++ = *(volatile unsigned long *)portp; 185} 186 187void _outsb(unsigned int port, const void * addr, unsigned long count) 188{ 189 const unsigned char *buf = addr; 190 unsigned char *portp; 191 192 if (port >= CFC_IOSTART && port <= CFC_IOEND) 193 pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char), 194 count, 1); 195 else { 196 portp = PORT2ADDR(port); 197 while (count--) 198 *(volatile unsigned char *)portp = *buf++; 199 } 200} 201 202void _outsw(unsigned int port, const void * addr, unsigned long count) 203{ 204 const unsigned short *buf = addr; 205 unsigned short *portp; 206 207 if (port >= CFC_IOSTART && port <= CFC_IOEND) 208 pcc_iowrite_word(0, port, (void *)addr, sizeof(unsigned short), 209 count, 1); 210 else { 211 portp = PORT2ADDR(port); 212 while (count--) 213 *(volatile unsigned short *)portp = *buf++; 214 } 215} 216 217void _outsl(unsigned int port, const void * addr, unsigned long count) 218{ 219 const unsigned long *buf = addr; 220 unsigned char *portp; 221 222 portp = PORT2ADDR(port); 223 while (count--) 224 *(volatile unsigned long *)portp = *buf++; 225} 226