15577ff1f7153b68a0b3432183266a194625c381
[pandora-kernel.git] / arch / sh / boards / mach-systemh / io.c
1 /*
2  * linux/arch/sh/boards/renesas/systemh/io.c
3  *
4  * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
5  * Based largely on io_se.c.
6  *
7  * I/O routine for Hitachi 7751 Systemh.
8  */
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/pci.h>
12 #include <mach/systemh7751.h>
13 #include <asm/addrspace.h>
14 #include <asm/io.h>
15
16 #define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area
17                                                 of smc lan chip*/
18 static inline volatile __u16 *
19 port2adr(unsigned int port)
20 {
21         if (port >= 0x2000)
22                 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
23         maybebadio((unsigned long)port);
24         return (volatile __u16*)port;
25 }
26
27 /*
28  * General outline: remap really low stuff [eventually] to SuperIO,
29  * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
30  * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
31  * should be way beyond the window, and is used  w/o translation for
32  * compatibility.
33  */
34 unsigned char sh7751systemh_inb(unsigned long port)
35 {
36         if (PXSEG(port))
37                 return *(volatile unsigned char *)port;
38         else if (port <= 0x3F1)
39                 return *(volatile unsigned char *)ETHER_IOMAP(port);
40         else
41                 return (*port2adr(port))&0xff;
42 }
43
44 unsigned char sh7751systemh_inb_p(unsigned long port)
45 {
46         unsigned char v;
47
48         if (PXSEG(port))
49                 v = *(volatile unsigned char *)port;
50         else if (port <= 0x3F1)
51                 v = *(volatile unsigned char *)ETHER_IOMAP(port);
52         else
53                 v = (*port2adr(port))&0xff;
54         ctrl_delay();
55         return v;
56 }
57
58 unsigned short sh7751systemh_inw(unsigned long port)
59 {
60         if (PXSEG(port))
61                 return *(volatile unsigned short *)port;
62         else if (port >= 0x2000)
63                 return *port2adr(port);
64         else if (port <= 0x3F1)
65                 return *(volatile unsigned int *)ETHER_IOMAP(port);
66         else
67                 maybebadio(port);
68         return 0;
69 }
70
71 unsigned int sh7751systemh_inl(unsigned long port)
72 {
73         if (PXSEG(port))
74                 return *(volatile unsigned long *)port;
75         else if (port >= 0x2000)
76                 return *port2adr(port);
77         else if (port <= 0x3F1)
78                 return *(volatile unsigned int *)ETHER_IOMAP(port);
79         else
80                 maybebadio(port);
81         return 0;
82 }
83
84 void sh7751systemh_outb(unsigned char value, unsigned long port)
85 {
86
87         if (PXSEG(port))
88                 *(volatile unsigned char *)port = value;
89         else if (port <= 0x3F1)
90                 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
91         else
92                 *(port2adr(port)) = value;
93 }
94
95 void sh7751systemh_outb_p(unsigned char value, unsigned long port)
96 {
97         if (PXSEG(port))
98                 *(volatile unsigned char *)port = value;
99         else if (port <= 0x3F1)
100                 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
101         else
102                 *(port2adr(port)) = value;
103         ctrl_delay();
104 }
105
106 void sh7751systemh_outw(unsigned short value, unsigned long port)
107 {
108         if (PXSEG(port))
109                 *(volatile unsigned short *)port = value;
110         else if (port >= 0x2000)
111                 *port2adr(port) = value;
112         else if (port <= 0x3F1)
113                 *(volatile unsigned short *)ETHER_IOMAP(port) = value;
114         else
115                 maybebadio(port);
116 }
117
118 void sh7751systemh_outl(unsigned int value, unsigned long port)
119 {
120         if (PXSEG(port))
121                 *(volatile unsigned long *)port = value;
122         else
123                 maybebadio(port);
124 }
125
126 void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count)
127 {
128         unsigned char *p = addr;
129         while (count--) *p++ = sh7751systemh_inb(port);
130 }
131
132 void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count)
133 {
134         unsigned short *p = addr;
135         while (count--) *p++ = sh7751systemh_inw(port);
136 }
137
138 void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count)
139 {
140         maybebadio(port);
141 }
142
143 void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count)
144 {
145         unsigned char *p = (unsigned char*)addr;
146         while (count--) sh7751systemh_outb(*p++, port);
147 }
148
149 void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count)
150 {
151         unsigned short *p = (unsigned short*)addr;
152         while (count--) sh7751systemh_outw(*p++, port);
153 }
154
155 void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count)
156 {
157         maybebadio(port);
158 }