aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-iop32x
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-iop32x')
-rw-r--r--arch/arm/mach-iop32x/Kconfig35
-rw-r--r--arch/arm/mach-iop32x/Makefile13
-rw-r--r--arch/arm/mach-iop32x/Makefile.boot3
-rw-r--r--arch/arm/mach-iop32x/glantank.c195
-rw-r--r--arch/arm/mach-iop32x/iq31244.c293
-rw-r--r--arch/arm/mach-iop32x/iq80321.c193
-rw-r--r--arch/arm/mach-iop32x/irq.c76
-rw-r--r--arch/arm/mach-iop32x/n2100.c251
8 files changed, 1059 insertions, 0 deletions
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig
new file mode 100644
index 000000000000..c072d94070da
--- /dev/null
+++ b/arch/arm/mach-iop32x/Kconfig
@@ -0,0 +1,35 @@
1if ARCH_IOP32X
2
3menu "IOP32x Implementation Options"
4
5comment "IOP32x Platform Types"
6
7config MACH_GLANTANK
8 bool "Enable support for the IO-Data GLAN Tank"
9 help
10 Say Y here if you want to run your kernel on the GLAN Tank
11 NAS appliance or machines from IO-Data's HDL-Gxxx, HDL-GWxxx
12 and HDL-GZxxx series.
13
14config ARCH_IQ80321
15 bool "Enable support for IQ80321"
16 help
17 Say Y here if you want to run your kernel on the Intel IQ80321
18 evaluation kit for the IOP321 processor.
19
20config ARCH_IQ31244
21 bool "Enable support for EP80219/IQ31244"
22 help
23 Say Y here if you want to run your kernel on the Intel EP80219
24 evaluation kit for the Intel 80219 processor (a IOP321 variant)
25 or the IQ31244 evaluation kit for the IOP321 processor.
26
27config MACH_N2100
28 bool "Enable support for the Thecus n2100"
29 help
30 Say Y here if you want to run your kernel on the Thecus n2100
31 NAS appliance.
32
33endmenu
34
35endif
diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile
new file mode 100644
index 000000000000..7b05b37e1f94
--- /dev/null
+++ b/arch/arm/mach-iop32x/Makefile
@@ -0,0 +1,13 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := irq.o
6obj-m :=
7obj-n :=
8obj- :=
9
10obj-$(CONFIG_MACH_GLANTANK) += glantank.o
11obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
12obj-$(CONFIG_ARCH_IQ31244) += iq31244.o
13obj-$(CONFIG_MACH_N2100) += n2100.o
diff --git a/arch/arm/mach-iop32x/Makefile.boot b/arch/arm/mach-iop32x/Makefile.boot
new file mode 100644
index 000000000000..47000dccd61f
--- /dev/null
+++ b/arch/arm/mach-iop32x/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0xa0008000
2params_phys-y := 0xa0000100
3initrd_phys-y := 0xa0800000
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
new file mode 100644
index 000000000000..b9b765057dbe
--- /dev/null
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -0,0 +1,195 @@
1/*
2 * arch/arm/mach-iop32x/glantank.c
3 *
4 * Board support code for the GLAN Tank.
5 *
6 * Copyright (C) 2006 Martin Michlmayr <tbm@cyrius.com>
7 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/mm.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/pci.h>
19#include <linux/string.h>
20#include <linux/slab.h>
21#include <linux/serial_core.h>
22#include <linux/serial_8250.h>
23#include <linux/mtd/physmap.h>
24#include <linux/platform_device.h>
25#include <asm/hardware.h>
26#include <asm/io.h>
27#include <asm/irq.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/map.h>
30#include <asm/mach/pci.h>
31#include <asm/mach/time.h>
32#include <asm/mach-types.h>
33#include <asm/page.h>
34
35/*
36 * GLAN Tank timer tick configuration.
37 */
38static void __init glantank_timer_init(void)
39{
40 /* 33.333 MHz crystal. */
41 iop3xx_init_time(200000000);
42}
43
44static struct sys_timer glantank_timer = {
45 .init = glantank_timer_init,
46 .offset = iop3xx_gettimeoffset,
47};
48
49
50/*
51 * GLAN Tank I/O.
52 */
53static struct map_desc glantank_io_desc[] __initdata = {
54 { /* on-board devices */
55 .virtual = GLANTANK_UART,
56 .pfn = __phys_to_pfn(GLANTANK_UART),
57 .length = 0x00100000,
58 .type = MT_DEVICE
59 },
60};
61
62void __init glantank_map_io(void)
63{
64 iop3xx_map_io();
65 iotable_init(glantank_io_desc, ARRAY_SIZE(glantank_io_desc));
66}
67
68
69/*
70 * GLAN Tank PCI.
71 */
72#define INTA IRQ_IOP32X_XINT0
73#define INTB IRQ_IOP32X_XINT1
74#define INTC IRQ_IOP32X_XINT2
75#define INTD IRQ_IOP32X_XINT3
76
77static inline int __init
78glantank_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
79{
80 static int pci_irq_table[][4] = {
81 /*
82 * PCI IDSEL/INTPIN->INTLINE
83 * A B C D
84 */
85 {INTD, INTD, INTD, INTD}, /* UART (8250) */
86 {INTA, INTA, INTA, INTA}, /* Ethernet (E1000) */
87 {INTB, INTB, INTB, INTB}, /* IDE (AEC6280R) */
88 {INTC, INTC, INTC, INTC}, /* USB (NEC) */
89 };
90
91 BUG_ON(pin < 1 || pin > 4);
92
93 return pci_irq_table[slot % 4][pin - 1];
94}
95
96static struct hw_pci glantank_pci __initdata = {
97 .swizzle = pci_std_swizzle,
98 .nr_controllers = 1,
99 .setup = iop3xx_pci_setup,
100 .preinit = iop3xx_pci_preinit,
101 .scan = iop3xx_pci_scan_bus,
102 .map_irq = glantank_pci_map_irq,
103};
104
105static int __init glantank_pci_init(void)
106{
107 if (machine_is_glantank())
108 pci_common_init(&glantank_pci);
109
110 return 0;
111}
112
113subsys_initcall(glantank_pci_init);
114
115
116/*
117 * GLAN Tank machine initialization.
118 */
119static struct physmap_flash_data glantank_flash_data = {
120 .width = 1,
121};
122
123static struct resource glantank_flash_resource = {
124 .start = 0xf0000000,
125 .end = 0xf007ffff,
126 .flags = IORESOURCE_MEM,
127};
128
129static struct platform_device glantank_flash_device = {
130 .name = "physmap-flash",
131 .id = 0,
132 .dev = {
133 .platform_data = &glantank_flash_data,
134 },
135 .num_resources = 1,
136 .resource = &glantank_flash_resource,
137};
138
139static struct plat_serial8250_port glantank_serial_port[] = {
140 {
141 .mapbase = GLANTANK_UART,
142 .membase = (char *)GLANTANK_UART,
143 .irq = IRQ_IOP32X_XINT3,
144 .flags = UPF_SKIP_TEST,
145 .iotype = UPIO_MEM,
146 .regshift = 0,
147 .uartclk = 1843200,
148 },
149 { },
150};
151
152static struct resource glantank_uart_resource = {
153 .start = GLANTANK_UART,
154 .end = GLANTANK_UART + 7,
155 .flags = IORESOURCE_MEM,
156};
157
158static struct platform_device glantank_serial_device = {
159 .name = "serial8250",
160 .id = PLAT8250_DEV_PLATFORM,
161 .dev = {
162 .platform_data = glantank_serial_port,
163 },
164 .num_resources = 1,
165 .resource = &glantank_uart_resource,
166};
167
168static void glantank_power_off(void)
169{
170 __raw_writeb(0x01, 0xfe8d0004);
171
172 while (1)
173 ;
174}
175
176static void __init glantank_init_machine(void)
177{
178 platform_device_register(&iop3xx_i2c0_device);
179 platform_device_register(&iop3xx_i2c1_device);
180 platform_device_register(&glantank_flash_device);
181 platform_device_register(&glantank_serial_device);
182
183 pm_power_off = glantank_power_off;
184}
185
186MACHINE_START(GLANTANK, "GLAN Tank")
187 /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
188 .phys_io = GLANTANK_UART,
189 .io_pg_offst = ((GLANTANK_UART) >> 18) & 0xfffc,
190 .boot_params = 0xa0000100,
191 .map_io = glantank_map_io,
192 .init_irq = iop32x_init_irq,
193 .timer = &glantank_timer,
194 .init_machine = glantank_init_machine,
195MACHINE_END
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
new file mode 100644
index 000000000000..be4aedfa0de6
--- /dev/null
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -0,0 +1,293 @@
1/*
2 * arch/arm/mach-iop32x/iq31244.c
3 *
4 * Board support code for the Intel EP80219 and IQ31244 platforms.
5 *
6 * Author: Rory Bolt <rorybolt@pacbell.net>
7 * Copyright (C) 2002 Rory Bolt
8 * Copyright 2003 (c) MontaVista, Software, Inc.
9 * Copyright (C) 2004 Intel Corp.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/mm.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/pm.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25#include <linux/serial_core.h>
26#include <linux/serial_8250.h>
27#include <linux/mtd/physmap.h>
28#include <linux/platform_device.h>
29#include <asm/hardware.h>
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/mach/arch.h>
33#include <asm/mach/map.h>
34#include <asm/mach/pci.h>
35#include <asm/mach/time.h>
36#include <asm/mach-types.h>
37#include <asm/page.h>
38#include <asm/pgtable.h>
39
40
41/*
42 * The EP80219 and IQ31244 use the same machine ID. To find out
43 * which of the two we're running on, we look at the processor ID.
44 */
45static int is_80219(void)
46{
47 extern int processor_id;
48 return !!((processor_id & 0xffffffe0) == 0x69052e20);
49}
50
51
52/*
53 * EP80219/IQ31244 timer tick configuration.
54 */
55static void __init iq31244_timer_init(void)
56{
57 if (is_80219()) {
58 /* 33.333 MHz crystal. */
59 iop3xx_init_time(200000000);
60 } else {
61 /* 33.000 MHz crystal. */
62 iop3xx_init_time(198000000);
63 }
64}
65
66static struct sys_timer iq31244_timer = {
67 .init = iq31244_timer_init,
68 .offset = iop3xx_gettimeoffset,
69};
70
71
72/*
73 * IQ31244 I/O.
74 */
75static struct map_desc iq31244_io_desc[] __initdata = {
76 { /* on-board devices */
77 .virtual = IQ31244_UART,
78 .pfn = __phys_to_pfn(IQ31244_UART),
79 .length = 0x00100000,
80 .type = MT_DEVICE,
81 },
82};
83
84void __init iq31244_map_io(void)
85{
86 iop3xx_map_io();
87 iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc));
88}
89
90
91/*
92 * EP80219/IQ31244 PCI.
93 */
94static inline int __init
95ep80219_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
96{
97 int irq;
98
99 if (slot == 0) {
100 /* CFlash */
101 irq = IRQ_IOP32X_XINT1;
102 } else if (slot == 1) {
103 /* 82551 Pro 100 */
104 irq = IRQ_IOP32X_XINT0;
105 } else if (slot == 2) {
106 /* PCI-X Slot */
107 irq = IRQ_IOP32X_XINT3;
108 } else if (slot == 3) {
109 /* SATA */
110 irq = IRQ_IOP32X_XINT2;
111 } else {
112 printk(KERN_ERR "ep80219_pci_map_irq() called for unknown "
113 "device PCI:%d:%d:%d\n", dev->bus->number,
114 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
115 irq = -1;
116 }
117
118 return irq;
119}
120
121static struct hw_pci ep80219_pci __initdata = {
122 .swizzle = pci_std_swizzle,
123 .nr_controllers = 1,
124 .setup = iop3xx_pci_setup,
125 .preinit = iop3xx_pci_preinit,
126 .scan = iop3xx_pci_scan_bus,
127 .map_irq = ep80219_pci_map_irq,
128};
129
130static inline int __init
131iq31244_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
132{
133 int irq;
134
135 if (slot == 0) {
136 /* CFlash */
137 irq = IRQ_IOP32X_XINT1;
138 } else if (slot == 1) {
139 /* SATA */
140 irq = IRQ_IOP32X_XINT2;
141 } else if (slot == 2) {
142 /* PCI-X Slot */
143 irq = IRQ_IOP32X_XINT3;
144 } else if (slot == 3) {
145 /* 82546 GigE */
146 irq = IRQ_IOP32X_XINT0;
147 } else {
148 printk(KERN_ERR "iq31244_pci_map_irq called for unknown "
149 "device PCI:%d:%d:%d\n", dev->bus->number,
150 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
151 irq = -1;
152 }
153
154 return irq;
155}
156
157static struct hw_pci iq31244_pci __initdata = {
158 .swizzle = pci_std_swizzle,
159 .nr_controllers = 1,
160 .setup = iop3xx_pci_setup,
161 .preinit = iop3xx_pci_preinit,
162 .scan = iop3xx_pci_scan_bus,
163 .map_irq = iq31244_pci_map_irq,
164};
165
166static int __init iq31244_pci_init(void)
167{
168 if (machine_is_iq31244()) {
169 if (is_80219()) {
170 pci_common_init(&ep80219_pci);
171 } else {
172 pci_common_init(&iq31244_pci);
173 }
174 }
175
176 return 0;
177}
178
179subsys_initcall(iq31244_pci_init);
180
181
182/*
183 * IQ31244 machine initialisation.
184 */
185static struct physmap_flash_data iq31244_flash_data = {
186 .width = 2,
187};
188
189static struct resource iq31244_flash_resource = {
190 .start = 0xf0000000,
191 .end = 0xf07fffff,
192 .flags = IORESOURCE_MEM,
193};
194
195static struct platform_device iq31244_flash_device = {
196 .name = "physmap-flash",
197 .id = 0,
198 .dev = {
199 .platform_data = &iq31244_flash_data,
200 },
201 .num_resources = 1,
202 .resource = &iq31244_flash_resource,
203};
204
205static struct plat_serial8250_port iq31244_serial_port[] = {
206 {
207 .mapbase = IQ31244_UART,
208 .membase = (char *)IQ31244_UART,
209 .irq = IRQ_IOP32X_XINT1,
210 .flags = UPF_SKIP_TEST,
211 .iotype = UPIO_MEM,
212 .regshift = 0,
213 .uartclk = 1843200,
214 },
215 { },
216};
217
218static struct resource iq31244_uart_resource = {
219 .start = IQ31244_UART,
220 .end = IQ31244_UART + 7,
221 .flags = IORESOURCE_MEM,
222};
223
224static struct platform_device iq31244_serial_device = {
225 .name = "serial8250",
226 .id = PLAT8250_DEV_PLATFORM,
227 .dev = {
228 .platform_data = iq31244_serial_port,
229 },
230 .num_resources = 1,
231 .resource = &iq31244_uart_resource,
232};
233
234/*
235 * This function will send a SHUTDOWN_COMPLETE message to the PIC
236 * controller over I2C. We are not using the i2c subsystem since
237 * we are going to power off and it may be removed
238 */
239void ep80219_power_off(void)
240{
241 /*
242 * Send the Address byte w/ the start condition
243 */
244 *IOP3XX_IDBR1 = 0x60;
245 *IOP3XX_ICR1 = 0xE9;
246 mdelay(1);
247
248 /*
249 * Send the START_MSG byte w/ no start or stop condition
250 */
251 *IOP3XX_IDBR1 = 0x0F;
252 *IOP3XX_ICR1 = 0xE8;
253 mdelay(1);
254
255 /*
256 * Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or
257 * stop condition
258 */
259 *IOP3XX_IDBR1 = 0x03;
260 *IOP3XX_ICR1 = 0xE8;
261 mdelay(1);
262
263 /*
264 * Send an ignored byte w/ stop condition
265 */
266 *IOP3XX_IDBR1 = 0x00;
267 *IOP3XX_ICR1 = 0xEA;
268
269 while (1)
270 ;
271}
272
273static void __init iq31244_init_machine(void)
274{
275 platform_device_register(&iop3xx_i2c0_device);
276 platform_device_register(&iop3xx_i2c1_device);
277 platform_device_register(&iq31244_flash_device);
278 platform_device_register(&iq31244_serial_device);
279
280 if (is_80219())
281 pm_power_off = ep80219_power_off;
282}
283
284MACHINE_START(IQ31244, "Intel IQ31244")
285 /* Maintainer: Intel Corp. */
286 .phys_io = IQ31244_UART,
287 .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc,
288 .boot_params = 0xa0000100,
289 .map_io = iq31244_map_io,
290 .init_irq = iop32x_init_irq,
291 .timer = &iq31244_timer,
292 .init_machine = iq31244_init_machine,
293MACHINE_END
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
new file mode 100644
index 000000000000..1f37b5501888
--- /dev/null
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -0,0 +1,193 @@
1/*
2 * arch/arm/mach-iop32x/iq80321.c
3 *
4 * Board support code for the Intel IQ80321 platform.
5 *
6 * Author: Rory Bolt <rorybolt@pacbell.net>
7 * Copyright (C) 2002 Rory Bolt
8 * Copyright (C) 2004 Intel Corp.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/mm.h>
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/pci.h>
20#include <linux/string.h>
21#include <linux/slab.h>
22#include <linux/serial_core.h>
23#include <linux/serial_8250.h>
24#include <linux/mtd/physmap.h>
25#include <linux/platform_device.h>
26#include <asm/hardware.h>
27#include <asm/io.h>
28#include <asm/irq.h>
29#include <asm/mach/arch.h>
30#include <asm/mach/map.h>
31#include <asm/mach/pci.h>
32#include <asm/mach/time.h>
33#include <asm/mach-types.h>
34#include <asm/page.h>
35#include <asm/pgtable.h>
36
37/*
38 * IQ80321 timer tick configuration.
39 */
40static void __init iq80321_timer_init(void)
41{
42 /* 33.333 MHz crystal. */
43 iop3xx_init_time(200000000);
44}
45
46static struct sys_timer iq80321_timer = {
47 .init = iq80321_timer_init,
48 .offset = iop3xx_gettimeoffset,
49};
50
51
52/*
53 * IQ80321 I/O.
54 */
55static struct map_desc iq80321_io_desc[] __initdata = {
56 { /* on-board devices */
57 .virtual = IQ80321_UART,
58 .pfn = __phys_to_pfn(IQ80321_UART),
59 .length = 0x00100000,
60 .type = MT_DEVICE,
61 },
62};
63
64void __init iq80321_map_io(void)
65{
66 iop3xx_map_io();
67 iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
68}
69
70
71/*
72 * IQ80321 PCI.
73 */
74static inline int __init
75iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
76{
77 int irq;
78
79 if ((slot == 2 || slot == 6) && pin == 1) {
80 /* PCI-X Slot INTA */
81 irq = IRQ_IOP32X_XINT2;
82 } else if ((slot == 2 || slot == 6) && pin == 2) {
83 /* PCI-X Slot INTA */
84 irq = IRQ_IOP32X_XINT3;
85 } else if ((slot == 2 || slot == 6) && pin == 3) {
86 /* PCI-X Slot INTA */
87 irq = IRQ_IOP32X_XINT0;
88 } else if ((slot == 2 || slot == 6) && pin == 4) {
89 /* PCI-X Slot INTA */
90 irq = IRQ_IOP32X_XINT1;
91 } else if (slot == 4 || slot == 8) {
92 /* Gig-E */
93 irq = IRQ_IOP32X_XINT0;
94 } else {
95 printk(KERN_ERR "iq80321_pci_map_irq() called for unknown "
96 "device PCI:%d:%d:%d\n", dev->bus->number,
97 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
98 irq = -1;
99 }
100
101 return irq;
102}
103
104static struct hw_pci iq80321_pci __initdata = {
105 .swizzle = pci_std_swizzle,
106 .nr_controllers = 1,
107 .setup = iop3xx_pci_setup,
108 .preinit = iop3xx_pci_preinit,
109 .scan = iop3xx_pci_scan_bus,
110 .map_irq = iq80321_pci_map_irq,
111};
112
113static int __init iq80321_pci_init(void)
114{
115 if (machine_is_iq80321())
116 pci_common_init(&iq80321_pci);
117
118 return 0;
119}
120
121subsys_initcall(iq80321_pci_init);
122
123
124/*
125 * IQ80321 machine initialisation.
126 */
127static struct physmap_flash_data iq80321_flash_data = {
128 .width = 1,
129};
130
131static struct resource iq80321_flash_resource = {
132 .start = 0xf0000000,
133 .end = 0xf07fffff,
134 .flags = IORESOURCE_MEM,
135};
136
137static struct platform_device iq80321_flash_device = {
138 .name = "physmap-flash",
139 .id = 0,
140 .dev = {
141 .platform_data = &iq80321_flash_data,
142 },
143 .num_resources = 1,
144 .resource = &iq80321_flash_resource,
145};
146
147static struct plat_serial8250_port iq80321_serial_port[] = {
148 {
149 .mapbase = IQ80321_UART,
150 .membase = (char *)IQ80321_UART,
151 .irq = IRQ_IOP32X_XINT1,
152 .flags = UPF_SKIP_TEST,
153 .iotype = UPIO_MEM,
154 .regshift = 0,
155 .uartclk = 1843200,
156 },
157 { },
158};
159
160static struct resource iq80321_uart_resource = {
161 .start = IQ80321_UART,
162 .end = IQ80321_UART + 7,
163 .flags = IORESOURCE_MEM,
164};
165
166static struct platform_device iq80321_serial_device = {
167 .name = "serial8250",
168 .id = PLAT8250_DEV_PLATFORM,
169 .dev = {
170 .platform_data = iq80321_serial_port,
171 },
172 .num_resources = 1,
173 .resource = &iq80321_uart_resource,
174};
175
176static void __init iq80321_init_machine(void)
177{
178 platform_device_register(&iop3xx_i2c0_device);
179 platform_device_register(&iop3xx_i2c1_device);
180 platform_device_register(&iq80321_flash_device);
181 platform_device_register(&iq80321_serial_device);
182}
183
184MACHINE_START(IQ80321, "Intel IQ80321")
185 /* Maintainer: Intel Corp. */
186 .phys_io = IQ80321_UART,
187 .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc,
188 .boot_params = 0xa0000100,
189 .map_io = iq80321_map_io,
190 .init_irq = iop32x_init_irq,
191 .timer = &iq80321_timer,
192 .init_machine = iq80321_init_machine,
193MACHINE_END
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
new file mode 100644
index 000000000000..69d6302f40cf
--- /dev/null
+++ b/arch/arm/mach-iop32x/irq.c
@@ -0,0 +1,76 @@
1/*
2 * arch/arm/mach-iop32x/irq.c
3 *
4 * Generic IOP32X IRQ handling functionality
5 *
6 * Author: Rory Bolt <rorybolt@pacbell.net>
7 * Copyright (C) 2002 Rory Bolt
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <asm/mach/irq.h>
18#include <asm/irq.h>
19#include <asm/hardware.h>
20#include <asm/mach-types.h>
21
22static u32 iop32x_mask;
23
24static inline void intctl_write(u32 val)
25{
26 iop3xx_cp6_enable();
27 asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
28 iop3xx_cp6_disable();
29}
30
31static inline void intstr_write(u32 val)
32{
33 iop3xx_cp6_enable();
34 asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
35 iop3xx_cp6_disable();
36}
37
38static void
39iop32x_irq_mask(unsigned int irq)
40{
41 iop32x_mask &= ~(1 << irq);
42 intctl_write(iop32x_mask);
43}
44
45static void
46iop32x_irq_unmask(unsigned int irq)
47{
48 iop32x_mask |= 1 << irq;
49 intctl_write(iop32x_mask);
50}
51
52struct irq_chip ext_chip = {
53 .name = "IOP32x",
54 .ack = iop32x_irq_mask,
55 .mask = iop32x_irq_mask,
56 .unmask = iop32x_irq_unmask,
57};
58
59void __init iop32x_init_irq(void)
60{
61 int i;
62
63 intctl_write(0);
64 intstr_write(0);
65 if (machine_is_glantank() ||
66 machine_is_iq80321() ||
67 machine_is_iq31244() ||
68 machine_is_n2100())
69 *IOP3XX_PCIIRSR = 0x0f;
70
71 for (i = 0; i < NR_IRQS; i++) {
72 set_irq_chip(i, &ext_chip);
73 set_irq_handler(i, do_level_IRQ);
74 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
75 }
76}
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
new file mode 100644
index 000000000000..a2c94a47b2b2
--- /dev/null
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -0,0 +1,251 @@
1/*
2 * arch/arm/mach-iop32x/n2100.c
3 *
4 * Board support code for the Thecus N2100 platform.
5 *
6 * Author: Rory Bolt <rorybolt@pacbell.net>
7 * Copyright (C) 2002 Rory Bolt
8 * Copyright 2003 (c) MontaVista, Software, Inc.
9 * Copyright (C) 2004 Intel Corp.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/mm.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/pm.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25#include <linux/serial_core.h>
26#include <linux/serial_8250.h>
27#include <linux/mtd/physmap.h>
28#include <linux/platform_device.h>
29#include <linux/reboot.h>
30#include <asm/hardware.h>
31#include <asm/io.h>
32#include <asm/irq.h>
33#include <asm/mach/arch.h>
34#include <asm/mach/map.h>
35#include <asm/mach/pci.h>
36#include <asm/mach/time.h>
37#include <asm/mach-types.h>
38#include <asm/page.h>
39#include <asm/pgtable.h>
40
41/*
42 * N2100 timer tick configuration.
43 */
44static void __init n2100_timer_init(void)
45{
46 /* 33.000 MHz crystal. */
47 iop3xx_init_time(198000000);
48}
49
50static struct sys_timer n2100_timer = {
51 .init = n2100_timer_init,
52 .offset = iop3xx_gettimeoffset,
53};
54
55
56/*
57 * N2100 I/O.
58 */
59static struct map_desc n2100_io_desc[] __initdata = {
60 { /* on-board devices */
61 .virtual = N2100_UART,
62 .pfn = __phys_to_pfn(N2100_UART),
63 .length = 0x00100000,
64 .type = MT_DEVICE
65 },
66};
67
68void __init n2100_map_io(void)
69{
70 iop3xx_map_io();
71 iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc));
72}
73
74
75/*
76 * N2100 PCI.
77 */
78static inline int __init
79n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
80{
81 int irq;
82
83 if (PCI_SLOT(dev->devfn) == 1) {
84 /* RTL8110SB #1 */
85 irq = IRQ_IOP32X_XINT0;
86 } else if (PCI_SLOT(dev->devfn) == 2) {
87 /* RTL8110SB #2 */
88 irq = IRQ_IOP32X_XINT1;
89 } else if (PCI_SLOT(dev->devfn) == 3) {
90 /* Sil3512 */
91 irq = IRQ_IOP32X_XINT2;
92 } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) {
93 /* VT6212 INTA */
94 irq = IRQ_IOP32X_XINT1;
95 } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) {
96 /* VT6212 INTB */
97 irq = IRQ_IOP32X_XINT0;
98 } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) {
99 /* VT6212 INTC */
100 irq = IRQ_IOP32X_XINT2;
101 } else if (PCI_SLOT(dev->devfn) == 5) {
102 /* Mini-PCI slot */
103 irq = IRQ_IOP32X_XINT3;
104 } else {
105 printk(KERN_ERR "n2100_pci_map_irq() called for unknown "
106 "device PCI:%d:%d:%d\n", dev->bus->number,
107 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
108 irq = -1;
109 }
110
111 return irq;
112}
113
114static struct hw_pci n2100_pci __initdata = {
115 .swizzle = pci_std_swizzle,
116 .nr_controllers = 1,
117 .setup = iop3xx_pci_setup,
118 .preinit = iop3xx_pci_preinit,
119 .scan = iop3xx_pci_scan_bus,
120 .map_irq = n2100_pci_map_irq,
121};
122
123static int __init n2100_pci_init(void)
124{
125 if (machine_is_n2100())
126 pci_common_init(&n2100_pci);
127
128 return 0;
129}
130
131subsys_initcall(n2100_pci_init);
132
133
134/*
135 * N2100 machine initialisation.
136 */
137static struct physmap_flash_data n2100_flash_data = {
138 .width = 2,
139};
140
141static struct resource n2100_flash_resource = {
142 .start = 0xf0000000,
143 .end = 0xf0ffffff,
144 .flags = IORESOURCE_MEM,
145};
146
147static struct platform_device n2100_flash_device = {
148 .name = "physmap-flash",
149 .id = 0,
150 .dev = {
151 .platform_data = &n2100_flash_data,
152 },
153 .num_resources = 1,
154 .resource = &n2100_flash_resource,
155};
156
157
158static struct plat_serial8250_port n2100_serial_port[] = {
159 {
160 .mapbase = N2100_UART,
161 .membase = (char *)N2100_UART,
162 .irq = 0,
163 .flags = UPF_SKIP_TEST,
164 .iotype = UPIO_MEM,
165 .regshift = 0,
166 .uartclk = 1843200,
167 },
168 { },
169};
170
171static struct resource n2100_uart_resource = {
172 .start = N2100_UART,
173 .end = N2100_UART + 7,
174 .flags = IORESOURCE_MEM,
175};
176
177static struct platform_device n2100_serial_device = {
178 .name = "serial8250",
179 .id = PLAT8250_DEV_PLATFORM,
180 .dev = {
181 .platform_data = n2100_serial_port,
182 },
183 .num_resources = 1,
184 .resource = &n2100_uart_resource,
185};
186
187
188/*
189 * Pull PCA9532 GPIO #8 low to power off the machine.
190 */
191static void n2100_power_off(void)
192{
193 local_irq_disable();
194
195 /* Start condition, I2C address of PCA9532, write transaction. */
196 *IOP3XX_IDBR0 = 0xc0;
197 *IOP3XX_ICR0 = 0xe9;
198 mdelay(1);
199
200 /* Write address 0x08. */
201 *IOP3XX_IDBR0 = 0x08;
202 *IOP3XX_ICR0 = 0xe8;
203 mdelay(1);
204
205 /* Write data 0x01, stop condition. */
206 *IOP3XX_IDBR0 = 0x01;
207 *IOP3XX_ICR0 = 0xea;
208
209 while (1)
210 ;
211}
212
213
214static struct timer_list power_button_poll_timer;
215
216static void power_button_poll(unsigned long dummy)
217{
218 if (gpio_line_get(N2100_POWER_BUTTON) == 0) {
219 ctrl_alt_del();
220 return;
221 }
222
223 power_button_poll_timer.expires = jiffies + (HZ / 10);
224 add_timer(&power_button_poll_timer);
225}
226
227
228static void __init n2100_init_machine(void)
229{
230 platform_device_register(&iop3xx_i2c0_device);
231 platform_device_register(&n2100_flash_device);
232 platform_device_register(&n2100_serial_device);
233
234 pm_power_off = n2100_power_off;
235
236 init_timer(&power_button_poll_timer);
237 power_button_poll_timer.function = power_button_poll;
238 power_button_poll_timer.expires = jiffies + (HZ / 10);
239 add_timer(&power_button_poll_timer);
240}
241
242MACHINE_START(N2100, "Thecus N2100")
243 /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
244 .phys_io = N2100_UART,
245 .io_pg_offst = ((N2100_UART) >> 18) & 0xfffc,
246 .boot_params = 0xa0000100,
247 .map_io = n2100_map_io,
248 .init_irq = iop32x_init_irq,
249 .timer = &n2100_timer,
250 .init_machine = n2100_init_machine,
251MACHINE_END