aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 11:16:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 11:16:37 -0400
commit13bbd8d90647132fc295d73b122567eb8987d298 (patch)
tree466ae1f00a5965308ce2e7695d4bfe88d87b9610 /arch/powerpc/platforms
parent18e6756a6b463e09fd3873592ec6b0579c78103d (diff)
parent9020fc960b8f5fbca0de6e4d11881ddc827aa61d (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (25 commits) [POWERPC] Add support for the mpc832x mds board [POWERPC] Add initial support for the e300c2 core [POWERPC] Add MPC8360EMDS default dts file [POWERPC] Add MPC8360EMDS board support [POWERPC] Add QUICC Engine (QE) infrastructure [POWERPC] Add QE device tree node definition [POWERPC] Don't try to just continue if xmon has no input device [POWERPC] Fix a printk in pseries_mpic_init_IRQ [POWERPC] Get default baud rate in udbg_scc [POWERPC] Fix zImage.coff on oldworld PowerMac [POWERPC] Fix xmon=off and cleanup xmon initialisation [POWERPC] Cleanup include/asm-powerpc/xmon.h [POWERPC] Update swim3 printk after blkdev.h change [POWERPC] Cell interrupt rework POWERPC: mpc82xx merge: board-specific/platform stuff(resend) POWERPC: 8272ads merge to powerpc: common stuff POWERPC: Added devicetree for mpc8272ads board [POWERPC] iSeries has no legacy I/O [POWERPC] implement BEGIN/END_FW_FTR_SECTION [POWERPC] iSeries does not need pcibios_fixup_resources ...
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig21
-rw-r--r--arch/powerpc/platforms/82xx/Makefile5
-rw-r--r--arch/powerpc/platforms/82xx/m82xx_pci.h19
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx.c111
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx_ads.c661
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads.h67
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig13
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c215
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.h19
-rw-r--r--arch/powerpc/platforms/83xx/mpc8360e_pb.c219
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c235
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h97
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c9
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c19
-rw-r--r--arch/powerpc/platforms/iseries/pci.c8
-rw-r--r--arch/powerpc/platforms/iseries/setup.c16
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c14
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
18 files changed, 1614 insertions, 136 deletions
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
new file mode 100644
index 000000000000..47d841ecf2e2
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -0,0 +1,21 @@
1menu "Platform support"
2 depends on PPC_82xx
3
4choice
5 prompt "Machine Type"
6 default MPC82xx_ADS
7
8config MPC82xx_ADS
9 bool "Freescale MPC82xx ADS"
10 select DEFAULT_UIMAGE
11 select PQ2ADS
12 select 8272
13 select 8260
14 select CPM2
15 select FSL_SOC
16 help
17 This option enables support for the MPC8272 ADS board
18
19endchoice
20
21endmenu
diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile
new file mode 100644
index 000000000000..d9fd4c84d2e0
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the PowerPC 82xx linux kernel.
3#
4obj-$(CONFIG_PPC_82xx) += mpc82xx.o
5obj-$(CONFIG_MPC82xx_ADS) += mpc82xx_ads.o
diff --git a/arch/powerpc/platforms/82xx/m82xx_pci.h b/arch/powerpc/platforms/82xx/m82xx_pci.h
new file mode 100644
index 000000000000..9cd8893b5a32
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/m82xx_pci.h
@@ -0,0 +1,19 @@
1#ifndef _PPC_KERNEL_M82XX_PCI_H
2#define _PPC_KERNEL_M82XX_PCI_H
3
4/*
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <asm/m8260_pci.h>
12
13#define SIU_INT_IRQ1 ((uint)0x13 + CPM_IRQ_OFFSET)
14
15#ifndef _IO_BASE
16#define _IO_BASE isa_io_base
17#endif
18
19#endif /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/powerpc/platforms/82xx/mpc82xx.c b/arch/powerpc/platforms/82xx/mpc82xx.c
new file mode 100644
index 000000000000..89d702de4863
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx.c
@@ -0,0 +1,111 @@
1/*
2 * MPC82xx setup and early boot code plus other random bits.
3 *
4 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5 *
6 * Copyright (c) 2006 MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/stddef.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/errno.h>
19#include <linux/reboot.h>
20#include <linux/pci.h>
21#include <linux/interrupt.h>
22#include <linux/kdev_t.h>
23#include <linux/major.h>
24#include <linux/console.h>
25#include <linux/delay.h>
26#include <linux/seq_file.h>
27#include <linux/root_dev.h>
28#include <linux/initrd.h>
29#include <linux/module.h>
30#include <linux/fsl_devices.h>
31#include <linux/fs_uart_pd.h>
32
33#include <asm/system.h>
34#include <asm/pgtable.h>
35#include <asm/page.h>
36#include <asm/atomic.h>
37#include <asm/time.h>
38#include <asm/io.h>
39#include <asm/machdep.h>
40#include <asm/bootinfo.h>
41#include <asm/pci-bridge.h>
42#include <asm/mpc8260.h>
43#include <asm/irq.h>
44#include <mm/mmu_decl.h>
45#include <asm/prom.h>
46#include <asm/cpm2.h>
47#include <asm/udbg.h>
48#include <asm/i8259.h>
49#include <linux/fs_enet_pd.h>
50
51#include <sysdev/fsl_soc.h>
52#include <sysdev/cpm2_pic.h>
53
54#include "pq2ads_pd.h"
55
56static int __init get_freq(char *name, unsigned long *val)
57{
58 struct device_node *cpu;
59 unsigned int *fp;
60 int found = 0;
61
62 /* The cpu node should have timebase and clock frequency properties */
63 cpu = of_find_node_by_type(NULL, "cpu");
64
65 if (cpu) {
66 fp = (unsigned int *)get_property(cpu, name, NULL);
67 if (fp) {
68 found = 1;
69 *val = *fp++;
70 }
71
72 of_node_put(cpu);
73 }
74
75 return found;
76}
77
78void __init m82xx_calibrate_decr(void)
79{
80 ppc_tb_freq = 125000000;
81 if (!get_freq("bus-frequency", &ppc_tb_freq)) {
82 printk(KERN_ERR "WARNING: Estimating decrementer frequency "
83 "(not found)\n");
84 }
85 ppc_tb_freq /= 4;
86 ppc_proc_freq = 1000000000;
87 if (!get_freq("clock-frequency", &ppc_proc_freq))
88 printk(KERN_ERR "WARNING: Estimating processor frequency"
89 "(not found)\n");
90}
91
92void mpc82xx_ads_show_cpuinfo(struct seq_file *m)
93{
94 uint pvid, svid, phid1;
95 uint memsize = total_memory;
96
97 pvid = mfspr(SPRN_PVR);
98 svid = mfspr(SPRN_SVR);
99
100 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
101 seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
102 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
103 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
104
105 /* Display cpu Pll setting */
106 phid1 = mfspr(SPRN_HID1);
107 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f));
108
109 /* Display the amount of memory */
110 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
111}
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
new file mode 100644
index 000000000000..4276f087f26e
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -0,0 +1,661 @@
1/*
2 * MPC82xx_ads setup and early boot code plus other random bits.
3 *
4 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5 * m82xx_restart fix by Wade Farnsworth <wfarnsworth@mvista.com>
6 *
7 * Copyright (c) 2006 MontaVista Software, Inc.
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
16#include <linux/config.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/reboot.h>
22#include <linux/pci.h>
23#include <linux/interrupt.h>
24#include <linux/kdev_t.h>
25#include <linux/major.h>
26#include <linux/console.h>
27#include <linux/delay.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/initrd.h>
31#include <linux/module.h>
32#include <linux/fsl_devices.h>
33#include <linux/fs_uart_pd.h>
34
35#include <asm/system.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <asm/atomic.h>
39#include <asm/time.h>
40#include <asm/io.h>
41#include <asm/machdep.h>
42#include <asm/bootinfo.h>
43#include <asm/pci-bridge.h>
44#include <asm/mpc8260.h>
45#include <asm/irq.h>
46#include <mm/mmu_decl.h>
47#include <asm/prom.h>
48#include <asm/cpm2.h>
49#include <asm/udbg.h>
50#include <asm/i8259.h>
51#include <linux/fs_enet_pd.h>
52
53#include <sysdev/fsl_soc.h>
54#include <../sysdev/cpm2_pic.h>
55
56#include "pq2ads_pd.h"
57
58#ifdef CONFIG_PCI
59static uint pci_clk_frq;
60static struct {
61 unsigned long *pci_int_stat_reg;
62 unsigned long *pci_int_mask_reg;
63} pci_regs;
64
65static unsigned long pci_int_base;
66static struct irq_host *pci_pic_host;
67static struct device_node *pci_pic_node;
68#endif
69
70static void __init mpc82xx_ads_pic_init(void)
71{
72 struct device_node *np = of_find_compatible_node(NULL, "cpm-pic", "CPM2");
73 struct resource r;
74 cpm2_map_t *cpm_reg;
75
76 if (np == NULL) {
77 printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
78 return;
79 }
80 if (of_address_to_resource(np, 0, &r)) {
81 printk(KERN_ERR "PIC init: invalid resource\n");
82 of_node_put(np);
83 return;
84 }
85 cpm2_pic_init(np);
86 of_node_put(np);
87
88 /* Initialize the default interrupt mapping priorities,
89 * in case the boot rom changed something on us.
90 */
91 cpm_reg = (cpm2_map_t *) ioremap(get_immrbase(), sizeof(cpm2_map_t));
92 cpm_reg->im_intctl.ic_siprr = 0x05309770;
93 iounmap(cpm_reg);
94#ifdef CONFIG_PCI
95 /* Initialize stuff for the 82xx CPLD IC and install demux */
96 m82xx_pci_init_irq();
97#endif
98}
99
100static void init_fcc1_ioports(struct fs_platform_info *fpi)
101{
102 struct io_port *io;
103 u32 tempval;
104 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
105 struct device_node *np;
106 struct resource r;
107 u32 *bcsr;
108
109 np = of_find_node_by_type(NULL, "memory");
110 if (!np) {
111 printk(KERN_INFO "No memory node in device tree\n");
112 return;
113 }
114 if (of_address_to_resource(np, 1, &r)) {
115 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
116 return;
117 }
118 of_node_put(np);
119 bcsr = ioremap(r.start + 4, sizeof(u32));
120 io = &immap->im_ioport;
121
122 /* Enable the PHY */
123 clrbits32(bcsr, BCSR1_FETHIEN);
124 setbits32(bcsr, BCSR1_FETH_RST);
125
126 /* FCC1 pins are on port A/C. */
127 /* Configure port A and C pins for FCC1 Ethernet. */
128
129 tempval = in_be32(&io->iop_pdira);
130 tempval &= ~PA1_DIRA0;
131 tempval |= PA1_DIRA1;
132 out_be32(&io->iop_pdira, tempval);
133
134 tempval = in_be32(&io->iop_psora);
135 tempval &= ~PA1_PSORA0;
136 tempval |= PA1_PSORA1;
137 out_be32(&io->iop_psora, tempval);
138
139 setbits32(&io->iop_ppara, PA1_DIRA0 | PA1_DIRA1);
140
141 /* Alter clocks */
142 tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
143
144 clrbits32(&io->iop_psorc, tempval);
145 clrbits32(&io->iop_pdirc, tempval);
146 setbits32(&io->iop_pparc, tempval);
147
148 cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_rx, CPM_CLK_RX);
149 cpm2_clk_setup(CPM_CLK_FCC1, fpi->clk_tx, CPM_CLK_TX);
150
151 iounmap(bcsr);
152 iounmap(immap);
153}
154
155static void init_fcc2_ioports(struct fs_platform_info *fpi)
156{
157 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
158 struct device_node *np;
159 struct resource r;
160 u32 *bcsr;
161
162 struct io_port *io;
163 u32 tempval;
164
165 np = of_find_node_by_type(NULL, "memory");
166 if (!np) {
167 printk(KERN_INFO "No memory node in device tree\n");
168 return;
169 }
170 if (of_address_to_resource(np, 1, &r)) {
171 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
172 return;
173 }
174 of_node_put(np);
175 io = &immap->im_ioport;
176 bcsr = ioremap(r.start + 12, sizeof(u32));
177
178 /* Enable the PHY */
179 clrbits32(bcsr, BCSR3_FETHIEN2);
180 setbits32(bcsr, BCSR3_FETH2_RST);
181
182 /* FCC2 are port B/C. */
183 /* Configure port A and C pins for FCC2 Ethernet. */
184
185 tempval = in_be32(&io->iop_pdirb);
186 tempval &= ~PB2_DIRB0;
187 tempval |= PB2_DIRB1;
188 out_be32(&io->iop_pdirb, tempval);
189
190 tempval = in_be32(&io->iop_psorb);
191 tempval &= ~PB2_PSORB0;
192 tempval |= PB2_PSORB1;
193 out_be32(&io->iop_psorb, tempval);
194
195 setbits32(&io->iop_pparb, PB2_DIRB0 | PB2_DIRB1);
196
197 tempval = PC_CLK(fpi->clk_tx - 8) | PC_CLK(fpi->clk_rx - 8);
198
199 /* Alter clocks */
200 clrbits32(&io->iop_psorc, tempval);
201 clrbits32(&io->iop_pdirc, tempval);
202 setbits32(&io->iop_pparc, tempval);
203
204 cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_rx, CPM_CLK_RX);
205 cpm2_clk_setup(CPM_CLK_FCC2, fpi->clk_tx, CPM_CLK_TX);
206
207 iounmap(bcsr);
208 iounmap(immap);
209}
210
211void init_fcc_ioports(struct fs_platform_info *fpi)
212{
213 int fcc_no = fs_get_fcc_index(fpi->fs_no);
214
215 switch (fcc_no) {
216 case 0:
217 init_fcc1_ioports(fpi);
218 break;
219 case 1:
220 init_fcc2_ioports(fpi);
221 break;
222 default:
223 printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n");
224 return;
225 }
226}
227
228static void init_scc1_uart_ioports(struct fs_uart_platform_info *data)
229{
230 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
231
232 /* SCC1 is only on port D */
233 setbits32(&immap->im_ioport.iop_ppard, 0x00000003);
234 clrbits32(&immap->im_ioport.iop_psord, 0x00000001);
235 setbits32(&immap->im_ioport.iop_psord, 0x00000002);
236 clrbits32(&immap->im_ioport.iop_pdird, 0x00000001);
237 setbits32(&immap->im_ioport.iop_pdird, 0x00000002);
238
239 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
240 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
241 setbits32(&immap->im_cpmux.cmx_scr,
242 ((data->clk_tx - 1) << (4 - data->clk_tx)));
243 setbits32(&immap->im_cpmux.cmx_scr,
244 ((data->clk_rx - 1) << (4 - data->clk_rx)));
245
246 iounmap(immap);
247}
248
249static void init_scc4_uart_ioports(struct fs_uart_platform_info *data)
250{
251 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
252
253 setbits32(&immap->im_ioport.iop_ppard, 0x00000600);
254 clrbits32(&immap->im_ioport.iop_psord, 0x00000600);
255 clrbits32(&immap->im_ioport.iop_pdird, 0x00000200);
256 setbits32(&immap->im_ioport.iop_pdird, 0x00000400);
257
258 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000007 << (4 - data->clk_tx)));
259 clrbits32(&immap->im_cpmux.cmx_scr, (0x00000038 << (4 - data->clk_rx)));
260 setbits32(&immap->im_cpmux.cmx_scr,
261 ((data->clk_tx - 1) << (4 - data->clk_tx)));
262 setbits32(&immap->im_cpmux.cmx_scr,
263 ((data->clk_rx - 1) << (4 - data->clk_rx)));
264
265 iounmap(immap);
266}
267
268void init_scc_ioports(struct fs_uart_platform_info *data)
269{
270 int scc_no = fs_get_scc_index(data->fs_no);
271
272 switch (scc_no) {
273 case 0:
274 init_scc1_uart_ioports(data);
275 data->brg = data->clk_rx;
276 break;
277 case 3:
278 init_scc4_uart_ioports(data);
279 data->brg = data->clk_rx;
280 break;
281 default:
282 printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
283 return;
284 }
285}
286
287void __init m82xx_board_setup(void)
288{
289 cpm2_map_t *immap = ioremap(get_immrbase(), sizeof(cpm2_map_t));
290 struct device_node *np;
291 struct resource r;
292 u32 *bcsr;
293
294 np = of_find_node_by_type(NULL, "memory");
295 if (!np) {
296 printk(KERN_INFO "No memory node in device tree\n");
297 return;
298 }
299 if (of_address_to_resource(np, 1, &r)) {
300 printk(KERN_INFO "No memory reg property [1] in devicetree\n");
301 return;
302 }
303 of_node_put(np);
304 bcsr = ioremap(r.start + 4, sizeof(u32));
305 /* Enable the 2nd UART port */
306 clrbits32(bcsr, BCSR1_RS232_EN2);
307
308#ifdef CONFIG_SERIAL_CPM_SCC1
309 clrbits32((u32 *) & immap->im_scc[0].scc_sccm,
310 UART_SCCM_TX | UART_SCCM_RX);
311 clrbits32((u32 *) & immap->im_scc[0].scc_gsmrl,
312 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
313#endif
314
315#ifdef CONFIG_SERIAL_CPM_SCC2
316 clrbits32((u32 *) & immap->im_scc[1].scc_sccm,
317 UART_SCCM_TX | UART_SCCM_RX);
318 clrbits32((u32 *) & immap->im_scc[1].scc_gsmrl,
319 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
320#endif
321
322#ifdef CONFIG_SERIAL_CPM_SCC3
323 clrbits32((u32 *) & immap->im_scc[2].scc_sccm,
324 UART_SCCM_TX | UART_SCCM_RX);
325 clrbits32((u32 *) & immap->im_scc[2].scc_gsmrl,
326 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
327#endif
328
329#ifdef CONFIG_SERIAL_CPM_SCC4
330 clrbits32((u32 *) & immap->im_scc[3].scc_sccm,
331 UART_SCCM_TX | UART_SCCM_RX);
332 clrbits32((u32 *) & immap->im_scc[3].scc_gsmrl,
333 SCC_GSMRL_ENR | SCC_GSMRL_ENT);
334#endif
335
336 iounmap(bcsr);
337 iounmap(immap);
338}
339
340#ifdef CONFIG_PCI
341static void m82xx_pci_mask_irq(unsigned int irq)
342{
343 int bit = irq - pci_int_base;
344
345 *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
346 return;
347}
348
349static void m82xx_pci_unmask_irq(unsigned int irq)
350{
351 int bit = irq - pci_int_base;
352
353 *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
354 return;
355}
356
357static void m82xx_pci_mask_and_ack(unsigned int irq)
358{
359 int bit = irq - pci_int_base;
360
361 *pci_regs.pci_int_mask_reg |= (1 << (31 - bit));
362 return;
363}
364
365static void m82xx_pci_end_irq(unsigned int irq)
366{
367 int bit = irq - pci_int_base;
368
369 *pci_regs.pci_int_mask_reg &= ~(1 << (31 - bit));
370 return;
371}
372
373struct hw_interrupt_type m82xx_pci_ic = {
374 .typename = "MPC82xx ADS PCI",
375 .name = "MPC82xx ADS PCI",
376 .enable = m82xx_pci_unmask_irq,
377 .disable = m82xx_pci_mask_irq,
378 .ack = m82xx_pci_mask_and_ack,
379 .end = m82xx_pci_end_irq,
380 .mask = m82xx_pci_mask_irq,
381 .mask_ack = m82xx_pci_mask_and_ack,
382 .unmask = m82xx_pci_unmask_irq,
383 .eoi = m82xx_pci_end_irq,
384};
385
386static void
387m82xx_pci_irq_demux(unsigned int irq, struct irq_desc *desc,
388 struct pt_regs *regs)
389{
390 unsigned long stat, mask, pend;
391 int bit;
392
393 for (;;) {
394 stat = *pci_regs.pci_int_stat_reg;
395 mask = *pci_regs.pci_int_mask_reg;
396 pend = stat & ~mask & 0xf0000000;
397 if (!pend)
398 break;
399 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
400 if (pend & 0x80000000)
401 __do_IRQ(pci_int_base + bit, regs);
402 }
403 }
404}
405
406static int pci_pic_host_match(struct irq_host *h, struct device_node *node)
407{
408 return node == pci_pic_node;
409}
410
411static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
412 irq_hw_number_t hw)
413{
414 get_irq_desc(virq)->status |= IRQ_LEVEL;
415 set_irq_chip(virq, &m82xx_pci_ic);
416 return 0;
417}
418
419static void pci_host_unmap(struct irq_host *h, unsigned int virq)
420{
421 /* remove chip and handler */
422 set_irq_chip(virq, NULL);
423}
424
425static struct irq_host_ops pci_pic_host_ops = {
426 .match = pci_pic_host_match,
427 .map = pci_pic_host_map,
428 .unmap = pci_host_unmap,
429};
430
431void m82xx_pci_init_irq(void)
432{
433 int irq;
434 cpm2_map_t *immap;
435 struct device_node *np;
436 struct resource r;
437 const u32 *regs;
438 unsigned int size;
439 const u32 *irq_map;
440 int i;
441 unsigned int irq_max, irq_min;
442
443 if ((np = of_find_node_by_type(NULL, "soc")) == NULL) {
444 printk(KERN_INFO "No SOC node in device tree\n");
445 return;
446 }
447 memset(&r, 0, sizeof(r));
448 if (of_address_to_resource(np, 0, &r)) {
449 printk(KERN_INFO "No SOC reg property in device tree\n");
450 return;
451 }
452 immap = ioremap(r.start, sizeof(*immap));
453 of_node_put(np);
454
455 /* install the demultiplexer for the PCI cascade interrupt */
456 np = of_find_node_by_type(NULL, "pci");
457 if (!np) {
458 printk(KERN_INFO "No pci node on device tree\n");
459 iounmap(immap);
460 return;
461 }
462 irq_map = get_property(np, "interrupt-map", &size);
463 if ((!irq_map) || (size <= 7)) {
464 printk(KERN_INFO "No interrupt-map property of pci node\n");
465 iounmap(immap);
466 return;
467 }
468 size /= sizeof(irq_map[0]);
469 for (i = 0, irq_max = 0, irq_min = 512; i < size; i += 7, irq_map += 7) {
470 if (irq_map[5] < irq_min)
471 irq_min = irq_map[5];
472 if (irq_map[5] > irq_max)
473 irq_max = irq_map[5];
474 }
475 pci_int_base = irq_min;
476 irq = irq_of_parse_and_map(np, 0);
477 set_irq_chained_handler(irq, m82xx_pci_irq_demux);
478 of_node_put(np);
479 np = of_find_node_by_type(NULL, "pci-pic");
480 if (!np) {
481 printk(KERN_INFO "No pci pic node on device tree\n");
482 iounmap(immap);
483 return;
484 }
485 pci_pic_node = of_node_get(np);
486 /* PCI interrupt controller registers: status and mask */
487 regs = get_property(np, "reg", &size);
488 if ((!regs) || (size <= 2)) {
489 printk(KERN_INFO "No reg property in pci pic node\n");
490 iounmap(immap);
491 return;
492 }
493 pci_regs.pci_int_stat_reg =
494 ioremap(regs[0], sizeof(*pci_regs.pci_int_stat_reg));
495 pci_regs.pci_int_mask_reg =
496 ioremap(regs[1], sizeof(*pci_regs.pci_int_mask_reg));
497 of_node_put(np);
498 /* configure chip select for PCI interrupt controller */
499 immap->im_memctl.memc_br3 = regs[0] | 0x00001801;
500 immap->im_memctl.memc_or3 = 0xffff8010;
501 /* make PCI IRQ level sensitive */
502 immap->im_intctl.ic_siexr &= ~(1 << (14 - (irq - SIU_INT_IRQ1)));
503
504 /* mask all PCI interrupts */
505 *pci_regs.pci_int_mask_reg |= 0xfff00000;
506 iounmap(immap);
507 pci_pic_host =
508 irq_alloc_host(IRQ_HOST_MAP_LINEAR, irq_max - irq_min + 1,
509 &pci_pic_host_ops, irq_max + 1);
510 return;
511}
512
513static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
514{
515 if (bus == 0 && PCI_SLOT(devfn) == 0)
516 return PCIBIOS_DEVICE_NOT_FOUND;
517 else
518 return PCIBIOS_SUCCESSFUL;
519}
520
521static void
522__init mpc82xx_pcibios_fixup(void)
523{
524 struct pci_dev *dev = NULL;
525
526 for_each_pci_dev(dev) {
527 pci_read_irq_line(dev);
528 }
529}
530
531void __init add_bridge(struct device_node *np)
532{
533 int len;
534 struct pci_controller *hose;
535 struct resource r;
536 const int *bus_range;
537 const void *ptr;
538
539 memset(&r, 0, sizeof(r));
540 if (of_address_to_resource(np, 0, &r)) {
541 printk(KERN_INFO "No PCI reg property in device tree\n");
542 return;
543 }
544 if (!(ptr = get_property(np, "clock-frequency", NULL))) {
545 printk(KERN_INFO "No clock-frequency property in PCI node");
546 return;
547 }
548 pci_clk_frq = *(uint *) ptr;
549 of_node_put(np);
550 bus_range = get_property(np, "bus-range", &len);
551 if (bus_range == NULL || len < 2 * sizeof(int)) {
552 printk(KERN_WARNING "Can't get bus-range for %s, assume"
553 " bus 0\n", np->full_name);
554 }
555
556 pci_assign_all_buses = 1;
557
558 hose = pcibios_alloc_controller();
559
560 if (!hose)
561 return;
562
563 hose->arch_data = np;
564 hose->set_cfg_type = 1;
565
566 hose->first_busno = bus_range ? bus_range[0] : 0;
567 hose->last_busno = bus_range ? bus_range[1] : 0xff;
568 hose->bus_offset = 0;
569
570 hose->set_cfg_type = 1;
571
572 setup_indirect_pci(hose,
573 r.start + offsetof(pci_cpm2_t, pci_cfg_addr),
574 r.start + offsetof(pci_cpm2_t, pci_cfg_data));
575
576 pci_process_bridge_OF_ranges(hose, np, 1);
577}
578#endif
579
580/*
581 * Setup the architecture
582 */
583static void __init mpc82xx_ads_setup_arch(void)
584{
585#ifdef CONFIG_PCI
586 struct device_node *np;
587#endif
588
589 if (ppc_md.progress)
590 ppc_md.progress("mpc82xx_ads_setup_arch()", 0);
591 cpm2_reset();
592
593 /* Map I/O region to a 256MB BAT */
594
595 m82xx_board_setup();
596
597#ifdef CONFIG_PCI
598 ppc_md.pci_exclude_device = m82xx_pci_exclude_device;
599 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
600 add_bridge(np);
601
602 of_node_put(np);
603 ppc_md.pci_map_irq = NULL;
604 ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
605 ppc_md.pcibios_fixup_bus = NULL;
606#endif
607
608#ifdef CONFIG_ROOT_NFS
609 ROOT_DEV = Root_NFS;
610#else
611 ROOT_DEV = Root_HDA1;
612#endif
613
614 if (ppc_md.progress)
615 ppc_md.progress("mpc82xx_ads_setup_arch(), finish", 0);
616}
617
618/*
619 * Called very early, device-tree isn't unflattened
620 */
621static int __init mpc82xx_ads_probe(void)
622{
623 /* We always match for now, eventually we should look at
624 * the flat dev tree to ensure this is the board we are
625 * supposed to run on
626 */
627 return 1;
628}
629
630#define RMR_CSRE 0x00000001
631static void m82xx_restart(char *cmd)
632{
633 __volatile__ unsigned char dummy;
634
635 local_irq_disable();
636 ((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
637
638 /* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
639 mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
640 dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
641 printk("Restart failed\n");
642 while (1) ;
643}
644
645static void m82xx_halt(void)
646{
647 local_irq_disable();
648 while (1) ;
649}
650
651define_machine(mpc82xx_ads)
652{
653 .name = "MPC82xx ADS",
654 .probe = mpc82xx_ads_probe,
655 .setup_arch = mpc82xx_ads_setup_arch,
656 .init_IRQ = mpc82xx_ads_pic_init,
657 .show_cpuinfo = mpc82xx_ads_show_cpuinfo,
658 .get_irq = cpm2_get_irq,
659 .calibrate_decr = m82xx_calibrate_decr,
660 .restart = m82xx_restart,.halt = m82xx_halt,
661};
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
new file mode 100644
index 000000000000..a7348213508f
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -0,0 +1,67 @@
1/*
2 * PQ2/mpc8260 board-specific stuff
3 *
4 * A collection of structures, addresses, and values associated with
5 * the Freescale MPC8260ADS/MPC8266ADS-PCI boards.
6 * Copied from the RPX-Classic and SBS8260 stuff.
7 *
8 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
9 *
10 * Originally written by Dan Malek for Motorola MPC8260 family
11 *
12 * Copyright (c) 2001 Dan Malek <dan@embeddedalley.com>
13 * Copyright (c) 2006 MontaVista Software, Inc.
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20
21#ifdef __KERNEL__
22#ifndef __MACH_ADS8260_DEFS
23#define __MACH_ADS8260_DEFS
24
25#include <linux/config.h>
26
27#include <asm/ppcboot.h>
28
29/* For our show_cpuinfo hooks. */
30#define CPUINFO_VENDOR "Freescale Semiconductor"
31#define CPUINFO_MACHINE "PQ2 ADS PowerPC"
32
33/* Backword-compatibility stuff for the drivers */
34#define CPM_MAP_ADDR ((uint)0xf0000000)
35#define CPM_IRQ_OFFSET 0
36
37/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
38 * only on word boundaries.
39 * Not all are used (yet), or are interesting to us (yet).
40 */
41
42/* Things of interest in the CSR.
43 */
44#define BCSR0_LED0 ((uint)0x02000000) /* 0 == on */
45#define BCSR0_LED1 ((uint)0x01000000) /* 0 == on */
46#define BCSR1_FETHIEN ((uint)0x08000000) /* 0 == enable*/
47#define BCSR1_FETH_RST ((uint)0x04000000) /* 0 == reset */
48#define BCSR1_RS232_EN1 ((uint)0x02000000) /* 0 ==enable */
49#define BCSR1_RS232_EN2 ((uint)0x01000000) /* 0 ==enable */
50#define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable*/
51#define BCSR3_FETH2_RS ((uint)0x80000000) /* 0 == reset */
52
53/* cpm serial driver works with constants below */
54
55#define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET)
56#define SIU_INT_SMC2i ((uint)0x05+CPM_IRQ_OFFSET)
57#define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET)
58#define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET)
59#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
60#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
61
62void m82xx_pci_init_irq(void);
63void mpc82xx_ads_show_cpuinfo(struct seq_file*);
64void m82xx_calibrate_decr(void);
65
66#endif /* __MACH_ADS8260_DEFS */
67#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 5fe7b7faf45f..0975e94ac7c4 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -5,6 +5,13 @@ choice
5 prompt "Machine Type" 5 prompt "Machine Type"
6 default MPC834x_SYS 6 default MPC834x_SYS
7 7
8config MPC832x_MDS
9 bool "Freescale MPC832x MDS"
10 select DEFAULT_UIMAGE
11 select QUICC_ENGINE
12 help
13 This option enables support for the MPC832x MDS evaluation board.
14
8config MPC834x_SYS 15config MPC834x_SYS
9 bool "Freescale MPC834x SYS" 16 bool "Freescale MPC834x SYS"
10 select DEFAULT_UIMAGE 17 select DEFAULT_UIMAGE
@@ -27,6 +34,12 @@ config MPC834x_ITX
27 34
28endchoice 35endchoice
29 36
37config PPC_MPC832x
38 bool
39 select PPC_UDBG_16550
40 select PPC_INDIRECT_PCI
41 default y if MPC832x_MDS
42
30config MPC834x 43config MPC834x
31 bool 44 bool
32 select PPC_UDBG_16550 45 select PPC_UDBG_16550
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
new file mode 100644
index 000000000000..54dea9d42dc9
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -0,0 +1,215 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Description:
5 * MPC832xE MDS board specific routines.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/reboot.h>
18#include <linux/pci.h>
19#include <linux/kdev_t.h>
20#include <linux/major.h>
21#include <linux/console.h>
22#include <linux/delay.h>
23#include <linux/seq_file.h>
24#include <linux/root_dev.h>
25#include <linux/initrd.h>
26
27#include <asm/system.h>
28#include <asm/atomic.h>
29#include <asm/time.h>
30#include <asm/io.h>
31#include <asm/machdep.h>
32#include <asm/ipic.h>
33#include <asm/bootinfo.h>
34#include <asm/irq.h>
35#include <asm/prom.h>
36#include <asm/udbg.h>
37#include <sysdev/fsl_soc.h>
38#include <asm/qe.h>
39#include <asm/qe_ic.h>
40
41#include "mpc83xx.h"
42#include "mpc832x_mds.h"
43
44#undef DEBUG
45#ifdef DEBUG
46#define DBG(fmt...) udbg_printf(fmt)
47#else
48#define DBG(fmt...)
49#endif
50
51#ifndef CONFIG_PCI
52unsigned long isa_io_base = 0;
53unsigned long isa_mem_base = 0;
54#endif
55
56static u8 *bcsr_regs = NULL;
57
58u8 *get_bcsr(void)
59{
60 return bcsr_regs;
61}
62
63/* ************************************************************************
64 *
65 * Setup the architecture
66 *
67 */
68static void __init mpc832x_sys_setup_arch(void)
69{
70 struct device_node *np;
71
72 if (ppc_md.progress)
73 ppc_md.progress("mpc832x_sys_setup_arch()", 0);
74
75 np = of_find_node_by_type(NULL, "cpu");
76 if (np != 0) {
77 unsigned int *fp =
78 (int *)get_property(np, "clock-frequency", NULL);
79 if (fp != 0)
80 loops_per_jiffy = *fp / HZ;
81 else
82 loops_per_jiffy = 50000000 / HZ;
83 of_node_put(np);
84 }
85
86 /* Map BCSR area */
87 np = of_find_node_by_name(NULL, "bcsr");
88 if (np != 0) {
89 struct resource res;
90
91 of_address_to_resource(np, 0, &res);
92 bcsr_regs = ioremap(res.start, res.end - res.start +1);
93 of_node_put(np);
94 }
95
96#ifdef CONFIG_PCI
97 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
98 add_bridge(np);
99
100 ppc_md.pci_swizzle = common_swizzle;
101 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
102#endif
103
104#ifdef CONFIG_QUICC_ENGINE
105 qe_reset();
106
107 if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
108 par_io_init(np);
109 of_node_put(np);
110
111 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
112 par_io_of_config(np);
113 }
114
115 if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
116 != NULL){
117 /* Reset the Ethernet PHY */
118 bcsr_regs[9] &= ~0x20;
119 udelay(1000);
120 bcsr_regs[9] |= 0x20;
121 iounmap(bcsr_regs);
122 of_node_put(np);
123 }
124
125#endif /* CONFIG_QUICC_ENGINE */
126
127#ifdef CONFIG_BLK_DEV_INITRD
128 if (initrd_start)
129 ROOT_DEV = Root_RAM0;
130 else
131#endif
132#ifdef CONFIG_ROOT_NFS
133 ROOT_DEV = Root_NFS;
134#else
135 ROOT_DEV = Root_HDA1;
136#endif
137}
138
139void __init mpc832x_sys_init_IRQ(void)
140{
141
142 struct device_node *np;
143
144 np = of_find_node_by_type(NULL, "ipic");
145 if (!np)
146 return;
147
148 ipic_init(np, 0);
149
150 /* Initialize the default interrupt mapping priorities,
151 * in case the boot rom changed something on us.
152 */
153 ipic_set_default_priority();
154 of_node_put(np);
155
156#ifdef CONFIG_QUICC_ENGINE
157 np = of_find_node_by_type(NULL, "qeic");
158 if (!np)
159 return;
160
161 qe_ic_init(np, 0);
162 of_node_put(np);
163#endif /* CONFIG_QUICC_ENGINE */
164}
165
166#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
167extern ulong ds1374_get_rtc_time(void);
168extern int ds1374_set_rtc_time(ulong);
169
170static int __init mpc832x_rtc_hookup(void)
171{
172 struct timespec tv;
173
174 ppc_md.get_rtc_time = ds1374_get_rtc_time;
175 ppc_md.set_rtc_time = ds1374_set_rtc_time;
176
177 tv.tv_nsec = 0;
178 tv.tv_sec = (ppc_md.get_rtc_time) ();
179 do_settimeofday(&tv);
180
181 return 0;
182}
183
184late_initcall(mpc832x_rtc_hookup);
185#endif
186
187/*
188 * Called very early, MMU is off, device-tree isn't unflattened
189 */
190static int __init mpc832x_sys_probe(void)
191{
192 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
193 "model", NULL);
194
195 if (model == NULL)
196 return 0;
197 if (strcmp(model, "MPC8323EMDS"))
198 return 0;
199
200 DBG("%s found\n", model);
201
202 return 1;
203}
204
205define_machine(mpc832x_mds) {
206 .name = "MPC832x MDS",
207 .probe = mpc832x_sys_probe,
208 .setup_arch = mpc832x_sys_setup_arch,
209 .init_IRQ = mpc832x_sys_init_IRQ,
210 .get_irq = ipic_get_irq,
211 .restart = mpc83xx_restart,
212 .time_init = mpc83xx_time_init,
213 .calibrate_decr = generic_calibrate_decr,
214 .progress = udbg_progress,
215};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.h b/arch/powerpc/platforms/83xx/mpc832x_mds.h
new file mode 100644
index 000000000000..a49588904f8a
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Description:
5 * MPC832x MDS board specific header.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#ifndef __MACH_MPC832x_MDS_H__
15#define __MACH_MPC832x_MDS_H__
16
17extern u8 *get_bcsr(void);
18
19#endif /* __MACH_MPC832x_MDS_H__ */
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
new file mode 100644
index 000000000000..c0191900fc25
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
3 *
4 * Author: Li Yang <LeoLi@freescale.com>
5 * Yin Olivia <Hong-hua.Yin@freescale.com>
6 *
7 * Description:
8 * MPC8360E MDS PB board specific routines.
9 *
10 * Changelog:
11 * Jun 21, 2006 Initial version
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/stddef.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/errno.h>
23#include <linux/reboot.h>
24#include <linux/pci.h>
25#include <linux/kdev_t.h>
26#include <linux/major.h>
27#include <linux/console.h>
28#include <linux/delay.h>
29#include <linux/seq_file.h>
30#include <linux/root_dev.h>
31#include <linux/initrd.h>
32
33#include <asm/system.h>
34#include <asm/atomic.h>
35#include <asm/time.h>
36#include <asm/io.h>
37#include <asm/machdep.h>
38#include <asm/ipic.h>
39#include <asm/bootinfo.h>
40#include <asm/irq.h>
41#include <asm/prom.h>
42#include <asm/udbg.h>
43#include <sysdev/fsl_soc.h>
44#include <asm/qe.h>
45#include <asm/qe_ic.h>
46
47#include "mpc83xx.h"
48
49#undef DEBUG
50#ifdef DEBUG
51#define DBG(fmt...) udbg_printf(fmt)
52#else
53#define DBG(fmt...)
54#endif
55
56#ifndef CONFIG_PCI
57unsigned long isa_io_base = 0;
58unsigned long isa_mem_base = 0;
59#endif
60
61static u8 *bcsr_regs = NULL;
62
63u8 *get_bcsr(void)
64{
65 return bcsr_regs;
66}
67
68/* ************************************************************************
69 *
70 * Setup the architecture
71 *
72 */
73static void __init mpc8360_sys_setup_arch(void)
74{
75 struct device_node *np;
76
77 if (ppc_md.progress)
78 ppc_md.progress("mpc8360_sys_setup_arch()", 0);
79
80 np = of_find_node_by_type(NULL, "cpu");
81 if (np != 0) {
82 const unsigned int *fp =
83 get_property(np, "clock-frequency", NULL);
84 if (fp != 0)
85 loops_per_jiffy = *fp / HZ;
86 else
87 loops_per_jiffy = 50000000 / HZ;
88 of_node_put(np);
89 }
90
91 /* Map BCSR area */
92 np = of_find_node_by_name(NULL, "bcsr");
93 if (np != 0) {
94 struct resource res;
95
96 of_address_to_resource(np, 0, &res);
97 bcsr_regs = ioremap(res.start, res.end - res.start +1);
98 of_node_put(np);
99 }
100
101#ifdef CONFIG_PCI
102 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
103 add_bridge(np);
104
105 ppc_md.pci_swizzle = common_swizzle;
106 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
107#endif
108
109#ifdef CONFIG_QUICC_ENGINE
110 qe_reset();
111
112 if ((np = of_find_node_by_name(np, "par_io")) != NULL) {
113 par_io_init(np);
114 of_node_put(np);
115
116 for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
117 par_io_of_config(np);
118 }
119
120 if ((np = of_find_compatible_node(NULL, "network", "ucc_geth"))
121 != NULL){
122 /* Reset the Ethernet PHY */
123 bcsr_regs[9] &= ~0x20;
124 udelay(1000);
125 bcsr_regs[9] |= 0x20;
126 iounmap(bcsr_regs);
127 of_node_put(np);
128 }
129
130#endif /* CONFIG_QUICC_ENGINE */
131
132#ifdef CONFIG_BLK_DEV_INITRD
133 if (initrd_start)
134 ROOT_DEV = Root_RAM0;
135 else
136#endif
137#ifdef CONFIG_ROOT_NFS
138 ROOT_DEV = Root_NFS;
139#else
140 ROOT_DEV = Root_HDA1;
141#endif
142}
143
144void __init mpc8360_sys_init_IRQ(void)
145{
146
147 struct device_node *np;
148
149 np = of_find_node_by_type(NULL, "ipic");
150 if (!np)
151 return;
152
153 ipic_init(np, 0);
154
155 /* Initialize the default interrupt mapping priorities,
156 * in case the boot rom changed something on us.
157 */
158 ipic_set_default_priority();
159 of_node_put(np);
160
161#ifdef CONFIG_QUICC_ENGINE
162 np = of_find_node_by_type(NULL, "qeic");
163 if (!np)
164 return;
165
166 qe_ic_init(np, 0);
167 of_node_put(np);
168#endif /* CONFIG_QUICC_ENGINE */
169}
170
171#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
172extern ulong ds1374_get_rtc_time(void);
173extern int ds1374_set_rtc_time(ulong);
174
175static int __init mpc8360_rtc_hookup(void)
176{
177 struct timespec tv;
178
179 ppc_md.get_rtc_time = ds1374_get_rtc_time;
180 ppc_md.set_rtc_time = ds1374_set_rtc_time;
181
182 tv.tv_nsec = 0;
183 tv.tv_sec = (ppc_md.get_rtc_time) ();
184 do_settimeofday(&tv);
185
186 return 0;
187}
188
189late_initcall(mpc8360_rtc_hookup);
190#endif
191
192/*
193 * Called very early, MMU is off, device-tree isn't unflattened
194 */
195static int __init mpc8360_sys_probe(void)
196{
197 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
198 "model", NULL);
199 if (model == NULL)
200 return 0;
201 if (strcmp(model, "MPC8360EPB"))
202 return 0;
203
204 DBG("MPC8360EMDS-PB found\n");
205
206 return 1;
207}
208
209define_machine(mpc8360_sys) {
210 .name = "MPC8360E PB",
211 .probe = mpc8360_sys_probe,
212 .setup_arch = mpc8360_sys_setup_arch,
213 .init_IRQ = mpc8360_sys_init_IRQ,
214 .get_irq = ipic_get_irq,
215 .restart = mpc83xx_restart,
216 .time_init = mpc83xx_time_init,
217 .calibrate_decr = generic_calibrate_decr,
218 .progress = udbg_progress,
219};
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 6b57a47c5d37..6cc59e0b4582 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -21,6 +21,12 @@
21 * You should have received a copy of the GNU General Public License 21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * TODO:
26 * - Fix various assumptions related to HW CPU numbers vs. linux CPU numbers
27 * vs node numbers in the setup code
28 * - Implement proper handling of maxcpus=1/2 (that is, routing of irqs from
29 * a non-active node to the active node)
24 */ 30 */
25 31
26#include <linux/interrupt.h> 32#include <linux/interrupt.h>
@@ -44,24 +50,25 @@ struct iic {
44 u8 target_id; 50 u8 target_id;
45 u8 eoi_stack[16]; 51 u8 eoi_stack[16];
46 int eoi_ptr; 52 int eoi_ptr;
47 struct irq_host *host; 53 struct device_node *node;
48}; 54};
49 55
50static DEFINE_PER_CPU(struct iic, iic); 56static DEFINE_PER_CPU(struct iic, iic);
51#define IIC_NODE_COUNT 2 57#define IIC_NODE_COUNT 2
52static struct irq_host *iic_hosts[IIC_NODE_COUNT]; 58static struct irq_host *iic_host;
53 59
54/* Convert between "pending" bits and hw irq number */ 60/* Convert between "pending" bits and hw irq number */
55static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits) 61static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
56{ 62{
57 unsigned char unit = bits.source & 0xf; 63 unsigned char unit = bits.source & 0xf;
64 unsigned char node = bits.source >> 4;
65 unsigned char class = bits.class & 3;
58 66
67 /* Decode IPIs */
59 if (bits.flags & CBE_IIC_IRQ_IPI) 68 if (bits.flags & CBE_IIC_IRQ_IPI)
60 return IIC_IRQ_IPI0 | (bits.prio >> 4); 69 return IIC_IRQ_TYPE_IPI | (bits.prio >> 4);
61 else if (bits.class <= 3)
62 return (bits.class << 4) | unit;
63 else 70 else
64 return IIC_IRQ_INVALID; 71 return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
65} 72}
66 73
67static void iic_mask(unsigned int irq) 74static void iic_mask(unsigned int irq)
@@ -86,21 +93,70 @@ static struct irq_chip iic_chip = {
86 .eoi = iic_eoi, 93 .eoi = iic_eoi,
87}; 94};
88 95
96
97static void iic_ioexc_eoi(unsigned int irq)
98{
99}
100
101static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc,
102 struct pt_regs *regs)
103{
104 struct cbe_iic_regs *node_iic = desc->handler_data;
105 unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
106 unsigned long bits, ack;
107 int cascade;
108
109 for (;;) {
110 bits = in_be64(&node_iic->iic_is);
111 if (bits == 0)
112 break;
113 /* pre-ack edge interrupts */
114 ack = bits & IIC_ISR_EDGE_MASK;
115 if (ack)
116 out_be64(&node_iic->iic_is, ack);
117 /* handle them */
118 for (cascade = 63; cascade >= 0; cascade--)
119 if (bits & (0x8000000000000000UL >> cascade)) {
120 unsigned int cirq =
121 irq_linear_revmap(iic_host,
122 base | cascade);
123 if (cirq != NO_IRQ)
124 generic_handle_irq(cirq, regs);
125 }
126 /* post-ack level interrupts */
127 ack = bits & ~IIC_ISR_EDGE_MASK;
128 if (ack)
129 out_be64(&node_iic->iic_is, ack);
130 }
131 desc->chip->eoi(irq);
132}
133
134
135static struct irq_chip iic_ioexc_chip = {
136 .typename = " CELL-IOEX",
137 .mask = iic_mask,
138 .unmask = iic_unmask,
139 .eoi = iic_ioexc_eoi,
140};
141
89/* Get an IRQ number from the pending state register of the IIC */ 142/* Get an IRQ number from the pending state register of the IIC */
90static unsigned int iic_get_irq(struct pt_regs *regs) 143static unsigned int iic_get_irq(struct pt_regs *regs)
91{ 144{
92 struct cbe_iic_pending_bits pending; 145 struct cbe_iic_pending_bits pending;
93 struct iic *iic; 146 struct iic *iic;
147 unsigned int virq;
94 148
95 iic = &__get_cpu_var(iic); 149 iic = &__get_cpu_var(iic);
96 *(unsigned long *) &pending = 150 *(unsigned long *) &pending =
97 in_be64((unsigned long __iomem *) &iic->regs->pending_destr); 151 in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
152 if (!(pending.flags & CBE_IIC_IRQ_VALID))
153 return NO_IRQ;
154 virq = irq_linear_revmap(iic_host, iic_pending_to_hwnum(pending));
155 if (virq == NO_IRQ)
156 return NO_IRQ;
98 iic->eoi_stack[++iic->eoi_ptr] = pending.prio; 157 iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
99 BUG_ON(iic->eoi_ptr > 15); 158 BUG_ON(iic->eoi_ptr > 15);
100 if (pending.flags & CBE_IIC_IRQ_VALID) 159 return virq;
101 return irq_linear_revmap(iic->host,
102 iic_pending_to_hwnum(pending));
103 return NO_IRQ;
104} 160}
105 161
106#ifdef CONFIG_SMP 162#ifdef CONFIG_SMP
@@ -108,12 +164,7 @@ static unsigned int iic_get_irq(struct pt_regs *regs)
108/* Use the highest interrupt priorities for IPI */ 164/* Use the highest interrupt priorities for IPI */
109static inline int iic_ipi_to_irq(int ipi) 165static inline int iic_ipi_to_irq(int ipi)
110{ 166{
111 return IIC_IRQ_IPI0 + IIC_NUM_IPIS - 1 - ipi; 167 return IIC_IRQ_TYPE_IPI + 0xf - ipi;
112}
113
114static inline int iic_irq_to_ipi(int irq)
115{
116 return IIC_NUM_IPIS - 1 - (irq - IIC_IRQ_IPI0);
117} 168}
118 169
119void iic_setup_cpu(void) 170void iic_setup_cpu(void)
@@ -123,7 +174,7 @@ void iic_setup_cpu(void)
123 174
124void iic_cause_IPI(int cpu, int mesg) 175void iic_cause_IPI(int cpu, int mesg)
125{ 176{
126 out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); 177 out_be64(&per_cpu(iic, cpu).regs->generate, (0xf - mesg) << 4);
127} 178}
128 179
129u8 iic_get_target_id(int cpu) 180u8 iic_get_target_id(int cpu)
@@ -134,9 +185,7 @@ EXPORT_SYMBOL_GPL(iic_get_target_id);
134 185
135struct irq_host *iic_get_irq_host(int node) 186struct irq_host *iic_get_irq_host(int node)
136{ 187{
137 if (node < 0 || node >= IIC_NODE_COUNT) 188 return iic_host;
138 return NULL;
139 return iic_hosts[node];
140} 189}
141EXPORT_SYMBOL_GPL(iic_get_irq_host); 190EXPORT_SYMBOL_GPL(iic_get_irq_host);
142 191
@@ -149,34 +198,20 @@ static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
149 198
150 return IRQ_HANDLED; 199 return IRQ_HANDLED;
151} 200}
152
153static void iic_request_ipi(int ipi, const char *name) 201static void iic_request_ipi(int ipi, const char *name)
154{ 202{
155 int node, virq; 203 int virq;
156 204
157 for (node = 0; node < IIC_NODE_COUNT; node++) { 205 virq = irq_create_mapping(iic_host, iic_ipi_to_irq(ipi));
158 char *rname; 206 if (virq == NO_IRQ) {
159 if (iic_hosts[node] == NULL) 207 printk(KERN_ERR
160 continue; 208 "iic: failed to map IPI %s\n", name);
161 virq = irq_create_mapping(iic_hosts[node], 209 return;
162 iic_ipi_to_irq(ipi));
163 if (virq == NO_IRQ) {
164 printk(KERN_ERR
165 "iic: failed to map IPI %s on node %d\n",
166 name, node);
167 continue;
168 }
169 rname = kzalloc(strlen(name) + 16, GFP_KERNEL);
170 if (rname)
171 sprintf(rname, "%s node %d", name, node);
172 else
173 rname = (char *)name;
174 if (request_irq(virq, iic_ipi_action, IRQF_DISABLED,
175 rname, (void *)(long)ipi))
176 printk(KERN_ERR
177 "iic: failed to request IPI %s on node %d\n",
178 name, node);
179 } 210 }
211 if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, name,
212 (void *)(long)ipi))
213 printk(KERN_ERR
214 "iic: failed to request IPI %s\n", name);
180} 215}
181 216
182void iic_request_IPIs(void) 217void iic_request_IPIs(void)
@@ -193,16 +228,24 @@ void iic_request_IPIs(void)
193 228
194static int iic_host_match(struct irq_host *h, struct device_node *node) 229static int iic_host_match(struct irq_host *h, struct device_node *node)
195{ 230{
196 return h->host_data != NULL && node == h->host_data; 231 return device_is_compatible(node,
232 "IBM,CBEA-Internal-Interrupt-Controller");
197} 233}
198 234
199static int iic_host_map(struct irq_host *h, unsigned int virq, 235static int iic_host_map(struct irq_host *h, unsigned int virq,
200 irq_hw_number_t hw) 236 irq_hw_number_t hw)
201{ 237{
202 if (hw < IIC_IRQ_IPI0) 238 switch (hw & IIC_IRQ_TYPE_MASK) {
203 set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); 239 case IIC_IRQ_TYPE_IPI:
204 else
205 set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq); 240 set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
241 break;
242 case IIC_IRQ_TYPE_IOEXC:
243 set_irq_chip_and_handler(virq, &iic_ioexc_chip,
244 handle_fasteoi_irq);
245 break;
246 default:
247 set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
248 }
206 return 0; 249 return 0;
207} 250}
208 251
@@ -211,11 +254,39 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
211 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 254 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
212 255
213{ 256{
214 /* Currently, we don't translate anything. That needs to be fixed as 257 unsigned int node, ext, unit, class;
215 * we get better defined device-trees. iic interrupts have to be 258 const u32 *val;
216 * explicitely mapped by whoever needs them 259
217 */ 260 if (!device_is_compatible(ct,
218 return -ENODEV; 261 "IBM,CBEA-Internal-Interrupt-Controller"))
262 return -ENODEV;
263 if (intsize != 1)
264 return -ENODEV;
265 val = get_property(ct, "#interrupt-cells", NULL);
266 if (val == NULL || *val != 1)
267 return -ENODEV;
268
269 node = intspec[0] >> 24;
270 ext = (intspec[0] >> 16) & 0xff;
271 class = (intspec[0] >> 8) & 0xff;
272 unit = intspec[0] & 0xff;
273
274 /* Check if node is in supported range */
275 if (node > 1)
276 return -EINVAL;
277
278 /* Build up interrupt number, special case for IO exceptions */
279 *out_hwirq = (node << IIC_IRQ_NODE_SHIFT);
280 if (unit == IIC_UNIT_IIC && class == 1)
281 *out_hwirq |= IIC_IRQ_TYPE_IOEXC | ext;
282 else
283 *out_hwirq |= IIC_IRQ_TYPE_NORMAL |
284 (class << IIC_IRQ_CLASS_SHIFT) | unit;
285
286 /* Dummy flags, ignored by iic code */
287 *out_flags = IRQ_TYPE_EDGE_RISING;
288
289 return 0;
219} 290}
220 291
221static struct irq_host_ops iic_host_ops = { 292static struct irq_host_ops iic_host_ops = {
@@ -225,7 +296,7 @@ static struct irq_host_ops iic_host_ops = {
225}; 296};
226 297
227static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr, 298static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
228 struct irq_host *host) 299 struct device_node *node)
229{ 300{
230 /* XXX FIXME: should locate the linux CPU number from the HW cpu 301 /* XXX FIXME: should locate the linux CPU number from the HW cpu
231 * number properly. We are lucky for now 302 * number properly. We are lucky for now
@@ -237,19 +308,19 @@ static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
237 308
238 iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe); 309 iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe);
239 iic->eoi_stack[0] = 0xff; 310 iic->eoi_stack[0] = 0xff;
240 iic->host = host; 311 iic->node = of_node_get(node);
241 out_be64(&iic->regs->prio, 0); 312 out_be64(&iic->regs->prio, 0);
242 313
243 printk(KERN_INFO "IIC for CPU %d at %lx mapped to %p, target id 0x%x\n", 314 printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n",
244 hw_cpu, addr, iic->regs, iic->target_id); 315 hw_cpu, iic->target_id, node->full_name);
245} 316}
246 317
247static int __init setup_iic(void) 318static int __init setup_iic(void)
248{ 319{
249 struct device_node *dn; 320 struct device_node *dn;
250 struct resource r0, r1; 321 struct resource r0, r1;
251 struct irq_host *host; 322 unsigned int node, cascade, found = 0;
252 int found = 0; 323 struct cbe_iic_regs *node_iic;
253 const u32 *np; 324 const u32 *np;
254 325
255 for (dn = NULL; 326 for (dn = NULL;
@@ -269,19 +340,33 @@ static int __init setup_iic(void)
269 of_node_put(dn); 340 of_node_put(dn);
270 return -ENODEV; 341 return -ENODEV;
271 } 342 }
272 host = NULL; 343 found++;
273 if (found < IIC_NODE_COUNT) { 344 init_one_iic(np[0], r0.start, dn);
274 host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 345 init_one_iic(np[1], r1.start, dn);
275 IIC_SOURCE_COUNT, 346
276 &iic_host_ops, 347 /* Setup cascade for IO exceptions. XXX cleanup tricks to get
277 IIC_IRQ_INVALID); 348 * node vs CPU etc...
278 iic_hosts[found] = host; 349 * Note that we configure the IIC_IRR here with a hard coded
279 BUG_ON(iic_hosts[found] == NULL); 350 * priority of 1. We might want to improve that later.
280 iic_hosts[found]->host_data = of_node_get(dn); 351 */
281 found++; 352 node = np[0] >> 1;
282 } 353 node_iic = cbe_get_cpu_iic_regs(np[0]);
283 init_one_iic(np[0], r0.start, host); 354 cascade = node << IIC_IRQ_NODE_SHIFT;
284 init_one_iic(np[1], r1.start, host); 355 cascade |= 1 << IIC_IRQ_CLASS_SHIFT;
356 cascade |= IIC_UNIT_IIC;
357 cascade = irq_create_mapping(iic_host, cascade);
358 if (cascade == NO_IRQ)
359 continue;
360 set_irq_data(cascade, node_iic);
361 set_irq_chained_handler(cascade , iic_ioexc_cascade);
362 out_be64(&node_iic->iic_ir,
363 (1 << 12) /* priority */ |
364 (node << 4) /* dest node */ |
365 IIC_UNIT_THREAD_0 /* route them to thread 0 */);
366 /* Flush pending (make sure it triggers if there is
367 * anything pending
368 */
369 out_be64(&node_iic->iic_is, 0xfffffffffffffffful);
285 } 370 }
286 371
287 if (found) 372 if (found)
@@ -292,6 +377,12 @@ static int __init setup_iic(void)
292 377
293void __init iic_init_IRQ(void) 378void __init iic_init_IRQ(void)
294{ 379{
380 /* Setup an irq host data structure */
381 iic_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
382 &iic_host_ops, IIC_IRQ_INVALID);
383 BUG_ON(iic_host == NULL);
384 irq_set_default_host(iic_host);
385
295 /* Discover and initialize iics */ 386 /* Discover and initialize iics */
296 if (setup_iic() < 0) 387 if (setup_iic() < 0)
297 panic("IIC: Failed to initialize !\n"); 388 panic("IIC: Failed to initialize !\n");
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index 5560a92ec3ab..9ba1d3c17b4b 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -2,48 +2,76 @@
2#define ASM_CELL_PIC_H 2#define ASM_CELL_PIC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4/* 4/*
5 * Mapping of IIC pending bits into per-node 5 * Mapping of IIC pending bits into per-node interrupt numbers.
6 * interrupt numbers.
7 * 6 *
8 * IRQ FF CC SS PP FF CC SS PP Description 7 * Interrupt numbers are in the range 0...0x1ff where the top bit
8 * (0x100) represent the source node. Only 2 nodes are supported with
9 * the current code though it's trivial to extend that if necessary using
10 * higher level bits
9 * 11 *
10 * 00-3f 80 02 +0 00 - 80 02 +0 3f South Bridge 12 * The bottom 8 bits are split into 2 type bits and 6 data bits that
11 * 00-3f 80 02 +b 00 - 80 02 +b 3f South Bridge 13 * depend on the type:
12 * 41-4a 80 00 +1 ** - 80 00 +a ** SPU Class 0
13 * 51-5a 80 01 +1 ** - 80 01 +a ** SPU Class 1
14 * 61-6a 80 02 +1 ** - 80 02 +a ** SPU Class 2
15 * 70-7f C0 ** ** 00 - C0 ** ** 0f IPI
16 * 14 *
17 * F flags 15 * 00 (0x00 | data) : normal interrupt. data is (class << 4) | source
18 * C class 16 * 01 (0x40 | data) : IO exception. data is the exception number as
19 * S source 17 * defined by bit numbers in IIC_SR
20 * P Priority 18 * 10 (0x80 | data) : IPI. data is the IPI number (obtained from the priority)
21 * + node number 19 * and node is always 0 (IPIs are per-cpu, their source is
22 * * don't care 20 * not relevant)
21 * 11 (0xc0 | data) : reserved
23 * 22 *
24 * A node consists of a Cell Broadband Engine and an optional 23 * In addition, interrupt number 0x80000000 is defined as always invalid
25 * south bridge device providing a maximum of 64 IRQs. 24 * (that is the node field is expected to never extend to move than 23 bits)
26 * The south bridge may be connected to either IOIF0
27 * or IOIF1.
28 * Each SPE is represented as three IRQ lines, one per
29 * interrupt class.
30 * 16 IRQ numbers are reserved for inter processor
31 * interruptions, although these are only used in the
32 * range of the first node.
33 * 25 *
34 * This scheme needs 128 IRQ numbers per BIF node ID,
35 * which means that with the total of 512 lines
36 * available, we can have a maximum of four nodes.
37 */ 26 */
38 27
39enum { 28enum {
40 IIC_IRQ_INVALID = 0xff, 29 IIC_IRQ_INVALID = 0x80000000u,
41 IIC_IRQ_MAX = 0x3f, 30 IIC_IRQ_NODE_MASK = 0x100,
42 IIC_IRQ_EXT_IOIF0 = 0x20, 31 IIC_IRQ_NODE_SHIFT = 8,
43 IIC_IRQ_EXT_IOIF1 = 0x2b, 32 IIC_IRQ_MAX = 0x1ff,
44 IIC_IRQ_IPI0 = 0x40, 33 IIC_IRQ_TYPE_MASK = 0xc0,
45 IIC_NUM_IPIS = 0x10, /* IRQs reserved for IPI */ 34 IIC_IRQ_TYPE_NORMAL = 0x00,
46 IIC_SOURCE_COUNT = 0x50, 35 IIC_IRQ_TYPE_IOEXC = 0x40,
36 IIC_IRQ_TYPE_IPI = 0x80,
37 IIC_IRQ_CLASS_SHIFT = 4,
38 IIC_IRQ_CLASS_0 = 0x00,
39 IIC_IRQ_CLASS_1 = 0x10,
40 IIC_IRQ_CLASS_2 = 0x20,
41 IIC_SOURCE_COUNT = 0x200,
42
43 /* Here are defined the various source/dest units. Avoid using those
44 * definitions if you can, they are mostly here for reference
45 */
46 IIC_UNIT_SPU_0 = 0x4,
47 IIC_UNIT_SPU_1 = 0x7,
48 IIC_UNIT_SPU_2 = 0x3,
49 IIC_UNIT_SPU_3 = 0x8,
50 IIC_UNIT_SPU_4 = 0x2,
51 IIC_UNIT_SPU_5 = 0x9,
52 IIC_UNIT_SPU_6 = 0x1,
53 IIC_UNIT_SPU_7 = 0xa,
54 IIC_UNIT_IOC_0 = 0x0,
55 IIC_UNIT_IOC_1 = 0xb,
56 IIC_UNIT_THREAD_0 = 0xe, /* target only */
57 IIC_UNIT_THREAD_1 = 0xf, /* target only */
58 IIC_UNIT_IIC = 0xe, /* source only (IO exceptions) */
59
60 /* Base numbers for the external interrupts */
61 IIC_IRQ_EXT_IOIF0 =
62 IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_0,
63 IIC_IRQ_EXT_IOIF1 =
64 IIC_IRQ_TYPE_NORMAL | IIC_IRQ_CLASS_2 | IIC_UNIT_IOC_1,
65
66 /* Base numbers for the IIC_ISR interrupts */
67 IIC_IRQ_IOEX_TMI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 63,
68 IIC_IRQ_IOEX_PMI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 62,
69 IIC_IRQ_IOEX_ATI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 61,
70 IIC_IRQ_IOEX_MATBFI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 60,
71 IIC_IRQ_IOEX_ELDI = IIC_IRQ_TYPE_IOEXC | IIC_IRQ_CLASS_1 | 59,
72
73 /* Which bits in IIC_ISR are edge sensitive */
74 IIC_ISR_EDGE_MASK = 0x4ul,
47}; 75};
48 76
49extern void iic_init_IRQ(void); 77extern void iic_init_IRQ(void);
@@ -52,7 +80,6 @@ extern void iic_request_IPIs(void);
52extern void iic_setup_cpu(void); 80extern void iic_setup_cpu(void);
53 81
54extern u8 iic_get_target_id(int cpu); 82extern u8 iic_get_target_id(int cpu);
55extern struct irq_host *iic_get_irq_host(int node);
56 83
57extern void spider_init_IRQ(void); 84extern void spider_init_IRQ(void);
58 85
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 742a03282b44..608b1ebc56b2 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -243,7 +243,6 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
243 const u32 *imap, *tmp; 243 const u32 *imap, *tmp;
244 int imaplen, intsize, unit; 244 int imaplen, intsize, unit;
245 struct device_node *iic; 245 struct device_node *iic;
246 struct irq_host *iic_host;
247 246
248#if 0 /* Enable that when we have a way to retreive the node as well */ 247#if 0 /* Enable that when we have a way to retreive the node as well */
249 /* First, we check wether we have a real "interrupts" in the device 248 /* First, we check wether we have a real "interrupts" in the device
@@ -289,11 +288,11 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
289 * the iic host from the iic OF node, but that way I'm still compatible 288 * the iic host from the iic OF node, but that way I'm still compatible
290 * with really really old old firmwares for which we don't have a node 289 * with really really old old firmwares for which we don't have a node
291 */ 290 */
292 iic_host = iic_get_irq_host(pic->node_id);
293 if (iic_host == NULL)
294 return NO_IRQ;
295 /* Manufacture an IIC interrupt number of class 2 */ 291 /* Manufacture an IIC interrupt number of class 2 */
296 virq = irq_create_mapping(iic_host, 0x20 | unit); 292 virq = irq_create_mapping(NULL,
293 (pic->node_id << IIC_IRQ_NODE_SHIFT) |
294 (2 << IIC_IRQ_CLASS_SHIFT) |
295 unit);
297 if (virq == NO_IRQ) 296 if (virq == NO_IRQ)
298 printk(KERN_ERR "spider_pic: failed to map cascade !"); 297 printk(KERN_ERR "spider_pic: failed to map cascade !");
299 return virq; 298 return virq;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 0f5c8ebc7fc3..f78680346e5f 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -568,24 +568,23 @@ static void spu_unmap(struct spu *spu)
568/* This function shall be abstracted for HV platforms */ 568/* This function shall be abstracted for HV platforms */
569static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 569static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
570{ 570{
571 struct irq_host *host;
572 unsigned int isrc; 571 unsigned int isrc;
573 const u32 *tmp; 572 const u32 *tmp;
574 573
575 host = iic_get_irq_host(spu->node); 574 /* Get the interrupt source unit from the device-tree */
576 if (host == NULL)
577 return -ENODEV;
578
579 /* Get the interrupt source from the device-tree */
580 tmp = get_property(np, "isrc", NULL); 575 tmp = get_property(np, "isrc", NULL);
581 if (!tmp) 576 if (!tmp)
582 return -ENODEV; 577 return -ENODEV;
583 spu->isrc = isrc = tmp[0]; 578 isrc = tmp[0];
579
580 /* Add the node number */
581 isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
582 spu->isrc = isrc;
584 583
585 /* Now map interrupts of all 3 classes */ 584 /* Now map interrupts of all 3 classes */
586 spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc); 585 spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
587 spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc); 586 spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
588 spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc); 587 spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
589 588
590 /* Right now, we only fail if class 2 failed */ 589 /* Right now, we only fail if class 2 failed */
591 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; 590 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 3eb12065df23..4aa165e010d9 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -262,14 +262,6 @@ void __init iSeries_pci_final_fixup(void)
262 mf_display_src(0xC9000200); 262 mf_display_src(0xC9000200);
263} 263}
264 264
265void pcibios_fixup_bus(struct pci_bus *PciBus)
266{
267}
268
269void pcibios_fixup_resources(struct pci_dev *pdev)
270{
271}
272
273/* 265/*
274 * Look down the chain to find the matching Device Device 266 * Look down the chain to find the matching Device Device
275 */ 267 */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 7f1953066ff8..a0ff7ba7d666 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -649,15 +649,21 @@ static void iseries_dedicated_idle(void)
649void __init iSeries_init_IRQ(void) { } 649void __init iSeries_init_IRQ(void) { }
650#endif 650#endif
651 651
652/*
653 * iSeries has no legacy IO, anything calling this function has to
654 * fail or bad things will happen
655 */
656static int iseries_check_legacy_ioport(unsigned int baseport)
657{
658 return -ENODEV;
659}
660
652static int __init iseries_probe(void) 661static int __init iseries_probe(void)
653{ 662{
654 unsigned long root = of_get_flat_dt_root(); 663 unsigned long root = of_get_flat_dt_root();
655 if (!of_flat_dt_is_compatible(root, "IBM,iSeries")) 664 if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
656 return 0; 665 return 0;
657 666
658 powerpc_firmware_features |= FW_FEATURE_ISERIES;
659 powerpc_firmware_features |= FW_FEATURE_LPAR;
660
661 hpte_init_iSeries(); 667 hpte_init_iSeries();
662 668
663 return 1; 669 return 1;
@@ -680,6 +686,7 @@ define_machine(iseries) {
680 .calibrate_decr = generic_calibrate_decr, 686 .calibrate_decr = generic_calibrate_decr,
681 .progress = iSeries_progress, 687 .progress = iSeries_progress,
682 .probe = iseries_probe, 688 .probe = iseries_probe,
689 .check_legacy_ioport = iseries_check_legacy_ioport,
683 /* XXX Implement enable_pmcs for iSeries */ 690 /* XXX Implement enable_pmcs for iSeries */
684}; 691};
685 692
@@ -687,6 +694,9 @@ void * __init iSeries_early_setup(void)
687{ 694{
688 unsigned long phys_mem_size; 695 unsigned long phys_mem_size;
689 696
697 powerpc_firmware_features |= FW_FEATURE_ISERIES;
698 powerpc_firmware_features |= FW_FEATURE_LPAR;
699
690 iSeries_fixup_klimit(); 700 iSeries_fixup_klimit();
691 701
692 /* 702 /*
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index ce1a235855f7..379db05b0082 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -111,8 +111,6 @@ void udbg_scc_init(int force_scc)
111 pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch, 111 pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
112 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); 112 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
113 113
114
115 /* Setup for 57600 8N1 */
116 if (ch == ch_a) 114 if (ch == ch_a)
117 addr += 0x20; 115 addr += 0x20;
118 sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ; 116 sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
@@ -125,9 +123,21 @@ void udbg_scc_init(int force_scc)
125 x = in_8(sccc); 123 x = in_8(sccc);
126 out_8(sccc, 0x09); /* reset A or B side */ 124 out_8(sccc, 0x09); /* reset A or B side */
127 out_8(sccc, 0xc0); 125 out_8(sccc, 0xc0);
126
127 /* If SCC was the OF output port, read the BRG value, else
128 * Setup for 57600 8N1
129 */
130 if (ch_def != NULL) {
131 out_8(sccc, 13);
132 scc_inittab[1] = in_8(sccc);
133 out_8(sccc, 12);
134 scc_inittab[3] = in_8(sccc);
135 }
136
128 for (i = 0; i < sizeof(scc_inittab); ++i) 137 for (i = 0; i < sizeof(scc_inittab); ++i)
129 out_8(sccc, scc_inittab[i]); 138 out_8(sccc, scc_inittab[i]);
130 139
140
131 udbg_putc = udbg_scc_putc; 141 udbg_putc = udbg_scc_putc;
132 udbg_getc = udbg_scc_getc; 142 udbg_getc = udbg_scc_getc;
133 udbg_getc_poll = udbg_scc_getc_poll; 143 udbg_getc_poll = udbg_scc_getc_poll;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 43dbf737698c..f82b13e531a3 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -180,7 +180,7 @@ static void __init pseries_mpic_init_IRQ(void)
180 180
181 cascade_irq = irq_of_parse_and_map(cascade, 0); 181 cascade_irq = irq_of_parse_and_map(cascade, 0);
182 if (cascade == NO_IRQ) { 182 if (cascade == NO_IRQ) {
183 printk(KERN_ERR "xics: failed to map cascade interrupt"); 183 printk(KERN_ERR "mpic: failed to map cascade interrupt");
184 return; 184 return;
185 } 185 }
186 186