1 /* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal Exp $
3 * linux/arch/sh/kernel/io_se.c
5 * Copyright (C) 2000 Kazumoto Kojima
7 * I/O routine for Hitachi SolutionEngine.
11 #include <linux/kernel.h>
12 #include <linux/types.h>
16 /* SH pcmcia io window base, start and end. */
17 int sh_pcic_io_wbase = 0xb8400000;
23 /* MS7750 requires special versions of in*, out* routines, since
24 PC-like io ports are located at upper half byte of 16-bit word which
25 can be accessed only with 16-bit wide. */
27 static inline volatile __u16 *
28 port2adr(unsigned int port)
30 if (port & 0xff000000)
31 return ( volatile __u16 *) port;
33 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
34 else if (port >= 0x1000)
35 return (volatile __u16 *) (PA_83902 + (port << 1));
36 else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
37 return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1));
39 return (volatile __u16 *) (PA_SUPERIO + (port << 1));
43 shifted_port(unsigned long port)
45 /* For IDE registers, value is not shifted */
46 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
52 unsigned char se_inb(unsigned long port)
54 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
55 return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
56 else if (shifted_port(port))
57 return (*port2adr(port) >> 8);
59 return (*port2adr(port))&0xff;
62 unsigned char se_inb_p(unsigned long port)
66 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
67 v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
68 else if (shifted_port(port))
69 v = (*port2adr(port) >> 8);
71 v = (*port2adr(port))&0xff;
76 unsigned short se_inw(unsigned long port)
79 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
80 return *port2adr(port);
86 unsigned int se_inl(unsigned long port)
92 void se_outb(unsigned char value, unsigned long port)
94 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
95 *(__u8 *)(sh_pcic_io_wbase + port) = value;
96 else if (shifted_port(port))
97 *(port2adr(port)) = value << 8;
99 *(port2adr(port)) = value;
102 void se_outb_p(unsigned char value, unsigned long port)
104 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
105 *(__u8 *)(sh_pcic_io_wbase + port) = value;
106 else if (shifted_port(port))
107 *(port2adr(port)) = value << 8;
109 *(port2adr(port)) = value;
113 void se_outw(unsigned short value, unsigned long port)
115 if (port >= 0x2000 ||
116 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
117 *port2adr(port) = value;
122 void se_outl(unsigned int value, unsigned long port)
127 void se_insb(unsigned long port, void *addr, unsigned long count)
129 volatile __u16 *p = port2adr(port);
132 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
133 volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
136 } else if (shifted_port(port)) {
145 void se_insw(unsigned long port, void *addr, unsigned long count)
147 volatile __u16 *p = port2adr(port);
153 void se_insl(unsigned long port, void *addr, unsigned long count)
158 void se_outsb(unsigned long port, const void *addr, unsigned long count)
160 volatile __u16 *p = port2adr(port);
161 const __u8 *ap = addr;
163 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
164 volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port);
167 } else if (shifted_port(port)) {
176 void se_outsw(unsigned long port, const void *addr, unsigned long count)
178 volatile __u16 *p = port2adr(port);
179 const __u16 *ap = addr;
184 void se_outsl(unsigned long port, const void *addr, unsigned long count)