aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ixp4xx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/arm/mach-ixp4xx
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/arm/mach-ixp4xx')
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig127
-rw-r--r--arch/arm/mach-ixp4xx/Makefile11
-rw-r--r--arch/arm/mach-ixp4xx/Makefile.boot3
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c527
-rw-r--r--arch/arm/mach-ixp4xx/common.c353
-rw-r--r--arch/arm/mach-ixp4xx/coyote-pci.c70
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c130
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-pci.c101
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-setup.c153
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-pci.c84
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c181
-rw-r--r--arch/arm/mach-ixp4xx/ixdpg425-pci.c66
12 files changed, 1806 insertions, 0 deletions
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
new file mode 100644
index 000000000000..aacb5f9200ea
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -0,0 +1,127 @@
1if ARCH_IXP4XX
2
3config ARCH_SUPPORTS_BIG_ENDIAN
4 bool
5 default y
6
7menu "Intel IXP4xx Implementation Options"
8
9comment "IXP4xx Platforms"
10
11config ARCH_AVILA
12 bool "Avila"
13 help
14 Say 'Y' here if you want your kernel to support the Gateworks
15 Avila Network Platform. For more information on this platform,
16 see <file:Documentation/arm/IXP4xx>.
17
18config ARCH_ADI_COYOTE
19 bool "Coyote"
20 help
21 Say 'Y' here if you want your kernel to support the ADI
22 Engineering Coyote Gateway Reference Platform. For more
23 information on this platform, see <file:Documentation/arm/IXP4xx>.
24
25config ARCH_IXDP425
26 bool "IXDP425"
27 help
28 Say 'Y' here if you want your kernel to support Intel's
29 IXDP425 Development Platform (Also known as Richfield).
30 For more information on this platform, see <file:Documentation/arm/IXP4xx>.
31
32config MACH_IXDPG425
33 bool "IXDPG425"
34 help
35 Say 'Y' here if you want your kernel to support Intel's
36 IXDPG425 Development Platform (Also known as Montajade).
37 For more information on this platform, see <file:Documentation/arm/IXP4xx>.
38
39config MACH_IXDP465
40 bool "IXDP465"
41 help
42 Say 'Y' here if you want your kernel to support Intel's
43 IXDP465 Development Platform (Also known as BMP).
44 For more information on this platform, see Documentation/arm/IXP4xx.
45
46
47#
48# IXCDP1100 is the exact same HW as IXDP425, but with a different machine
49# number from the bootloader due to marketing monkeys, so we just enable it
50# by default if IXDP425 is enabled.
51#
52config ARCH_IXCDP1100
53 bool
54 depends on ARCH_IXDP425
55 default y
56
57config ARCH_PRPMC1100
58 bool "PrPMC1100"
59 help
60 Say 'Y' here if you want your kernel to support the Motorola
61 PrPCM1100 Processor Mezanine Module. For more information on
62 this platform, see <file:Documentation/arm/IXP4xx>.
63
64#
65# Avila and IXDP share the same source for now. Will change in future
66#
67config ARCH_IXDP4XX
68 bool
69 depends on ARCH_IXDP425 || ARCH_AVILA || MACH_IXDP465
70 default y
71
72#
73# Certain registers and IRQs are only enabled if supporting IXP465 CPUs
74#
75config CPU_IXP46X
76 bool
77 depends on MACH_IXDP465
78 default y
79
80config MACH_GTWX5715
81 bool "Gemtek WX5715 (Linksys WRV54G)"
82 depends on ARCH_IXP4XX
83 help
84 This board is currently inside the Linksys WRV54G Gateways.
85
86 IXP425 - 266mhz
87 32mb SDRAM
88 8mb Flash
89 miniPCI slot 0 does not have a card connector soldered to the board
90 miniPCI slot 1 has an ISL3880 802.11g card (Prism54)
91 npe0 is connected to a Kendin KS8995M Switch (4 ports)
92 npe1 is the "wan" port
93 "Console" UART is available on J11 as console
94 "High Speed" UART is n/c (as far as I can tell)
95 20 Pin ARM/Xscale JTAG interface on J2
96
97
98comment "IXP4xx Options"
99
100config IXP4XX_INDIRECT_PCI
101 bool "Use indirect PCI memory access"
102 help
103 IXP4xx provides two methods of accessing PCI memory space:
104
105 1) A direct mapped window from 0x48000000 to 0x4bffffff (64MB).
106 To access PCI via this space, we simply ioremap() the BAR
107 into the kernel and we can use the standard read[bwl]/write[bwl]
108 macros. This is the preferred method due to speed but it
109 limits the system to just 64MB of PCI memory. This can be
110 problamatic if using video cards and other memory-heavy devices.
111
112 2) If > 64MB of memory space is required, the IXP4xx can be
113 configured to use indirect registers to access PCI This allows
114 for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus.
115 The disadvantadge of this is that every PCI access requires
116 three local register accesses plus a spinlock, but in some
117 cases the performance hit is acceptable. In addition, you cannot
118 mmap() PCI devices in this case due to the indirect nature
119 of the PCI window.
120
121 By default, the direct method is used. Choose this option if you
122 need to use the indirect method instead. If you don't know
123 what you need, leave this option unselected.
124
125endmenu
126
127endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
new file mode 100644
index 000000000000..ddecbda4a633
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y += common.o common-pci.o
6
7obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o
8obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o
9obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o
10obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o
11
diff --git a/arch/arm/mach-ixp4xx/Makefile.boot b/arch/arm/mach-ixp4xx/Makefile.boot
new file mode 100644
index 000000000000..d84c5807a43d
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x00008000
2params_phys-y := 0x00000100
3
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
new file mode 100644
index 000000000000..94bcdb933e41
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -0,0 +1,527 @@
1/*
2 * arch/arm/mach-ixp4xx/common-pci.c
3 *
4 * IXP4XX PCI routines for all platforms
5 *
6 * Maintainer: Deepak Saxena <dsaxena@plexity.net>
7 *
8 * Copyright (C) 2002 Intel Corporation.
9 * Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com>
10 * Copyright (C) 2003-2004 MontaVista Software, Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/pci.h>
21#include <linux/interrupt.h>
22#include <linux/mm.h>
23#include <linux/init.h>
24#include <linux/ioport.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/device.h>
28#include <asm/dma-mapping.h>
29
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/sizes.h>
33#include <asm/system.h>
34#include <asm/mach/pci.h>
35#include <asm/hardware.h>
36
37
38/*
39 * IXP4xx PCI read function is dependent on whether we are
40 * running A0 or B0 (AppleGate) silicon.
41 */
42int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
43
44/*
45 * Base address for PCI regsiter region
46 */
47unsigned long ixp4xx_pci_reg_base = 0;
48
49/*
50 * PCI cfg an I/O routines are done by programming a
51 * command/byte enable register, and then read/writing
52 * the data from a data regsiter. We need to ensure
53 * these transactions are atomic or we will end up
54 * with corrupt data on the bus or in a driver.
55 */
56static DEFINE_SPINLOCK(ixp4xx_pci_lock);
57
58/*
59 * Read from PCI config space
60 */
61static void crp_read(u32 ad_cbe, u32 *data)
62{
63 unsigned long flags;
64 spin_lock_irqsave(&ixp4xx_pci_lock, flags);
65 *PCI_CRP_AD_CBE = ad_cbe;
66 *data = *PCI_CRP_RDATA;
67 spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
68}
69
70/*
71 * Write to PCI config space
72 */
73static void crp_write(u32 ad_cbe, u32 data)
74{
75 unsigned long flags;
76 spin_lock_irqsave(&ixp4xx_pci_lock, flags);
77 *PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
78 *PCI_CRP_WDATA = data;
79 spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
80}
81
82static inline int check_master_abort(void)
83{
84 /* check Master Abort bit after access */
85 unsigned long isr = *PCI_ISR;
86
87 if (isr & PCI_ISR_PFE) {
88 /* make sure the Master Abort bit is reset */
89 *PCI_ISR = PCI_ISR_PFE;
90 pr_debug("%s failed\n", __FUNCTION__);
91 return 1;
92 }
93
94 return 0;
95}
96
97int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
98{
99 unsigned long flags;
100 int retval = 0;
101 int i;
102
103 spin_lock_irqsave(&ixp4xx_pci_lock, flags);
104
105 *PCI_NP_AD = addr;
106
107 /*
108 * PCI workaround - only works if NP PCI space reads have
109 * no side effects!!! Read 8 times. last one will be good.
110 */
111 for (i = 0; i < 8; i++) {
112 *PCI_NP_CBE = cmd;
113 *data = *PCI_NP_RDATA;
114 *data = *PCI_NP_RDATA;
115 }
116
117 if(check_master_abort())
118 retval = 1;
119
120 spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
121 return retval;
122}
123
124int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
125{
126 unsigned long flags;
127 int retval = 0;
128
129 spin_lock_irqsave(&ixp4xx_pci_lock, flags);
130
131 *PCI_NP_AD = addr;
132
133 /* set up and execute the read */
134 *PCI_NP_CBE = cmd;
135
136 /* the result of the read is now in NP_RDATA */
137 *data = *PCI_NP_RDATA;
138
139 if(check_master_abort())
140 retval = 1;
141
142 spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
143 return retval;
144}
145
146int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
147{
148 unsigned long flags;
149 int retval = 0;
150
151 spin_lock_irqsave(&ixp4xx_pci_lock, flags);
152
153 *PCI_NP_AD = addr;
154
155 /* set up the write */
156 *PCI_NP_CBE = cmd;
157
158 /* execute the write by writing to NP_WDATA */
159 *PCI_NP_WDATA = data;
160
161 if(check_master_abort())
162 retval = 1;
163
164 spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
165 return retval;
166}
167
168static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
169{
170 u32 addr;
171 if (!bus_num) {
172 /* type 0 */
173 addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
174 (where & ~3);
175 } else {
176 /* type 1 */
177 addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
178 ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
179 }
180 return addr;
181}
182
183/*
184 * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
185 * 0 and 3 are not valid indexes...
186 */
187static u32 bytemask[] = {
188 /*0*/ 0,
189 /*1*/ 0xff,
190 /*2*/ 0xffff,
191 /*3*/ 0,
192 /*4*/ 0xffffffff,
193};
194
195static u32 local_byte_lane_enable_bits(u32 n, int size)
196{
197 if (size == 1)
198 return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
199 if (size == 2)
200 return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
201 if (size == 4)
202 return 0;
203 return 0xffffffff;
204}
205
206static int local_read_config(int where, int size, u32 *value)
207{
208 u32 n, data;
209 pr_debug("local_read_config from %d size %d\n", where, size);
210 n = where % 4;
211 crp_read(where & ~3, &data);
212 *value = (data >> (8*n)) & bytemask[size];
213 pr_debug("local_read_config read %#x\n", *value);
214 return PCIBIOS_SUCCESSFUL;
215}
216
217static int local_write_config(int where, int size, u32 value)
218{
219 u32 n, byte_enables, data;
220 pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
221 n = where % 4;
222 byte_enables = local_byte_lane_enable_bits(n, size);
223 if (byte_enables == 0xffffffff)
224 return PCIBIOS_BAD_REGISTER_NUMBER;
225 data = value << (8*n);
226 crp_write((where & ~3) | byte_enables, data);
227 return PCIBIOS_SUCCESSFUL;
228}
229
230static u32 byte_lane_enable_bits(u32 n, int size)
231{
232 if (size == 1)
233 return (0xf & ~BIT(n)) << 4;
234 if (size == 2)
235 return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
236 if (size == 4)
237 return 0;
238 return 0xffffffff;
239}
240
241static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
242{
243 u32 n, byte_enables, addr, data;
244 u8 bus_num = bus->number;
245
246 pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
247 bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
248
249 *value = 0xffffffff;
250 n = where % 4;
251 byte_enables = byte_lane_enable_bits(n, size);
252 if (byte_enables == 0xffffffff)
253 return PCIBIOS_BAD_REGISTER_NUMBER;
254
255 addr = ixp4xx_config_addr(bus_num, devfn, where);
256 if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
257 return PCIBIOS_DEVICE_NOT_FOUND;
258
259 *value = (data >> (8*n)) & bytemask[size];
260 pr_debug("read_config_byte read %#x\n", *value);
261 return PCIBIOS_SUCCESSFUL;
262}
263
264static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
265{
266 u32 n, byte_enables, addr, data;
267 u8 bus_num = bus->number;
268
269 pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
270 size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
271
272 n = where % 4;
273 byte_enables = byte_lane_enable_bits(n, size);
274 if (byte_enables == 0xffffffff)
275 return PCIBIOS_BAD_REGISTER_NUMBER;
276
277 addr = ixp4xx_config_addr(bus_num, devfn, where);
278 data = value << (8*n);
279 if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
280 return PCIBIOS_DEVICE_NOT_FOUND;
281
282 return PCIBIOS_SUCCESSFUL;
283}
284
285struct pci_ops ixp4xx_ops = {
286 .read = ixp4xx_pci_read_config,
287 .write = ixp4xx_pci_write_config,
288};
289
290/*
291 * PCI abort handler
292 */
293static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
294{
295 u32 isr, status;
296
297 isr = *PCI_ISR;
298 local_read_config(PCI_STATUS, 2, &status);
299 pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
300 "status = %#x\n", addr, isr, status);
301
302 /* make sure the Master Abort bit is reset */
303 *PCI_ISR = PCI_ISR_PFE;
304 status |= PCI_STATUS_REC_MASTER_ABORT;
305 local_write_config(PCI_STATUS, 2, status);
306
307 /*
308 * If it was an imprecise abort, then we need to correct the
309 * return address to be _after_ the instruction.
310 */
311 if (fsr & (1 << 10))
312 regs->ARM_pc += 4;
313
314 return 0;
315}
316
317
318/*
319 * Setup DMA mask to 64MB on PCI devices. Ignore all other devices.
320 */
321static int ixp4xx_pci_platform_notify(struct device *dev)
322{
323 if(dev->bus == &pci_bus_type) {
324 *dev->dma_mask = SZ_64M - 1;
325 dev->coherent_dma_mask = SZ_64M - 1;
326 dmabounce_register_dev(dev, 2048, 4096);
327 }
328 return 0;
329}
330
331static int ixp4xx_pci_platform_notify_remove(struct device *dev)
332{
333 if(dev->bus == &pci_bus_type) {
334 dmabounce_unregister_dev(dev);
335 }
336 return 0;
337}
338
339int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
340{
341 return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
342}
343
344void __init ixp4xx_pci_preinit(void)
345{
346 unsigned long processor_id;
347
348 asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
349
350 /*
351 * Determine which PCI read method to use.
352 * Rev 0 IXP425 requires workaround.
353 */
354 if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
355 printk("PCI: IXP42x A0 silicon detected - "
356 "PCI Non-Prefetch Workaround Enabled\n");
357 ixp4xx_pci_read = ixp4xx_pci_read_errata;
358 } else
359 ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
360
361
362 /* hook in our fault handler for PCI errors */
363 hook_fault_code(16+6, abort_handler, SIGBUS, "imprecise external abort");
364
365 pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
366
367 /*
368 * We use identity AHB->PCI address translation
369 * in the 0x48000000 to 0x4bffffff address space
370 */
371 *PCI_PCIMEMBASE = 0x48494A4B;
372
373 /*
374 * We also use identity PCI->AHB address translation
375 * in 4 16MB BARs that begin at the physical memory start
376 */
377 *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
378 ((PHYS_OFFSET & 0xFF000000) >> 8) +
379 ((PHYS_OFFSET & 0xFF000000) >> 16) +
380 ((PHYS_OFFSET & 0xFF000000) >> 24) +
381 0x00010203;
382
383 if (*PCI_CSR & PCI_CSR_HOST) {
384 printk("PCI: IXP4xx is host\n");
385
386 pr_debug("setup BARs in controller\n");
387
388 /*
389 * We configure the PCI inbound memory windows to be
390 * 1:1 mapped to SDRAM
391 */
392 local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET + 0x00000000);
393 local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + 0x01000000);
394 local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + 0x02000000);
395 local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + 0x03000000);
396
397 /*
398 * Enable CSR window at 0xff000000.
399 */
400 local_write_config(PCI_BASE_ADDRESS_4, 4, 0xff000008);
401
402 /*
403 * Enable the IO window to be way up high, at 0xfffffc00
404 */
405 local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
406 } else {
407 printk("PCI: IXP4xx is target - No bus scan performed\n");
408 }
409
410 printk("PCI: IXP4xx Using %s access for memory space\n",
411#ifndef CONFIG_IXP4XX_INDIRECT_PCI
412 "direct"
413#else
414 "indirect"
415#endif
416 );
417
418 pr_debug("clear error bits in ISR\n");
419 *PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
420
421 /*
422 * Set Initialize Complete in PCI Control Register: allow IXP4XX to
423 * respond to PCI configuration cycles. Specify that the AHB bus is
424 * operating in big endian mode. Set up byte lane swapping between
425 * little-endian PCI and the big-endian AHB bus
426 */
427#ifdef __ARMEB__
428 *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
429#else
430 *PCI_CSR = PCI_CSR_IC;
431#endif
432
433 pr_debug("DONE\n");
434}
435
436int ixp4xx_setup(int nr, struct pci_sys_data *sys)
437{
438 struct resource *res;
439
440 if (nr >= 1)
441 return 0;
442
443 res = kmalloc(sizeof(*res) * 2, GFP_KERNEL);
444 if (res == NULL) {
445 /*
446 * If we're out of memory this early, something is wrong,
447 * so we might as well catch it here.
448 */
449 panic("PCI: unable to allocate resources?\n");
450 }
451 memset(res, 0, sizeof(*res) * 2);
452
453 local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
454
455 res[0].name = "PCI I/O Space";
456 res[0].start = 0x00001000;
457 res[0].end = 0xffff0000;
458 res[0].flags = IORESOURCE_IO;
459
460 res[1].name = "PCI Memory Space";
461 res[1].start = 0x48000000;
462#ifndef CONFIG_IXP4XX_INDIRECT_PCI
463 res[1].end = 0x4bffffff;
464#else
465 res[1].end = 0x4fffffff;
466#endif
467 res[1].flags = IORESOURCE_MEM;
468
469 request_resource(&ioport_resource, &res[0]);
470 request_resource(&iomem_resource, &res[1]);
471
472 sys->resource[0] = &res[0];
473 sys->resource[1] = &res[1];
474 sys->resource[2] = NULL;
475
476 platform_notify = ixp4xx_pci_platform_notify;
477 platform_notify_remove = ixp4xx_pci_platform_notify_remove;
478
479 return 1;
480}
481
482struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
483{
484 return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
485}
486
487/*
488 * We override these so we properly do dmabounce otherwise drivers
489 * are able to set the dma_mask to 0xffffffff and we can no longer
490 * trap bounces. :(
491 *
492 * We just return true on everyhing except for < 64MB in which case
493 * we will fail miseralby and die since we can't handle that case.
494 */
495int
496pci_set_dma_mask(struct pci_dev *dev, u64 mask)
497{
498 if (mask >= SZ_64M - 1 )
499 return 0;
500
501 return -EIO;
502}
503
504int
505pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
506{
507 if (mask >= SZ_64M - 1 )
508 return 0;
509
510 return -EIO;
511}
512
513int
514pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
515{
516 if (mask >= SZ_64M - 1 )
517 return 0;
518
519 return -EIO;
520}
521
522EXPORT_SYMBOL(pci_set_dma_mask);
523EXPORT_SYMBOL(pci_dac_set_dma_mask);
524EXPORT_SYMBOL(pci_set_consistent_dma_mask);
525EXPORT_SYMBOL(ixp4xx_pci_read);
526EXPORT_SYMBOL(ixp4xx_pci_write);
527
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
new file mode 100644
index 000000000000..267ba02d77dc
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -0,0 +1,353 @@
1/*
2 * arch/arm/mach-ixp4xx/common.c
3 *
4 * Generic code shared across all IXP4XX platforms
5 *
6 * Maintainer: Deepak Saxena <dsaxena@plexity.net>
7 *
8 * Copyright 2002 (c) Intel Corporation
9 * Copyright 2003-2004 (c) MontaVista, Software, Inc.
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/init.h>
20#include <linux/serial.h>
21#include <linux/sched.h>
22#include <linux/tty.h>
23#include <linux/serial_core.h>
24#include <linux/bootmem.h>
25#include <linux/interrupt.h>
26#include <linux/bitops.h>
27#include <linux/time.h>
28#include <linux/timex.h>
29
30#include <asm/hardware.h>
31#include <asm/uaccess.h>
32#include <asm/io.h>
33#include <asm/pgtable.h>
34#include <asm/page.h>
35#include <asm/irq.h>
36
37#include <asm/mach/map.h>
38#include <asm/mach/irq.h>
39#include <asm/mach/time.h>
40
41enum ixp4xx_irq_type {
42 IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
43};
44static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
45
46/*************************************************************************
47 * GPIO acces functions
48 *************************************************************************/
49
50/*
51 * Configure GPIO line for input, interrupt, or output operation
52 *
53 * TODO: Enable/disable the irq_desc based on interrupt or output mode.
54 * TODO: Should these be named ixp4xx_gpio_?
55 */
56void gpio_line_config(u8 line, u32 style)
57{
58 static const int gpio2irq[] = {
59 6, 7, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
60 };
61 u32 enable;
62 volatile u32 *int_reg;
63 u32 int_style;
64 enum ixp4xx_irq_type irq_type;
65
66 enable = *IXP4XX_GPIO_GPOER;
67
68 if (style & IXP4XX_GPIO_OUT) {
69 enable &= ~((1) << line);
70 } else if (style & IXP4XX_GPIO_IN) {
71 enable |= ((1) << line);
72
73 switch (style & IXP4XX_GPIO_INTSTYLE_MASK)
74 {
75 case (IXP4XX_GPIO_ACTIVE_HIGH):
76 int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
77 irq_type = IXP4XX_IRQ_LEVEL;
78 break;
79 case (IXP4XX_GPIO_ACTIVE_LOW):
80 int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
81 irq_type = IXP4XX_IRQ_LEVEL;
82 break;
83 case (IXP4XX_GPIO_RISING_EDGE):
84 int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
85 irq_type = IXP4XX_IRQ_EDGE;
86 break;
87 case (IXP4XX_GPIO_FALLING_EDGE):
88 int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
89 irq_type = IXP4XX_IRQ_EDGE;
90 break;
91 case (IXP4XX_GPIO_TRANSITIONAL):
92 int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
93 irq_type = IXP4XX_IRQ_EDGE;
94 break;
95 default:
96 int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
97 irq_type = IXP4XX_IRQ_LEVEL;
98 break;
99 }
100
101 if (style & IXP4XX_GPIO_INTSTYLE_MASK)
102 ixp4xx_config_irq(gpio2irq[line], irq_type);
103
104 if (line >= 8) { /* pins 8-15 */
105 line -= 8;
106 int_reg = IXP4XX_GPIO_GPIT2R;
107 }
108 else { /* pins 0-7 */
109 int_reg = IXP4XX_GPIO_GPIT1R;
110 }
111
112 /* Clear the style for the appropriate pin */
113 *int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
114 (line * IXP4XX_GPIO_STYLE_SIZE));
115
116 /* Set the new style */
117 *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
118 }
119
120 *IXP4XX_GPIO_GPOER = enable;
121}
122
123EXPORT_SYMBOL(gpio_line_config);
124
125/*************************************************************************
126 * IXP4xx chipset I/O mapping
127 *************************************************************************/
128static struct map_desc ixp4xx_io_desc[] __initdata = {
129 { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
130 .virtual = IXP4XX_PERIPHERAL_BASE_VIRT,
131 .physical = IXP4XX_PERIPHERAL_BASE_PHYS,
132 .length = IXP4XX_PERIPHERAL_REGION_SIZE,
133 .type = MT_DEVICE
134 }, { /* Expansion Bus Config Registers */
135 .virtual = IXP4XX_EXP_CFG_BASE_VIRT,
136 .physical = IXP4XX_EXP_CFG_BASE_PHYS,
137 .length = IXP4XX_EXP_CFG_REGION_SIZE,
138 .type = MT_DEVICE
139 }, { /* PCI Registers */
140 .virtual = IXP4XX_PCI_CFG_BASE_VIRT,
141 .physical = IXP4XX_PCI_CFG_BASE_PHYS,
142 .length = IXP4XX_PCI_CFG_REGION_SIZE,
143 .type = MT_DEVICE
144 }
145};
146
147void __init ixp4xx_map_io(void)
148{
149 iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
150}
151
152
153/*************************************************************************
154 * IXP4xx chipset IRQ handling
155 *
156 * TODO: GPIO IRQs should be marked invalid until the user of the IRQ
157 * (be it PCI or something else) configures that GPIO line
158 * as an IRQ.
159 **************************************************************************/
160static void ixp4xx_irq_mask(unsigned int irq)
161{
162 if (cpu_is_ixp46x() && irq >= 32)
163 *IXP4XX_ICMR2 &= ~(1 << (irq - 32));
164 else
165 *IXP4XX_ICMR &= ~(1 << irq);
166}
167
168static void ixp4xx_irq_unmask(unsigned int irq)
169{
170 if (cpu_is_ixp46x() && irq >= 32)
171 *IXP4XX_ICMR2 |= (1 << (irq - 32));
172 else
173 *IXP4XX_ICMR |= (1 << irq);
174}
175
176static void ixp4xx_irq_ack(unsigned int irq)
177{
178 static int irq2gpio[32] = {
179 -1, -1, -1, -1, -1, -1, 0, 1,
180 -1, -1, -1, -1, -1, -1, -1, -1,
181 -1, -1, -1, 2, 3, 4, 5, 6,
182 7, 8, 9, 10, 11, 12, -1, -1,
183 };
184 int line = (irq < 32) ? irq2gpio[irq] : -1;
185
186 if (line >= 0)
187 gpio_line_isr_clear(line);
188}
189
190/*
191 * Level triggered interrupts on GPIO lines can only be cleared when the
192 * interrupt condition disappears.
193 */
194static void ixp4xx_irq_level_unmask(unsigned int irq)
195{
196 ixp4xx_irq_ack(irq);
197 ixp4xx_irq_unmask(irq);
198}
199
200static struct irqchip ixp4xx_irq_level_chip = {
201 .ack = ixp4xx_irq_mask,
202 .mask = ixp4xx_irq_mask,
203 .unmask = ixp4xx_irq_level_unmask,
204};
205
206static struct irqchip ixp4xx_irq_edge_chip = {
207 .ack = ixp4xx_irq_ack,
208 .mask = ixp4xx_irq_mask,
209 .unmask = ixp4xx_irq_unmask,
210};
211
212static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type)
213{
214 switch (type) {
215 case IXP4XX_IRQ_LEVEL:
216 set_irq_chip(irq, &ixp4xx_irq_level_chip);
217 set_irq_handler(irq, do_level_IRQ);
218 break;
219 case IXP4XX_IRQ_EDGE:
220 set_irq_chip(irq, &ixp4xx_irq_edge_chip);
221 set_irq_handler(irq, do_edge_IRQ);
222 break;
223 }
224 set_irq_flags(irq, IRQF_VALID);
225}
226
227void __init ixp4xx_init_irq(void)
228{
229 int i = 0;
230
231 /* Route all sources to IRQ instead of FIQ */
232 *IXP4XX_ICLR = 0x0;
233
234 /* Disable all interrupt */
235 *IXP4XX_ICMR = 0x0;
236
237 if (cpu_is_ixp46x()) {
238 /* Route upper 32 sources to IRQ instead of FIQ */
239 *IXP4XX_ICLR2 = 0x00;
240
241 /* Disable upper 32 interrupts */
242 *IXP4XX_ICMR2 = 0x00;
243 }
244
245 /* Default to all level triggered */
246 for(i = 0; i < NR_IRQS; i++)
247 ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL);
248}
249
250
251/*************************************************************************
252 * IXP4xx timer tick
253 * We use OS timer1 on the CPU for the timer tick and the timestamp
254 * counter as a source of real clock ticks to account for missed jiffies.
255 *************************************************************************/
256
257static unsigned volatile last_jiffy_time;
258
259#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
260
261/* IRQs are disabled before entering here from do_gettimeofday() */
262static unsigned long ixp4xx_gettimeoffset(void)
263{
264 u32 elapsed;
265
266 elapsed = *IXP4XX_OSTS - last_jiffy_time;
267
268 return elapsed / CLOCK_TICKS_PER_USEC;
269}
270
271static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
272{
273 write_seqlock(&xtime_lock);
274
275 /* Clear Pending Interrupt by writing '1' to it */
276 *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
277
278 /*
279 * Catch up with the real idea of time
280 */
281 while ((*IXP4XX_OSTS - last_jiffy_time) > LATCH) {
282 timer_tick(regs);
283 last_jiffy_time += LATCH;
284 }
285
286 write_sequnlock(&xtime_lock);
287
288 return IRQ_HANDLED;
289}
290
291static struct irqaction ixp4xx_timer_irq = {
292 .name = "IXP4xx Timer Tick",
293 .flags = SA_INTERRUPT,
294 .handler = ixp4xx_timer_interrupt
295};
296
297static void __init ixp4xx_timer_init(void)
298{
299 /* Clear Pending Interrupt by writing '1' to it */
300 *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
301
302 /* Setup the Timer counter value */
303 *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
304
305 /* Reset time-stamp counter */
306 *IXP4XX_OSTS = 0;
307 last_jiffy_time = 0;
308
309 /* Connect the interrupt handler and enable the interrupt */
310 setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
311}
312
313struct sys_timer ixp4xx_timer = {
314 .init = ixp4xx_timer_init,
315 .offset = ixp4xx_gettimeoffset,
316};
317
318static struct resource ixp46x_i2c_resources[] = {
319 [0] = {
320 .start = 0xc8011000,
321 .end = 0xc801101c,
322 .flags = IORESOURCE_MEM,
323 },
324 [1] = {
325 .start = IRQ_IXP4XX_I2C,
326 .end = IRQ_IXP4XX_I2C,
327 .flags = IORESOURCE_IRQ
328 }
329};
330
331/*
332 * I2C controller. The IXP46x uses the same block as the IOP3xx, so
333 * we just use the same device name.
334 */
335static struct platform_device ixp46x_i2c_controller = {
336 .name = "IOP3xx-I2C",
337 .id = 0,
338 .num_resources = 2,
339 .resource = ixp46x_i2c_resources
340};
341
342static struct platform_device *ixp46x_devices[] __initdata = {
343 &ixp46x_i2c_controller
344};
345
346void __init ixp4xx_sys_init(void)
347{
348 if (cpu_is_ixp46x()) {
349 platform_add_devices(ixp46x_devices,
350 ARRAY_SIZE(ixp46x_devices));
351 }
352}
353
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
new file mode 100644
index 000000000000..afafb42ae129
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -0,0 +1,70 @@
1/*
2 * arch/arch/mach-ixp4xx/coyote-pci.c
3 *
4 * PCI setup routines for ADI Engineering Coyote platform
5 *
6 * Copyright (C) 2002 Jungo Software Technologies.
7 * Copyright (C) 2003 MontaVista Softwrae, Inc.
8 *
9 * Maintainer: Deepak Saxena <dsaxena@mvista.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/pci.h>
19#include <linux/init.h>
20
21#include <asm/mach-types.h>
22#include <asm/hardware.h>
23#include <asm/irq.h>
24
25#include <asm/mach/pci.h>
26
27extern void ixp4xx_pci_preinit(void);
28extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
29extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
30
31void __init coyote_pci_preinit(void)
32{
33 gpio_line_config(COYOTE_PCI_SLOT0_PIN,
34 IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
35
36 gpio_line_config(COYOTE_PCI_SLOT1_PIN,
37 IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
38
39 gpio_line_isr_clear(COYOTE_PCI_SLOT0_PIN);
40 gpio_line_isr_clear(COYOTE_PCI_SLOT1_PIN);
41
42 ixp4xx_pci_preinit();
43}
44
45static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
46{
47 if (slot == COYOTE_PCI_SLOT0_DEVID)
48 return IRQ_COYOTE_PCI_SLOT0;
49 else if (slot == COYOTE_PCI_SLOT1_DEVID)
50 return IRQ_COYOTE_PCI_SLOT1;
51 else return -1;
52}
53
54struct hw_pci coyote_pci __initdata = {
55 .nr_controllers = 1,
56 .preinit = coyote_pci_preinit,
57 .swizzle = pci_std_swizzle,
58 .setup = ixp4xx_setup,
59 .scan = ixp4xx_scan_bus,
60 .map_irq = coyote_map_irq,
61};
62
63int __init coyote_pci_init(void)
64{
65 if (machine_is_adi_coyote())
66 pci_common_init(&coyote_pci);
67 return 0;
68}
69
70subsys_initcall(coyote_pci_init);
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
new file mode 100644
index 000000000000..8a05a1227e5f
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -0,0 +1,130 @@
1/*
2 * arch/arm/mach-ixp4xx/coyote-setup.c
3 *
4 * Board setup for ADI Engineering and IXDGP425 boards
5 *
6 * Copyright (C) 2003-2005 MontaVista Software, Inc.
7 *
8 * Author: Deepak Saxena <dsaxena@plexity.net>
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/device.h>
14#include <linux/serial.h>
15#include <linux/tty.h>
16#include <linux/serial_8250.h>
17
18#include <asm/types.h>
19#include <asm/setup.h>
20#include <asm/memory.h>
21#include <asm/hardware.h>
22#include <asm/irq.h>
23#include <asm/mach-types.h>
24#include <asm/mach/arch.h>
25#include <asm/mach/flash.h>
26
27void __init coyote_map_io(void)
28{
29 ixp4xx_map_io();
30}
31
32static struct flash_platform_data coyote_flash_data = {
33 .map_name = "cfi_probe",
34 .width = 2,
35};
36
37static struct resource coyote_flash_resource = {
38 .start = COYOTE_FLASH_BASE,
39 .end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE,
40 .flags = IORESOURCE_MEM,
41};
42
43static struct platform_device coyote_flash = {
44 .name = "IXP4XX-Flash",
45 .id = 0,
46 .dev = {
47 .platform_data = &coyote_flash_data,
48 },
49 .num_resources = 1,
50 .resource = &coyote_flash_resource,
51};
52
53static struct resource coyote_uart_resource = {
54 .start = IXP4XX_UART2_BASE_PHYS,
55 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
56 .flags = IORESOURCE_MEM,
57};
58
59static struct plat_serial8250_port coyote_uart_data = {
60 .mapbase = IXP4XX_UART2_BASE_PHYS,
61 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
62 .irq = IRQ_IXP4XX_UART2,
63 .flags = UPF_BOOT_AUTOCONF,
64 .iotype = UPIO_MEM,
65 .regshift = 2,
66 .uartclk = IXP4XX_UART_XTAL,
67};
68
69static struct platform_device coyote_uart = {
70 .name = "serial8250",
71 .id = 0,
72 .dev = {
73 .platform_data = &coyote_uart_data,
74 },
75 .num_resources = 1,
76 .resource = &coyote_uart_resource,
77};
78
79static struct platform_device *coyote_devices[] __initdata = {
80 &coyote_flash,
81 &coyote_uart
82};
83
84static void __init coyote_init(void)
85{
86 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
87 *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
88
89 if (machine_is_ixdpg425()) {
90 coyote_uart_data.membase =
91 (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET);
92 coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS;
93 coyote_uart_data.irq = IRQ_IXP4XX_UART1;
94 }
95
96
97 ixp4xx_sys_init();
98 platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));
99}
100
101#ifdef CONFIG_ARCH_ADI_COYOTE
102MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
103 MAINTAINER("MontaVista Software, Inc.")
104 BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
105 IXP4XX_PERIPHERAL_BASE_VIRT)
106 MAPIO(coyote_map_io)
107 INITIRQ(ixp4xx_init_irq)
108 .timer = &ixp4xx_timer,
109 BOOT_PARAMS(0x0100)
110 INIT_MACHINE(coyote_init)
111MACHINE_END
112#endif
113
114/*
115 * IXDPG425 is identical to Coyote except for which serial port
116 * is connected.
117 */
118#ifdef CONFIG_MACH_IXDPG425
119MACHINE_START(IXDPG425, "Intel IXDPG425")
120 MAINTAINER("MontaVista Software, Inc.")
121 BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
122 IXP4XX_PERIPHERAL_BASE_VIRT)
123 MAPIO(coyote_map_io)
124 INITIRQ(ixp4xx_init_irq)
125 .timer = &ixp4xx_timer,
126 BOOT_PARAMS(0x0100)
127 INIT_MACHINE(coyote_init)
128MACHINE_END
129#endif
130
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
new file mode 100644
index 000000000000..b18035824e3e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -0,0 +1,101 @@
1/*
2 * arch/arm/mach-ixp4xx/gtwx5715-pci.c
3 *
4 * Gemtek GTWX5715 (Linksys WRV54G) board setup
5 *
6 * Copyright (C) 2004 George T. Joseph
7 * Derived from Coyote
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 */
24
25#include <linux/pci.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <asm/mach-types.h>
29#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/arch/gtwx5715.h>
32#include <asm/mach/pci.h>
33
34extern void ixp4xx_pci_preinit(void);
35extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
36extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
37
38 /*
39 * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
40 * Slot 0 isn't actually populated with a card connector but
41 * we initialize it anyway in case a future version has the
42 * slot populated or someone with good soldering skills has
43 * some free time.
44 */
45
46
47static void gtwx5715_init_gpio(u8 pin, u32 style)
48{
49 gpio_line_config(pin, style | IXP4XX_GPIO_ACTIVE_LOW);
50
51 if (style & IXP4XX_GPIO_IN) gpio_line_isr_clear(pin);
52}
53
54void __init gtwx5715_pci_preinit(void)
55{
56 gtwx5715_init_gpio(GTWX5715_PCI_SLOT0_INTA_GPIO, IXP4XX_GPIO_IN);
57 gtwx5715_init_gpio(GTWX5715_PCI_SLOT1_INTA_GPIO, IXP4XX_GPIO_IN);
58
59 ixp4xx_pci_preinit();
60}
61
62
63static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
64{
65 int rc;
66 static int gtwx5715_irqmap
67 [GTWX5715_PCI_SLOT_COUNT]
68 [GTWX5715_PCI_INT_PIN_COUNT] = {
69 {GTWX5715_PCI_SLOT0_INTA_IRQ, GTWX5715_PCI_SLOT0_INTB_IRQ},
70 {GTWX5715_PCI_SLOT1_INTA_IRQ, GTWX5715_PCI_SLOT1_INTB_IRQ},
71};
72
73 if (slot >= GTWX5715_PCI_SLOT_COUNT ||
74 pin >= GTWX5715_PCI_INT_PIN_COUNT) rc = -1;
75 else
76 rc = gtwx5715_irqmap[slot][pin-1];
77
78 printk("%s: Mapped slot %d pin %d to IRQ %d\n", __FUNCTION__,slot, pin, rc);
79 return(rc);
80}
81
82struct hw_pci gtwx5715_pci __initdata = {
83 .nr_controllers = 1,
84 .preinit = gtwx5715_pci_preinit,
85 .swizzle = pci_std_swizzle,
86 .setup = ixp4xx_setup,
87 .scan = ixp4xx_scan_bus,
88 .map_irq = gtwx5715_map_irq,
89};
90
91int __init gtwx5715_pci_init(void)
92{
93 if (machine_is_gtwx5715())
94 {
95 pci_common_init(&gtwx5715_pci);
96 }
97
98 return 0;
99}
100
101subsys_initcall(gtwx5715_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
new file mode 100644
index 000000000000..e77c86efd21d
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -0,0 +1,153 @@
1/*
2 * arch/arm/mach-ixp4xx/gtwx5715-setup.c
3 *
4 * Gemtek GTWX5715 (Linksys WRV54G) board settup
5 *
6 * Copyright (C) 2004 George T. Joseph
7 * Derived from Coyote
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 */
24
25#include <linux/init.h>
26#include <linux/device.h>
27#include <linux/serial.h>
28#include <linux/tty.h>
29#include <linux/serial_8250.h>
30
31#include <asm/types.h>
32#include <asm/setup.h>
33#include <asm/memory.h>
34#include <asm/hardware.h>
35#include <asm/irq.h>
36#include <asm/mach-types.h>
37#include <asm/mach/arch.h>
38#include <asm/mach/flash.h>
39#include <asm/arch/gtwx5715.h>
40
41/*
42 * Xscale UART registers are 32 bits wide with only the least
43 * significant 8 bits having any meaning. From a configuration
44 * perspective, this means 2 things...
45 *
46 * Setting .regshift = 2 so that the standard 16550 registers
47 * line up on every 4th byte.
48 *
49 * Shifting the register start virtual address +3 bytes when
50 * compiled big-endian. Since register writes are done on a
51 * single byte basis, if the shift isn't done the driver will
52 * write the value into the most significant byte of the register,
53 * which is ignored, instead of the least significant.
54 */
55
56#ifdef __ARMEB__
57#define REG_OFFSET 3
58#else
59#define REG_OFFSET 0
60#endif
61
62/*
63 * Only the second or "console" uart is connected on the gtwx5715.
64 */
65
66static struct resource gtwx5715_uart_resources[] = {
67 {
68 .start = IXP4XX_UART2_BASE_PHYS,
69 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
70 .flags = IORESOURCE_MEM,
71 },
72 {
73 .start = IRQ_IXP4XX_UART2,
74 .end = IRQ_IXP4XX_UART2,
75 .flags = IORESOURCE_IRQ,
76 },
77 { },
78};
79
80
81static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
82 {
83 .mapbase = IXP4XX_UART2_BASE_PHYS,
84 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
85 .irq = IRQ_IXP4XX_UART2,
86 .flags = UPF_BOOT_AUTOCONF,
87 .iotype = UPIO_MEM,
88 .regshift = 2,
89 .uartclk = IXP4XX_UART_XTAL,
90 },
91 { },
92};
93
94static struct platform_device gtwx5715_uart_device = {
95 .name = "serial8250",
96 .id = 0,
97 .dev = {
98 .platform_data = gtwx5715_uart_platform_data,
99 },
100 .num_resources = 2,
101 .resource = gtwx5715_uart_resources,
102};
103
104
105void __init gtwx5715_map_io(void)
106{
107 ixp4xx_map_io();
108}
109
110static struct flash_platform_data gtwx5715_flash_data = {
111 .map_name = "cfi_probe",
112 .width = 2,
113};
114
115static struct resource gtwx5715_flash_resource = {
116 .start = GTWX5715_FLASH_BASE,
117 .end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE,
118 .flags = IORESOURCE_MEM,
119};
120
121static struct platform_device gtwx5715_flash = {
122 .name = "IXP4XX-Flash",
123 .id = 0,
124 .dev = {
125 .platform_data = &gtwx5715_flash_data,
126 },
127 .num_resources = 1,
128 .resource = &gtwx5715_flash_resource,
129};
130
131static struct platform_device *gtwx5715_devices[] __initdata = {
132 &gtwx5715_uart_device,
133 &gtwx5715_flash,
134};
135
136static void __init gtwx5715_init(void)
137{
138 platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices));
139}
140
141
142MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
143 MAINTAINER("George Joseph")
144 BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS,
145 IXP4XX_UART2_BASE_VIRT)
146 MAPIO(gtwx5715_map_io)
147 INITIRQ(ixp4xx_init_irq)
148 .timer = &ixp4xx_timer,
149 BOOT_PARAMS(0x0100)
150 INIT_MACHINE(gtwx5715_init)
151MACHINE_END
152
153
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
new file mode 100644
index 000000000000..c2ab9ebb5980
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -0,0 +1,84 @@
1/*
2 * arch/arm/mach-ixp4xx/ixdp425-pci.c
3 *
4 * IXDP425 board-level PCI initialization
5 *
6 * Copyright (C) 2002 Intel Corporation.
7 * Copyright (C) 2003-2004 MontaVista Software, Inc.
8 *
9 * Maintainer: Deepak Saxena <dsaxena@plexity.net>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/kernel.h>
18#include <linux/config.h>
19#include <linux/pci.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22
23#include <asm/mach/pci.h>
24#include <asm/irq.h>
25#include <asm/hardware.h>
26#include <asm/mach-types.h>
27
28void __init ixdp425_pci_preinit(void)
29{
30 gpio_line_config(IXDP425_PCI_INTA_PIN,
31 IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
32 gpio_line_config(IXDP425_PCI_INTB_PIN,
33 IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
34 gpio_line_config(IXDP425_PCI_INTC_PIN,
35 IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
36 gpio_line_config(IXDP425_PCI_INTD_PIN,
37 IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
38
39 gpio_line_isr_clear(IXDP425_PCI_INTA_PIN);
40 gpio_line_isr_clear(IXDP425_PCI_INTB_PIN);
41 gpio_line_isr_clear(IXDP425_PCI_INTC_PIN);
42 gpio_line_isr_clear(IXDP425_PCI_INTD_PIN);
43
44 ixp4xx_pci_preinit();
45}
46
47static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
48{
49 static int pci_irq_table[IXDP425_PCI_IRQ_LINES] = {
50 IRQ_IXDP425_PCI_INTA,
51 IRQ_IXDP425_PCI_INTB,
52 IRQ_IXDP425_PCI_INTC,
53 IRQ_IXDP425_PCI_INTD
54 };
55
56 int irq = -1;
57
58 if (slot >= 1 && slot <= IXDP425_PCI_MAX_DEV &&
59 pin >= 1 && pin <= IXDP425_PCI_IRQ_LINES) {
60 irq = pci_irq_table[(slot + pin - 2) % 4];
61 }
62
63 return irq;
64}
65
66struct hw_pci ixdp425_pci __initdata = {
67 .nr_controllers = 1,
68 .preinit = ixdp425_pci_preinit,
69 .swizzle = pci_std_swizzle,
70 .setup = ixp4xx_setup,
71 .scan = ixp4xx_scan_bus,
72 .map_irq = ixdp425_map_irq,
73};
74
75int __init ixdp425_pci_init(void)
76{
77 if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
78 machine_is_avila() || machine_is_ixdp465())
79 pci_common_init(&ixdp425_pci);
80 return 0;
81}
82
83subsys_initcall(ixdp425_pci_init);
84
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
new file mode 100644
index 000000000000..77346c1f676b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -0,0 +1,181 @@
1/*
2 * arch/arm/mach-ixp4xx/ixdp425-setup.c
3 *
4 * IXDP425/IXCDP1100 board-setup
5 *
6 * Copyright (C) 2003-2005 MontaVista Software, Inc.
7 *
8 * Author: Deepak Saxena <dsaxena@plexity.net>
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/device.h>
14#include <linux/serial.h>
15#include <linux/tty.h>
16#include <linux/serial_8250.h>
17
18#include <asm/types.h>
19#include <asm/setup.h>
20#include <asm/memory.h>
21#include <asm/hardware.h>
22#include <asm/mach-types.h>
23#include <asm/irq.h>
24#include <asm/mach/arch.h>
25#include <asm/mach/flash.h>
26
27void __init ixdp425_map_io(void)
28{
29 ixp4xx_map_io();
30}
31
32static struct flash_platform_data ixdp425_flash_data = {
33 .map_name = "cfi_probe",
34 .width = 2,
35};
36
37static struct resource ixdp425_flash_resource = {
38 .start = IXDP425_FLASH_BASE,
39 .end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE,
40 .flags = IORESOURCE_MEM,
41};
42
43static struct platform_device ixdp425_flash = {
44 .name = "IXP4XX-Flash",
45 .id = 0,
46 .dev = {
47 .platform_data = &ixdp425_flash_data,
48 },
49 .num_resources = 1,
50 .resource = &ixdp425_flash_resource,
51};
52
53static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = {
54 .sda_pin = IXDP425_SDA_PIN,
55 .scl_pin = IXDP425_SCL_PIN,
56};
57
58static struct platform_device ixdp425_i2c_controller = {
59 .name = "IXP4XX-I2C",
60 .id = 0,
61 .dev = {
62 .platform_data = &ixdp425_i2c_gpio_pins,
63 },
64 .num_resources = 0
65};
66
67static struct resource ixdp425_uart_resources[] = {
68 {
69 .start = IXP4XX_UART1_BASE_PHYS,
70 .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
71 .flags = IORESOURCE_MEM
72 },
73 {
74 .start = IXP4XX_UART2_BASE_PHYS,
75 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
76 .flags = IORESOURCE_MEM
77 }
78};
79
80static struct plat_serial8250_port ixdp425_uart_data[] = {
81 {
82 .mapbase = IXP4XX_UART1_BASE_PHYS,
83 .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
84 .irq = IRQ_IXP4XX_UART1,
85 .flags = UPF_BOOT_AUTOCONF,
86 .iotype = UPIO_MEM,
87 .regshift = 2,
88 .uartclk = IXP4XX_UART_XTAL,
89 },
90 {
91 .mapbase = IXP4XX_UART2_BASE_PHYS,
92 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
93 .irq = IRQ_IXP4XX_UART1,
94 .flags = UPF_BOOT_AUTOCONF,
95 .iotype = UPIO_MEM,
96 .regshift = 2,
97 .uartclk = IXP4XX_UART_XTAL,
98 }
99};
100
101static struct platform_device ixdp425_uart = {
102 .name = "serial8250",
103 .id = 0,
104 .dev.platform_data = ixdp425_uart_data,
105 .num_resources = 2,
106 .resource = ixdp425_uart_resources
107};
108
109static struct platform_device *ixdp425_devices[] __initdata = {
110 &ixdp425_i2c_controller,
111 &ixdp425_flash,
112 &ixdp425_uart
113};
114
115
116static void __init ixdp425_init(void)
117{
118 ixp4xx_sys_init();
119
120 /*
121 * IXP465 has 32MB window
122 */
123 if (machine_is_ixdp465()) {
124 ixdp425_flash_resource.end += IXDP425_FLASH_SIZE;
125 }
126
127 platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
128}
129
130MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
131 MAINTAINER("MontaVista Software, Inc.")
132 BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
133 IXP4XX_PERIPHERAL_BASE_VIRT)
134 MAPIO(ixdp425_map_io)
135 INITIRQ(ixp4xx_init_irq)
136 .timer = &ixp4xx_timer,
137 BOOT_PARAMS(0x0100)
138 INIT_MACHINE(ixdp425_init)
139MACHINE_END
140
141MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
142 MAINTAINER("MontaVista Software, Inc.")
143 BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
144 IXP4XX_PERIPHERAL_BASE_VIRT)
145 MAPIO(ixdp425_map_io)
146 INITIRQ(ixp4xx_init_irq)
147 .timer = &ixp4xx_timer,
148 BOOT_PARAMS(0x0100)
149 INIT_MACHINE(ixdp425_init)
150MACHINE_END
151
152MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
153 MAINTAINER("MontaVista Software, Inc.")
154 BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
155 IXP4XX_PERIPHERAL_BASE_VIRT)
156 MAPIO(ixdp425_map_io)
157 INITIRQ(ixp4xx_init_irq)
158 .timer = &ixp4xx_timer,
159 BOOT_PARAMS(0x0100)
160 INIT_MACHINE(ixdp425_init)
161MACHINE_END
162
163/*
164 * Avila is functionally equivalent to IXDP425 except that it adds
165 * a CF IDE slot hanging off the expansion bus. When we have a
166 * driver for IXP4xx CF IDE with driver model support we'll move
167 * Avila to it's own setup file.
168 */
169#ifdef CONFIG_ARCH_AVILA
170MACHINE_START(AVILA, "Gateworks Avila Network Platform")
171 MAINTAINER("Deepak Saxena <dsaxena@plexity.net>")
172 BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
173 IXP4XX_PERIPHERAL_BASE_VIRT)
174 MAPIO(ixdp425_map_io)
175 INITIRQ(ixp4xx_init_irq)
176 .timer = &ixp4xx_timer,
177 BOOT_PARAMS(0x0100)
178 INIT_MACHINE(ixdp425_init)
179MACHINE_END
180#endif
181
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
new file mode 100644
index 000000000000..ce4563f00676
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -0,0 +1,66 @@
1/*
2 * arch/arch/mach-ixp4xx/ixdpg425-pci.c
3 *
4 * PCI setup routines for Intel IXDPG425 Platform
5 *
6 * Copyright (C) 2004 MontaVista Softwrae, Inc.
7 *
8 * Maintainer: Deepak Saxena <dsaxena@plexity.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/pci.h>
18#include <linux/init.h>
19
20#include <asm/mach-types.h>
21#include <asm/hardware.h>
22#include <asm/irq.h>
23
24#include <asm/mach/pci.h>
25
26extern void ixp4xx_pci_preinit(void);
27extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
28extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
29
30void __init ixdpg425_pci_preinit(void)
31{
32 gpio_line_config(6, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
33 gpio_line_config(7, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
34
35 gpio_line_isr_clear(6);
36 gpio_line_isr_clear(7);
37
38 ixp4xx_pci_preinit();
39}
40
41static int __init ixdpg425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
42{
43 if (slot == 12 || slot == 13)
44 return IRQ_IXP4XX_GPIO7;
45 else if (slot == 14)
46 return IRQ_IXP4XX_GPIO6;
47 else return -1;
48}
49
50struct hw_pci ixdpg425_pci __initdata = {
51 .nr_controllers = 1,
52 .preinit = ixdpg425_pci_preinit,
53 .swizzle = pci_std_swizzle,
54 .setup = ixp4xx_setup,
55 .scan = ixp4xx_scan_bus,
56 .map_irq = ixdpg425_map_irq,
57};
58
59int __init ixdpg425_pci_init(void)
60{
61 if (machine_is_ixdpg425())
62 pci_common_init(&ixdpg425_pci);
63 return 0;
64}
65
66subsys_initcall(ixdpg425_pci_init);