]>
Commit | Line | Data |
---|---|---|
fafb7a97 | 1 | /* |
1da177e4 LT |
2 | * Copyright (C) 2000 Kazumoto Kojima |
3 | * | |
4 | * I/O routine for Hitachi SolutionEngine. | |
1da177e4 | 5 | */ |
1da177e4 LT |
6 | #include <linux/kernel.h> |
7 | #include <linux/types.h> | |
8 | #include <asm/io.h> | |
939a24a6 | 9 | #include <mach-se/mach/se.h> |
1da177e4 | 10 | |
1da177e4 LT |
11 | /* MS7750 requires special versions of in*, out* routines, since |
12 | PC-like io ports are located at upper half byte of 16-bit word which | |
13 | can be accessed only with 16-bit wide. */ | |
14 | ||
15 | static inline volatile __u16 * | |
16 | port2adr(unsigned int port) | |
17 | { | |
9465a54f NI |
18 | if (port & 0xff000000) |
19 | return ( volatile __u16 *) port; | |
1da177e4 LT |
20 | if (port >= 0x2000) |
21 | return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); | |
22 | else if (port >= 0x1000) | |
23 | return (volatile __u16 *) (PA_83902 + (port << 1)); | |
1da177e4 LT |
24 | else |
25 | return (volatile __u16 *) (PA_SUPERIO + (port << 1)); | |
26 | } | |
27 | ||
28 | static inline int | |
29 | shifted_port(unsigned long port) | |
30 | { | |
31 | /* For IDE registers, value is not shifted */ | |
32 | if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) | |
33 | return 0; | |
34 | else | |
35 | return 1; | |
36 | } | |
37 | ||
1da177e4 LT |
38 | unsigned char se_inb(unsigned long port) |
39 | { | |
fafb7a97 NI |
40 | if (shifted_port(port)) |
41 | return (*port2adr(port) >> 8); | |
1da177e4 | 42 | else |
fafb7a97 | 43 | return (*port2adr(port))&0xff; |
1da177e4 LT |
44 | } |
45 | ||
46 | unsigned char se_inb_p(unsigned long port) | |
47 | { | |
48 | unsigned long v; | |
49 | ||
fafb7a97 NI |
50 | if (shifted_port(port)) |
51 | v = (*port2adr(port) >> 8); | |
1da177e4 | 52 | else |
fafb7a97 | 53 | v = (*port2adr(port))&0xff; |
959f85f8 | 54 | ctrl_delay(); |
1da177e4 LT |
55 | return v; |
56 | } | |
57 | ||
58 | unsigned short se_inw(unsigned long port) | |
59 | { | |
fafb7a97 | 60 | if (port >= 0x2000) |
1da177e4 LT |
61 | return *port2adr(port); |
62 | else | |
373e68b5 | 63 | maybebadio(port); |
1da177e4 LT |
64 | return 0; |
65 | } | |
66 | ||
67 | unsigned int se_inl(unsigned long port) | |
68 | { | |
373e68b5 | 69 | maybebadio(port); |
1da177e4 LT |
70 | return 0; |
71 | } | |
72 | ||
73 | void se_outb(unsigned char value, unsigned long port) | |
74 | { | |
fafb7a97 | 75 | if (shifted_port(port)) |
1da177e4 LT |
76 | *(port2adr(port)) = value << 8; |
77 | else | |
78 | *(port2adr(port)) = value; | |
79 | } | |
80 | ||
81 | void se_outb_p(unsigned char value, unsigned long port) | |
82 | { | |
fafb7a97 | 83 | if (shifted_port(port)) |
1da177e4 LT |
84 | *(port2adr(port)) = value << 8; |
85 | else | |
86 | *(port2adr(port)) = value; | |
959f85f8 | 87 | ctrl_delay(); |
1da177e4 LT |
88 | } |
89 | ||
90 | void se_outw(unsigned short value, unsigned long port) | |
91 | { | |
fafb7a97 | 92 | if (port >= 0x2000) |
1da177e4 LT |
93 | *port2adr(port) = value; |
94 | else | |
373e68b5 | 95 | maybebadio(port); |
1da177e4 LT |
96 | } |
97 | ||
98 | void se_outl(unsigned int value, unsigned long port) | |
99 | { | |
373e68b5 | 100 | maybebadio(port); |
1da177e4 LT |
101 | } |
102 | ||
103 | void se_insb(unsigned long port, void *addr, unsigned long count) | |
104 | { | |
105 | volatile __u16 *p = port2adr(port); | |
106 | __u8 *ap = addr; | |
107 | ||
fafb7a97 | 108 | if (shifted_port(port)) { |
1da177e4 LT |
109 | while (count--) |
110 | *ap++ = *p >> 8; | |
111 | } else { | |
112 | while (count--) | |
113 | *ap++ = *p; | |
114 | } | |
115 | } | |
116 | ||
117 | void se_insw(unsigned long port, void *addr, unsigned long count) | |
118 | { | |
119 | volatile __u16 *p = port2adr(port); | |
120 | __u16 *ap = addr; | |
121 | while (count--) | |
122 | *ap++ = *p; | |
123 | } | |
124 | ||
125 | void se_insl(unsigned long port, void *addr, unsigned long count) | |
126 | { | |
373e68b5 | 127 | maybebadio(port); |
1da177e4 LT |
128 | } |
129 | ||
130 | void se_outsb(unsigned long port, const void *addr, unsigned long count) | |
131 | { | |
132 | volatile __u16 *p = port2adr(port); | |
133 | const __u8 *ap = addr; | |
134 | ||
fafb7a97 | 135 | if (shifted_port(port)) { |
1da177e4 LT |
136 | while (count--) |
137 | *p = *ap++ << 8; | |
138 | } else { | |
139 | while (count--) | |
140 | *p = *ap++; | |
141 | } | |
142 | } | |
143 | ||
144 | void se_outsw(unsigned long port, const void *addr, unsigned long count) | |
145 | { | |
146 | volatile __u16 *p = port2adr(port); | |
147 | const __u16 *ap = addr; | |
fafb7a97 | 148 | |
1da177e4 LT |
149 | while (count--) |
150 | *p = *ap++; | |
151 | } | |
152 | ||
153 | void se_outsl(unsigned long port, const void *addr, unsigned long count) | |
154 | { | |
373e68b5 | 155 | maybebadio(port); |
1da177e4 | 156 | } |