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
)