aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-15 11:07:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-15 11:07:35 -0400
commit5f2434a66dfa4701b81b79a78eaf9c32da0f8839 (patch)
tree8c38f1fb0d0fbcd15e496df89be00ad8c4918a43 /arch/powerpc/platforms
parent278429cff8809958d25415ba0ed32b59866ab1a8 (diff)
parent6dc6472581f693b5fc95aebedf67b4960fb85cf0 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (158 commits) powerpc: Fix CHRP PCI config access for indirect_pci powerpc/chrp: Fix detection of Python PCI host bridge on IBM CHRPs powerpc: Fix 32-bit SMP boot on CHRP powerpc: Fix link errors on 32-bit machines using legacy DMA powerpc/pci: Improve detection of unassigned bridge resources hvc_console: Fix free_irq in spinlocked section powerpc: Get USE_STRICT_MM_TYPECHECKS working again powerpc: Reflect the used arguments in machine_init() prototype powerpc: Fix DMA offset for non-coherent DMA powerpc: fix fsl_upm nand driver modular build powerpc/83xx: add NAND support for the MPC8360E-RDK boards powerpc: FPGA support for GE Fanuc SBC610 i2c: MPC8349E-mITX Power Management and GPIO expander driver powerpc: reserve two DMA channels for audio in MPC8610 HPCD device tree powerpc: document the "fsl,ssi-dma-channel" compatible property powerpc: disable CHRP and PMAC support in various defconfigs OF: add fsl,mcu-mpc8349emitx to the exception list powerpc/83xx: add DS1374 RTC support for the MPC837xE-MDS boards powerpc: remove support for bootmem-allocated memory for the DIU driver powerpc: remove non-dependent load fsl_booke PTE_64BIT ...
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/44x/Kconfig42
-rw-r--r--arch/powerpc/platforms/44x/Makefile8
-rw-r--r--arch/powerpc/platforms/44x/bamboo.c62
-rw-r--r--arch/powerpc/platforms/44x/canyonlands.c63
-rw-r--r--arch/powerpc/platforms/44x/katmai.c62
-rw-r--r--arch/powerpc/platforms/44x/ppc44x_simple.c88
-rw-r--r--arch/powerpc/platforms/44x/rainier.c62
-rw-r--r--arch/powerpc/platforms/44x/sequoia.c63
-rw-r--r--arch/powerpc/platforms/44x/taishan.c72
-rw-r--r--arch/powerpc/platforms/512x/Kconfig2
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c10
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c5
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c13
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig8
-rw-r--r--arch/powerpc/platforms/82xx/Makefile1
-rw-r--r--arch/powerpc/platforms/82xx/mgcoge.c129
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig5
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_mds.c8
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c1
-rw-r--r--arch/powerpc/platforms/85xx/sbc8560.c3
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig9
-rw-r--r--arch/powerpc/platforms/86xx/Makefile1
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c258
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.h11
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c221
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c8
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c8
-rw-r--r--arch/powerpc/platforms/8xx/Kconfig6
-rw-r--r--arch/powerpc/platforms/8xx/Makefile1
-rw-r--r--arch/powerpc/platforms/8xx/mgsuvd.c92
-rw-r--r--arch/powerpc/platforms/Kconfig21
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype17
-rw-r--r--arch/powerpc/platforms/cell/iommu.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c11
-rw-r--r--arch/powerpc/platforms/chrp/pci.c4
-rw-r--r--arch/powerpc/platforms/chrp/time.c24
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c1
-rw-r--r--arch/powerpc/platforms/iseries/exception.S23
-rw-r--r--arch/powerpc/platforms/iseries/mf.c26
-rw-r--r--arch/powerpc/platforms/maple/time.c24
-rw-r--r--arch/powerpc/platforms/powermac/feature.c2
-rw-r--r--arch/powerpc/platforms/powermac/smp.c4
-rw-r--r--arch/powerpc/platforms/powermac/time.c3
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c2
-rw-r--r--arch/powerpc/platforms/pseries/cmm.c4
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c2
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c6
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c26
-rw-r--r--arch/powerpc/platforms/pseries/smp.c32
-rw-r--r--arch/powerpc/platforms/pseries/xics.c550
-rw-r--r--arch/powerpc/platforms/pseries/xics.h12
54 files changed, 1314 insertions, 812 deletions
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 249ba01c6674..79c1154f88d4 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -2,6 +2,7 @@ config BAMBOO
2 bool "Bamboo" 2 bool "Bamboo"
3 depends on 44x 3 depends on 44x
4 default n 4 default n
5 select PPC44x_SIMPLE
5 select 440EP 6 select 440EP
6 select PCI 7 select PCI
7 help 8 help
@@ -30,6 +31,7 @@ config SEQUOIA
30 bool "Sequoia" 31 bool "Sequoia"
31 depends on 44x 32 depends on 44x
32 default n 33 default n
34 select PPC44x_SIMPLE
33 select 440EPX 35 select 440EPX
34 help 36 help
35 This option enables support for the AMCC PPC440EPX evaluation board. 37 This option enables support for the AMCC PPC440EPX evaluation board.
@@ -38,6 +40,7 @@ config TAISHAN
38 bool "Taishan" 40 bool "Taishan"
39 depends on 44x 41 depends on 44x
40 default n 42 default n
43 select PPC44x_SIMPLE
41 select 440GX 44 select 440GX
42 select PCI 45 select PCI
43 help 46 help
@@ -48,6 +51,7 @@ config KATMAI
48 bool "Katmai" 51 bool "Katmai"
49 depends on 44x 52 depends on 44x
50 default n 53 default n
54 select PPC44x_SIMPLE
51 select 440SPe 55 select 440SPe
52 select PCI 56 select PCI
53 select PPC4xx_PCI_EXPRESS 57 select PPC4xx_PCI_EXPRESS
@@ -58,6 +62,7 @@ config RAINIER
58 bool "Rainier" 62 bool "Rainier"
59 depends on 44x 63 depends on 44x
60 default n 64 default n
65 select PPC44x_SIMPLE
61 select 440GRX 66 select 440GRX
62 select PCI 67 select PCI
63 help 68 help
@@ -76,20 +81,48 @@ config WARP
76 See http://www.pikatechnologies.com/ and follow the "PIKA for Computer 81 See http://www.pikatechnologies.com/ and follow the "PIKA for Computer
77 Telephony Developers" link for more information. 82 Telephony Developers" link for more information.
78 83
84config ARCHES
85 bool "Arches"
86 depends on 44x
87 default n
88 select PPC44x_SIMPLE
89 select 460EX # Odd since it uses 460GT but the effects are the same
90 select PCI
91 select PPC4xx_PCI_EXPRESS
92 help
93 This option enables support for the AMCC Dual PPC460GT evaluation board.
94
79config CANYONLANDS 95config CANYONLANDS
80 bool "Canyonlands" 96 bool "Canyonlands"
81 depends on 44x 97 depends on 44x
82 default n 98 default n
99 select PPC44x_SIMPLE
83 select 460EX 100 select 460EX
84 select PCI 101 select PCI
85 select PPC4xx_PCI_EXPRESS 102 select PPC4xx_PCI_EXPRESS
103 select IBM_NEW_EMAC_RGMII
104 select IBM_NEW_EMAC_ZMII
86 help 105 help
87 This option enables support for the AMCC PPC460EX evaluation board. 106 This option enables support for the AMCC PPC460EX evaluation board.
88 107
108config GLACIER
109 bool "Glacier"
110 depends on 44x
111 default n
112 select PPC44x_SIMPLE
113 select 460EX # Odd since it uses 460GT but the effects are the same
114 select PCI
115 select PPC4xx_PCI_EXPRESS
116 select IBM_NEW_EMAC_RGMII
117 select IBM_NEW_EMAC_ZMII
118 help
119 This option enables support for the AMCC PPC460GT evaluation board.
120
89config YOSEMITE 121config YOSEMITE
90 bool "Yosemite" 122 bool "Yosemite"
91 depends on 44x 123 depends on 44x
92 default n 124 default n
125 select PPC44x_SIMPLE
93 select 440EP 126 select 440EP
94 select PCI 127 select PCI
95 help 128 help
@@ -127,6 +160,13 @@ config XILINX_VIRTEX440_GENERIC_BOARD
127 Most Virtex 5 designs should use this unless it needs to do some 160 Most Virtex 5 designs should use this unless it needs to do some
128 special configuration at board probe time. 161 special configuration at board probe time.
129 162
163config PPC44x_SIMPLE
164 bool "Simple PowerPC 44x board support"
165 depends on 44x
166 default n
167 help
168 This option enables the simple PowerPC 44x platform support.
169
130# 44x specific CPU modules, selected based on the board above. 170# 44x specific CPU modules, selected based on the board above.
131config 440EP 171config 440EP
132 bool 172 bool
@@ -170,8 +210,6 @@ config 460EX
170 bool 210 bool
171 select PPC_FPU 211 select PPC_FPU
172 select IBM_NEW_EMAC_EMAC4 212 select IBM_NEW_EMAC_EMAC4
173 select IBM_NEW_EMAC_RGMII
174 select IBM_NEW_EMAC_ZMII
175 select IBM_NEW_EMAC_TAH 213 select IBM_NEW_EMAC_TAH
176 214
177# 44x errata/workaround config symbols, selected by the CPU models above 215# 44x errata/workaround config symbols, selected by the CPU models above
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index 8d0b1a192d62..698133180aee 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -1,13 +1,7 @@
1obj-$(CONFIG_44x) := misc_44x.o idle.o 1obj-$(CONFIG_44x) := misc_44x.o idle.o
2obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o
2obj-$(CONFIG_EBONY) += ebony.o 3obj-$(CONFIG_EBONY) += ebony.o
3obj-$(CONFIG_TAISHAN) += taishan.o
4obj-$(CONFIG_BAMBOO) += bamboo.o
5obj-$(CONFIG_YOSEMITE) += bamboo.o
6obj-$(CONFIG_SAM440EP) += sam440ep.o 4obj-$(CONFIG_SAM440EP) += sam440ep.o
7obj-$(CONFIG_SEQUOIA) += sequoia.o
8obj-$(CONFIG_KATMAI) += katmai.o
9obj-$(CONFIG_RAINIER) += rainier.o
10obj-$(CONFIG_WARP) += warp.o 5obj-$(CONFIG_WARP) += warp.o
11obj-$(CONFIG_WARP) += warp-nand.o 6obj-$(CONFIG_WARP) += warp-nand.o
12obj-$(CONFIG_CANYONLANDS) += canyonlands.o
13obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o 7obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
diff --git a/arch/powerpc/platforms/44x/bamboo.c b/arch/powerpc/platforms/44x/bamboo.c
deleted file mode 100644
index cef169e95156..000000000000
--- a/arch/powerpc/platforms/44x/bamboo.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Bamboo board specific routines
3 *
4 * Wade Farnsworth <wfarnsworth@mvista.com>
5 * Copyright 2004 MontaVista Software Inc.
6 *
7 * Rewritten and ported to the merged powerpc tree:
8 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
9 * Copyright 2007 IBM Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/init.h>
17#include <linux/of_platform.h>
18
19#include <asm/machdep.h>
20#include <asm/prom.h>
21#include <asm/udbg.h>
22#include <asm/time.h>
23#include <asm/uic.h>
24#include <asm/pci-bridge.h>
25#include <asm/ppc4xx.h>
26
27static __initdata struct of_device_id bamboo_of_bus[] = {
28 { .compatible = "ibm,plb4", },
29 { .compatible = "ibm,opb", },
30 { .compatible = "ibm,ebc", },
31 {},
32};
33
34static int __init bamboo_device_probe(void)
35{
36 of_platform_bus_probe(NULL, bamboo_of_bus, NULL);
37
38 return 0;
39}
40machine_device_initcall(bamboo, bamboo_device_probe);
41
42static int __init bamboo_probe(void)
43{
44 unsigned long root = of_get_flat_dt_root();
45
46 if (!of_flat_dt_is_compatible(root, "amcc,bamboo"))
47 return 0;
48
49 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
50
51 return 1;
52}
53
54define_machine(bamboo) {
55 .name = "Bamboo",
56 .probe = bamboo_probe,
57 .progress = udbg_progress,
58 .init_IRQ = uic_init_tree,
59 .get_irq = uic_get_irq,
60 .restart = ppc4xx_reset_system,
61 .calibrate_decr = generic_calibrate_decr,
62};
diff --git a/arch/powerpc/platforms/44x/canyonlands.c b/arch/powerpc/platforms/44x/canyonlands.c
deleted file mode 100644
index 3949289f51df..000000000000
--- a/arch/powerpc/platforms/44x/canyonlands.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Canyonlands board specific routines
3 *
4 * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
5 *
6 * Based on the Katmai code by
7 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
8 * Copyright 2007 IBM Corp.
9 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
10 * Copyright 2007 IBM Corporation
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17#include <linux/init.h>
18#include <linux/of_platform.h>
19
20#include <asm/machdep.h>
21#include <asm/prom.h>
22#include <asm/udbg.h>
23#include <asm/time.h>
24#include <asm/uic.h>
25#include <asm/pci-bridge.h>
26#include <asm/ppc4xx.h>
27
28static __initdata struct of_device_id canyonlands_of_bus[] = {
29 { .compatible = "ibm,plb4", },
30 { .compatible = "ibm,opb", },
31 { .compatible = "ibm,ebc", },
32 {},
33};
34
35static int __init canyonlands_device_probe(void)
36{
37 of_platform_bus_probe(NULL, canyonlands_of_bus, NULL);
38
39 return 0;
40}
41machine_device_initcall(canyonlands, canyonlands_device_probe);
42
43static int __init canyonlands_probe(void)
44{
45 unsigned long root = of_get_flat_dt_root();
46
47 if (!of_flat_dt_is_compatible(root, "amcc,canyonlands"))
48 return 0;
49
50 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
51
52 return 1;
53}
54
55define_machine(canyonlands) {
56 .name = "Canyonlands",
57 .probe = canyonlands_probe,
58 .progress = udbg_progress,
59 .init_IRQ = uic_init_tree,
60 .get_irq = uic_get_irq,
61 .restart = ppc4xx_reset_system,
62 .calibrate_decr = generic_calibrate_decr,
63};
diff --git a/arch/powerpc/platforms/44x/katmai.c b/arch/powerpc/platforms/44x/katmai.c
deleted file mode 100644
index 44f4b3a00ced..000000000000
--- a/arch/powerpc/platforms/44x/katmai.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Katmai board specific routines
3 *
4 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
5 * Copyright 2007 IBM Corp.
6 *
7 * Based on the Bamboo code by
8 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
9 * Copyright 2007 IBM Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/init.h>
17#include <linux/of_platform.h>
18
19#include <asm/machdep.h>
20#include <asm/prom.h>
21#include <asm/udbg.h>
22#include <asm/time.h>
23#include <asm/uic.h>
24#include <asm/pci-bridge.h>
25#include <asm/ppc4xx.h>
26
27static __initdata struct of_device_id katmai_of_bus[] = {
28 { .compatible = "ibm,plb4", },
29 { .compatible = "ibm,opb", },
30 { .compatible = "ibm,ebc", },
31 {},
32};
33
34static int __init katmai_device_probe(void)
35{
36 of_platform_bus_probe(NULL, katmai_of_bus, NULL);
37
38 return 0;
39}
40machine_device_initcall(katmai, katmai_device_probe);
41
42static int __init katmai_probe(void)
43{
44 unsigned long root = of_get_flat_dt_root();
45
46 if (!of_flat_dt_is_compatible(root, "amcc,katmai"))
47 return 0;
48
49 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
50
51 return 1;
52}
53
54define_machine(katmai) {
55 .name = "Katmai",
56 .probe = katmai_probe,
57 .progress = udbg_progress,
58 .init_IRQ = uic_init_tree,
59 .get_irq = uic_get_irq,
60 .restart = ppc4xx_reset_system,
61 .calibrate_decr = generic_calibrate_decr,
62};
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
new file mode 100644
index 000000000000..29671262801f
--- /dev/null
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -0,0 +1,88 @@
1/*
2 * Generic PowerPC 44x platform support
3 *
4 * Copyright 2008 IBM Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License.
9 *
10 * This implements simple platform support for PowerPC 44x chips. This is
11 * mostly used for eval boards or other simple and "generic" 44x boards. If
12 * your board has custom functions or hardware, then you will likely want to
13 * implement your own board.c file to accommodate it.
14 */
15
16#include <asm/machdep.h>
17#include <asm/pci-bridge.h>
18#include <asm/ppc4xx.h>
19#include <asm/prom.h>
20#include <asm/time.h>
21#include <asm/udbg.h>
22#include <asm/uic.h>
23
24#include <linux/init.h>
25#include <linux/of_platform.h>
26
27static __initdata struct of_device_id ppc44x_of_bus[] = {
28 { .compatible = "ibm,plb4", },
29 { .compatible = "ibm,opb", },
30 { .compatible = "ibm,ebc", },
31 { .compatible = "simple-bus", },
32 {},
33};
34
35static int __init ppc44x_device_probe(void)
36{
37 of_platform_bus_probe(NULL, ppc44x_of_bus, NULL);
38
39 return 0;
40}
41machine_device_initcall(ppc44x_simple, ppc44x_device_probe);
42
43/* This is the list of boards that can be supported by this simple
44 * platform code. This does _not_ mean the boards are compatible,
45 * as they most certainly are not from a device tree perspective.
46 * However, their differences are handled by the device tree and the
47 * drivers and therefore they don't need custom board support files.
48 *
49 * Again, if your board needs to do things differently then create a
50 * board.c file for it rather than adding it to this list.
51 */
52static char *board[] __initdata = {
53 "amcc,arches",
54 "amcc,bamboo",
55 "amcc,canyonlands",
56 "amcc,glacier",
57 "ibm,ebony",
58 "amcc,katmai",
59 "amcc,rainier",
60 "amcc,sequoia",
61 "amcc,taishan",
62 "amcc,yosemite"
63};
64
65static int __init ppc44x_probe(void)
66{
67 unsigned long root = of_get_flat_dt_root();
68 int i = 0;
69
70 for (i = 0; i < ARRAY_SIZE(board); i++) {
71 if (of_flat_dt_is_compatible(root, board[i])) {
72 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
73 return 1;
74 }
75 }
76
77 return 0;
78}
79
80define_machine(ppc44x_simple) {
81 .name = "PowerPC 44x Platform",
82 .probe = ppc44x_probe,
83 .progress = udbg_progress,
84 .init_IRQ = uic_init_tree,
85 .get_irq = uic_get_irq,
86 .restart = ppc4xx_reset_system,
87 .calibrate_decr = generic_calibrate_decr,
88};
diff --git a/arch/powerpc/platforms/44x/rainier.c b/arch/powerpc/platforms/44x/rainier.c
deleted file mode 100644
index 4f1ff84c4b63..000000000000
--- a/arch/powerpc/platforms/44x/rainier.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Rainier board specific routines
3 *
4 * Valentine Barshak <vbarshak@ru.mvista.com>
5 * Copyright 2007 MontaVista Software Inc.
6 *
7 * Based on the Bamboo code by
8 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
9 * Copyright 2007 IBM Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/init.h>
17#include <linux/of_platform.h>
18
19#include <asm/machdep.h>
20#include <asm/prom.h>
21#include <asm/udbg.h>
22#include <asm/time.h>
23#include <asm/uic.h>
24#include <asm/pci-bridge.h>
25#include <asm/ppc4xx.h>
26
27static __initdata struct of_device_id rainier_of_bus[] = {
28 { .compatible = "ibm,plb4", },
29 { .compatible = "ibm,opb", },
30 { .compatible = "ibm,ebc", },
31 {},
32};
33
34static int __init rainier_device_probe(void)
35{
36 of_platform_bus_probe(NULL, rainier_of_bus, NULL);
37
38 return 0;
39}
40machine_device_initcall(rainier, rainier_device_probe);
41
42static int __init rainier_probe(void)
43{
44 unsigned long root = of_get_flat_dt_root();
45
46 if (!of_flat_dt_is_compatible(root, "amcc,rainier"))
47 return 0;
48
49 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
50
51 return 1;
52}
53
54define_machine(rainier) {
55 .name = "Rainier",
56 .probe = rainier_probe,
57 .progress = udbg_progress,
58 .init_IRQ = uic_init_tree,
59 .get_irq = uic_get_irq,
60 .restart = ppc4xx_reset_system,
61 .calibrate_decr = generic_calibrate_decr,
62};
diff --git a/arch/powerpc/platforms/44x/sequoia.c b/arch/powerpc/platforms/44x/sequoia.c
deleted file mode 100644
index 49eb73daacdf..000000000000
--- a/arch/powerpc/platforms/44x/sequoia.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Sequoia board specific routines
3 *
4 * Valentine Barshak <vbarshak@ru.mvista.com>
5 * Copyright 2007 MontaVista Software Inc.
6 *
7 * Based on the Bamboo code by
8 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
9 * Copyright 2007 IBM Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <linux/init.h>
17#include <linux/of_platform.h>
18
19#include <asm/machdep.h>
20#include <asm/prom.h>
21#include <asm/udbg.h>
22#include <asm/time.h>
23#include <asm/uic.h>
24#include <asm/pci-bridge.h>
25
26#include <asm/ppc4xx.h>
27
28static __initdata struct of_device_id sequoia_of_bus[] = {
29 { .compatible = "ibm,plb4", },
30 { .compatible = "ibm,opb", },
31 { .compatible = "ibm,ebc", },
32 {},
33};
34
35static int __init sequoia_device_probe(void)
36{
37 of_platform_bus_probe(NULL, sequoia_of_bus, NULL);
38
39 return 0;
40}
41machine_device_initcall(sequoia, sequoia_device_probe);
42
43static int __init sequoia_probe(void)
44{
45 unsigned long root = of_get_flat_dt_root();
46
47 if (!of_flat_dt_is_compatible(root, "amcc,sequoia"))
48 return 0;
49
50 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
51
52 return 1;
53}
54
55define_machine(sequoia) {
56 .name = "Sequoia",
57 .probe = sequoia_probe,
58 .progress = udbg_progress,
59 .init_IRQ = uic_init_tree,
60 .get_irq = uic_get_irq,
61 .restart = ppc4xx_reset_system,
62 .calibrate_decr = generic_calibrate_decr,
63};
diff --git a/arch/powerpc/platforms/44x/taishan.c b/arch/powerpc/platforms/44x/taishan.c
deleted file mode 100644
index 49c78b2098b4..000000000000
--- a/arch/powerpc/platforms/44x/taishan.c
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * Taishan board specific routines based off ebony.c code
3 * original copyrights below
4 *
5 * Matt Porter <mporter@kernel.crashing.org>
6 * Copyright 2002-2005 MontaVista Software Inc.
7 *
8 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
9 * Copyright (c) 2003-2005 Zultys Technologies
10 *
11 * Rewritten and ported to the merged powerpc tree:
12 * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
13 *
14 * Modified from ebony.c for taishan:
15 * Copyright 2007 Hugh Blemings <hugh@au.ibm.com>, IBM Corporation.
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version.
21 */
22
23#include <linux/init.h>
24#include <linux/of_platform.h>
25
26#include <asm/machdep.h>
27#include <asm/prom.h>
28#include <asm/udbg.h>
29#include <asm/time.h>
30#include <asm/uic.h>
31#include <asm/pci-bridge.h>
32#include <asm/ppc4xx.h>
33
34static __initdata struct of_device_id taishan_of_bus[] = {
35 { .compatible = "ibm,plb4", },
36 { .compatible = "ibm,opb", },
37 { .compatible = "ibm,ebc", },
38 {},
39};
40
41static int __init taishan_device_probe(void)
42{
43 of_platform_bus_probe(NULL, taishan_of_bus, NULL);
44
45 return 0;
46}
47machine_device_initcall(taishan, taishan_device_probe);
48
49/*
50 * Called very early, MMU is off, device-tree isn't unflattened
51 */
52static int __init taishan_probe(void)
53{
54 unsigned long root = of_get_flat_dt_root();
55
56 if (!of_flat_dt_is_compatible(root, "amcc,taishan"))
57 return 0;
58
59 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
60
61 return 1;
62}
63
64define_machine(taishan) {
65 .name = "Taishan",
66 .probe = taishan_probe,
67 .progress = udbg_progress,
68 .init_IRQ = uic_init_tree,
69 .get_irq = uic_get_irq,
70 .restart = ppc4xx_reset_system,
71 .calibrate_decr = generic_calibrate_decr,
72};
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index c62f893ede19..326852c78b8f 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -3,6 +3,8 @@ config PPC_MPC512x
3 select FSL_SOC 3 select FSL_SOC
4 select IPIC 4 select IPIC
5 select PPC_CLOCK 5 select PPC_CLOCK
6 select PPC_PCI_CHOICE
7 select FSL_PCI if PCI
6 8
7config PPC_MPC5121 9config PPC_MPC5121
8 bool 10 bool
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
index 5ebf6939a697..441abc488851 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -22,16 +22,26 @@
22#include <asm/prom.h> 22#include <asm/prom.h>
23#include <asm/time.h> 23#include <asm/time.h>
24 24
25#include <sysdev/fsl_pci.h>
26
25#include "mpc512x.h" 27#include "mpc512x.h"
26#include "mpc5121_ads.h" 28#include "mpc5121_ads.h"
27 29
28static void __init mpc5121_ads_setup_arch(void) 30static void __init mpc5121_ads_setup_arch(void)
29{ 31{
32#ifdef CONFIG_PCI
33 struct device_node *np;
34#endif
30 printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n"); 35 printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n");
31 /* 36 /*
32 * cpld regs are needed early 37 * cpld regs are needed early
33 */ 38 */
34 mpc5121_ads_cpld_map(); 39 mpc5121_ads_cpld_map();
40
41#ifdef CONFIG_PCI
42 for_each_compatible_node(np, "pci", "fsl,mpc5121-pci")
43 mpc83xx_add_bridge(np);
44#endif
35} 45}
36 46
37static void __init mpc5121_ads_init_IRQ(void) 47static void __init mpc5121_ads_init_IRQ(void)
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 4d5fd1dbd400..044b4e6e8743 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -90,7 +90,7 @@ mpc5200_setup_xlb_arbiter(void)
90 of_node_put(np); 90 of_node_put(np);
91 if (!xlb) { 91 if (!xlb) {
92 printk(KERN_ERR __FILE__ ": " 92 printk(KERN_ERR __FILE__ ": "
93 "Error mapping XLB in mpc52xx_setup_cpu(). " 93 "Error mapping XLB in mpc52xx_setup_cpu(). "
94 "Expect some abnormal behavior\n"); 94 "Expect some abnormal behavior\n");
95 return; 95 return;
96 } 96 }
@@ -216,7 +216,8 @@ mpc52xx_restart(char *cmd)
216 out_be32(&mpc52xx_wdt->count, 0x000000ff); 216 out_be32(&mpc52xx_wdt->count, 0x000000ff);
217 out_be32(&mpc52xx_wdt->mode, 0x00009004); 217 out_be32(&mpc52xx_wdt->mode, 0x00009004);
218 } else 218 } else
219 printk("mpc52xx_restart: Can't access wdt. " 219 printk(KERN_ERR __FILE__ ": "
220 "mpc52xx_restart: Can't access wdt. "
220 "Restart impossible, system halted.\n"); 221 "Restart impossible, system halted.\n");
221 222
222 while (1); 223 while (1);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 5a382bb15f62..b49a18527661 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -265,8 +265,11 @@ mpc52xx_pci_setup(struct pci_controller *hose,
265 /* Memory windows */ 265 /* Memory windows */
266 res = &hose->mem_resources[0]; 266 res = &hose->mem_resources[0];
267 if (res->flags) { 267 if (res->flags) {
268 pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n", 268 pr_debug("mem_resource[0] = "
269 res->start, res->end, res->flags); 269 "{.start=%llx, .end=%llx, .flags=%llx}\n",
270 (unsigned long long)res->start,
271 (unsigned long long)res->end,
272 (unsigned long long)res->flags);
270 out_be32(&pci_regs->iw0btar, 273 out_be32(&pci_regs->iw0btar,
271 MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start, 274 MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
272 res->end - res->start + 1)); 275 res->end - res->start + 1));
@@ -297,9 +300,11 @@ mpc52xx_pci_setup(struct pci_controller *hose,
297 printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__); 300 printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
298 return; 301 return;
299 } 302 }
300 pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} " 303 pr_debug(".io_resource={.start=%llx,.end=%llx,.flags=%llx} "
301 ".io_base_phys=0x%p\n", 304 ".io_base_phys=0x%p\n",
302 res->start, res->end, res->flags, (void*)hose->io_base_phys); 305 (unsigned long long)res->start,
306 (unsigned long long)res->end,
307 (unsigned long long)res->flags, (void*)hose->io_base_phys);
303 out_be32(&pci_regs->iw2btar, 308 out_be32(&pci_regs->iw2btar,
304 MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys, 309 MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
305 res->start, 310 res->start,
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
index 75eb1ede5497..30f008b2f92e 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -38,6 +38,14 @@ config EP8248E
38 This board is also resold by Freescale as the QUICCStart 38 This board is also resold by Freescale as the QUICCStart
39 MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE. 39 MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE.
40 40
41config MGCOGE
42 bool "Keymile MGCOGE"
43 select 8272
44 select 8260
45 select FSL_SOC
46 help
47 This enables support for the Keymile MGCOGE board.
48
41endif 49endif
42 50
43config PQ2ADS 51config PQ2ADS
diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile
index 6cd5cd59bf2a..d982793f4dbd 100644
--- a/arch/powerpc/platforms/82xx/Makefile
+++ b/arch/powerpc/platforms/82xx/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_CPM2) += pq2.o
6obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o 6obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o
7obj-$(CONFIG_PQ2FADS) += pq2fads.o 7obj-$(CONFIG_PQ2FADS) += pq2fads.o
8obj-$(CONFIG_EP8248E) += ep8248e.o 8obj-$(CONFIG_EP8248E) += ep8248e.o
9obj-$(CONFIG_MGCOGE) += mgcoge.o
diff --git a/arch/powerpc/platforms/82xx/mgcoge.c b/arch/powerpc/platforms/82xx/mgcoge.c
new file mode 100644
index 000000000000..c2af169c1d1d
--- /dev/null
+++ b/arch/powerpc/platforms/82xx/mgcoge.c
@@ -0,0 +1,129 @@
1/*
2 * Keymile mgcoge support
3 * Copyright 2008 DENX Software Engineering GmbH
4 * Author: Heiko Schocher <hs@denx.de>
5 *
6 * based on code from:
7 * Copyright 2007 Freescale Semiconductor, Inc.
8 * Author: Scott Wood <scottwood@freescale.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/fsl_devices.h>
19#include <linux/of_platform.h>
20
21#include <asm/io.h>
22#include <asm/cpm2.h>
23#include <asm/udbg.h>
24#include <asm/machdep.h>
25#include <asm/time.h>
26#include <asm/mpc8260.h>
27#include <asm/prom.h>
28
29#include <sysdev/fsl_soc.h>
30#include <sysdev/cpm2_pic.h>
31
32#include "pq2.h"
33
34static void __init mgcoge_pic_init(void)
35{
36 struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic");
37 if (!np) {
38 printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
39 return;
40 }
41
42 cpm2_pic_init(np);
43 of_node_put(np);
44}
45
46struct cpm_pin {
47 int port, pin, flags;
48};
49
50static __initdata struct cpm_pin mgcoge_pins[] = {
51
52 /* SMC2 */
53 {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
54 {1, 9, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
55
56 /* SCC4 */
57 {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
58 {3, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
59 {3, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
60 {3, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
61 {4, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
62 {4, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
63};
64
65static void __init init_ioports(void)
66{
67 int i;
68
69 for (i = 0; i < ARRAY_SIZE(mgcoge_pins); i++) {
70 const struct cpm_pin *pin = &mgcoge_pins[i];
71 cpm2_set_pin(pin->port - 1, pin->pin, pin->flags);
72 }
73
74 cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8);
75 cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK7, CPM_CLK_RX);
76 cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK8, CPM_CLK_TX);
77}
78
79static void __init mgcoge_setup_arch(void)
80{
81 if (ppc_md.progress)
82 ppc_md.progress("mgcoge_setup_arch()", 0);
83
84 cpm2_reset();
85
86 /* When this is set, snooping CPM DMA from RAM causes
87 * machine checks. See erratum SIU18.
88 */
89 clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP);
90
91 init_ioports();
92
93 if (ppc_md.progress)
94 ppc_md.progress("mgcoge_setup_arch(), finish", 0);
95}
96
97static __initdata struct of_device_id of_bus_ids[] = {
98 { .compatible = "simple-bus", },
99 {},
100};
101
102static int __init declare_of_platform_devices(void)
103{
104 of_platform_bus_probe(NULL, of_bus_ids, NULL);
105
106 return 0;
107}
108machine_device_initcall(mgcoge, declare_of_platform_devices);
109
110/*
111 * Called very early, device-tree isn't unflattened
112 */
113static int __init mgcoge_probe(void)
114{
115 unsigned long root = of_get_flat_dt_root();
116 return of_flat_dt_is_compatible(root, "keymile,mgcoge");
117}
118
119define_machine(mgcoge)
120{
121 .name = "Keymile MGCOGE",
122 .probe = mgcoge_probe,
123 .setup_arch = mgcoge_setup_arch,
124 .init_IRQ = mgcoge_pic_init,
125 .get_irq = cpm2_get_irq,
126 .calibrate_decr = generic_calibrate_decr,
127 .restart = pq2_restart,
128 .progress = udbg_progress,
129};
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 6159c5d4e5f1..83c664afc897 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -19,7 +19,6 @@ config MPC831x_RDB
19config MPC832x_MDS 19config MPC832x_MDS
20 bool "Freescale MPC832x MDS" 20 bool "Freescale MPC832x MDS"
21 select DEFAULT_UIMAGE 21 select DEFAULT_UIMAGE
22 select QUICC_ENGINE
23 select PPC_MPC832x 22 select PPC_MPC832x
24 help 23 help
25 This option enables support for the MPC832x MDS evaluation board. 24 This option enables support for the MPC832x MDS evaluation board.
@@ -27,7 +26,6 @@ config MPC832x_MDS
27config MPC832x_RDB 26config MPC832x_RDB
28 bool "Freescale MPC832x RDB" 27 bool "Freescale MPC832x RDB"
29 select DEFAULT_UIMAGE 28 select DEFAULT_UIMAGE
30 select QUICC_ENGINE
31 select PPC_MPC832x 29 select PPC_MPC832x
32 help 30 help
33 This option enables support for the MPC8323 RDB board. 31 This option enables support for the MPC8323 RDB board.
@@ -57,15 +55,12 @@ config MPC834x_ITX
57config MPC836x_MDS 55config MPC836x_MDS
58 bool "Freescale MPC836x MDS" 56 bool "Freescale MPC836x MDS"
59 select DEFAULT_UIMAGE 57 select DEFAULT_UIMAGE
60 select QUICC_ENGINE
61 help 58 help
62 This option enables support for the MPC836x MDS Processor Board. 59 This option enables support for the MPC836x MDS Processor Board.
63 60
64config MPC836x_RDK 61config MPC836x_RDK
65 bool "Freescale/Logic MPC836x RDK" 62 bool "Freescale/Logic MPC836x RDK"
66 select DEFAULT_UIMAGE 63 select DEFAULT_UIMAGE
67 select QUICC_ENGINE
68 select QE_GPIO
69 select FSL_GTM 64 select FSL_GTM
70 select FSL_LBC 65 select FSL_LBC
71 help 66 help
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
index be62de23bead..8bb13c807142 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -85,8 +85,14 @@ static void __init mpc837x_mds_setup_arch(void)
85 ppc_md.progress("mpc837x_mds_setup_arch()", 0); 85 ppc_md.progress("mpc837x_mds_setup_arch()", 0);
86 86
87#ifdef CONFIG_PCI 87#ifdef CONFIG_PCI
88 for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") 88 for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") {
89 if (!of_device_is_available(np)) {
90 pr_warning("%s: disabled by the firmware.\n",
91 np->full_name);
92 continue;
93 }
89 mpc83xx_add_bridge(np); 94 mpc83xx_add_bridge(np);
95 }
90#endif 96#endif
91 mpc837xmds_usb_cfg(); 97 mpc837xmds_usb_cfg();
92} 98}
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 291675b0097a..b79dc710ed34 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -33,7 +33,6 @@ config MPC85xx_CDS
33config MPC85xx_MDS 33config MPC85xx_MDS
34 bool "Freescale MPC85xx MDS" 34 bool "Freescale MPC85xx MDS"
35 select DEFAULT_UIMAGE 35 select DEFAULT_UIMAGE
36 select QUICC_ENGINE
37 select PHYLIB 36 select PHYLIB
38 help 37 help
39 This option enables support for the MPC85xx MDS board 38 This option enables support for the MPC85xx MDS board
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index d17807a6b89a..0293e3d3580f 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -213,7 +213,6 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
213 svid = mfspr(SPRN_SVR); 213 svid = mfspr(SPRN_SVR);
214 214
215 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); 215 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
216 seq_printf(m, "Machine\t\t: mpc85xx\n");
217 seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 216 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
218 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 217 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
219 218
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index 6509ade71668..0c9a856f66b6 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -156,7 +156,7 @@ static void __init init_ioports(void)
156 int i; 156 int i;
157 157
158 for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) { 158 for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) {
159 struct cpm_pin *pin = &sbc8560_pins[i]; 159 const struct cpm_pin *pin = &sbc8560_pins[i];
160 cpm2_set_pin(pin->port, pin->pin, pin->flags); 160 cpm2_set_pin(pin->port, pin->pin, pin->flags);
161 } 161 }
162 162
@@ -200,7 +200,6 @@ static void sbc8560_show_cpuinfo(struct seq_file *m)
200 svid = mfspr(SPRN_SVR); 200 svid = mfspr(SPRN_SVR);
201 201
202 seq_printf(m, "Vendor\t\t: Wind River\n"); 202 seq_printf(m, "Vendor\t\t: Wind River\n");
203 seq_printf(m, "Machine\t\t: SBC8560\n");
204 seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 203 seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
205 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 204 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
206 205
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 9355a5269431..77dd797a2580 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -31,6 +31,13 @@ config MPC8610_HPCD
31 help 31 help
32 This option enables support for the MPC8610 HPCD board. 32 This option enables support for the MPC8610 HPCD board.
33 33
34config GEF_SBC610
35 bool "GE Fanuc SBC610"
36 select DEFAULT_UIMAGE
37 select HAS_RAPIDIO
38 help
39 This option enables support for GE Fanuc's SBC610.
40
34endif 41endif
35 42
36config MPC8641 43config MPC8641
@@ -39,7 +46,7 @@ config MPC8641
39 select FSL_PCI if PCI 46 select FSL_PCI if PCI
40 select PPC_UDBG_16550 47 select PPC_UDBG_16550
41 select MPIC 48 select MPIC
42 default y if MPC8641_HPCN || SBC8641D 49 default y if MPC8641_HPCN || SBC8641D || GEF_SBC610
43 50
44config MPC8610 51config MPC8610
45 bool 52 bool
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index 8fee37dec795..4a56ff619afd 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_SMP) += mpc86xx_smp.o
7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o 7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
8obj-$(CONFIG_SBC8641D) += sbc8641d.o 8obj-$(CONFIG_SBC8641D) += sbc8641d.o
9obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o 9obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
10obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
new file mode 100644
index 000000000000..50d0a2b63809
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -0,0 +1,258 @@
1/*
2 * Interrupt handling for GE Fanuc's FPGA based PIC
3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com>
5 *
6 * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/stddef.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/interrupt.h>
18#include <linux/spinlock.h>
19
20#include <asm/byteorder.h>
21#include <asm/io.h>
22#include <asm/prom.h>
23#include <asm/irq.h>
24
25#include "gef_pic.h"
26
27#define DEBUG
28#undef DEBUG
29
30#ifdef DEBUG
31#define DBG(fmt...) do { printk(KERN_DEBUG "gef_pic: " fmt); } while (0)
32#else
33#define DBG(fmt...) do { } while (0)
34#endif
35
36#define GEF_PIC_NUM_IRQS 32
37
38/* Interrupt Controller Interface Registers */
39#define GEF_PIC_INTR_STATUS 0x0000
40
41#define GEF_PIC_INTR_MASK(cpu) (0x0010 + (0x4 * cpu))
42#define GEF_PIC_CPU0_INTR_MASK GEF_PIC_INTR_MASK(0)
43#define GEF_PIC_CPU1_INTR_MASK GEF_PIC_INTR_MASK(1)
44
45#define GEF_PIC_MCP_MASK(cpu) (0x0018 + (0x4 * cpu))
46#define GEF_PIC_CPU0_MCP_MASK GEF_PIC_MCP_MASK(0)
47#define GEF_PIC_CPU1_MCP_MASK GEF_PIC_MCP_MASK(1)
48
49#define gef_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
50
51
52static DEFINE_SPINLOCK(gef_pic_lock);
53
54static void __iomem *gef_pic_irq_reg_base;
55static struct irq_host *gef_pic_irq_host;
56static int gef_pic_cascade_irq;
57
58/*
59 * Interrupt Controller Handling
60 *
61 * The interrupt controller handles interrupts for most on board interrupts,
62 * apart from PCI interrupts. For example on SBC610:
63 *
64 * 17:31 RO Reserved
65 * 16 RO PCI Express Doorbell 3 Status
66 * 15 RO PCI Express Doorbell 2 Status
67 * 14 RO PCI Express Doorbell 1 Status
68 * 13 RO PCI Express Doorbell 0 Status
69 * 12 RO Real Time Clock Interrupt Status
70 * 11 RO Temperature Interrupt Status
71 * 10 RO Temperature Critical Interrupt Status
72 * 9 RO Ethernet PHY1 Interrupt Status
73 * 8 RO Ethernet PHY3 Interrupt Status
74 * 7 RO PEX8548 Interrupt Status
75 * 6 RO Reserved
76 * 5 RO Watchdog 0 Interrupt Status
77 * 4 RO Watchdog 1 Interrupt Status
78 * 3 RO AXIS Message FIFO A Interrupt Status
79 * 2 RO AXIS Message FIFO B Interrupt Status
80 * 1 RO AXIS Message FIFO C Interrupt Status
81 * 0 RO AXIS Message FIFO D Interrupt Status
82 *
83 * Interrupts can be forwarded to one of two output lines. Nothing
84 * clever is done, so if the masks are incorrectly set, a single input
85 * interrupt could generate interrupts on both output lines!
86 *
87 * The dual lines are there to allow the chained interrupts to be easily
88 * passed into two different cores. We currently do not use this functionality
89 * in this driver.
90 *
91 * Controller can also be configured to generate Machine checks (MCP), again on
92 * two lines, to be attached to two different cores. It is suggested that these
93 * should be masked out.
94 */
95
96void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
97{
98 unsigned int cascade_irq;
99
100 /*
101 * See if we actually have an interrupt, call generic handling code if
102 * we do.
103 */
104 cascade_irq = gef_pic_get_irq();
105
106 if (cascade_irq != NO_IRQ)
107 generic_handle_irq(cascade_irq);
108
109 desc->chip->eoi(irq);
110
111}
112
113static void gef_pic_mask(unsigned int virq)
114{
115 unsigned long flags;
116 unsigned int hwirq;
117 u32 mask;
118
119 hwirq = gef_irq_to_hw(virq);
120
121 spin_lock_irqsave(&gef_pic_lock, flags);
122 mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
123 mask &= ~(1 << hwirq);
124 out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
125 spin_unlock_irqrestore(&gef_pic_lock, flags);
126}
127
128static void gef_pic_mask_ack(unsigned int virq)
129{
130 /* Don't think we actually have to do anything to ack an interrupt,
131 * we just need to clear down the devices interrupt and it will go away
132 */
133 gef_pic_mask(virq);
134}
135
136static void gef_pic_unmask(unsigned int virq)
137{
138 unsigned long flags;
139 unsigned int hwirq;
140 u32 mask;
141
142 hwirq = gef_irq_to_hw(virq);
143
144 spin_lock_irqsave(&gef_pic_lock, flags);
145 mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
146 mask |= (1 << hwirq);
147 out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask);
148 spin_unlock_irqrestore(&gef_pic_lock, flags);
149}
150
151static struct irq_chip gef_pic_chip = {
152 .typename = "gefp",
153 .mask = gef_pic_mask,
154 .mask_ack = gef_pic_mask_ack,
155 .unmask = gef_pic_unmask,
156};
157
158
159/* When an interrupt is being configured, this call allows some flexibilty
160 * in deciding which irq_chip structure is used
161 */
162static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
163 irq_hw_number_t hwirq)
164{
165 /* All interrupts are LEVEL sensitive */
166 get_irq_desc(virq)->status |= IRQ_LEVEL;
167 set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
168
169 return 0;
170}
171
172static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
173 u32 *intspec, unsigned int intsize,
174 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
175{
176
177 *out_hwirq = intspec[0];
178 if (intsize > 1)
179 *out_flags = intspec[1];
180 else
181 *out_flags = IRQ_TYPE_LEVEL_HIGH;
182
183 return 0;
184}
185
186static struct irq_host_ops gef_pic_host_ops = {
187 .map = gef_pic_host_map,
188 .xlate = gef_pic_host_xlate,
189};
190
191
192/*
193 * Initialisation of PIC, this should be called in BSP
194 */
195void __init gef_pic_init(struct device_node *np)
196{
197 unsigned long flags;
198
199 /* Map the devices registers into memory */
200 gef_pic_irq_reg_base = of_iomap(np, 0);
201
202 spin_lock_irqsave(&gef_pic_lock, flags);
203
204 /* Initialise everything as masked. */
205 out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0);
206 out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_INTR_MASK, 0);
207
208 out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0);
209 out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0);
210
211 spin_unlock_irqrestore(&gef_pic_lock, flags);
212
213 /* Map controller */
214 gef_pic_cascade_irq = irq_of_parse_and_map(np, 0);
215 if (gef_pic_cascade_irq == NO_IRQ) {
216 printk(KERN_ERR "SBC610: failed to map cascade interrupt");
217 return;
218 }
219
220 /* Setup an irq_host structure */
221 gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
222 GEF_PIC_NUM_IRQS,
223 &gef_pic_host_ops, NO_IRQ);
224 if (gef_pic_irq_host == NULL)
225 return;
226
227 /* Chain with parent controller */
228 set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade);
229}
230
231/*
232 * This is called when we receive an interrupt with apparently comes from this
233 * chip - check, returning the highest interrupt generated or return NO_IRQ
234 */
235unsigned int gef_pic_get_irq(void)
236{
237 u32 cause, mask, active;
238 unsigned int virq = NO_IRQ;
239 int hwirq;
240
241 cause = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_STATUS);
242
243 mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
244
245 active = cause & mask;
246
247 if (active) {
248 for (hwirq = GEF_PIC_NUM_IRQS - 1; hwirq > -1; hwirq--) {
249 if (active & (0x1 << hwirq))
250 break;
251 }
252 virq = irq_linear_revmap(gef_pic_irq_host,
253 (irq_hw_number_t)hwirq);
254 }
255
256 return virq;
257}
258
diff --git a/arch/powerpc/platforms/86xx/gef_pic.h b/arch/powerpc/platforms/86xx/gef_pic.h
new file mode 100644
index 000000000000..6149916da3f4
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_pic.h
@@ -0,0 +1,11 @@
1#ifndef __GEF_PIC_H__
2#define __GEF_PIC_H__
3
4#include <linux/init.h>
5
6void gef_pic_cascade(unsigned int, struct irq_desc *);
7unsigned int gef_pic_get_irq(void);
8void gef_pic_init(struct device_node *);
9
10#endif /* __GEF_PIC_H__ */
11
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
new file mode 100644
index 000000000000..821c45fac18b
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -0,0 +1,221 @@
1/*
2 * GE Fanuc SBC610 board support
3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com>
5 *
6 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, 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 * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines)
14 * Copyright 2006 Freescale Semiconductor Inc.
15 *
16 * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c
17 */
18
19#include <linux/stddef.h>
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/kdev_t.h>
23#include <linux/delay.h>
24#include <linux/seq_file.h>
25#include <linux/of_platform.h>
26
27#include <asm/system.h>
28#include <asm/time.h>
29#include <asm/machdep.h>
30#include <asm/pci-bridge.h>
31#include <asm/mpc86xx.h>
32#include <asm/prom.h>
33#include <mm/mmu_decl.h>
34#include <asm/udbg.h>
35
36#include <asm/mpic.h>
37
38#include <sysdev/fsl_pci.h>
39#include <sysdev/fsl_soc.h>
40
41#include "mpc86xx.h"
42#include "gef_pic.h"
43
44#undef DEBUG
45
46#ifdef DEBUG
47#define DBG (fmt...) do { printk(KERN_ERR "SBC610: " fmt); } while (0)
48#else
49#define DBG (fmt...) do { } while (0)
50#endif
51
52void __iomem *sbc610_regs;
53
54static void __init gef_sbc610_init_irq(void)
55{
56 struct device_node *cascade_node = NULL;
57
58 mpc86xx_init_irq();
59
60 /*
61 * There is a simple interrupt handler in the main FPGA, this needs
62 * to be cascaded into the MPIC
63 */
64 cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic");
65 if (!cascade_node) {
66 printk(KERN_WARNING "SBC610: No FPGA PIC\n");
67 return;
68 }
69
70 gef_pic_init(cascade_node);
71 of_node_put(cascade_node);
72}
73
74static void __init gef_sbc610_setup_arch(void)
75{
76 struct device_node *regs;
77#ifdef CONFIG_PCI
78 struct device_node *np;
79
80 for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
81 fsl_add_bridge(np, 1);
82 }
83#endif
84
85 printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n");
86
87#ifdef CONFIG_SMP
88 mpc86xx_smp_init();
89#endif
90
91 /* Remap basic board registers */
92 regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
93 if (regs) {
94 sbc610_regs = of_iomap(regs, 0);
95 if (sbc610_regs == NULL)
96 printk(KERN_WARNING "Unable to map board registers\n");
97 of_node_put(regs);
98 }
99}
100
101/* Return the PCB revision */
102static unsigned int gef_sbc610_get_pcb_rev(void)
103{
104 unsigned int reg;
105
106 reg = ioread32(sbc610_regs);
107 return (reg >> 8) & 0xff;
108}
109
110/* Return the board (software) revision */
111static unsigned int gef_sbc610_get_board_rev(void)
112{
113 unsigned int reg;
114
115 reg = ioread32(sbc610_regs);
116 return (reg >> 16) & 0xff;
117}
118
119/* Return the FPGA revision */
120static unsigned int gef_sbc610_get_fpga_rev(void)
121{
122 unsigned int reg;
123
124 reg = ioread32(sbc610_regs);
125 return (reg >> 24) & 0xf;
126}
127
128static void gef_sbc610_show_cpuinfo(struct seq_file *m)
129{
130 uint memsize = total_memory;
131 uint svid = mfspr(SPRN_SVR);
132
133 seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
134
135 seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(),
136 ('A' + gef_sbc610_get_board_rev() - 1));
137 seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev());
138
139 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
140 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
141}
142
143static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev)
144{
145 unsigned int val;
146
147 printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
148
149 /* Ensure ports 1, 2, 3, 4 & 5 are enabled */
150 pci_read_config_dword(pdev, 0xe0, &val);
151 pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5);
152
153 /* System clock is 48-MHz Oscillator and EHCI Enabled. */
154 pci_write_config_dword(pdev, 0xe4, 1 << 5);
155}
156DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
157 gef_sbc610_nec_fixup);
158
159/*
160 * Called very early, device-tree isn't unflattened
161 *
162 * This function is called to determine whether the BSP is compatible with the
163 * supplied device-tree, which is assumed to be the correct one for the actual
164 * board. It is expected thati, in the future, a kernel may support multiple
165 * boards.
166 */
167static int __init gef_sbc610_probe(void)
168{
169 unsigned long root = of_get_flat_dt_root();
170
171 if (of_flat_dt_is_compatible(root, "gef,sbc610"))
172 return 1;
173
174 return 0;
175}
176
177static long __init mpc86xx_time_init(void)
178{
179 unsigned int temp;
180
181 /* Set the time base to zero */
182 mtspr(SPRN_TBWL, 0);
183 mtspr(SPRN_TBWU, 0);
184
185 temp = mfspr(SPRN_HID0);
186 temp |= HID0_TBEN;
187 mtspr(SPRN_HID0, temp);
188 asm volatile("isync");
189
190 return 0;
191}
192
193static __initdata struct of_device_id of_bus_ids[] = {
194 { .compatible = "simple-bus", },
195 {},
196};
197
198static int __init declare_of_platform_devices(void)
199{
200 printk(KERN_DEBUG "Probe platform devices\n");
201 of_platform_bus_probe(NULL, of_bus_ids, NULL);
202
203 return 0;
204}
205machine_device_initcall(gef_sbc610, declare_of_platform_devices);
206
207define_machine(gef_sbc610) {
208 .name = "GE Fanuc SBC610",
209 .probe = gef_sbc610_probe,
210 .setup_arch = gef_sbc610_setup_arch,
211 .init_IRQ = gef_sbc610_init_irq,
212 .show_cpuinfo = gef_sbc610_show_cpuinfo,
213 .get_irq = mpic_get_irq,
214 .restart = fsl_rstcr_restart,
215 .time_init = mpc86xx_time_init,
216 .calibrate_decr = generic_calibrate_decr,
217 .progress = udbg_progress,
218#ifdef CONFIG_PCI
219 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
220#endif
221};
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 5eedb710896e..e8d54ac5292c 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -238,7 +238,6 @@ static void __init mpc86xx_hpcd_setup_arch(void)
238 } 238 }
239#endif 239#endif
240#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) 240#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
241 preallocate_diu_videomemory();
242 diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format; 241 diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format;
243 diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table; 242 diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table;
244 diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port; 243 diu_ops.set_monitor_port = mpc8610hpcd_set_monitor_port;
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index f712d9c0991b..2672829a71dc 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -101,19 +101,11 @@ mpc86xx_hpcn_setup_arch(void)
101static void 101static void
102mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) 102mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
103{ 103{
104 struct device_node *root;
105 uint memsize = total_memory; 104 uint memsize = total_memory;
106 const char *model = "";
107 uint svid = mfspr(SPRN_SVR); 105 uint svid = mfspr(SPRN_SVR);
108 106
109 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); 107 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
110 108
111 root = of_find_node_by_path("/");
112 if (root)
113 model = of_get_property(root, "model", NULL);
114 seq_printf(m, "Machine\t\t: %s\n", model);
115 of_node_put(root);
116
117 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 109 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
118 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); 110 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
119} 111}
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 00e6fad3b3ca..da677a74e2d1 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -63,19 +63,11 @@ sbc8641_setup_arch(void)
63static void 63static void
64sbc8641_show_cpuinfo(struct seq_file *m) 64sbc8641_show_cpuinfo(struct seq_file *m)
65{ 65{
66 struct device_node *root;
67 uint memsize = total_memory; 66 uint memsize = total_memory;
68 const char *model = "";
69 uint svid = mfspr(SPRN_SVR); 67 uint svid = mfspr(SPRN_SVR);
70 68
71 seq_printf(m, "Vendor\t\t: Wind River Systems\n"); 69 seq_printf(m, "Vendor\t\t: Wind River Systems\n");
72 70
73 root = of_find_node_by_path("/");
74 if (root)
75 model = of_get_property(root, "model", NULL);
76 seq_printf(m, "Machine\t\t: %s\n", model);
77 of_node_put(root);
78
79 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 71 seq_printf(m, "SVR\t\t: 0x%x\n", svid);
80 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); 72 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
81} 73}
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index 71d7562e190b..48a920a98e7b 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -49,6 +49,12 @@ config PPC_ADDER875
49 This enables support for the Analogue & Micro Adder 875 49 This enables support for the Analogue & Micro Adder 875
50 board. 50 board.
51 51
52config PPC_MGSUVD
53 bool "MGSUVD"
54 select CPM1
55 help
56 This enables support for the Keymile MGSUVD board.
57
52endchoice 58endchoice
53 59
54menu "Freescale Ethernet driver platform-specific options" 60menu "Freescale Ethernet driver platform-specific options"
diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile
index 7b71d9c8fb45..bdbfd7496018 100644
--- a/arch/powerpc/platforms/8xx/Makefile
+++ b/arch/powerpc/platforms/8xx/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
6obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o 6obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o
7obj-$(CONFIG_PPC_EP88XC) += ep88xc.o 7obj-$(CONFIG_PPC_EP88XC) += ep88xc.o
8obj-$(CONFIG_PPC_ADDER875) += adder875.o 8obj-$(CONFIG_PPC_ADDER875) += adder875.o
9obj-$(CONFIG_PPC_MGSUVD) += mgsuvd.o
diff --git a/arch/powerpc/platforms/8xx/mgsuvd.c b/arch/powerpc/platforms/8xx/mgsuvd.c
new file mode 100644
index 000000000000..ca3cb071772c
--- /dev/null
+++ b/arch/powerpc/platforms/8xx/mgsuvd.c
@@ -0,0 +1,92 @@
1/*
2 *
3 * Platform setup for the Keymile mgsuvd board
4 *
5 * Heiko Schocher <hs@denx.de>
6 *
7 * Copyright 2008 DENX Software Engineering GmbH
8 *
9 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied.
12 */
13
14#include <linux/ioport.h>
15#include <linux/of_platform.h>
16
17#include <asm/io.h>
18#include <asm/machdep.h>
19#include <asm/processor.h>
20#include <asm/cpm1.h>
21#include <asm/prom.h>
22#include <asm/fs_pd.h>
23
24#include "mpc8xx.h"
25
26struct cpm_pin {
27 int port, pin, flags;
28};
29
30static __initdata struct cpm_pin mgsuvd_pins[] = {
31 /* SMC1 */
32 {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
33 {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
34
35 /* SCC3 */
36 {CPM_PORTA, 10, CPM_PIN_INPUT},
37 {CPM_PORTA, 11, CPM_PIN_INPUT},
38 {CPM_PORTA, 3, CPM_PIN_INPUT},
39 {CPM_PORTA, 2, CPM_PIN_INPUT},
40 {CPM_PORTC, 13, CPM_PIN_INPUT},
41};
42
43static void __init init_ioports(void)
44{
45 int i;
46
47 for (i = 0; i < ARRAY_SIZE(mgsuvd_pins); i++) {
48 struct cpm_pin *pin = &mgsuvd_pins[i];
49 cpm1_set_pin(pin->port, pin->pin, pin->flags);
50 }
51
52 setbits16(&mpc8xx_immr->im_ioport.iop_pcso, 0x300);
53 cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK5, CPM_CLK_RX);
54 cpm1_clk_setup(CPM_CLK_SCC3, CPM_CLK6, CPM_CLK_TX);
55 cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
56}
57
58static void __init mgsuvd_setup_arch(void)
59{
60 cpm_reset();
61 init_ioports();
62}
63
64static __initdata struct of_device_id of_bus_ids[] = {
65 { .compatible = "simple-bus" },
66 {},
67};
68
69static int __init declare_of_platform_devices(void)
70{
71 of_platform_bus_probe(NULL, of_bus_ids, NULL);
72 return 0;
73}
74machine_device_initcall(mgsuvd, declare_of_platform_devices);
75
76static int __init mgsuvd_probe(void)
77{
78 unsigned long root = of_get_flat_dt_root();
79 return of_flat_dt_is_compatible(root, "keymile,mgsuvd");
80}
81
82define_machine(mgsuvd) {
83 .name = "MGSUVD",
84 .probe = mgsuvd_probe,
85 .setup_arch = mgsuvd_setup_arch,
86 .init_IRQ = mpc8xx_pics_init,
87 .get_irq = mpc8xx_get_irq,
88 .restart = mpc8xx_restart,
89 .calibrate_decr = mpc8xx_calibrate_decr,
90 .set_rtc_time = mpc8xx_set_rtc_time,
91 .get_rtc_time = mpc8xx_get_rtc_time,
92};
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 4c900efa164e..47e956c871fe 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -239,7 +239,8 @@ config TAU_AVERAGE
239 If in doubt, say N here. 239 If in doubt, say N here.
240 240
241config QUICC_ENGINE 241config QUICC_ENGINE
242 bool 242 bool "Freescale QUICC Engine (QE) Support"
243 depends on FSL_SOC
243 select PPC_LIB_RHEAP 244 select PPC_LIB_RHEAP
244 select CRC32 245 select CRC32
245 help 246 help
@@ -248,6 +249,15 @@ config QUICC_ENGINE
248 Selecting this option means that you wish to build a kernel 249 Selecting this option means that you wish to build a kernel
249 for a machine with a QE coprocessor. 250 for a machine with a QE coprocessor.
250 251
252config QE_GPIO
253 bool "QE GPIO support"
254 depends on QUICC_ENGINE
255 select GENERIC_GPIO
256 select ARCH_REQUIRE_GPIOLIB
257 help
258 Say Y here if you're going to use hardware that connects to the
259 QE GPIOs.
260
251config CPM2 261config CPM2
252 bool "Enable support for the CPM2 (Communications Processor Module)" 262 bool "Enable support for the CPM2 (Communications Processor Module)"
253 depends on MPC85xx || 8260 263 depends on MPC85xx || 8260
@@ -293,4 +303,13 @@ config OF_RTC
293 303
294source "arch/powerpc/sysdev/bestcomm/Kconfig" 304source "arch/powerpc/sysdev/bestcomm/Kconfig"
295 305
306config MPC8xxx_GPIO
307 bool "MPC8xxx GPIO support"
308 depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || PPC_85xx || PPC_86xx
309 select GENERIC_GPIO
310 select ARCH_REQUIRE_GPIOLIB
311 help
312 Say Y here if you're going to use hardware that connects to the
313 MPC831x/834x/837x/8572/8610 GPIOs.
314
296endmenu 315endmenu
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 7f6512733862..439c5ba34ecf 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -50,6 +50,7 @@ config 44x
50 select PPC_UDBG_16550 50 select PPC_UDBG_16550
51 select 4xx_SOC 51 select 4xx_SOC
52 select PPC_PCI_CHOICE 52 select PPC_PCI_CHOICE
53 select PHYS_64BIT
53 54
54config E200 55config E200
55 bool "Freescale e200" 56 bool "Freescale e200"
@@ -128,18 +129,20 @@ config FSL_EMB_PERFMON
128 129
129config PTE_64BIT 130config PTE_64BIT
130 bool 131 bool
131 depends on 44x || E500 132 depends on 44x || E500 || PPC_86xx
132 default y if 44x 133 default y if PHYS_64BIT
133 default y if E500 && PHYS_64BIT
134 134
135config PHYS_64BIT 135config PHYS_64BIT
136 bool 'Large physical address support' if E500 136 bool 'Large physical address support' if E500 || PPC_86xx
137 depends on 44x || E500 137 depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx
138 select RESOURCES_64BIT 138 select RESOURCES_64BIT
139 default y if 44x
140 ---help--- 139 ---help---
141 This option enables kernel support for larger than 32-bit physical 140 This option enables kernel support for larger than 32-bit physical
142 addresses. This features is not be available on all e500 cores. 141 addresses. This feature may not be available on all cores.
142
143 If you have more than 3.5GB of RAM or so, you also need to enable
144 SWIOTLB under Kernel Options for this to work. The actual number
145 is platform-dependent.
143 146
144 If in doubt, say N here. 147 If in doubt, say N here.
145 148
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index e06420af5fe9..ef92e7146215 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -556,11 +556,11 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
556 * node's iommu. We -might- do something smarter later though it may 556 * node's iommu. We -might- do something smarter later though it may
557 * never be necessary 557 * never be necessary
558 */ 558 */
559 iommu = cell_iommu_for_node(archdata->numa_node); 559 iommu = cell_iommu_for_node(dev_to_node(dev));
560 if (iommu == NULL || list_empty(&iommu->windows)) { 560 if (iommu == NULL || list_empty(&iommu->windows)) {
561 printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", 561 printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
562 archdata->of_node ? archdata->of_node->full_name : "?", 562 archdata->of_node ? archdata->of_node->full_name : "?",
563 archdata->numa_node); 563 dev_to_node(dev));
564 return NULL; 564 return NULL;
565 } 565 }
566 window = list_entry(iommu->windows.next, struct iommu_window, list); 566 window = list_entry(iommu->windows.next, struct iommu_window, list);
@@ -577,7 +577,7 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
577 return iommu_alloc_coherent(dev, cell_get_iommu_table(dev), 577 return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
578 size, dma_handle, 578 size, dma_handle,
579 device_to_mask(dev), flag, 579 device_to_mask(dev), flag,
580 dev->archdata.numa_node); 580 dev_to_node(dev));
581 else 581 else
582 return dma_direct_ops.alloc_coherent(dev, size, dma_handle, 582 return dma_direct_ops.alloc_coherent(dev, size, dma_handle,
583 flag); 583 flag);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 2c8b8091250f..cb85d237e492 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -298,8 +298,8 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
298 298
299 d_instantiate(dentry, inode); 299 d_instantiate(dentry, inode);
300 dget(dentry); 300 dget(dentry);
301 dir->i_nlink++; 301 inc_nlink(dir);
302 dentry->d_inode->i_nlink++; 302 inc_nlink(dentry->d_inode);
303 goto out; 303 goto out;
304 304
305out_free_ctx: 305out_free_ctx:
@@ -496,6 +496,8 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
496 ret = spufs_context_open(dget(dentry), mntget(mnt)); 496 ret = spufs_context_open(dget(dentry), mntget(mnt));
497 if (ret < 0) { 497 if (ret < 0) {
498 WARN_ON(spufs_rmdir(inode, dentry)); 498 WARN_ON(spufs_rmdir(inode, dentry));
499 if (affinity)
500 mutex_unlock(&gang->aff_mutex);
499 mutex_unlock(&inode->i_mutex); 501 mutex_unlock(&inode->i_mutex);
500 spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); 502 spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
501 goto out; 503 goto out;
@@ -538,8 +540,8 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
538 inode->i_fop = &simple_dir_operations; 540 inode->i_fop = &simple_dir_operations;
539 541
540 d_instantiate(dentry, inode); 542 d_instantiate(dentry, inode);
541 dir->i_nlink++; 543 inc_nlink(dir);
542 dentry->d_inode->i_nlink++; 544 inc_nlink(dentry->d_inode);
543 return ret; 545 return ret;
544 546
545out_iput: 547out_iput:
@@ -755,6 +757,7 @@ spufs_create_root(struct super_block *sb, void *data)
755 inode->i_op = &simple_dir_inode_operations; 757 inode->i_op = &simple_dir_inode_operations;
756 inode->i_fop = &simple_dir_operations; 758 inode->i_fop = &simple_dir_operations;
757 SPUFS_I(inode)->i_ctx = NULL; 759 SPUFS_I(inode)->i_ctx = NULL;
760 inc_nlink(inode);
758 761
759 ret = -EINVAL; 762 ret = -EINVAL;
760 if (!spufs_parse_options(sb, data, inode)) 763 if (!spufs_parse_options(sb, data, inode))
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 768c262b9368..d3cde6b9d2df 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -260,13 +260,13 @@ chrp_find_bridges(void)
260 dev->full_name); 260 dev->full_name);
261 continue; 261 continue;
262 } 262 }
263 hose->first_busno = bus_range[0]; 263 hose->first_busno = hose->self_busno = bus_range[0];
264 hose->last_busno = bus_range[1]; 264 hose->last_busno = bus_range[1];
265 265
266 model = of_get_property(dev, "model", NULL); 266 model = of_get_property(dev, "model", NULL);
267 if (model == NULL) 267 if (model == NULL)
268 model = "<none>"; 268 model = "<none>";
269 if (of_device_is_compatible(dev, "IBM,python")) { 269 if (strncmp(model, "IBM, Python", 11) == 0) {
270 setup_python(hose, dev); 270 setup_python(hose, dev);
271 } else if (is_mot 271 } else if (is_mot
272 || strncmp(model, "Motorola, Grackle", 17) == 0) { 272 || strncmp(model, "Motorola, Grackle", 17) == 0) {
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index 96d1e4b3c493..054dfe5b8e77 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -94,12 +94,12 @@ int chrp_set_rtc_time(struct rtc_time *tmarg)
94 chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 94 chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
95 95
96 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 96 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
97 BIN_TO_BCD(tm.tm_sec); 97 tm.tm_sec = bin2bcd(tm.tm_sec);
98 BIN_TO_BCD(tm.tm_min); 98 tm.tm_min = bin2bcd(tm.tm_min);
99 BIN_TO_BCD(tm.tm_hour); 99 tm.tm_hour = bin2bcd(tm.tm_hour);
100 BIN_TO_BCD(tm.tm_mon); 100 tm.tm_mon = bin2bcd(tm.tm_mon);
101 BIN_TO_BCD(tm.tm_mday); 101 tm.tm_mday = bin2bcd(tm.tm_mday);
102 BIN_TO_BCD(tm.tm_year); 102 tm.tm_year = bin2bcd(tm.tm_year);
103 } 103 }
104 chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS); 104 chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
105 chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES); 105 chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
@@ -136,12 +136,12 @@ void chrp_get_rtc_time(struct rtc_time *tm)
136 } while (sec != chrp_cmos_clock_read(RTC_SECONDS)); 136 } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
137 137
138 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 138 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
139 BCD_TO_BIN(sec); 139 sec = bcd2bin(sec);
140 BCD_TO_BIN(min); 140 min = bcd2bin(min);
141 BCD_TO_BIN(hour); 141 hour = bcd2bin(hour);
142 BCD_TO_BIN(day); 142 day = bcd2bin(day);
143 BCD_TO_BIN(mon); 143 mon = bcd2bin(mon);
144 BCD_TO_BIN(year); 144 year = bcd2bin(year);
145 } 145 }
146 if (year < 70) 146 if (year < 70)
147 year += 100; 147 year += 100;
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 84e2d78b9a62..7a2ba39d7811 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -164,7 +164,6 @@ static void __init mpc7448_hpc2_init_IRQ(void)
164void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) 164void mpc7448_hpc2_show_cpuinfo(struct seq_file *m)
165{ 165{
166 seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); 166 seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
167 seq_printf(m, "machine\t\t: MPC7448hpc2\n");
168} 167}
169 168
170void mpc7448_hpc2_restart(char *cmd) 169void mpc7448_hpc2_restart(char *cmd)
diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S
index 8ff330d026ca..2f581521eb9b 100644
--- a/arch/powerpc/platforms/iseries/exception.S
+++ b/arch/powerpc/platforms/iseries/exception.S
@@ -38,12 +38,13 @@
38 38
39 .globl system_reset_iSeries 39 .globl system_reset_iSeries
40system_reset_iSeries: 40system_reset_iSeries:
41 bl .relative_toc
41 mfspr r13,SPRN_SPRG3 /* Get alpaca address */ 42 mfspr r13,SPRN_SPRG3 /* Get alpaca address */
42 LOAD_REG_IMMEDIATE(r23, alpaca) 43 LOAD_REG_ADDR(r23, alpaca)
43 li r0,ALPACA_SIZE 44 li r0,ALPACA_SIZE
44 sub r23,r13,r23 45 sub r23,r13,r23
45 divdu r23,r23,r0 /* r23 has cpu number */ 46 divdu r23,r23,r0 /* r23 has cpu number */
46 LOAD_REG_IMMEDIATE(r13, paca) 47 LOAD_REG_ADDR(r13, paca)
47 mulli r0,r23,PACA_SIZE 48 mulli r0,r23,PACA_SIZE
48 add r13,r13,r0 49 add r13,r13,r0
49 mtspr SPRN_SPRG3,r13 /* Save it away for the future */ 50 mtspr SPRN_SPRG3,r13 /* Save it away for the future */
@@ -60,14 +61,14 @@ system_reset_iSeries:
60 mtspr SPRN_CTRLT,r4 61 mtspr SPRN_CTRLT,r4
61 62
62/* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */ 63/* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */
63/* In the UP case we'll yeild() later, and we will not access the paca anyway */ 64/* In the UP case we'll yield() later, and we will not access the paca anyway */
64#ifdef CONFIG_SMP 65#ifdef CONFIG_SMP
651: 661:
66 HMT_LOW 67 HMT_LOW
67 LOAD_REG_IMMEDIATE(r23, __secondary_hold_spinloop) 68 LOAD_REG_ADDR(r23, __secondary_hold_spinloop)
68 ld r23,0(r23) 69 ld r23,0(r23)
69 sync 70 sync
70 LOAD_REG_IMMEDIATE(r3,current_set) 71 LOAD_REG_ADDR(r3,current_set)
71 sldi r28,r24,3 /* get current_set[cpu#] */ 72 sldi r28,r24,3 /* get current_set[cpu#] */
72 ldx r3,r3,r28 73 ldx r3,r3,r28
73 addi r1,r3,THREAD_SIZE 74 addi r1,r3,THREAD_SIZE
@@ -90,7 +91,7 @@ system_reset_iSeries:
90 lbz r23,PACAPROCSTART(r13) /* Test if this processor 91 lbz r23,PACAPROCSTART(r13) /* Test if this processor
91 * should start */ 92 * should start */
92 sync 93 sync
93 LOAD_REG_IMMEDIATE(r3,current_set) 94 LOAD_REG_ADDR(r3,current_set)
94 sldi r28,r24,3 /* get current_set[cpu#] */ 95 sldi r28,r24,3 /* get current_set[cpu#] */
95 ldx r3,r3,r28 96 ldx r3,r3,r28
96 addi r1,r3,THREAD_SIZE 97 addi r1,r3,THREAD_SIZE
@@ -255,8 +256,8 @@ hardware_interrupt_iSeries_masked:
255 256
256_INIT_STATIC(__start_initialization_iSeries) 257_INIT_STATIC(__start_initialization_iSeries)
257 /* Clear out the BSS */ 258 /* Clear out the BSS */
258 LOAD_REG_IMMEDIATE(r11,__bss_stop) 259 LOAD_REG_ADDR(r11,__bss_stop)
259 LOAD_REG_IMMEDIATE(r8,__bss_start) 260 LOAD_REG_ADDR(r8,__bss_start)
260 sub r11,r11,r8 /* bss size */ 261 sub r11,r11,r8 /* bss size */
261 addi r11,r11,7 /* round up to an even double word */ 262 addi r11,r11,7 /* round up to an even double word */
262 rldicl. r11,r11,61,3 /* shift right by 3 */ 263 rldicl. r11,r11,61,3 /* shift right by 3 */
@@ -267,15 +268,11 @@ _INIT_STATIC(__start_initialization_iSeries)
2673: stdu r0,8(r8) 2683: stdu r0,8(r8)
268 bdnz 3b 269 bdnz 3b
2694: 2704:
270 LOAD_REG_IMMEDIATE(r1,init_thread_union) 271 LOAD_REG_ADDR(r1,init_thread_union)
271 addi r1,r1,THREAD_SIZE 272 addi r1,r1,THREAD_SIZE
272 li r0,0 273 li r0,0
273 stdu r0,-STACK_FRAME_OVERHEAD(r1) 274 stdu r0,-STACK_FRAME_OVERHEAD(r1)
274 275
275 LOAD_REG_IMMEDIATE(r2,__toc_start)
276 addi r2,r2,0x4000
277 addi r2,r2,0x4000
278
279 bl .iSeries_early_setup 276 bl .iSeries_early_setup
280 bl .early_setup 277 bl .early_setup
281 278
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 731d7b157749..3689c2413d24 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -722,13 +722,13 @@ static int mf_set_rtc(struct rtc_time *tm)
722 day = tm->tm_mday; 722 day = tm->tm_mday;
723 mon = tm->tm_mon + 1; 723 mon = tm->tm_mon + 1;
724 724
725 BIN_TO_BCD(sec); 725 sec = bin2bcd(sec);
726 BIN_TO_BCD(min); 726 min = bin2bcd(min);
727 BIN_TO_BCD(hour); 727 hour = bin2bcd(hour);
728 BIN_TO_BCD(mon); 728 mon = bin2bcd(mon);
729 BIN_TO_BCD(day); 729 day = bin2bcd(day);
730 BIN_TO_BCD(y1); 730 y1 = bin2bcd(y1);
731 BIN_TO_BCD(y2); 731 y2 = bin2bcd(y2);
732 732
733 memset(ce_time, 0, sizeof(ce_time)); 733 memset(ce_time, 0, sizeof(ce_time));
734 ce_time[3] = 0x41; 734 ce_time[3] = 0x41;
@@ -777,12 +777,12 @@ static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
777 u8 day = ce_msg[10]; 777 u8 day = ce_msg[10];
778 u8 mon = ce_msg[11]; 778 u8 mon = ce_msg[11];
779 779
780 BCD_TO_BIN(sec); 780 sec = bcd2bin(sec);
781 BCD_TO_BIN(min); 781 min = bcd2bin(min);
782 BCD_TO_BIN(hour); 782 hour = bcd2bin(hour);
783 BCD_TO_BIN(day); 783 day = bcd2bin(day);
784 BCD_TO_BIN(mon); 784 mon = bcd2bin(mon);
785 BCD_TO_BIN(year); 785 year = bcd2bin(year);
786 786
787 if (year <= 69) 787 if (year <= 69)
788 year += 100; 788 year += 100;
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 53bca132fb48..eac569dee27c 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -68,12 +68,12 @@ void maple_get_rtc_time(struct rtc_time *tm)
68 68
69 if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY) 69 if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
70 || RTC_ALWAYS_BCD) { 70 || RTC_ALWAYS_BCD) {
71 BCD_TO_BIN(tm->tm_sec); 71 tm->tm_sec = bcd2bin(tm->tm_sec);
72 BCD_TO_BIN(tm->tm_min); 72 tm->tm_min = bcd2bin(tm->tm_min);
73 BCD_TO_BIN(tm->tm_hour); 73 tm->tm_hour = bcd2bin(tm->tm_hour);
74 BCD_TO_BIN(tm->tm_mday); 74 tm->tm_mday = bcd2bin(tm->tm_mday);
75 BCD_TO_BIN(tm->tm_mon); 75 tm->tm_mon = bcd2bin(tm->tm_mon);
76 BCD_TO_BIN(tm->tm_year); 76 tm->tm_year = bcd2bin(tm->tm_year);
77 } 77 }
78 if ((tm->tm_year + 1900) < 1970) 78 if ((tm->tm_year + 1900) < 1970)
79 tm->tm_year += 100; 79 tm->tm_year += 100;
@@ -104,12 +104,12 @@ int maple_set_rtc_time(struct rtc_time *tm)
104 year = tm->tm_year; 104 year = tm->tm_year;
105 105
106 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 106 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
107 BIN_TO_BCD(sec); 107 sec = bin2bcd(sec);
108 BIN_TO_BCD(min); 108 min = bin2bcd(min);
109 BIN_TO_BCD(hour); 109 hour = bin2bcd(hour);
110 BIN_TO_BCD(mon); 110 mon = bin2bcd(mon);
111 BIN_TO_BCD(mday); 111 mday = bin2bcd(mday);
112 BIN_TO_BCD(year); 112 year = bin2bcd(year);
113 } 113 }
114 maple_clock_write(sec, RTC_SECONDS); 114 maple_clock_write(sec, RTC_SECONDS);
115 maple_clock_write(min, RTC_MINUTES); 115 maple_clock_write(min, RTC_MINUTES);
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 5169ecc37123..e6c0040ee797 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2677,7 +2677,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2677 macio_chips[i].of_node = node; 2677 macio_chips[i].of_node = node;
2678 macio_chips[i].type = type; 2678 macio_chips[i].type = type;
2679 macio_chips[i].base = base; 2679 macio_chips[i].base = base;
2680 macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; 2680 macio_chips[i].flags = MACIO_FLAG_SCCA_ON | MACIO_FLAG_SCCB_ON;
2681 macio_chips[i].name = macio_names[type]; 2681 macio_chips[i].name = macio_names[type];
2682 revp = of_get_property(node, "revision-id", NULL); 2682 revp = of_get_property(node, "revision-id", NULL);
2683 if (revp) 2683 if (revp)
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 4ae3d00e0bdd..40f72c2a4699 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -787,7 +787,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
787{ 787{
788 unsigned int save_vector; 788 unsigned int save_vector;
789 unsigned long target, flags; 789 unsigned long target, flags;
790 unsigned int *vector = (unsigned int *)(KERNELBASE+0x100); 790 unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
791 791
792 if (nr < 0 || nr > 3) 792 if (nr < 0 || nr > 3)
793 return; 793 return;
@@ -801,7 +801,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
801 save_vector = *vector; 801 save_vector = *vector;
802 802
803 /* Setup fake reset vector that does 803 /* Setup fake reset vector that does
804 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE 804 * b __secondary_start_pmac_0 + nr*8
805 */ 805 */
806 target = (unsigned long) __secondary_start_pmac_0 + nr * 8; 806 target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
807 patch_branch(vector, target, BRANCH_SET_LINK); 807 patch_branch(vector, target, BRANCH_SET_LINK);
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index bbbefd64ab59..59eb840d8ce2 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -93,11 +93,14 @@ static void to_rtc_time(unsigned long now, struct rtc_time *tm)
93} 93}
94#endif 94#endif
95 95
96#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) || \
97 defined(CONFIG_PMAC_SMU)
96static unsigned long from_rtc_time(struct rtc_time *tm) 98static unsigned long from_rtc_time(struct rtc_time *tm)
97{ 99{
98 return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 100 return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
99 tm->tm_hour, tm->tm_min, tm->tm_sec); 101 tm->tm_hour, tm->tm_min, tm->tm_sec);
100} 102}
103#endif
101 104
102#ifdef CONFIG_ADB_CUDA 105#ifdef CONFIG_ADB_CUDA
103static unsigned long cuda_get_time(void) 106static unsigned long cuda_get_time(void)
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 280ee88cb0b0..a789bf58ca8b 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -762,7 +762,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
762 }; 762 };
763 763
764 dev->core.archdata.of_node = NULL; 764 dev->core.archdata.of_node = NULL;
765 dev->core.archdata.numa_node = 0; 765 set_dev_node(&dev->core, 0);
766 766
767 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); 767 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
768 768
diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
index 38fe32a7cc70..5cd4d2761620 100644
--- a/arch/powerpc/platforms/pseries/cmm.c
+++ b/arch/powerpc/platforms/pseries/cmm.c
@@ -121,7 +121,7 @@ static long cmm_alloc_pages(long nr)
121 npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN | 121 npa = (struct cmm_page_array *)__get_free_page(GFP_NOIO | __GFP_NOWARN |
122 __GFP_NORETRY | __GFP_NOMEMALLOC); 122 __GFP_NORETRY | __GFP_NOMEMALLOC);
123 if (!npa) { 123 if (!npa) {
124 pr_info("%s: Can not allocate new page list\n", __FUNCTION__); 124 pr_info("%s: Can not allocate new page list\n", __func__);
125 free_page(addr); 125 free_page(addr);
126 break; 126 break;
127 } 127 }
@@ -138,7 +138,7 @@ static long cmm_alloc_pages(long nr)
138 } 138 }
139 139
140 if ((rc = plpar_page_set_loaned(__pa(addr)))) { 140 if ((rc = plpar_page_set_loaned(__pa(addr)))) {
141 pr_err("%s: Can not set page to loaned. rc=%ld\n", __FUNCTION__, rc); 141 pr_err("%s: Can not set page to loaned. rc=%ld\n", __func__, rc);
142 spin_unlock(&cmm_lock); 142 spin_unlock(&cmm_lock);
143 free_page(addr); 143 free_page(addr);
144 break; 144 break;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 8c1ca477c52c..0ad56ff7b4a0 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -41,7 +41,7 @@ static inline const char * pcid_name (struct pci_dev *pdev)
41 return ""; 41 return "";
42} 42}
43 43
44#ifdef DEBUG 44#if 0
45static void print_device_node_tree(struct pci_dn *pdn, int dent) 45static void print_device_node_tree(struct pci_dn *pdn, int dent)
46{ 46{
47 int i; 47 int i;
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index a1a368dd2d99..140d02a5232a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -21,7 +21,7 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
21 struct zone *zone; 21 struct zone *zone;
22 int ret; 22 int ret;
23 23
24 start_pfn = base >> PFN_SECTION_SHIFT; 24 start_pfn = base >> PAGE_SHIFT;
25 zone = page_zone(pfn_to_page(start_pfn)); 25 zone = page_zone(pfn_to_page(start_pfn));
26 26
27 /* 27 /*
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 7637bd38c795..c591a25b0b0d 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -466,11 +466,11 @@ static int do_update_property(char *buf, size_t bufsize)
466 else 466 else
467 action = PSERIES_DRCONF_MEM_REMOVE; 467 action = PSERIES_DRCONF_MEM_REMOVE;
468 468
469 blocking_notifier_call_chain(&pSeries_reconfig_chain, 469 rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
470 action, value); 470 action, value);
471 } 471 }
472 472
473 return 0; 473 return rc;
474} 474}
475 475
476/** 476/**
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index c9ffd8c225f1..f4e55be2eea9 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -295,19 +295,29 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf,
295 if (!tmp) 295 if (!tmp)
296 return -ENOMEM; 296 return -ENOMEM;
297 297
298
299 spin_lock_irqsave(&rtasd_log_lock, s); 298 spin_lock_irqsave(&rtasd_log_lock, s);
300 /* if it's 0, then we know we got the last one (the one in NVRAM) */ 299 /* if it's 0, then we know we got the last one (the one in NVRAM) */
301 if (rtas_log_size == 0 && logging_enabled) 300 while (rtas_log_size == 0) {
302 nvram_clear_error_log(); 301 if (file->f_flags & O_NONBLOCK) {
303 spin_unlock_irqrestore(&rtasd_log_lock, s); 302 spin_unlock_irqrestore(&rtasd_log_lock, s);
303 error = -EAGAIN;
304 goto out;
305 }
304 306
307 if (!logging_enabled) {
308 spin_unlock_irqrestore(&rtasd_log_lock, s);
309 error = -ENODATA;
310 goto out;
311 }
312 nvram_clear_error_log();
305 313
306 error = wait_event_interruptible(rtas_log_wait, rtas_log_size); 314 spin_unlock_irqrestore(&rtasd_log_lock, s);
307 if (error) 315 error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
308 goto out; 316 if (error)
317 goto out;
318 spin_lock_irqsave(&rtasd_log_lock, s);
319 }
309 320
310 spin_lock_irqsave(&rtasd_log_lock, s);
311 offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); 321 offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
312 memcpy(tmp, &rtas_log_buf[offset], count); 322 memcpy(tmp, &rtas_log_buf[offset], count);
313 323
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 9d8f8c84ab89..e00f96baa381 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -37,7 +37,6 @@
37#include <asm/paca.h> 37#include <asm/paca.h>
38#include <asm/time.h> 38#include <asm/time.h>
39#include <asm/machdep.h> 39#include <asm/machdep.h>
40#include "xics.h"
41#include <asm/cputable.h> 40#include <asm/cputable.h>
42#include <asm/firmware.h> 41#include <asm/firmware.h>
43#include <asm/system.h> 42#include <asm/system.h>
@@ -49,6 +48,7 @@
49 48
50#include "plpar_wrappers.h" 49#include "plpar_wrappers.h"
51#include "pseries.h" 50#include "pseries.h"
51#include "xics.h"
52 52
53 53
54/* 54/*
@@ -105,36 +105,6 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
105} 105}
106 106
107#ifdef CONFIG_XICS 107#ifdef CONFIG_XICS
108static inline void smp_xics_do_message(int cpu, int msg)
109{
110 set_bit(msg, &xics_ipi_message[cpu].value);
111 mb();
112 xics_cause_IPI(cpu);
113}
114
115static void smp_xics_message_pass(int target, int msg)
116{
117 unsigned int i;
118
119 if (target < NR_CPUS) {
120 smp_xics_do_message(target, msg);
121 } else {
122 for_each_online_cpu(i) {
123 if (target == MSG_ALL_BUT_SELF
124 && i == smp_processor_id())
125 continue;
126 smp_xics_do_message(i, msg);
127 }
128 }
129}
130
131static int __init smp_xics_probe(void)
132{
133 xics_request_IPIs();
134
135 return cpus_weight(cpu_possible_map);
136}
137
138static void __devinit smp_xics_setup_cpu(int cpu) 108static void __devinit smp_xics_setup_cpu(int cpu)
139{ 109{
140 if (cpu != boot_cpuid) 110 if (cpu != boot_cpuid)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 0fc830f576f5..e1904774a70f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -9,32 +9,30 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12
13#include <linux/types.h> 12#include <linux/types.h>
14#include <linux/threads.h> 13#include <linux/threads.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/irq.h> 15#include <linux/irq.h>
17#include <linux/smp.h> 16#include <linux/smp.h>
18#include <linux/interrupt.h> 17#include <linux/interrupt.h>
19#include <linux/signal.h>
20#include <linux/init.h> 18#include <linux/init.h>
21#include <linux/gfp.h>
22#include <linux/radix-tree.h> 19#include <linux/radix-tree.h>
23#include <linux/cpu.h> 20#include <linux/cpu.h>
21#include <linux/of.h>
24 22
25#include <asm/firmware.h> 23#include <asm/firmware.h>
26#include <asm/prom.h>
27#include <asm/io.h> 24#include <asm/io.h>
28#include <asm/pgtable.h> 25#include <asm/pgtable.h>
29#include <asm/smp.h> 26#include <asm/smp.h>
30#include <asm/rtas.h> 27#include <asm/rtas.h>
31#include <asm/hvcall.h> 28#include <asm/hvcall.h>
32#include <asm/machdep.h> 29#include <asm/machdep.h>
33#include <asm/i8259.h>
34 30
35#include "xics.h" 31#include "xics.h"
36#include "plpar_wrappers.h" 32#include "plpar_wrappers.h"
37 33
34static struct irq_host *xics_host;
35
38#define XICS_IPI 2 36#define XICS_IPI 2
39#define XICS_IRQ_SPURIOUS 0 37#define XICS_IRQ_SPURIOUS 0
40 38
@@ -47,6 +45,20 @@
47 */ 45 */
48#define IPI_PRIORITY 4 46#define IPI_PRIORITY 4
49 47
48static unsigned int default_server = 0xFF;
49static unsigned int default_distrib_server = 0;
50static unsigned int interrupt_server_size = 8;
51
52/* RTAS service tokens */
53static int ibm_get_xive;
54static int ibm_set_xive;
55static int ibm_int_on;
56static int ibm_int_off;
57
58
59/* Direct hardware low level accessors */
60
61/* The part of the interrupt presentation layer that we care about */
50struct xics_ipl { 62struct xics_ipl {
51 union { 63 union {
52 u32 word; 64 u32 word;
@@ -65,27 +77,6 @@ struct xics_ipl {
65 77
66static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; 78static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
67 79
68static unsigned int default_server = 0xFF;
69static unsigned int default_distrib_server = 0;
70static unsigned int interrupt_server_size = 8;
71
72static struct irq_host *xics_host;
73
74/*
75 * XICS only has a single IPI, so encode the messages per CPU
76 */
77struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
78
79/* RTAS service tokens */
80static int ibm_get_xive;
81static int ibm_set_xive;
82static int ibm_int_on;
83static int ibm_int_off;
84
85
86/* Direct HW low level accessors */
87
88
89static inline unsigned int direct_xirr_info_get(void) 80static inline unsigned int direct_xirr_info_get(void)
90{ 81{
91 int cpu = smp_processor_id(); 82 int cpu = smp_processor_id();
@@ -93,7 +84,7 @@ static inline unsigned int direct_xirr_info_get(void)
93 return in_be32(&xics_per_cpu[cpu]->xirr.word); 84 return in_be32(&xics_per_cpu[cpu]->xirr.word);
94} 85}
95 86
96static inline void direct_xirr_info_set(int value) 87static inline void direct_xirr_info_set(unsigned int value)
97{ 88{
98 int cpu = smp_processor_id(); 89 int cpu = smp_processor_id();
99 90
@@ -115,7 +106,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
115 106
116/* LPAR low level accessors */ 107/* LPAR low level accessors */
117 108
118
119static inline unsigned int lpar_xirr_info_get(void) 109static inline unsigned int lpar_xirr_info_get(void)
120{ 110{
121 unsigned long lpar_rc; 111 unsigned long lpar_rc;
@@ -127,15 +117,14 @@ static inline unsigned int lpar_xirr_info_get(void)
127 return (unsigned int)return_value; 117 return (unsigned int)return_value;
128} 118}
129 119
130static inline void lpar_xirr_info_set(int value) 120static inline void lpar_xirr_info_set(unsigned int value)
131{ 121{
132 unsigned long lpar_rc; 122 unsigned long lpar_rc;
133 unsigned long val64 = value & 0xffffffff;
134 123
135 lpar_rc = plpar_eoi(val64); 124 lpar_rc = plpar_eoi(value);
136 if (lpar_rc != H_SUCCESS) 125 if (lpar_rc != H_SUCCESS)
137 panic("bad return code EOI - rc = %ld, value=%lx\n", lpar_rc, 126 panic("bad return code EOI - rc = %ld, value=%x\n", lpar_rc,
138 val64); 127 value);
139} 128}
140 129
141static inline void lpar_cppr_info(u8 value) 130static inline void lpar_cppr_info(u8 value)
@@ -157,48 +146,7 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
157} 146}
158 147
159 148
160/* High level handlers and init code */ 149/* Interface to generic irq subsystem */
161
162static void xics_update_irq_servers(void)
163{
164 int i, j;
165 struct device_node *np;
166 u32 ilen;
167 const u32 *ireg, *isize;
168 u32 hcpuid;
169
170 /* Find the server numbers for the boot cpu. */
171 np = of_get_cpu_node(boot_cpuid, NULL);
172 BUG_ON(!np);
173
174 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
175 if (!ireg) {
176 of_node_put(np);
177 return;
178 }
179
180 i = ilen / sizeof(int);
181 hcpuid = get_hard_smp_processor_id(boot_cpuid);
182
183 /* Global interrupt distribution server is specified in the last
184 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
185 * entry fom this property for current boot cpu id and use it as
186 * default distribution server
187 */
188 for (j = 0; j < i; j += 2) {
189 if (ireg[j] == hcpuid) {
190 default_server = hcpuid;
191 default_distrib_server = ireg[j+1];
192
193 isize = of_get_property(np,
194 "ibm,interrupt-server#-size", NULL);
195 if (isize)
196 interrupt_server_size = *isize;
197 }
198 }
199
200 of_node_put(np);
201}
202 150
203#ifdef CONFIG_SMP 151#ifdef CONFIG_SMP
204static int get_irq_server(unsigned int virq, unsigned int strict_check) 152static int get_irq_server(unsigned int virq, unsigned int strict_check)
@@ -208,9 +156,6 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
208 cpumask_t cpumask = irq_desc[virq].affinity; 156 cpumask_t cpumask = irq_desc[virq].affinity;
209 cpumask_t tmp = CPU_MASK_NONE; 157 cpumask_t tmp = CPU_MASK_NONE;
210 158
211 if (! cpu_isset(default_server, cpu_online_map))
212 xics_update_irq_servers();
213
214 if (!distribute_irqs) 159 if (!distribute_irqs)
215 return default_server; 160 return default_server;
216 161
@@ -238,7 +183,6 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
238} 183}
239#endif 184#endif
240 185
241
242static void xics_unmask_irq(unsigned int virq) 186static void xics_unmask_irq(unsigned int virq)
243{ 187{
244 unsigned int irq; 188 unsigned int irq;
@@ -257,21 +201,28 @@ static void xics_unmask_irq(unsigned int virq)
257 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 201 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
258 DEFAULT_PRIORITY); 202 DEFAULT_PRIORITY);
259 if (call_status != 0) { 203 if (call_status != 0) {
260 printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_set_xive " 204 printk(KERN_ERR
261 "returned %d\n", irq, call_status); 205 "%s: ibm_set_xive irq %u server %x returned %d\n",
262 printk("set_xive %x, server %x\n", ibm_set_xive, server); 206 __func__, irq, server, call_status);
263 return; 207 return;
264 } 208 }
265 209
266 /* Now unmask the interrupt (often a no-op) */ 210 /* Now unmask the interrupt (often a no-op) */
267 call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); 211 call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
268 if (call_status != 0) { 212 if (call_status != 0) {
269 printk(KERN_ERR "xics_enable_irq: irq=%u: ibm_int_on " 213 printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
270 "returned %d\n", irq, call_status); 214 __func__, irq, call_status);
271 return; 215 return;
272 } 216 }
273} 217}
274 218
219static unsigned int xics_startup(unsigned int virq)
220{
221 /* unmask it */
222 xics_unmask_irq(virq);
223 return 0;
224}
225
275static void xics_mask_real_irq(unsigned int irq) 226static void xics_mask_real_irq(unsigned int irq)
276{ 227{
277 int call_status; 228 int call_status;
@@ -281,8 +232,8 @@ static void xics_mask_real_irq(unsigned int irq)
281 232
282 call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); 233 call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
283 if (call_status != 0) { 234 if (call_status != 0) {
284 printk(KERN_ERR "xics_disable_real_irq: irq=%u: " 235 printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
285 "ibm_int_off returned %d\n", irq, call_status); 236 __func__, irq, call_status);
286 return; 237 return;
287 } 238 }
288 239
@@ -290,8 +241,8 @@ static void xics_mask_real_irq(unsigned int irq)
290 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, 241 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq,
291 default_server, 0xff); 242 default_server, 0xff);
292 if (call_status != 0) { 243 if (call_status != 0) {
293 printk(KERN_ERR "xics_disable_irq: irq=%u: ibm_set_xive(0xff)" 244 printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
294 " returned %d\n", irq, call_status); 245 __func__, irq, call_status);
295 return; 246 return;
296 } 247 }
297} 248}
@@ -308,132 +259,77 @@ static void xics_mask_irq(unsigned int virq)
308 xics_mask_real_irq(irq); 259 xics_mask_real_irq(irq);
309} 260}
310 261
311static unsigned int xics_startup(unsigned int virq) 262static void xics_mask_unknown_vec(unsigned int vec)
312{
313 unsigned int irq;
314
315 /* force a reverse mapping of the interrupt so it gets in the cache */
316 irq = (unsigned int)irq_map[virq].hwirq;
317 irq_radix_revmap(xics_host, irq);
318
319 /* unmask it */
320 xics_unmask_irq(virq);
321 return 0;
322}
323
324static void xics_eoi_direct(unsigned int virq)
325{ 263{
326 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 264 printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
327 265 xics_mask_real_irq(vec);
328 iosync();
329 direct_xirr_info_set((0xff << 24) | irq);
330} 266}
331 267
332 268static inline unsigned int xics_xirr_vector(unsigned int xirr)
333static void xics_eoi_lpar(unsigned int virq)
334{ 269{
335 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 270 /*
336 271 * The top byte is the old cppr, to be restored on EOI.
337 iosync(); 272 * The remaining 24 bits are the vector.
338 lpar_xirr_info_set((0xff << 24) | irq); 273 */
274 return xirr & 0x00ffffff;
339} 275}
340 276
341static inline unsigned int xics_remap_irq(unsigned int vec) 277static unsigned int xics_get_irq_direct(void)
342{ 278{
279 unsigned int xirr = direct_xirr_info_get();
280 unsigned int vec = xics_xirr_vector(xirr);
343 unsigned int irq; 281 unsigned int irq;
344 282
345 vec &= 0x00ffffff;
346
347 if (vec == XICS_IRQ_SPURIOUS) 283 if (vec == XICS_IRQ_SPURIOUS)
348 return NO_IRQ; 284 return NO_IRQ;
349 irq = irq_radix_revmap(xics_host, vec); 285
286 irq = irq_radix_revmap_lookup(xics_host, vec);
350 if (likely(irq != NO_IRQ)) 287 if (likely(irq != NO_IRQ))
351 return irq; 288 return irq;
352 289
353 printk(KERN_ERR "Interrupt %u (real) is invalid," 290 /* We don't have a linux mapping, so have rtas mask it. */
354 " disabling it.\n", vec); 291 xics_mask_unknown_vec(vec);
355 xics_mask_real_irq(vec);
356 return NO_IRQ;
357}
358 292
359static unsigned int xics_get_irq_direct(void) 293 /* We might learn about it later, so EOI it */
360{ 294 direct_xirr_info_set(xirr);
361 return xics_remap_irq(direct_xirr_info_get()); 295 return NO_IRQ;
362} 296}
363 297
364static unsigned int xics_get_irq_lpar(void) 298static unsigned int xics_get_irq_lpar(void)
365{ 299{
366 return xics_remap_irq(lpar_xirr_info_get()); 300 unsigned int xirr = lpar_xirr_info_get();
367} 301 unsigned int vec = xics_xirr_vector(xirr);
368 302 unsigned int irq;
369#ifdef CONFIG_SMP
370
371static irqreturn_t xics_ipi_dispatch(int cpu)
372{
373 WARN_ON(cpu_is_offline(cpu));
374 303
375 while (xics_ipi_message[cpu].value) { 304 if (vec == XICS_IRQ_SPURIOUS)
376 if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, 305 return NO_IRQ;
377 &xics_ipi_message[cpu].value)) {
378 mb();
379 smp_message_recv(PPC_MSG_CALL_FUNCTION);
380 }
381 if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
382 &xics_ipi_message[cpu].value)) {
383 mb();
384 smp_message_recv(PPC_MSG_RESCHEDULE);
385 }
386 if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
387 &xics_ipi_message[cpu].value)) {
388 mb();
389 smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
390 }
391#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
392 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
393 &xics_ipi_message[cpu].value)) {
394 mb();
395 smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
396 }
397#endif
398 }
399 return IRQ_HANDLED;
400}
401 306
402static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id) 307 irq = irq_radix_revmap_lookup(xics_host, vec);
403{ 308 if (likely(irq != NO_IRQ))
404 int cpu = smp_processor_id(); 309 return irq;
405 310
406 direct_qirr_info(cpu, 0xff); 311 /* We don't have a linux mapping, so have RTAS mask it. */
312 xics_mask_unknown_vec(vec);
407 313
408 return xics_ipi_dispatch(cpu); 314 /* We might learn about it later, so EOI it */
315 lpar_xirr_info_set(xirr);
316 return NO_IRQ;
409} 317}
410 318
411static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id) 319static void xics_eoi_direct(unsigned int virq)
412{ 320{
413 int cpu = smp_processor_id(); 321 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
414
415 lpar_qirr_info(cpu, 0xff);
416 322
417 return xics_ipi_dispatch(cpu); 323 iosync();
324 direct_xirr_info_set((0xff << 24) | irq);
418} 325}
419 326
420void xics_cause_IPI(int cpu) 327static void xics_eoi_lpar(unsigned int virq)
421{ 328{
422 if (firmware_has_feature(FW_FEATURE_LPAR)) 329 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
423 lpar_qirr_info(cpu, IPI_PRIORITY);
424 else
425 direct_qirr_info(cpu, IPI_PRIORITY);
426}
427
428#endif /* CONFIG_SMP */
429 330
430static void xics_set_cpu_priority(unsigned char cppr)
431{
432 if (firmware_has_feature(FW_FEATURE_LPAR))
433 lpar_cppr_info(cppr);
434 else
435 direct_cppr_info(cppr);
436 iosync(); 331 iosync();
332 lpar_xirr_info_set((0xff << 24) | irq);
437} 333}
438 334
439static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) 335static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
@@ -450,8 +346,8 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
450 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); 346 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
451 347
452 if (status) { 348 if (status) {
453 printk(KERN_ERR "xics_set_affinity: irq=%u ibm,get-xive " 349 printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
454 "returns %d\n", irq, status); 350 __func__, irq, status);
455 return; 351 return;
456 } 352 }
457 353
@@ -463,8 +359,9 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
463 if (irq_server == -1) { 359 if (irq_server == -1) {
464 char cpulist[128]; 360 char cpulist[128];
465 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); 361 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
466 printk(KERN_WARNING "xics_set_affinity: No online cpus in " 362 printk(KERN_WARNING
467 "the mask %s for irq %d\n", cpulist, virq); 363 "%s: No online cpus in the mask %s for irq %d\n",
364 __func__, cpulist, virq);
468 return; 365 return;
469 } 366 }
470 367
@@ -472,28 +369,12 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
472 irq, irq_server, xics_status[1]); 369 irq, irq_server, xics_status[1]);
473 370
474 if (status) { 371 if (status) {
475 printk(KERN_ERR "xics_set_affinity: irq=%u ibm,set-xive " 372 printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
476 "returns %d\n", irq, status); 373 __func__, irq, status);
477 return; 374 return;
478 } 375 }
479} 376}
480 377
481void xics_setup_cpu(void)
482{
483 xics_set_cpu_priority(0xff);
484
485 /*
486 * Put the calling processor into the GIQ. This is really only
487 * necessary from a secondary thread as the OF start-cpu interface
488 * performs this function for us on primary threads.
489 *
490 * XXX: undo of teardown on kexec needs this too, as may hotplug
491 */
492 rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
493 (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
494}
495
496
497static struct irq_chip xics_pic_direct = { 378static struct irq_chip xics_pic_direct = {
498 .typename = " XICS ", 379 .typename = " XICS ",
499 .startup = xics_startup, 380 .startup = xics_startup,
@@ -503,7 +384,6 @@ static struct irq_chip xics_pic_direct = {
503 .set_affinity = xics_set_affinity 384 .set_affinity = xics_set_affinity
504}; 385};
505 386
506
507static struct irq_chip xics_pic_lpar = { 387static struct irq_chip xics_pic_lpar = {
508 .typename = " XICS ", 388 .typename = " XICS ",
509 .startup = xics_startup, 389 .startup = xics_startup,
@@ -513,6 +393,9 @@ static struct irq_chip xics_pic_lpar = {
513 .set_affinity = xics_set_affinity 393 .set_affinity = xics_set_affinity
514}; 394};
515 395
396
397/* Interface to arch irq controller subsystem layer */
398
516/* Points to the irq_chip we're actually using */ 399/* Points to the irq_chip we're actually using */
517static struct irq_chip *xics_irq_chip; 400static struct irq_chip *xics_irq_chip;
518 401
@@ -530,6 +413,9 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
530{ 413{
531 pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw); 414 pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
532 415
416 /* Insert the interrupt mapping into the radix tree for fast lookup */
417 irq_radix_revmap_insert(xics_host, virq, hw);
418
533 get_irq_desc(virq)->status |= IRQ_LEVEL; 419 get_irq_desc(virq)->status |= IRQ_LEVEL;
534 set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq); 420 set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
535 return 0; 421 return 0;
@@ -569,10 +455,169 @@ static void __init xics_init_host(void)
569 irq_set_default_host(xics_host); 455 irq_set_default_host(xics_host);
570} 456}
571 457
458
459/* Inter-processor interrupt support */
460
461#ifdef CONFIG_SMP
462/*
463 * XICS only has a single IPI, so encode the messages per CPU
464 */
465struct xics_ipi_struct {
466 unsigned long value;
467 } ____cacheline_aligned;
468
469static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
470
471static inline void smp_xics_do_message(int cpu, int msg)
472{
473 set_bit(msg, &xics_ipi_message[cpu].value);
474 mb();
475 if (firmware_has_feature(FW_FEATURE_LPAR))
476 lpar_qirr_info(cpu, IPI_PRIORITY);
477 else
478 direct_qirr_info(cpu, IPI_PRIORITY);
479}
480
481void smp_xics_message_pass(int target, int msg)
482{
483 unsigned int i;
484
485 if (target < NR_CPUS) {
486 smp_xics_do_message(target, msg);
487 } else {
488 for_each_online_cpu(i) {
489 if (target == MSG_ALL_BUT_SELF
490 && i == smp_processor_id())
491 continue;
492 smp_xics_do_message(i, msg);
493 }
494 }
495}
496
497static irqreturn_t xics_ipi_dispatch(int cpu)
498{
499 WARN_ON(cpu_is_offline(cpu));
500
501 mb(); /* order mmio clearing qirr */
502 while (xics_ipi_message[cpu].value) {
503 if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION,
504 &xics_ipi_message[cpu].value)) {
505 smp_message_recv(PPC_MSG_CALL_FUNCTION);
506 }
507 if (test_and_clear_bit(PPC_MSG_RESCHEDULE,
508 &xics_ipi_message[cpu].value)) {
509 smp_message_recv(PPC_MSG_RESCHEDULE);
510 }
511 if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
512 &xics_ipi_message[cpu].value)) {
513 smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
514 }
515#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
516 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
517 &xics_ipi_message[cpu].value)) {
518 smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
519 }
520#endif
521 }
522 return IRQ_HANDLED;
523}
524
525static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id)
526{
527 int cpu = smp_processor_id();
528
529 direct_qirr_info(cpu, 0xff);
530
531 return xics_ipi_dispatch(cpu);
532}
533
534static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id)
535{
536 int cpu = smp_processor_id();
537
538 lpar_qirr_info(cpu, 0xff);
539
540 return xics_ipi_dispatch(cpu);
541}
542
543static void xics_request_ipi(void)
544{
545 unsigned int ipi;
546 int rc;
547
548 ipi = irq_create_mapping(xics_host, XICS_IPI);
549 BUG_ON(ipi == NO_IRQ);
550
551 /*
552 * IPIs are marked IRQF_DISABLED as they must run with irqs
553 * disabled
554 */
555 set_irq_handler(ipi, handle_percpu_irq);
556 if (firmware_has_feature(FW_FEATURE_LPAR))
557 rc = request_irq(ipi, xics_ipi_action_lpar,
558 IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
559 else
560 rc = request_irq(ipi, xics_ipi_action_direct,
561 IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
562 BUG_ON(rc);
563}
564
565int __init smp_xics_probe(void)
566{
567 xics_request_ipi();
568
569 return cpus_weight(cpu_possible_map);
570}
571
572#endif /* CONFIG_SMP */
573
574
575/* Initialization */
576
577static void xics_update_irq_servers(void)
578{
579 int i, j;
580 struct device_node *np;
581 u32 ilen;
582 const u32 *ireg, *isize;
583 u32 hcpuid;
584
585 /* Find the server numbers for the boot cpu. */
586 np = of_get_cpu_node(boot_cpuid, NULL);
587 BUG_ON(!np);
588
589 ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
590 if (!ireg) {
591 of_node_put(np);
592 return;
593 }
594
595 i = ilen / sizeof(int);
596 hcpuid = get_hard_smp_processor_id(boot_cpuid);
597
598 /* Global interrupt distribution server is specified in the last
599 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
600 * entry fom this property for current boot cpu id and use it as
601 * default distribution server
602 */
603 for (j = 0; j < i; j += 2) {
604 if (ireg[j] == hcpuid) {
605 default_server = hcpuid;
606 default_distrib_server = ireg[j+1];
607 }
608 }
609
610 /* get the bit size of server numbers */
611 isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
612 if (isize)
613 interrupt_server_size = *isize;
614
615 of_node_put(np);
616}
617
572static void __init xics_map_one_cpu(int hw_id, unsigned long addr, 618static void __init xics_map_one_cpu(int hw_id, unsigned long addr,
573 unsigned long size) 619 unsigned long size)
574{ 620{
575#ifdef CONFIG_SMP
576 int i; 621 int i;
577 622
578 /* This may look gross but it's good enough for now, we don't quite 623 /* This may look gross but it's good enough for now, we don't quite
@@ -586,11 +631,6 @@ static void __init xics_map_one_cpu(int hw_id, unsigned long addr,
586 return; 631 return;
587 } 632 }
588 } 633 }
589#else
590 if (hw_id != 0)
591 return;
592 xics_per_cpu[0] = ioremap(addr, size);
593#endif /* CONFIG_SMP */
594} 634}
595 635
596static void __init xics_init_one_node(struct device_node *np, 636static void __init xics_init_one_node(struct device_node *np,
@@ -652,15 +692,17 @@ void __init xics_init_IRQ(void)
652 692
653 for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") { 693 for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") {
654 found = 1; 694 found = 1;
655 if (firmware_has_feature(FW_FEATURE_LPAR)) 695 if (firmware_has_feature(FW_FEATURE_LPAR)) {
696 of_node_put(np);
656 break; 697 break;
698 }
657 xics_init_one_node(np, &indx); 699 xics_init_one_node(np, &indx);
658 } 700 }
659 if (found == 0) 701 if (found == 0)
660 return; 702 return;
661 703
662 xics_init_host();
663 xics_update_irq_servers(); 704 xics_update_irq_servers();
705 xics_init_host();
664 706
665 if (firmware_has_feature(FW_FEATURE_LPAR)) 707 if (firmware_has_feature(FW_FEATURE_LPAR))
666 ppc_md.get_irq = xics_get_irq_lpar; 708 ppc_md.get_irq = xics_get_irq_lpar;
@@ -672,30 +714,31 @@ void __init xics_init_IRQ(void)
672 ppc64_boot_msg(0x21, "XICS Done"); 714 ppc64_boot_msg(0x21, "XICS Done");
673} 715}
674 716
717/* Cpu startup, shutdown, and hotplug */
675 718
676#ifdef CONFIG_SMP 719static void xics_set_cpu_priority(unsigned char cppr)
677void xics_request_IPIs(void)
678{ 720{
679 unsigned int ipi;
680 int rc;
681
682 ipi = irq_create_mapping(xics_host, XICS_IPI);
683 BUG_ON(ipi == NO_IRQ);
684
685 /*
686 * IPIs are marked IRQF_DISABLED as they must run with irqs
687 * disabled
688 */
689 set_irq_handler(ipi, handle_percpu_irq);
690 if (firmware_has_feature(FW_FEATURE_LPAR)) 721 if (firmware_has_feature(FW_FEATURE_LPAR))
691 rc = request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED, 722 lpar_cppr_info(cppr);
692 "IPI", NULL);
693 else 723 else
694 rc = request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED, 724 direct_cppr_info(cppr);
695 "IPI", NULL); 725 iosync();
696 BUG_ON(rc); 726}
727
728/* Have the calling processor join or leave the specified global queue */
729static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
730{
731 int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
732 (1UL << interrupt_server_size) - 1 - gserver, join);
733 WARN_ON(status < 0);
734}
735
736void xics_setup_cpu(void)
737{
738 xics_set_cpu_priority(0xff);
739
740 xics_set_cpu_giq(default_distrib_server, 1);
697} 741}
698#endif /* CONFIG_SMP */
699 742
700void xics_teardown_cpu(void) 743void xics_teardown_cpu(void)
701{ 744{
@@ -703,9 +746,7 @@ void xics_teardown_cpu(void)
703 746
704 xics_set_cpu_priority(0); 747 xics_set_cpu_priority(0);
705 748
706 /* 749 /* Clear any pending IPI request */
707 * Clear IPI
708 */
709 if (firmware_has_feature(FW_FEATURE_LPAR)) 750 if (firmware_has_feature(FW_FEATURE_LPAR))
710 lpar_qirr_info(cpu, 0xff); 751 lpar_qirr_info(cpu, 0xff);
711 else 752 else
@@ -714,34 +755,28 @@ void xics_teardown_cpu(void)
714 755
715void xics_kexec_teardown_cpu(int secondary) 756void xics_kexec_teardown_cpu(int secondary)
716{ 757{
717 unsigned int ipi;
718 struct irq_desc *desc;
719
720 xics_teardown_cpu(); 758 xics_teardown_cpu();
721 759
722 /* 760 /*
723 * we need to EOI the IPI 761 * we take the ipi irq but and never return so we
762 * need to EOI the IPI, but want to leave our priority 0
724 * 763 *
725 * probably need to check all the other interrupts too 764 * should we check all the other interrupts too?
726 * should we be flagging idle loop instead? 765 * should we be flagging idle loop instead?
727 * or creating some task to be scheduled? 766 * or creating some task to be scheduled?
728 */ 767 */
729 768
730 ipi = irq_find_mapping(xics_host, XICS_IPI); 769 if (firmware_has_feature(FW_FEATURE_LPAR))
731 if (ipi == XICS_IRQ_SPURIOUS) 770 lpar_xirr_info_set((0x00 << 24) | XICS_IPI);
732 return; 771 else
733 desc = get_irq_desc(ipi); 772 direct_xirr_info_set((0x00 << 24) | XICS_IPI);
734 if (desc->chip && desc->chip->eoi)
735 desc->chip->eoi(ipi);
736 773
737 /* 774 /*
738 * Some machines need to have at least one cpu in the GIQ, 775 * Some machines need to have at least one cpu in the GIQ,
739 * so leave the master cpu in the group. 776 * so leave the master cpu in the group.
740 */ 777 */
741 if (secondary) 778 if (secondary)
742 rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 779 xics_set_cpu_giq(default_distrib_server, 0);
743 (1UL << interrupt_server_size) - 1 -
744 default_distrib_server, 0);
745} 780}
746 781
747#ifdef CONFIG_HOTPLUG_CPU 782#ifdef CONFIG_HOTPLUG_CPU
@@ -749,17 +784,18 @@ void xics_kexec_teardown_cpu(int secondary)
749/* Interrupts are disabled. */ 784/* Interrupts are disabled. */
750void xics_migrate_irqs_away(void) 785void xics_migrate_irqs_away(void)
751{ 786{
752 int status;
753 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); 787 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
754 unsigned int irq, virq; 788 unsigned int irq, virq;
755 789
790 /* If we used to be the default server, move to the new "boot_cpuid" */
791 if (hw_cpu == default_server)
792 xics_update_irq_servers();
793
756 /* Reject any interrupt that was queued to us... */ 794 /* Reject any interrupt that was queued to us... */
757 xics_set_cpu_priority(0); 795 xics_set_cpu_priority(0);
758 796
759 /* remove ourselves from the global interrupt queue */ 797 /* Remove ourselves from the global interrupt queue */
760 status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 798 xics_set_cpu_giq(default_distrib_server, 0);
761 (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
762 WARN_ON(status < 0);
763 799
764 /* Allow IPIs again... */ 800 /* Allow IPIs again... */
765 xics_set_cpu_priority(DEFAULT_PRIORITY); 801 xics_set_cpu_priority(DEFAULT_PRIORITY);
@@ -767,6 +803,7 @@ void xics_migrate_irqs_away(void)
767 for_each_irq(virq) { 803 for_each_irq(virq) {
768 struct irq_desc *desc; 804 struct irq_desc *desc;
769 int xics_status[2]; 805 int xics_status[2];
806 int status;
770 unsigned long flags; 807 unsigned long flags;
771 808
772 /* We cant set affinity on ISA interrupts */ 809 /* We cant set affinity on ISA interrupts */
@@ -790,9 +827,8 @@ void xics_migrate_irqs_away(void)
790 827
791 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); 828 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
792 if (status) { 829 if (status) {
793 printk(KERN_ERR "migrate_irqs_away: irq=%u " 830 printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
794 "ibm,get-xive returns %d\n", 831 __func__, irq, status);
795 virq, status);
796 goto unlock; 832 goto unlock;
797 } 833 }
798 834
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
index 1c5321ae8f2f..d1d5a83039ae 100644
--- a/arch/powerpc/platforms/pseries/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -12,20 +12,12 @@
12#ifndef _POWERPC_KERNEL_XICS_H 12#ifndef _POWERPC_KERNEL_XICS_H
13#define _POWERPC_KERNEL_XICS_H 13#define _POWERPC_KERNEL_XICS_H
14 14
15#include <linux/cache.h>
16
17extern void xics_init_IRQ(void); 15extern void xics_init_IRQ(void);
18extern void xics_setup_cpu(void); 16extern void xics_setup_cpu(void);
19extern void xics_teardown_cpu(void); 17extern void xics_teardown_cpu(void);
20extern void xics_kexec_teardown_cpu(int secondary); 18extern void xics_kexec_teardown_cpu(int secondary);
21extern void xics_cause_IPI(int cpu);
22extern void xics_request_IPIs(void);
23extern void xics_migrate_irqs_away(void); 19extern void xics_migrate_irqs_away(void);
24 20extern int smp_xics_probe(void);
25struct xics_ipi_struct { 21extern void smp_xics_message_pass(int target, int msg);
26 volatile unsigned long value;
27} ____cacheline_aligned;
28
29extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
30 22
31#endif /* _POWERPC_KERNEL_XICS_H */ 23#endif /* _POWERPC_KERNEL_XICS_H */