aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-iop32x
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2006-09-20 21:42:12 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-09-25 05:34:01 -0400
commite60d07b6cd38a7afb85f2cf51aebcb3359b63819 (patch)
tree639b895384a70502f2aac9e8f7bc82ec1a4930f4 /arch/arm/mach-iop32x
parent17b602b1c1a38f3f0a4461bb1f571346e751b36b (diff)
[ARM] 3850/1: iop3xx: add thecus n2100 support
Add support for the Thecus n2100 (80219-based.) Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-iop32x')
-rw-r--r--arch/arm/mach-iop32x/Kconfig6
-rw-r--r--arch/arm/mach-iop32x/Makefile1
-rw-r--r--arch/arm/mach-iop32x/irq.c3
-rw-r--r--arch/arm/mach-iop32x/n2100.c251
4 files changed, 260 insertions, 1 deletions
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig
index d7abfaa525c3..0a397a4a6ac9 100644
--- a/arch/arm/mach-iop32x/Kconfig
+++ b/arch/arm/mach-iop32x/Kconfig
@@ -17,6 +17,12 @@ config ARCH_IQ31244
17 evaluation kit for the Intel 80219 processor (a IOP321 variant) 17 evaluation kit for the Intel 80219 processor (a IOP321 variant)
18 or the IQ31244 evaluation kit for the IOP321 processor. 18 or the IQ31244 evaluation kit for the IOP321 processor.
19 19
20config MACH_N2100
21 bool "Enable support for the Thecus n2100"
22 help
23 Say Y here if you want to run your kernel on the Thecus n2100
24 NAS appliance.
25
20endmenu 26endmenu
21 27
22endif 28endif
diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile
index af1747ae392d..9c62470cd4f5 100644
--- a/arch/arm/mach-iop32x/Makefile
+++ b/arch/arm/mach-iop32x/Makefile
@@ -9,3 +9,4 @@ obj- :=
9 9
10obj-$(CONFIG_ARCH_IQ80321) += iq80321.o 10obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
11obj-$(CONFIG_ARCH_IQ31244) += iq31244.o 11obj-$(CONFIG_ARCH_IQ31244) += iq31244.o
12obj-$(CONFIG_MACH_N2100) += n2100.o
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 21294be5a369..17fb94e6e29f 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -63,7 +63,8 @@ void __init iop32x_init_irq(void)
63 intctl_write(0); 63 intctl_write(0);
64 intstr_write(0); 64 intstr_write(0);
65 if (machine_is_iq80321() || 65 if (machine_is_iq80321() ||
66 machine_is_iq31244()) 66 machine_is_iq31244() ||
67 machine_is_n2100())
67 *IOP3XX_PCIIRSR = 0x0f; 68 *IOP3XX_PCIIRSR = 0x0f;
68 69
69 for (i = 0; i < NR_IRQS; i++) { 70 for (i = 0; i < NR_IRQS; i++) {
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