io.c 6.8 KB
Newer Older
K
kogiidena 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * arch/sh/boards/landisk/io.c
 *
 * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
 * Based largely on io_se.c.
 *
 * I/O routine for I-O Data Device, Inc. LANDISK.
 *
 * Initial version only to support LAN access; some
 * placeholder code from io_landisk.c left in with the
 * expectation of later SuperIO and PCMCIA access.
 */
/*
 * modifed by kogiidena
 * 2005.03.03
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/landisk/iodata_landisk.h>
#include <asm/addrspace.h>
P
Paul Mundt 已提交
22
#include <asm/io.h>
K
kogiidena 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

#include <linux/module.h>
#include <linux/pci.h>
#include "../../drivers/pci/pci-sh7751.h"

extern void *area5_io_base;	/* Area 5 I/O Base address */
extern void *area6_io_base;	/* Area 6 I/O Base address */

/*
 * The 7751R LANDISK uses the built-in PCI controller (PCIC)
 * of the 7751R processor, and has a SuperIO accessible via the PCI.
 * The board also includes a PCMCIA controller on its memory bus,
 * like the other Solution Engine boards.
 */

#define PCIIOBR		(volatile long *)PCI_REG(SH7751_PCIIOBR)
#define PCIMBR          (volatile long *)PCI_REG(SH7751_PCIMBR)
#define PCI_IO_AREA	SH7751_PCI_IO_BASE
#define PCI_MEM_AREA	SH7751_PCI_CONFIG_BASE

#define PCI_IOMAP(adr)	(PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))

static inline void delay(void)
{
	ctrl_inw(0xa0000000);
}

static inline unsigned long port2adr(unsigned int port)
{
	if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
		if (port == 0x3f6)
			return ((unsigned long)area5_io_base + 0x2c);
		else
			return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
				((port - 0x1f0) << 1));
	else if ((0x170 <= port && port < 0x178) || port == 0x376)
		if (port == 0x376)
			return ((unsigned long)area6_io_base + 0x2c);
		else
			return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
				((port - 0x170) << 1));
	else
P
Paul Mundt 已提交
65
		maybebadio((unsigned long)port);
K
kogiidena 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

	return port;
}

/* In case someone configures the kernel w/o PCI support: in that */
/* scenario, don't ever bother to check for PCI-window addresses */

/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
#if defined(CONFIG_PCI)
#define CHECK_SH7751_PCIIO(port) \
  ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
#else
#define CHECK_SH_7751_PCIIO(port) (0)
#endif

/*
 * General outline: remap really low stuff [eventually] to SuperIO,
 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
 * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
 * should be way beyond the window, and is used  w/o translation for
 * compatibility.
 */
P
Paul Mundt 已提交
88
u8 landisk_inb(unsigned long port)
K
kogiidena 已提交
89 90
{
	if (PXSEG(port))
P
Paul Mundt 已提交
91
		return ctrl_inb(port);
K
kogiidena 已提交
92
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
93 94 95
		return ctrl_inb(PCI_IOMAP(port));

	return ctrl_inw(port2adr(port)) & 0xff;
K
kogiidena 已提交
96 97
}

P
Paul Mundt 已提交
98
u8 landisk_inb_p(unsigned long port)
K
kogiidena 已提交
99
{
P
Paul Mundt 已提交
100
	u8 v;
K
kogiidena 已提交
101 102

	if (PXSEG(port))
P
Paul Mundt 已提交
103
		v = ctrl_inb(port);
K
kogiidena 已提交
104
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
105
		v = ctrl_inb(PCI_IOMAP(port));
K
kogiidena 已提交
106
	else
P
Paul Mundt 已提交
107 108
		v = ctrl_inw(port2adr(port)) & 0xff;

K
kogiidena 已提交
109 110 111 112 113
	delay();

	return v;
}

P
Paul Mundt 已提交
114
u16 landisk_inw(unsigned long port)
K
kogiidena 已提交
115 116
{
	if (PXSEG(port))
P
Paul Mundt 已提交
117
		return ctrl_inw(port);
K
kogiidena 已提交
118
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
119
		return ctrl_inw(PCI_IOMAP(port));
K
kogiidena 已提交
120
	else
P
Paul Mundt 已提交
121
		maybebadio(port);
K
kogiidena 已提交
122 123 124 125

	return 0;
}

P
Paul Mundt 已提交
126
u32 landisk_inl(unsigned long port)
K
kogiidena 已提交
127 128
{
	if (PXSEG(port))
P
Paul Mundt 已提交
129
		return ctrl_inl(port);
K
kogiidena 已提交
130
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
131
		return ctrl_inl(PCI_IOMAP(port));
K
kogiidena 已提交
132
	else
P
Paul Mundt 已提交
133
		maybebadio(port);
K
kogiidena 已提交
134 135 136 137

	return 0;
}

P
Paul Mundt 已提交
138
void landisk_outb(u8 value, unsigned long port)
K
kogiidena 已提交
139 140
{
	if (PXSEG(port))
P
Paul Mundt 已提交
141
		ctrl_outb(value, port);
K
kogiidena 已提交
142
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
143
		ctrl_outb(value, PCI_IOMAP(port));
K
kogiidena 已提交
144
	else
P
Paul Mundt 已提交
145
		ctrl_outw(value, port2adr(port));
K
kogiidena 已提交
146 147
}

P
Paul Mundt 已提交
148
void landisk_outb_p(u8 value, unsigned long port)
K
kogiidena 已提交
149 150
{
	if (PXSEG(port))
P
Paul Mundt 已提交
151
		ctrl_outb(value, port);
K
kogiidena 已提交
152
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
153
		ctrl_outb(value, PCI_IOMAP(port));
K
kogiidena 已提交
154
	else
P
Paul Mundt 已提交
155
		ctrl_outw(value, port2adr(port));
K
kogiidena 已提交
156 157 158
	delay();
}

P
Paul Mundt 已提交
159
void landisk_outw(u16 value, unsigned long port)
K
kogiidena 已提交
160 161
{
	if (PXSEG(port))
P
Paul Mundt 已提交
162
		ctrl_outw(value, port);
K
kogiidena 已提交
163
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
164
		ctrl_outw(value, PCI_IOMAP(port));
K
kogiidena 已提交
165
	else
P
Paul Mundt 已提交
166
		maybebadio(port);
K
kogiidena 已提交
167 168
}

P
Paul Mundt 已提交
169
void landisk_outl(u32 value, unsigned long port)
K
kogiidena 已提交
170 171
{
	if (PXSEG(port))
P
Paul Mundt 已提交
172
		ctrl_outl(value, port);
K
kogiidena 已提交
173
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
174
		ctrl_outl(value, PCI_IOMAP(port));
K
kogiidena 已提交
175
	else
P
Paul Mundt 已提交
176
		maybebadio(port);
K
kogiidena 已提交
177 178
}

P
Paul Mundt 已提交
179
void landisk_insb(unsigned long port, void *dst, unsigned long count)
K
kogiidena 已提交
180
{
P
Paul Mundt 已提交
181 182
        volatile u16 *p;
        u8 *buf = dst;
K
kogiidena 已提交
183

P
Paul Mundt 已提交
184 185 186 187 188
        if (PXSEG(port)) {
                while (count--)
                        *buf++ = *(volatile u8 *)port;
	} else if (CHECK_SH7751_PCIIO(port)) {
                volatile u8 *bp = (volatile u8 *)PCI_IOMAP(port);
K
kogiidena 已提交
189

P
Paul Mundt 已提交
190 191 192 193 194 195
                while (count--)
                        *buf++ = *bp;
	} else {
                p = (volatile u16 *)port2adr(port);
                while (count--)
                        *buf++ = *p & 0xff;
K
kogiidena 已提交
196 197 198
	}
}

P
Paul Mundt 已提交
199
void landisk_insw(unsigned long port, void *dst, unsigned long count)
K
kogiidena 已提交
200
{
P
Paul Mundt 已提交
201 202
        volatile u16 *p;
        u16 *buf = dst;
K
kogiidena 已提交
203 204

	if (PXSEG(port))
P
Paul Mundt 已提交
205
		p = (volatile u16 *)port;
K
kogiidena 已提交
206
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
207
		p = (volatile u16 *)PCI_IOMAP(port);
K
kogiidena 已提交
208
	else
P
Paul Mundt 已提交
209
		p = (volatile u16 *)port2adr(port);
K
kogiidena 已提交
210
	while (count--)
P
Paul Mundt 已提交
211
		*buf++ = *p;
K
kogiidena 已提交
212 213
}

P
Paul Mundt 已提交
214
void landisk_insl(unsigned long port, void *dst, unsigned long count)
K
kogiidena 已提交
215
{
P
Paul Mundt 已提交
216 217
        u32 *buf = dst;

K
kogiidena 已提交
218
	if (CHECK_SH7751_PCIIO(port)) {
P
Paul Mundt 已提交
219
                volatile u32 *p = (volatile u32 *)PCI_IOMAP(port);
K
kogiidena 已提交
220

P
Paul Mundt 已提交
221 222
                while (count--)
                        *buf++ = *p;
K
kogiidena 已提交
223
	} else
P
Paul Mundt 已提交
224
		maybebadio(port);
K
kogiidena 已提交
225 226
}

P
Paul Mundt 已提交
227
void landisk_outsb(unsigned long port, const void *src, unsigned long count)
K
kogiidena 已提交
228
{
P
Paul Mundt 已提交
229 230 231
        volatile u16 *p;
        const u8 *buf = src;

K
kogiidena 已提交
232
	if (PXSEG(port))
P
Paul Mundt 已提交
233 234
                while (count--)
                        ctrl_outb(*buf++, port);
K
kogiidena 已提交
235
	else if (CHECK_SH7751_PCIIO(port)) {
P
Paul Mundt 已提交
236
                volatile u8 *bp = (volatile u8 *)PCI_IOMAP(port);
K
kogiidena 已提交
237

P
Paul Mundt 已提交
238 239
                while (count--)
                        *bp = *buf++;
K
kogiidena 已提交
240
	} else {
P
Paul Mundt 已提交
241 242 243
                p = (volatile u16 *)port2adr(port);
                while (count--)
                        *p = *buf++;
K
kogiidena 已提交
244 245 246
	}
}

P
Paul Mundt 已提交
247
void landisk_outsw(unsigned long port, const void *src, unsigned long count)
K
kogiidena 已提交
248
{
P
Paul Mundt 已提交
249 250
        volatile u16 *p;
        const u16 *buf = src;
K
kogiidena 已提交
251 252

	if (PXSEG(port))
P
Paul Mundt 已提交
253
                p = (volatile u16 *)port;
K
kogiidena 已提交
254
	else if (CHECK_SH7751_PCIIO(port))
P
Paul Mundt 已提交
255
                p = (volatile u16 *)PCI_IOMAP(port);
K
kogiidena 已提交
256
	else
P
Paul Mundt 已提交
257
                p = (volatile u16 *)port2adr(port);
K
kogiidena 已提交
258

P
Paul Mundt 已提交
259 260
        while (count--)
                *p = *buf++;
K
kogiidena 已提交
261 262
}

P
Paul Mundt 已提交
263
void landisk_outsl(unsigned long port, const void *src, unsigned long count)
K
kogiidena 已提交
264
{
P
Paul Mundt 已提交
265
        const u32 *buf = src;
K
kogiidena 已提交
266

P
Paul Mundt 已提交
267 268
	if (CHECK_SH7751_PCIIO(port)) {
                volatile u32 *p = (volatile u32 *)PCI_IOMAP(port);
K
kogiidena 已提交
269

P
Paul Mundt 已提交
270 271 272 273
                while (count--)
                        *p = *buf++;
	} else
		maybebadio(port);
K
kogiidena 已提交
274 275
}

P
Paul Mundt 已提交
276
void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
K
kogiidena 已提交
277
{
P
Paul Mundt 已提交
278 279 280 281
        if (PXSEG(port))
                return (void __iomem *)port;
        else if (CHECK_SH7751_PCIIO(port))
                return (void __iomem *)PCI_IOMAP(port);
K
kogiidena 已提交
282

P
Paul Mundt 已提交
283
        return (void __iomem *)port2adr(port);
K
kogiidena 已提交
284
}