PageRenderTime 27ms CodeModel.GetById 14ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/sh/boards/se/770x/io.c

https://bitbucket.org/evzijst/gittest
C | 226 lines | 179 code | 31 blank | 16 comment | 52 complexity | 73cdc2022674dea98eb5cc11b477845d MD5 | raw file
  1/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $
  2 *
  3 * linux/arch/sh/kernel/io_se.c
  4 *
  5 * Copyright (C) 2000  Kazumoto Kojima
  6 *
  7 * I/O routine for Hitachi SolutionEngine.
  8 *
  9 */
 10
 11#include <linux/kernel.h>
 12#include <linux/types.h>
 13#include <asm/io.h>
 14#include <asm/se/se.h>
 15
 16/* SH pcmcia io window base, start and end.  */
 17int sh_pcic_io_wbase = 0xb8400000;
 18int sh_pcic_io_start;
 19int sh_pcic_io_stop;
 20int sh_pcic_io_type;
 21int sh_pcic_io_dummy;
 22
 23static inline void delay(void)
 24{
 25	ctrl_inw(0xa0000000);
 26}
 27
 28/* MS7750 requires special versions of in*, out* routines, since
 29   PC-like io ports are located at upper half byte of 16-bit word which
 30   can be accessed only with 16-bit wide.  */
 31
 32static inline volatile __u16 *
 33port2adr(unsigned int port)
 34{
 35	if (port >= 0x2000)
 36		return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
 37	else if (port >= 0x1000)
 38		return (volatile __u16 *) (PA_83902 + (port << 1));
 39	else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
 40		return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1));
 41	else
 42		return (volatile __u16 *) (PA_SUPERIO + (port << 1));
 43}
 44
 45static inline int
 46shifted_port(unsigned long port)
 47{
 48	/* For IDE registers, value is not shifted */
 49	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
 50		return 0;
 51	else
 52		return 1;
 53}
 54
 55#define maybebadio(name,port) \
 56  printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
 57	 #name, (port), (__u32) __builtin_return_address(0))
 58
 59unsigned char se_inb(unsigned long port)
 60{
 61	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
 62		return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
 63	else if (shifted_port(port))
 64		return (*port2adr(port) >> 8); 
 65	else
 66		return (*port2adr(port))&0xff; 
 67}
 68
 69unsigned char se_inb_p(unsigned long port)
 70{
 71	unsigned long v;
 72
 73	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
 74		v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
 75	else if (shifted_port(port))
 76		v = (*port2adr(port) >> 8); 
 77	else
 78		v = (*port2adr(port))&0xff; 
 79	delay();
 80	return v;
 81}
 82
 83unsigned short se_inw(unsigned long port)
 84{
 85	if (port >= 0x2000 ||
 86	    (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
 87		return *port2adr(port);
 88	else
 89		maybebadio(inw, port);
 90	return 0;
 91}
 92
 93unsigned int se_inl(unsigned long port)
 94{
 95	maybebadio(inl, port);
 96	return 0;
 97}
 98
 99void se_outb(unsigned char value, unsigned long port)
100{
101	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
102		*(__u8 *)(sh_pcic_io_wbase + port) = value; 
103	else if (shifted_port(port))
104		*(port2adr(port)) = value << 8;
105	else
106		*(port2adr(port)) = value;
107}
108
109void se_outb_p(unsigned char value, unsigned long port)
110{
111	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
112		*(__u8 *)(sh_pcic_io_wbase + port) = value; 
113	else if (shifted_port(port))
114		*(port2adr(port)) = value << 8;
115	else
116		*(port2adr(port)) = value;
117	delay();
118}
119
120void se_outw(unsigned short value, unsigned long port)
121{
122	if (port >= 0x2000 ||
123	    (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
124		*port2adr(port) = value;
125	else
126		maybebadio(outw, port);
127}
128
129void se_outl(unsigned int value, unsigned long port)
130{
131	maybebadio(outl, port);
132}
133
134void se_insb(unsigned long port, void *addr, unsigned long count)
135{
136	volatile __u16 *p = port2adr(port);
137	__u8 *ap = addr;
138
139	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
140		volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
141		while (count--)
142			*ap++ = *bp;
143	} else if (shifted_port(port)) {
144		while (count--)
145			*ap++ = *p >> 8;
146	} else {
147		while (count--)
148			*ap++ = *p;
149	}
150}
151
152void se_insw(unsigned long port, void *addr, unsigned long count)
153{
154	volatile __u16 *p = port2adr(port);
155	__u16 *ap = addr;
156	while (count--)
157		*ap++ = *p;
158}
159
160void se_insl(unsigned long port, void *addr, unsigned long count)
161{
162	maybebadio(insl, port);
163}
164
165void se_outsb(unsigned long port, const void *addr, unsigned long count)
166{
167	volatile __u16 *p = port2adr(port);
168	const __u8 *ap = addr;
169
170	if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
171		volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port); 
172		while (count--)
173			*bp = *ap++;
174	} else if (shifted_port(port)) {
175		while (count--)
176			*p = *ap++ << 8;
177	} else {
178		while (count--)
179			*p = *ap++;
180	}
181}
182
183void se_outsw(unsigned long port, const void *addr, unsigned long count)
184{
185	volatile __u16 *p = port2adr(port);
186	const __u16 *ap = addr;
187	while (count--)
188		*p = *ap++;
189}
190
191void se_outsl(unsigned long port, const void *addr, unsigned long count)
192{
193	maybebadio(outsw, port);
194}
195
196/* Map ISA bus address to the real address. Only for PCMCIA.  */
197
198/* ISA page descriptor.  */
199static __u32 sh_isa_memmap[256];
200
201static int
202sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
203{
204	int idx;
205
206	if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
207		return -1;
208
209	idx = start >> 12;
210	sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
211#if 0
212	printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
213	       start, length, offset, idx, sh_isa_memmap[idx]);
214#endif
215	return 0;
216}
217
218unsigned long
219se_isa_port2addr(unsigned long offset)
220{
221	int idx;
222
223	idx = (offset >> 12) & 0xff;
224	offset &= 0xfff;
225	return sh_isa_memmap[idx] + offset;
226}