aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/boards/mach-microdev
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/boards/mach-microdev')
-rw-r--r--arch/sh/boards/mach-microdev/Makefile8
-rw-r--r--arch/sh/boards/mach-microdev/io.c367
-rw-r--r--arch/sh/boards/mach-microdev/irq.c183
-rw-r--r--arch/sh/boards/mach-microdev/led.c101
-rw-r--r--arch/sh/boards/mach-microdev/setup.c405
5 files changed, 1064 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-microdev/Makefile b/arch/sh/boards/mach-microdev/Makefile
new file mode 100644
index 000000000000..1387dd6c85eb
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the SuperH MicroDev specific parts of the kernel
3#
4
5obj-y := setup.o irq.o io.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
8
diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c
new file mode 100644
index 000000000000..9f8a540f7e14
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/io.c
@@ -0,0 +1,367 @@
1/*
2 * linux/arch/sh/boards/superh/microdev/io.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 * Copyright (C) 2003, 2004 SuperH, Inc.
6 * Copyright (C) 2004 Paul Mundt
7 *
8 * SuperH SH4-202 MicroDev board support.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 */
13
14#include <linux/init.h>
15#include <linux/pci.h>
16#include <linux/wait.h>
17#include <asm/io.h>
18#include <asm/microdev.h>
19
20 /*
21 * we need to have a 'safe' address to re-direct all I/O requests
22 * that we do not explicitly wish to handle. This safe address
23 * must have the following properies:
24 *
25 * * writes are ignored (no exception)
26 * * reads are benign (no side-effects)
27 * * accesses of width 1, 2 and 4-bytes are all valid.
28 *
29 * The Processor Version Register (PVR) has these properties.
30 */
31#define PVR 0xff000030 /* Processor Version Register */
32
33
34#define IO_IDE2_BASE 0x170ul /* I/O base for SMSC FDC37C93xAPM IDE #2 */
35#define IO_IDE1_BASE 0x1f0ul /* I/O base for SMSC FDC37C93xAPM IDE #1 */
36#define IO_ISP1161_BASE 0x290ul /* I/O port for Philips ISP1161x USB chip */
37#define IO_SERIAL2_BASE 0x2f8ul /* I/O base for SMSC FDC37C93xAPM Serial #2 */
38#define IO_LAN91C111_BASE 0x300ul /* I/O base for SMSC LAN91C111 Ethernet chip */
39#define IO_IDE2_MISC 0x376ul /* I/O misc for SMSC FDC37C93xAPM IDE #2 */
40#define IO_SUPERIO_BASE 0x3f0ul /* I/O base for SMSC FDC37C93xAPM SuperIO chip */
41#define IO_IDE1_MISC 0x3f6ul /* I/O misc for SMSC FDC37C93xAPM IDE #1 */
42#define IO_SERIAL1_BASE 0x3f8ul /* I/O base for SMSC FDC37C93xAPM Serial #1 */
43
44#define IO_ISP1161_EXTENT 0x04ul /* I/O extent for Philips ISP1161x USB chip */
45#define IO_LAN91C111_EXTENT 0x10ul /* I/O extent for SMSC LAN91C111 Ethernet chip */
46#define IO_SUPERIO_EXTENT 0x02ul /* I/O extent for SMSC FDC37C93xAPM SuperIO chip */
47#define IO_IDE_EXTENT 0x08ul /* I/O extent for IDE Task Register set */
48#define IO_SERIAL_EXTENT 0x10ul
49
50#define IO_LAN91C111_PHYS 0xa7500000ul /* Physical address of SMSC LAN91C111 Ethernet chip */
51#define IO_ISP1161_PHYS 0xa7700000ul /* Physical address of Philips ISP1161x USB chip */
52#define IO_SUPERIO_PHYS 0xa7800000ul /* Physical address of SMSC FDC37C93xAPM SuperIO chip */
53
54/*
55 * map I/O ports to memory-mapped addresses
56 */
57static unsigned long microdev_isa_port2addr(unsigned long offset)
58{
59 unsigned long result;
60
61 if ((offset >= IO_LAN91C111_BASE) &&
62 (offset < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
63 /*
64 * SMSC LAN91C111 Ethernet chip
65 */
66 result = IO_LAN91C111_PHYS + offset - IO_LAN91C111_BASE;
67 } else if ((offset >= IO_SUPERIO_BASE) &&
68 (offset < IO_SUPERIO_BASE + IO_SUPERIO_EXTENT)) {
69 /*
70 * SMSC FDC37C93xAPM SuperIO chip
71 *
72 * Configuration Registers
73 */
74 result = IO_SUPERIO_PHYS + (offset << 1);
75#if 0
76 } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG ||
77 offset == KBD_STATUS_REG) {
78 /*
79 * SMSC FDC37C93xAPM SuperIO chip
80 *
81 * PS/2 Keyboard + Mouse (ports 0x60 and 0x64).
82 */
83 result = IO_SUPERIO_PHYS + (offset << 1);
84#endif
85 } else if (((offset >= IO_IDE1_BASE) &&
86 (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) ||
87 (offset == IO_IDE1_MISC)) {
88 /*
89 * SMSC FDC37C93xAPM SuperIO chip
90 *
91 * IDE #1
92 */
93 result = IO_SUPERIO_PHYS + (offset << 1);
94 } else if (((offset >= IO_IDE2_BASE) &&
95 (offset < IO_IDE2_BASE + IO_IDE_EXTENT)) ||
96 (offset == IO_IDE2_MISC)) {
97 /*
98 * SMSC FDC37C93xAPM SuperIO chip
99 *
100 * IDE #2
101 */
102 result = IO_SUPERIO_PHYS + (offset << 1);
103 } else if ((offset >= IO_SERIAL1_BASE) &&
104 (offset < IO_SERIAL1_BASE + IO_SERIAL_EXTENT)) {
105 /*
106 * SMSC FDC37C93xAPM SuperIO chip
107 *
108 * Serial #1
109 */
110 result = IO_SUPERIO_PHYS + (offset << 1);
111 } else if ((offset >= IO_SERIAL2_BASE) &&
112 (offset < IO_SERIAL2_BASE + IO_SERIAL_EXTENT)) {
113 /*
114 * SMSC FDC37C93xAPM SuperIO chip
115 *
116 * Serial #2
117 */
118 result = IO_SUPERIO_PHYS + (offset << 1);
119 } else if ((offset >= IO_ISP1161_BASE) &&
120 (offset < IO_ISP1161_BASE + IO_ISP1161_EXTENT)) {
121 /*
122 * Philips USB ISP1161x chip
123 */
124 result = IO_ISP1161_PHYS + offset - IO_ISP1161_BASE;
125 } else {
126 /*
127 * safe default.
128 */
129 printk("Warning: unexpected port in %s( offset = 0x%lx )\n",
130 __func__, offset);
131 result = PVR;
132 }
133
134 return result;
135}
136
137#define PORT2ADDR(x) (microdev_isa_port2addr(x))
138
139static inline void delay(void)
140{
141#if defined(CONFIG_PCI)
142 /* System board present, just make a dummy SRAM access. (CS0 will be
143 mapped to PCI memory, probably good to avoid it.) */
144 ctrl_inw(0xa6800000);
145#else
146 /* CS0 will be mapped to flash, ROM etc so safe to access it. */
147 ctrl_inw(0xa0000000);
148#endif
149}
150
151unsigned char microdev_inb(unsigned long port)
152{
153#ifdef CONFIG_PCI
154 if (port >= PCIBIOS_MIN_IO)
155 return microdev_pci_inb(port);
156#endif
157 return *(volatile unsigned char*)PORT2ADDR(port);
158}
159
160unsigned short microdev_inw(unsigned long port)
161{
162#ifdef CONFIG_PCI
163 if (port >= PCIBIOS_MIN_IO)
164 return microdev_pci_inw(port);
165#endif
166 return *(volatile unsigned short*)PORT2ADDR(port);
167}
168
169unsigned int microdev_inl(unsigned long port)
170{
171#ifdef CONFIG_PCI
172 if (port >= PCIBIOS_MIN_IO)
173 return microdev_pci_inl(port);
174#endif
175 return *(volatile unsigned int*)PORT2ADDR(port);
176}
177
178void microdev_outw(unsigned short b, unsigned long port)
179{
180#ifdef CONFIG_PCI
181 if (port >= PCIBIOS_MIN_IO) {
182 microdev_pci_outw(b, port);
183 return;
184 }
185#endif
186 *(volatile unsigned short*)PORT2ADDR(port) = b;
187}
188
189void microdev_outb(unsigned char b, unsigned long port)
190{
191#ifdef CONFIG_PCI
192 if (port >= PCIBIOS_MIN_IO) {
193 microdev_pci_outb(b, port);
194 return;
195 }
196#endif
197
198 /*
199 * There is a board feature with the current SH4-202 MicroDev in
200 * that the 2 byte enables (nBE0 and nBE1) are tied together (and
201 * to the Chip Select Line (Ethernet_CS)). Due to this connectivity,
202 * it is not possible to safely perform 8-bit writes to the
203 * Ethernet registers, as 16-bits will be consumed from the Data
204 * lines (corrupting the other byte). Hence, this function is
205 * written to implement 16-bit read/modify/write for all byte-wide
206 * accesses.
207 *
208 * Note: there is no problem with byte READS (even or odd).
209 *
210 * Sean McGoogan - 16th June 2003.
211 */
212 if ((port >= IO_LAN91C111_BASE) &&
213 (port < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) {
214 /*
215 * Then are trying to perform a byte-write to the
216 * LAN91C111. This needs special care.
217 */
218 if (port % 2 == 1) { /* is the port odd ? */
219 /* unset bit-0, i.e. make even */
220 const unsigned long evenPort = port-1;
221 unsigned short word;
222
223 /*
224 * do a 16-bit read/write to write to 'port',
225 * preserving even byte.
226 *
227 * Even addresses are bits 0-7
228 * Odd addresses are bits 8-15
229 */
230 word = microdev_inw(evenPort);
231 word = (word & 0xffu) | (b << 8);
232 microdev_outw(word, evenPort);
233 } else {
234 /* else, we are trying to do an even byte write */
235 unsigned short word;
236
237 /*
238 * do a 16-bit read/write to write to 'port',
239 * preserving odd byte.
240 *
241 * Even addresses are bits 0-7
242 * Odd addresses are bits 8-15
243 */
244 word = microdev_inw(port);
245 word = (word & 0xff00u) | (b);
246 microdev_outw(word, port);
247 }
248 } else {
249 *(volatile unsigned char*)PORT2ADDR(port) = b;
250 }
251}
252
253void microdev_outl(unsigned int b, unsigned long port)
254{
255#ifdef CONFIG_PCI
256 if (port >= PCIBIOS_MIN_IO) {
257 microdev_pci_outl(b, port);
258 return;
259 }
260#endif
261 *(volatile unsigned int*)PORT2ADDR(port) = b;
262}
263
264unsigned char microdev_inb_p(unsigned long port)
265{
266 unsigned char v = microdev_inb(port);
267 delay();
268 return v;
269}
270
271unsigned short microdev_inw_p(unsigned long port)
272{
273 unsigned short v = microdev_inw(port);
274 delay();
275 return v;
276}
277
278unsigned int microdev_inl_p(unsigned long port)
279{
280 unsigned int v = microdev_inl(port);
281 delay();
282 return v;
283}
284
285void microdev_outb_p(unsigned char b, unsigned long port)
286{
287 microdev_outb(b, port);
288 delay();
289}
290
291void microdev_outw_p(unsigned short b, unsigned long port)
292{
293 microdev_outw(b, port);
294 delay();
295}
296
297void microdev_outl_p(unsigned int b, unsigned long port)
298{
299 microdev_outl(b, port);
300 delay();
301}
302
303void microdev_insb(unsigned long port, void *buffer, unsigned long count)
304{
305 volatile unsigned char *port_addr;
306 unsigned char *buf = buffer;
307
308 port_addr = (volatile unsigned char *)PORT2ADDR(port);
309
310 while (count--)
311 *buf++ = *port_addr;
312}
313
314void microdev_insw(unsigned long port, void *buffer, unsigned long count)
315{
316 volatile unsigned short *port_addr;
317 unsigned short *buf = buffer;
318
319 port_addr = (volatile unsigned short *)PORT2ADDR(port);
320
321 while (count--)
322 *buf++ = *port_addr;
323}
324
325void microdev_insl(unsigned long port, void *buffer, unsigned long count)
326{
327 volatile unsigned long *port_addr;
328 unsigned int *buf = buffer;
329
330 port_addr = (volatile unsigned long *)PORT2ADDR(port);
331
332 while (count--)
333 *buf++ = *port_addr;
334}
335
336void microdev_outsb(unsigned long port, const void *buffer, unsigned long count)
337{
338 volatile unsigned char *port_addr;
339 const unsigned char *buf = buffer;
340
341 port_addr = (volatile unsigned char *)PORT2ADDR(port);
342
343 while (count--)
344 *port_addr = *buf++;
345}
346
347void microdev_outsw(unsigned long port, const void *buffer, unsigned long count)
348{
349 volatile unsigned short *port_addr;
350 const unsigned short *buf = buffer;
351
352 port_addr = (volatile unsigned short *)PORT2ADDR(port);
353
354 while (count--)
355 *port_addr = *buf++;
356}
357
358void microdev_outsl(unsigned long port, const void *buffer, unsigned long count)
359{
360 volatile unsigned long *port_addr;
361 const unsigned int *buf = buffer;
362
363 port_addr = (volatile unsigned long *)PORT2ADDR(port);
364
365 while (count--)
366 *port_addr = *buf++;
367}
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
new file mode 100644
index 000000000000..4d335077a3ff
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -0,0 +1,183 @@
1/*
2 * arch/sh/boards/superh/microdev/irq.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 *
6 * SuperH SH4-202 MicroDev board support.
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11
12#include <linux/init.h>
13#include <linux/irq.h>
14#include <linux/interrupt.h>
15#include <asm/system.h>
16#include <asm/io.h>
17#include <asm/microdev.h>
18
19#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */
20
21static const struct {
22 unsigned char fpgaIrq;
23 unsigned char mapped;
24 const char *name;
25} fpgaIrqTable[NUM_EXTERNAL_IRQS] = {
26 { 0, 0, "unused" }, /* IRQ #0 IRL=15 0x200 */
27 { MICRODEV_FPGA_IRQ_KEYBOARD, 1, "keyboard" }, /* IRQ #1 IRL=14 0x220 */
28 { MICRODEV_FPGA_IRQ_SERIAL1, 1, "Serial #1"}, /* IRQ #2 IRL=13 0x240 */
29 { MICRODEV_FPGA_IRQ_ETHERNET, 1, "Ethernet" }, /* IRQ #3 IRL=12 0x260 */
30 { MICRODEV_FPGA_IRQ_SERIAL2, 0, "Serial #2"}, /* IRQ #4 IRL=11 0x280 */
31 { 0, 0, "unused" }, /* IRQ #5 IRL=10 0x2a0 */
32 { 0, 0, "unused" }, /* IRQ #6 IRL=9 0x2c0 */
33 { MICRODEV_FPGA_IRQ_USB_HC, 1, "USB" }, /* IRQ #7 IRL=8 0x2e0 */
34 { MICRODEV_IRQ_PCI_INTA, 1, "PCI INTA" }, /* IRQ #8 IRL=7 0x300 */
35 { MICRODEV_IRQ_PCI_INTB, 1, "PCI INTB" }, /* IRQ #9 IRL=6 0x320 */
36 { MICRODEV_IRQ_PCI_INTC, 1, "PCI INTC" }, /* IRQ #10 IRL=5 0x340 */
37 { MICRODEV_IRQ_PCI_INTD, 1, "PCI INTD" }, /* IRQ #11 IRL=4 0x360 */
38 { MICRODEV_FPGA_IRQ_MOUSE, 1, "mouse" }, /* IRQ #12 IRL=3 0x380 */
39 { MICRODEV_FPGA_IRQ_IDE2, 1, "IDE #2" }, /* IRQ #13 IRL=2 0x3a0 */
40 { MICRODEV_FPGA_IRQ_IDE1, 1, "IDE #1" }, /* IRQ #14 IRL=1 0x3c0 */
41 { 0, 0, "unused" }, /* IRQ #15 IRL=0 0x3e0 */
42};
43
44#if (MICRODEV_LINUX_IRQ_KEYBOARD != 1)
45# error Inconsistancy in defining the IRQ# for Keyboard!
46#endif
47
48#if (MICRODEV_LINUX_IRQ_ETHERNET != 3)
49# error Inconsistancy in defining the IRQ# for Ethernet!
50#endif
51
52#if (MICRODEV_LINUX_IRQ_USB_HC != 7)
53# error Inconsistancy in defining the IRQ# for USB!
54#endif
55
56#if (MICRODEV_LINUX_IRQ_MOUSE != 12)
57# error Inconsistancy in defining the IRQ# for PS/2 Mouse!
58#endif
59
60#if (MICRODEV_LINUX_IRQ_IDE2 != 13)
61# error Inconsistancy in defining the IRQ# for secondary IDE!
62#endif
63
64#if (MICRODEV_LINUX_IRQ_IDE1 != 14)
65# error Inconsistancy in defining the IRQ# for primary IDE!
66#endif
67
68static void enable_microdev_irq(unsigned int irq);
69static void disable_microdev_irq(unsigned int irq);
70
71 /* shutdown is same as "disable" */
72#define shutdown_microdev_irq disable_microdev_irq
73
74static void mask_and_ack_microdev(unsigned int);
75static void end_microdev_irq(unsigned int irq);
76
77static unsigned int startup_microdev_irq(unsigned int irq)
78{
79 enable_microdev_irq(irq);
80 return 0; /* never anything pending */
81}
82
83static struct hw_interrupt_type microdev_irq_type = {
84 .typename = "MicroDev-IRQ",
85 .startup = startup_microdev_irq,
86 .shutdown = shutdown_microdev_irq,
87 .enable = enable_microdev_irq,
88 .disable = disable_microdev_irq,
89 .ack = mask_and_ack_microdev,
90 .end = end_microdev_irq
91};
92
93static void disable_microdev_irq(unsigned int irq)
94{
95 unsigned int fpgaIrq;
96
97 if (irq >= NUM_EXTERNAL_IRQS)
98 return;
99 if (!fpgaIrqTable[irq].mapped)
100 return;
101
102 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
103
104 /* disable interrupts on the FPGA INTC register */
105 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
106}
107
108static void enable_microdev_irq(unsigned int irq)
109{
110 unsigned long priorityReg, priorities, pri;
111 unsigned int fpgaIrq;
112
113 if (unlikely(irq >= NUM_EXTERNAL_IRQS))
114 return;
115 if (unlikely(!fpgaIrqTable[irq].mapped))
116 return;
117
118 pri = 15 - irq;
119
120 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
121 priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
122
123 /* set priority for the interrupt */
124 priorities = ctrl_inl(priorityReg);
125 priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
126 priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
127 ctrl_outl(priorities, priorityReg);
128
129 /* enable interrupts on the FPGA INTC register */
130 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
131}
132
133 /* This functions sets the desired irq handler to be a MicroDev type */
134static void __init make_microdev_irq(unsigned int irq)
135{
136 disable_irq_nosync(irq);
137 irq_desc[irq].chip = &microdev_irq_type;
138 disable_microdev_irq(irq);
139}
140
141static void mask_and_ack_microdev(unsigned int irq)
142{
143 disable_microdev_irq(irq);
144}
145
146static void end_microdev_irq(unsigned int irq)
147{
148 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
149 enable_microdev_irq(irq);
150}
151
152extern void __init init_microdev_irq(void)
153{
154 int i;
155
156 /* disable interrupts on the FPGA INTC register */
157 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
158
159 for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
160 make_microdev_irq(i);
161}
162
163extern void microdev_print_fpga_intc_status(void)
164{
165 volatile unsigned int * const intenb = (unsigned int*)MICRODEV_FPGA_INTENB_REG;
166 volatile unsigned int * const intdsb = (unsigned int*)MICRODEV_FPGA_INTDSB_REG;
167 volatile unsigned int * const intpria = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(0);
168 volatile unsigned int * const intprib = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(8);
169 volatile unsigned int * const intpric = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(16);
170 volatile unsigned int * const intprid = (unsigned int*)MICRODEV_FPGA_INTPRI_REG(24);
171 volatile unsigned int * const intsrc = (unsigned int*)MICRODEV_FPGA_INTSRC_REG;
172 volatile unsigned int * const intreq = (unsigned int*)MICRODEV_FPGA_INTREQ_REG;
173
174 printk("-------------------------- microdev_print_fpga_intc_status() ------------------\n");
175 printk("FPGA_INTENB = 0x%08x\n", *intenb);
176 printk("FPGA_INTDSB = 0x%08x\n", *intdsb);
177 printk("FPGA_INTSRC = 0x%08x\n", *intsrc);
178 printk("FPGA_INTREQ = 0x%08x\n", *intreq);
179 printk("FPGA_INTPRI[3..0] = %08x:%08x:%08x:%08x\n", *intprid, *intpric, *intprib, *intpria);
180 printk("-------------------------------------------------------------------------------\n");
181}
182
183
diff --git a/arch/sh/boards/mach-microdev/led.c b/arch/sh/boards/mach-microdev/led.c
new file mode 100644
index 000000000000..36e54b47a752
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/led.c
@@ -0,0 +1,101 @@
1/*
2 * linux/arch/sh/boards/superh/microdev/led.c
3 *
4 * Copyright (C) 2002 Stuart Menefy <stuart.menefy@st.com>
5 * Copyright (C) 2003 Richard Curnow (Richard.Curnow@superh.com)
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#include <asm/io.h>
13
14#define LED_REGISTER 0xa6104d20
15
16static void mach_led_d9(int value)
17{
18 unsigned long reg;
19 reg = ctrl_inl(LED_REGISTER);
20 reg &= ~1;
21 reg |= (value & 1);
22 ctrl_outl(reg, LED_REGISTER);
23 return;
24}
25
26static void mach_led_d10(int value)
27{
28 unsigned long reg;
29 reg = ctrl_inl(LED_REGISTER);
30 reg &= ~2;
31 reg |= ((value & 1) << 1);
32 ctrl_outl(reg, LED_REGISTER);
33 return;
34}
35
36
37#ifdef CONFIG_HEARTBEAT
38#include <linux/sched.h>
39
40static unsigned char banner_table[] = {
41 0x11, 0x01, 0x11, 0x01, 0x11, 0x03,
42 0x11, 0x01, 0x11, 0x01, 0x13, 0x03,
43 0x11, 0x01, 0x13, 0x01, 0x13, 0x01, 0x11, 0x03,
44 0x11, 0x03,
45 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
46 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x11, 0x07,
47 0x13, 0x01, 0x13, 0x03,
48 0x11, 0x01, 0x11, 0x03,
49 0x13, 0x01, 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
50 0x11, 0x01, 0x13, 0x01, 0x11, 0x03,
51 0x13, 0x01, 0x13, 0x01, 0x13, 0x03,
52 0x13, 0x01, 0x11, 0x01, 0x11, 0x03,
53 0x11, 0x03,
54 0x11, 0x01, 0x11, 0x01, 0x11, 0x01, 0x13, 0x07,
55 0xff
56};
57
58static void banner(void)
59{
60 static int pos = 0;
61 static int count = 0;
62
63 if (count) {
64 count--;
65 } else {
66 int val = banner_table[pos];
67 if (val == 0xff) {
68 pos = 0;
69 val = banner_table[pos];
70 }
71 pos++;
72 mach_led_d10((val >> 4) & 1);
73 count = 10 * (val & 0xf);
74 }
75}
76
77/* From heartbeat_harp in the stboards directory */
78/* acts like an actual heart beat -- ie thump-thump-pause... */
79void microdev_heartbeat(void)
80{
81 static unsigned cnt = 0, period = 0, dist = 0;
82
83 if (cnt == 0 || cnt == dist)
84 mach_led_d9(1);
85 else if (cnt == 7 || cnt == dist+7)
86 mach_led_d9(0);
87
88 if (++cnt > period) {
89 cnt = 0;
90 /* The hyperbolic function below modifies the heartbeat period
91 * length in dependency of the current (5min) load. It goes
92 * through the points f(0)=126, f(1)=86, f(5)=51,
93 * f(inf)->30. */
94 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
95 dist = period / 4;
96 }
97
98 banner();
99}
100
101#endif
diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c
new file mode 100644
index 000000000000..fc8cd06d66cf
--- /dev/null
+++ b/arch/sh/boards/mach-microdev/setup.c
@@ -0,0 +1,405 @@
1/*
2 * arch/sh/boards/superh/microdev/setup.c
3 *
4 * Copyright (C) 2003 Sean McGoogan (Sean.McGoogan@superh.com)
5 * Copyright (C) 2003, 2004 SuperH, Inc.
6 * Copyright (C) 2004, 2005 Paul Mundt
7 *
8 * SuperH SH4-202 MicroDev board support.
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 */
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/ioport.h>
16#include <video/s1d13xxxfb.h>
17#include <asm/microdev.h>
18#include <asm/io.h>
19#include <asm/machvec.h>
20
21extern void microdev_heartbeat(void);
22
23
24/****************************************************************************/
25
26
27 /*
28 * Setup for the SMSC FDC37C93xAPM
29 */
30#define SMSC_CONFIG_PORT_ADDR (0x3F0)
31#define SMSC_INDEX_PORT_ADDR SMSC_CONFIG_PORT_ADDR
32#define SMSC_DATA_PORT_ADDR (SMSC_INDEX_PORT_ADDR + 1)
33
34#define SMSC_ENTER_CONFIG_KEY 0x55
35#define SMSC_EXIT_CONFIG_KEY 0xaa
36
37#define SMCS_LOGICAL_DEV_INDEX 0x07 /* Logical Device Number */
38#define SMSC_DEVICE_ID_INDEX 0x20 /* Device ID */
39#define SMSC_DEVICE_REV_INDEX 0x21 /* Device Revision */
40#define SMSC_ACTIVATE_INDEX 0x30 /* Activate */
41#define SMSC_PRIMARY_BASE_INDEX 0x60 /* Primary Base Address */
42#define SMSC_SECONDARY_BASE_INDEX 0x62 /* Secondary Base Address */
43#define SMSC_PRIMARY_INT_INDEX 0x70 /* Primary Interrupt Select */
44#define SMSC_SECONDARY_INT_INDEX 0x72 /* Secondary Interrupt Select */
45#define SMSC_HDCS0_INDEX 0xf0 /* HDCS0 Address Decoder */
46#define SMSC_HDCS1_INDEX 0xf1 /* HDCS1 Address Decoder */
47
48#define SMSC_IDE1_DEVICE 1 /* IDE #1 logical device */
49#define SMSC_IDE2_DEVICE 2 /* IDE #2 logical device */
50#define SMSC_PARALLEL_DEVICE 3 /* Parallel Port logical device */
51#define SMSC_SERIAL1_DEVICE 4 /* Serial #1 logical device */
52#define SMSC_SERIAL2_DEVICE 5 /* Serial #2 logical device */
53#define SMSC_KEYBOARD_DEVICE 7 /* Keyboard logical device */
54#define SMSC_CONFIG_REGISTERS 8 /* Configuration Registers (Aux I/O) */
55
56#define SMSC_READ_INDEXED(index) ({ \
57 outb((index), SMSC_INDEX_PORT_ADDR); \
58 inb(SMSC_DATA_PORT_ADDR); })
59#define SMSC_WRITE_INDEXED(val, index) ({ \
60 outb((index), SMSC_INDEX_PORT_ADDR); \
61 outb((val), SMSC_DATA_PORT_ADDR); })
62
63#define IDE1_PRIMARY_BASE 0x01f0 /* Task File Registe base for IDE #1 */
64#define IDE1_SECONDARY_BASE 0x03f6 /* Miscellaneous AT registers for IDE #1 */
65#define IDE2_PRIMARY_BASE 0x0170 /* Task File Registe base for IDE #2 */
66#define IDE2_SECONDARY_BASE 0x0376 /* Miscellaneous AT registers for IDE #2 */
67
68#define SERIAL1_PRIMARY_BASE 0x03f8
69#define SERIAL2_PRIMARY_BASE 0x02f8
70
71#define MSB(x) ( (x) >> 8 )
72#define LSB(x) ( (x) & 0xff )
73
74 /* General-Purpose base address on CPU-board FPGA */
75#define MICRODEV_FPGA_GP_BASE 0xa6100000ul
76
77 /* assume a Keyboard Controller is present */
78int microdev_kbd_controller_present = 1;
79
80static struct resource smc91x_resources[] = {
81 [0] = {
82 .start = 0x300,
83 .end = 0x300 + 0x0001000 - 1,
84 .flags = IORESOURCE_MEM,
85 },
86 [1] = {
87 .start = MICRODEV_LINUX_IRQ_ETHERNET,
88 .end = MICRODEV_LINUX_IRQ_ETHERNET,
89 .flags = IORESOURCE_IRQ,
90 },
91};
92
93static struct platform_device smc91x_device = {
94 .name = "smc91x",
95 .id = -1,
96 .num_resources = ARRAY_SIZE(smc91x_resources),
97 .resource = smc91x_resources,
98};
99
100#ifdef CONFIG_FB_S1D13XXX
101static struct s1d13xxxfb_regval s1d13806_initregs[] = {
102 { S1DREG_MISC, 0x00 },
103 { S1DREG_COM_DISP_MODE, 0x00 },
104 { S1DREG_GPIO_CNF0, 0x00 },
105 { S1DREG_GPIO_CNF1, 0x00 },
106 { S1DREG_GPIO_CTL0, 0x00 },
107 { S1DREG_GPIO_CTL1, 0x00 },
108 { S1DREG_CLK_CNF, 0x02 },
109 { S1DREG_LCD_CLK_CNF, 0x01 },
110 { S1DREG_CRT_CLK_CNF, 0x03 },
111 { S1DREG_MPLUG_CLK_CNF, 0x03 },
112 { S1DREG_CPU2MEM_WST_SEL, 0x02 },
113 { S1DREG_SDRAM_REF_RATE, 0x03 },
114 { S1DREG_SDRAM_TC0, 0x00 },
115 { S1DREG_SDRAM_TC1, 0x01 },
116 { S1DREG_MEM_CNF, 0x80 },
117 { S1DREG_PANEL_TYPE, 0x25 },
118 { S1DREG_MOD_RATE, 0x00 },
119 { S1DREG_LCD_DISP_HWIDTH, 0x63 },
120 { S1DREG_LCD_NDISP_HPER, 0x1e },
121 { S1DREG_TFT_FPLINE_START, 0x06 },
122 { S1DREG_TFT_FPLINE_PWIDTH, 0x03 },
123 { S1DREG_LCD_DISP_VHEIGHT0, 0x57 },
124 { S1DREG_LCD_DISP_VHEIGHT1, 0x02 },
125 { S1DREG_LCD_NDISP_VPER, 0x00 },
126 { S1DREG_TFT_FPFRAME_START, 0x0a },
127 { S1DREG_TFT_FPFRAME_PWIDTH, 0x81 },
128 { S1DREG_LCD_DISP_MODE, 0x03 },
129 { S1DREG_LCD_MISC, 0x00 },
130 { S1DREG_LCD_DISP_START0, 0x00 },
131 { S1DREG_LCD_DISP_START1, 0x00 },
132 { S1DREG_LCD_DISP_START2, 0x00 },
133 { S1DREG_LCD_MEM_OFF0, 0x90 },
134 { S1DREG_LCD_MEM_OFF1, 0x01 },
135 { S1DREG_LCD_PIX_PAN, 0x00 },
136 { S1DREG_LCD_DISP_FIFO_HTC, 0x00 },
137 { S1DREG_LCD_DISP_FIFO_LTC, 0x00 },
138 { S1DREG_CRT_DISP_HWIDTH, 0x63 },
139 { S1DREG_CRT_NDISP_HPER, 0x1f },
140 { S1DREG_CRT_HRTC_START, 0x04 },
141 { S1DREG_CRT_HRTC_PWIDTH, 0x8f },
142 { S1DREG_CRT_DISP_VHEIGHT0, 0x57 },
143 { S1DREG_CRT_DISP_VHEIGHT1, 0x02 },
144 { S1DREG_CRT_NDISP_VPER, 0x1b },
145 { S1DREG_CRT_VRTC_START, 0x00 },
146 { S1DREG_CRT_VRTC_PWIDTH, 0x83 },
147 { S1DREG_TV_OUT_CTL, 0x10 },
148 { S1DREG_CRT_DISP_MODE, 0x05 },
149 { S1DREG_CRT_DISP_START0, 0x00 },
150 { S1DREG_CRT_DISP_START1, 0x00 },
151 { S1DREG_CRT_DISP_START2, 0x00 },
152 { S1DREG_CRT_MEM_OFF0, 0x20 },
153 { S1DREG_CRT_MEM_OFF1, 0x03 },
154 { S1DREG_CRT_PIX_PAN, 0x00 },
155 { S1DREG_CRT_DISP_FIFO_HTC, 0x00 },
156 { S1DREG_CRT_DISP_FIFO_LTC, 0x00 },
157 { S1DREG_LCD_CUR_CTL, 0x00 },
158 { S1DREG_LCD_CUR_START, 0x01 },
159 { S1DREG_LCD_CUR_XPOS0, 0x00 },
160 { S1DREG_LCD_CUR_XPOS1, 0x00 },
161 { S1DREG_LCD_CUR_YPOS0, 0x00 },
162 { S1DREG_LCD_CUR_YPOS1, 0x00 },
163 { S1DREG_LCD_CUR_BCTL0, 0x00 },
164 { S1DREG_LCD_CUR_GCTL0, 0x00 },
165 { S1DREG_LCD_CUR_RCTL0, 0x00 },
166 { S1DREG_LCD_CUR_BCTL1, 0x1f },
167 { S1DREG_LCD_CUR_GCTL1, 0x3f },
168 { S1DREG_LCD_CUR_RCTL1, 0x1f },
169 { S1DREG_LCD_CUR_FIFO_HTC, 0x00 },
170 { S1DREG_CRT_CUR_CTL, 0x00 },
171 { S1DREG_CRT_CUR_START, 0x01 },
172 { S1DREG_CRT_CUR_XPOS0, 0x00 },
173 { S1DREG_CRT_CUR_XPOS1, 0x00 },
174 { S1DREG_CRT_CUR_YPOS0, 0x00 },
175 { S1DREG_CRT_CUR_YPOS1, 0x00 },
176 { S1DREG_CRT_CUR_BCTL0, 0x00 },
177 { S1DREG_CRT_CUR_GCTL0, 0x00 },
178 { S1DREG_CRT_CUR_RCTL0, 0x00 },
179 { S1DREG_CRT_CUR_BCTL1, 0x1f },
180 { S1DREG_CRT_CUR_GCTL1, 0x3f },
181 { S1DREG_CRT_CUR_RCTL1, 0x1f },
182 { S1DREG_CRT_CUR_FIFO_HTC, 0x00 },
183 { S1DREG_BBLT_CTL0, 0x00 },
184 { S1DREG_BBLT_CTL1, 0x00 },
185 { S1DREG_BBLT_CC_EXP, 0x00 },
186 { S1DREG_BBLT_OP, 0x00 },
187 { S1DREG_BBLT_SRC_START0, 0x00 },
188 { S1DREG_BBLT_SRC_START1, 0x00 },
189 { S1DREG_BBLT_SRC_START2, 0x00 },
190 { S1DREG_BBLT_DST_START0, 0x00 },
191 { S1DREG_BBLT_DST_START1, 0x00 },
192 { S1DREG_BBLT_DST_START2, 0x00 },
193 { S1DREG_BBLT_MEM_OFF0, 0x00 },
194 { S1DREG_BBLT_MEM_OFF1, 0x00 },
195 { S1DREG_BBLT_WIDTH0, 0x00 },
196 { S1DREG_BBLT_WIDTH1, 0x00 },
197 { S1DREG_BBLT_HEIGHT0, 0x00 },
198 { S1DREG_BBLT_HEIGHT1, 0x00 },
199 { S1DREG_BBLT_BGC0, 0x00 },
200 { S1DREG_BBLT_BGC1, 0x00 },
201 { S1DREG_BBLT_FGC0, 0x00 },
202 { S1DREG_BBLT_FGC1, 0x00 },
203 { S1DREG_LKUP_MODE, 0x00 },
204 { S1DREG_LKUP_ADDR, 0x00 },
205 { S1DREG_PS_CNF, 0x10 },
206 { S1DREG_PS_STATUS, 0x00 },
207 { S1DREG_CPU2MEM_WDOGT, 0x00 },
208 { S1DREG_COM_DISP_MODE, 0x02 },
209};
210
211static struct s1d13xxxfb_pdata s1d13806_platform_data = {
212 .initregs = s1d13806_initregs,
213 .initregssize = ARRAY_SIZE(s1d13806_initregs),
214};
215
216static struct resource s1d13806_resources[] = {
217 [0] = {
218 .start = 0x07200000,
219 .end = 0x07200000 + 0x00200000 - 1,
220 .flags = IORESOURCE_MEM,
221 },
222 [1] = {
223 .start = 0x07000000,
224 .end = 0x07000000 + 0x00200000 - 1,
225 .flags = IORESOURCE_MEM,
226 },
227};
228
229static struct platform_device s1d13806_device = {
230 .name = "s1d13806fb",
231 .id = -1,
232 .num_resources = ARRAY_SIZE(s1d13806_resources),
233 .resource = s1d13806_resources,
234
235 .dev = {
236 .platform_data = &s1d13806_platform_data,
237 },
238};
239#endif
240
241static struct platform_device *microdev_devices[] __initdata = {
242 &smc91x_device,
243#ifdef CONFIG_FB_S1D13XXX
244 &s1d13806_device,
245#endif
246};
247
248static int __init microdev_devices_setup(void)
249{
250 return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
251}
252
253/*
254 * Setup for the SMSC FDC37C93xAPM
255 */
256static int __init smsc_superio_setup(void)
257{
258
259 unsigned char devid, devrev;
260
261 /* Initially the chip is in run state */
262 /* Put it into configuration state */
263 outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
264
265 /* Read device ID info */
266 devid = SMSC_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
267 devrev = SMSC_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
268 if ( (devid==0x30) && (devrev==0x01) )
269 {
270 printk("SMSC FDC37C93xAPM SuperIO device detected\n");
271 }
272 else
273 { /* not the device identity we expected */
274 printk("Not detected a SMSC FDC37C93xAPM SuperIO device (devid=0x%02x, rev=0x%02x)\n",
275 devid, devrev);
276 /* inform the keyboard driver that we have no keyboard controller */
277 microdev_kbd_controller_present = 0;
278 /* little point in doing anything else in this functon */
279 return 0;
280 }
281
282 /* Select the keyboard device */
283 SMSC_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
284 /* enable it */
285 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
286 /* enable the interrupts */
287 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_KEYBOARD, SMSC_PRIMARY_INT_INDEX);
288 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_MOUSE, SMSC_SECONDARY_INT_INDEX);
289
290 /* Select the Serial #1 device */
291 SMSC_WRITE_INDEXED(SMSC_SERIAL1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
292 /* enable it */
293 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
294 /* program with port addresses */
295 SMSC_WRITE_INDEXED(MSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
296 SMSC_WRITE_INDEXED(LSB(SERIAL1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
297 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
298 /* enable the interrupts */
299 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL1, SMSC_PRIMARY_INT_INDEX);
300
301 /* Select the Serial #2 device */
302 SMSC_WRITE_INDEXED(SMSC_SERIAL2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
303 /* enable it */
304 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
305 /* program with port addresses */
306 SMSC_WRITE_INDEXED(MSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
307 SMSC_WRITE_INDEXED(LSB(SERIAL2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
308 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS0_INDEX);
309 /* enable the interrupts */
310 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_SERIAL2, SMSC_PRIMARY_INT_INDEX);
311
312 /* Select the IDE#1 device */
313 SMSC_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
314 /* enable it */
315 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
316 /* program with port addresses */
317 SMSC_WRITE_INDEXED(MSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
318 SMSC_WRITE_INDEXED(LSB(IDE1_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
319 SMSC_WRITE_INDEXED(MSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
320 SMSC_WRITE_INDEXED(LSB(IDE1_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
321 SMSC_WRITE_INDEXED(0x0c, SMSC_HDCS0_INDEX);
322 SMSC_WRITE_INDEXED(0x00, SMSC_HDCS1_INDEX);
323 /* select the interrupt */
324 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE1, SMSC_PRIMARY_INT_INDEX);
325
326 /* Select the IDE#2 device */
327 SMSC_WRITE_INDEXED(SMSC_IDE2_DEVICE, SMCS_LOGICAL_DEV_INDEX);
328 /* enable it */
329 SMSC_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
330 /* program with port addresses */
331 SMSC_WRITE_INDEXED(MSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+0);
332 SMSC_WRITE_INDEXED(LSB(IDE2_PRIMARY_BASE), SMSC_PRIMARY_BASE_INDEX+1);
333 SMSC_WRITE_INDEXED(MSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+0);
334 SMSC_WRITE_INDEXED(LSB(IDE2_SECONDARY_BASE), SMSC_SECONDARY_BASE_INDEX+1);
335 /* select the interrupt */
336 SMSC_WRITE_INDEXED(MICRODEV_FPGA_IRQ_IDE2, SMSC_PRIMARY_INT_INDEX);
337
338 /* Select the configuration registers */
339 SMSC_WRITE_INDEXED(SMSC_CONFIG_REGISTERS, SMCS_LOGICAL_DEV_INDEX);
340 /* enable the appropriate GPIO pins for IDE functionality:
341 * bit[0] In/Out 1==input; 0==output
342 * bit[1] Polarity 1==invert; 0==no invert
343 * bit[2] Int Enb #1 1==Enable Combined IRQ #1; 0==disable
344 * bit[3:4] Function Select 00==original; 01==Alternate Function #1
345 */
346 SMSC_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
347 SMSC_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
348 SMSC_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
349 SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
350 SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
351
352 /* Exit the configuration state */
353 outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
354
355 return 0;
356}
357
358static void __init microdev_setup(char **cmdline_p)
359{
360 int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
361 const int fpgaRevision = *fpgaRevisionRegister;
362 int * const CacheControlRegister = (int*)CCR;
363
364 device_initcall(microdev_devices_setup);
365 device_initcall(smsc_superio_setup);
366
367 printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
368 get_system_type(), fpgaRevision, *CacheControlRegister);
369}
370
371/*
372 * The Machine Vector
373 */
374static struct sh_machine_vector mv_sh4202_microdev __initmv = {
375 .mv_name = "SH4-202 MicroDev",
376 .mv_setup = microdev_setup,
377 .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */
378
379 .mv_inb = microdev_inb,
380 .mv_inw = microdev_inw,
381 .mv_inl = microdev_inl,
382 .mv_outb = microdev_outb,
383 .mv_outw = microdev_outw,
384 .mv_outl = microdev_outl,
385
386 .mv_inb_p = microdev_inb_p,
387 .mv_inw_p = microdev_inw_p,
388 .mv_inl_p = microdev_inl_p,
389 .mv_outb_p = microdev_outb_p,
390 .mv_outw_p = microdev_outw_p,
391 .mv_outl_p = microdev_outl_p,
392
393 .mv_insb = microdev_insb,
394 .mv_insw = microdev_insw,
395 .mv_insl = microdev_insl,
396 .mv_outsb = microdev_outsb,
397 .mv_outsw = microdev_outsw,
398 .mv_outsl = microdev_outsl,
399
400 .mv_init_irq = init_microdev_irq,
401
402#ifdef CONFIG_HEARTBEAT
403 .mv_heartbeat = microdev_heartbeat,
404#endif
405};