2 * arch/arm/mach-ixp23xx/ixdp2351.c
4 * IXDP2351 board-specific routines
6 * Author: Deepak Saxena <dsaxena@plexity.net>
8 * Copyright 2005 (c) MontaVista Software, Inc.
10 * Based on 2.4 code Copyright 2004 (c) Intel Corporation
12 * This file is licensed under the terms of the GNU General Public
13 * License version 2. This program is licensed "as is" without any
14 * warranty of any kind, whether express or implied.
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/spinlock.h>
20 #include <linux/sched.h>
21 #include <linux/interrupt.h>
22 #include <linux/irq.h>
23 #include <linux/serial.h>
24 #include <linux/tty.h>
25 #include <linux/bitops.h>
26 #include <linux/ioport.h>
27 #include <linux/serial.h>
28 #include <linux/serial_8250.h>
29 #include <linux/serial_core.h>
30 #include <linux/device.h>
32 #include <linux/pci.h>
33 #include <linux/mtd/physmap.h>
35 #include <asm/types.h>
36 #include <asm/setup.h>
37 #include <asm/memory.h>
38 #include <asm/hardware.h>
39 #include <asm/mach-types.h>
40 #include <asm/system.h>
41 #include <asm/tlbflush.h>
42 #include <asm/pgtable.h>
44 #include <asm/mach/map.h>
45 #include <asm/mach/irq.h>
46 #include <asm/mach/arch.h>
47 #include <asm/mach/irq.h>
48 #include <asm/mach/pci.h>
51 * IXDP2351 Interrupt Handling
53 static void ixdp2351_inta_mask(unsigned int irq
)
55 *IXDP2351_CPLD_INTA_MASK_SET_REG
= IXDP2351_INTA_IRQ_MASK(irq
);
58 static void ixdp2351_inta_unmask(unsigned int irq
)
60 *IXDP2351_CPLD_INTA_MASK_CLR_REG
= IXDP2351_INTA_IRQ_MASK(irq
);
63 static void ixdp2351_inta_handler(unsigned int irq
, struct irqdesc
*desc
, struct pt_regs
*regs
)
66 *IXDP2351_CPLD_INTA_STAT_REG
& IXDP2351_INTA_IRQ_VALID
;
69 desc
->chip
->mask(irq
);
71 for (i
= 0; i
< IXDP2351_INTA_IRQ_NUM
; i
++) {
72 if (ex_interrupt
& (1 << i
)) {
73 struct irqdesc
*cpld_desc
;
75 IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE
+ i
);
76 cpld_desc
= irq_desc
+ cpld_irq
;
77 desc_handle_irq(cpld_irq
, cpld_desc
, regs
);
81 desc
->chip
->unmask(irq
);
84 static struct irqchip ixdp2351_inta_chip
= {
85 .ack
= ixdp2351_inta_mask
,
86 .mask
= ixdp2351_inta_mask
,
87 .unmask
= ixdp2351_inta_unmask
90 static void ixdp2351_intb_mask(unsigned int irq
)
92 *IXDP2351_CPLD_INTB_MASK_SET_REG
= IXDP2351_INTB_IRQ_MASK(irq
);
95 static void ixdp2351_intb_unmask(unsigned int irq
)
97 *IXDP2351_CPLD_INTB_MASK_CLR_REG
= IXDP2351_INTB_IRQ_MASK(irq
);
100 static void ixdp2351_intb_handler(unsigned int irq
, struct irqdesc
*desc
, struct pt_regs
*regs
)
103 *IXDP2351_CPLD_INTB_STAT_REG
& IXDP2351_INTB_IRQ_VALID
;
106 desc
->chip
->ack(irq
);
108 for (i
= 0; i
< IXDP2351_INTB_IRQ_NUM
; i
++) {
109 if (ex_interrupt
& (1 << i
)) {
110 struct irqdesc
*cpld_desc
;
112 IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE
+ i
);
113 cpld_desc
= irq_desc
+ cpld_irq
;
114 desc_handle_irq(cpld_irq
, cpld_desc
, regs
);
118 desc
->chip
->unmask(irq
);
121 static struct irqchip ixdp2351_intb_chip
= {
122 .ack
= ixdp2351_intb_mask
,
123 .mask
= ixdp2351_intb_mask
,
124 .unmask
= ixdp2351_intb_unmask
127 void ixdp2351_init_irq(void)
131 /* Mask all interrupts from CPLD, disable simulation */
132 *IXDP2351_CPLD_INTA_MASK_SET_REG
= (u16
) -1;
133 *IXDP2351_CPLD_INTB_MASK_SET_REG
= (u16
) -1;
134 *IXDP2351_CPLD_INTA_SIM_REG
= 0;
135 *IXDP2351_CPLD_INTB_SIM_REG
= 0;
139 for (irq
= IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE
);
141 IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE
+ IXDP2351_INTA_IRQ_NUM
);
143 if (IXDP2351_INTA_IRQ_MASK(irq
) & IXDP2351_INTA_IRQ_VALID
) {
144 set_irq_flags(irq
, IRQF_VALID
);
145 set_irq_handler(irq
, do_level_IRQ
);
146 set_irq_chip(irq
, &ixdp2351_inta_chip
);
150 for (irq
= IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE
);
152 IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE
+ IXDP2351_INTB_IRQ_NUM
);
154 if (IXDP2351_INTB_IRQ_MASK(irq
) & IXDP2351_INTB_IRQ_VALID
) {
155 set_irq_flags(irq
, IRQF_VALID
);
156 set_irq_handler(irq
, do_level_IRQ
);
157 set_irq_chip(irq
, &ixdp2351_intb_chip
);
161 set_irq_chained_handler(IRQ_IXP23XX_INTA
, ixdp2351_inta_handler
);
162 set_irq_chained_handler(IRQ_IXP23XX_INTB
, ixdp2351_intb_handler
);
170 * This board does not do normal PCI IRQ routing, or any
171 * sort of swizzling, so we just need to check where on the
172 * bus the device is and figure out what CPLD pin it is
175 #define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
177 static int __init
ixdp2351_map_irq(struct pci_dev
*dev
, u8 slot
, u8 pin
)
179 u8 bus
= dev
->bus
->number
;
180 u32 devpin
= DEVPIN(PCI_SLOT(dev
->devfn
), pin
);
181 struct pci_bus
*tmp_bus
= dev
->bus
;
183 /* Primary bus, no interrupts here */
187 /* Lookup first leaf in bus tree */
188 while ((tmp_bus
->parent
!= NULL
) && (tmp_bus
->parent
->parent
!= NULL
))
189 tmp_bus
= tmp_bus
->parent
;
191 /* Select between known bridges */
192 switch (tmp_bus
->self
->devfn
| (tmp_bus
->self
->bus
->number
<< 8)) {
193 /* Device is located after first bridge */
195 if (tmp_bus
== dev
->bus
) {
196 /* Device is located directy after first bridge */
199 case DEVPIN(1, 1): /* Onboard 82546 ch 0 */
200 return IRQ_IXDP2351_INTA_82546
;
201 case DEVPIN(1, 2): /* Onboard 82546 ch 1 */
202 return IRQ_IXDP2351_INTB_82546
;
204 case DEVPIN(0, 1): /* PMCP INTA# */
205 case DEVPIN(2, 4): /* PMCS INTD# */
206 return IRQ_IXDP2351_SPCI_PMC_INTA
;
207 case DEVPIN(0, 2): /* PMCP INTB# */
208 case DEVPIN(2, 1): /* PMCS INTA# */
209 return IRQ_IXDP2351_SPCI_PMC_INTB
;
210 case DEVPIN(0, 3): /* PMCP INTC# */
211 case DEVPIN(2, 2): /* PMCS INTB# */
212 return IRQ_IXDP2351_SPCI_PMC_INTC
;
213 case DEVPIN(0, 4): /* PMCP INTD# */
214 case DEVPIN(2, 3): /* PMCS INTC# */
215 return IRQ_IXDP2351_SPCI_PMC_INTD
;
218 /* Device is located indirectly after first bridge */
219 /* Not supported now */
224 if (tmp_bus
== dev
->bus
) {
225 /* Device is located directy after second bridge */
226 /* Secondary bus of second bridge */
228 case DEVPIN(0, 1): /* DB#0 */
232 return IRQ_IXDP2351_SPCI_DB_0
;
233 case DEVPIN(1, 1): /* DB#1 */
237 return IRQ_IXDP2351_SPCI_DB_1
;
238 case DEVPIN(2, 1): /* FIC1 */
242 case DEVPIN(3, 1): /* FIC2 */
246 return IRQ_IXDP2351_SPCI_FIC
;
249 /* Device is located indirectly after second bridge */
250 /* Not supported now */
259 struct hw_pci ixdp2351_pci __initdata
= {
261 .preinit
= ixp23xx_pci_preinit
,
262 .setup
= ixp23xx_pci_setup
,
263 .scan
= ixp23xx_pci_scan_bus
,
264 .map_irq
= ixdp2351_map_irq
,
267 int __init
ixdp2351_pci_init(void)
269 if (machine_is_ixdp2351())
270 pci_common_init(&ixdp2351_pci
);
275 subsys_initcall(ixdp2351_pci_init
);
278 * IXDP2351 Static Mapped I/O
280 static struct map_desc ixdp2351_io_desc
[] __initdata
= {
282 .virtual = IXDP2351_NP_VIRT_BASE
,
283 .pfn
= __phys_to_pfn((u64
)IXDP2351_NP_PHYS_BASE
),
284 .length
= IXDP2351_NP_PHYS_SIZE
,
287 .virtual = IXDP2351_BB_BASE_VIRT
,
288 .pfn
= __phys_to_pfn((u64
)IXDP2351_BB_BASE_PHYS
),
289 .length
= IXDP2351_BB_SIZE
,
294 static void __init
ixdp2351_map_io(void)
297 iotable_init(ixdp2351_io_desc
, ARRAY_SIZE(ixdp2351_io_desc
));
300 static struct physmap_flash_data ixdp2351_flash_data
= {
304 static struct resource ixdp2351_flash_resource
= {
307 .flags
= IORESOURCE_MEM
,
310 static struct platform_device ixdp2351_flash
= {
311 .name
= "physmap-flash",
314 .platform_data
= &ixdp2351_flash_data
,
317 .resource
= &ixdp2351_flash_resource
,
320 static void __init
ixdp2351_init(void)
322 platform_device_register(&ixdp2351_flash
);
325 * Mark flash as writeable
327 IXP23XX_EXP_CS0
[0] |= IXP23XX_FLASH_WRITABLE
;
328 IXP23XX_EXP_CS0
[1] |= IXP23XX_FLASH_WRITABLE
;
329 IXP23XX_EXP_CS0
[2] |= IXP23XX_FLASH_WRITABLE
;
330 IXP23XX_EXP_CS0
[3] |= IXP23XX_FLASH_WRITABLE
;
335 MACHINE_START(IXDP2351
, "Intel IXDP2351 Development Platform")
336 /* Maintainer: MontaVista Software, Inc. */
337 .phys_io
= IXP23XX_PERIPHERAL_PHYS
,
338 .io_pg_offst
= ((IXP23XX_PERIPHERAL_VIRT
>> 18)) & 0xfffc,
339 .map_io
= ixdp2351_map_io
,
340 .init_irq
= ixdp2351_init_irq
,
341 .timer
= &ixp23xx_timer
,
342 .boot_params
= 0x00000100,
343 .init_machine
= ixdp2351_init
,