diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-15 11:07:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-15 11:07:35 -0400 |
commit | 5f2434a66dfa4701b81b79a78eaf9c32da0f8839 (patch) | |
tree | 8c38f1fb0d0fbcd15e496df89be00ad8c4918a43 /arch/powerpc/platforms | |
parent | 278429cff8809958d25415ba0ed32b59866ab1a8 (diff) | |
parent | 6dc6472581f693b5fc95aebedf67b4960fb85cf0 (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')
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 | ||
84 | config 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 | |||
79 | config CANYONLANDS | 95 | config 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 | ||
108 | config 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 | |||
89 | config YOSEMITE | 121 | config 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 | ||
163 | config 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. |
131 | config 440EP | 171 | config 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 @@ | |||
1 | obj-$(CONFIG_44x) := misc_44x.o idle.o | 1 | obj-$(CONFIG_44x) := misc_44x.o idle.o |
2 | obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o | ||
2 | obj-$(CONFIG_EBONY) += ebony.o | 3 | obj-$(CONFIG_EBONY) += ebony.o |
3 | obj-$(CONFIG_TAISHAN) += taishan.o | ||
4 | obj-$(CONFIG_BAMBOO) += bamboo.o | ||
5 | obj-$(CONFIG_YOSEMITE) += bamboo.o | ||
6 | obj-$(CONFIG_SAM440EP) += sam440ep.o | 4 | obj-$(CONFIG_SAM440EP) += sam440ep.o |
7 | obj-$(CONFIG_SEQUOIA) += sequoia.o | ||
8 | obj-$(CONFIG_KATMAI) += katmai.o | ||
9 | obj-$(CONFIG_RAINIER) += rainier.o | ||
10 | obj-$(CONFIG_WARP) += warp.o | 5 | obj-$(CONFIG_WARP) += warp.o |
11 | obj-$(CONFIG_WARP) += warp-nand.o | 6 | obj-$(CONFIG_WARP) += warp-nand.o |
12 | obj-$(CONFIG_CANYONLANDS) += canyonlands.o | ||
13 | obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o | 7 | obj-$(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 | |||
27 | static __initdata struct of_device_id bamboo_of_bus[] = { | ||
28 | { .compatible = "ibm,plb4", }, | ||
29 | { .compatible = "ibm,opb", }, | ||
30 | { .compatible = "ibm,ebc", }, | ||
31 | {}, | ||
32 | }; | ||
33 | |||
34 | static int __init bamboo_device_probe(void) | ||
35 | { | ||
36 | of_platform_bus_probe(NULL, bamboo_of_bus, NULL); | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | machine_device_initcall(bamboo, bamboo_device_probe); | ||
41 | |||
42 | static 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 | |||
54 | define_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 | |||
28 | static __initdata struct of_device_id canyonlands_of_bus[] = { | ||
29 | { .compatible = "ibm,plb4", }, | ||
30 | { .compatible = "ibm,opb", }, | ||
31 | { .compatible = "ibm,ebc", }, | ||
32 | {}, | ||
33 | }; | ||
34 | |||
35 | static int __init canyonlands_device_probe(void) | ||
36 | { | ||
37 | of_platform_bus_probe(NULL, canyonlands_of_bus, NULL); | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | machine_device_initcall(canyonlands, canyonlands_device_probe); | ||
42 | |||
43 | static 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 | |||
55 | define_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 | |||
27 | static __initdata struct of_device_id katmai_of_bus[] = { | ||
28 | { .compatible = "ibm,plb4", }, | ||
29 | { .compatible = "ibm,opb", }, | ||
30 | { .compatible = "ibm,ebc", }, | ||
31 | {}, | ||
32 | }; | ||
33 | |||
34 | static int __init katmai_device_probe(void) | ||
35 | { | ||
36 | of_platform_bus_probe(NULL, katmai_of_bus, NULL); | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | machine_device_initcall(katmai, katmai_device_probe); | ||
41 | |||
42 | static 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 | |||
54 | define_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 | |||
27 | static __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 | |||
35 | static int __init ppc44x_device_probe(void) | ||
36 | { | ||
37 | of_platform_bus_probe(NULL, ppc44x_of_bus, NULL); | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | machine_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 | */ | ||
52 | static 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 | |||
65 | static 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 | |||
80 | define_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 | |||
27 | static __initdata struct of_device_id rainier_of_bus[] = { | ||
28 | { .compatible = "ibm,plb4", }, | ||
29 | { .compatible = "ibm,opb", }, | ||
30 | { .compatible = "ibm,ebc", }, | ||
31 | {}, | ||
32 | }; | ||
33 | |||
34 | static int __init rainier_device_probe(void) | ||
35 | { | ||
36 | of_platform_bus_probe(NULL, rainier_of_bus, NULL); | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | machine_device_initcall(rainier, rainier_device_probe); | ||
41 | |||
42 | static 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 | |||
54 | define_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 | |||
28 | static __initdata struct of_device_id sequoia_of_bus[] = { | ||
29 | { .compatible = "ibm,plb4", }, | ||
30 | { .compatible = "ibm,opb", }, | ||
31 | { .compatible = "ibm,ebc", }, | ||
32 | {}, | ||
33 | }; | ||
34 | |||
35 | static int __init sequoia_device_probe(void) | ||
36 | { | ||
37 | of_platform_bus_probe(NULL, sequoia_of_bus, NULL); | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | machine_device_initcall(sequoia, sequoia_device_probe); | ||
42 | |||
43 | static 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 | |||
55 | define_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 | |||
34 | static __initdata struct of_device_id taishan_of_bus[] = { | ||
35 | { .compatible = "ibm,plb4", }, | ||
36 | { .compatible = "ibm,opb", }, | ||
37 | { .compatible = "ibm,ebc", }, | ||
38 | {}, | ||
39 | }; | ||
40 | |||
41 | static int __init taishan_device_probe(void) | ||
42 | { | ||
43 | of_platform_bus_probe(NULL, taishan_of_bus, NULL); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | machine_device_initcall(taishan, taishan_device_probe); | ||
48 | |||
49 | /* | ||
50 | * Called very early, MMU is off, device-tree isn't unflattened | ||
51 | */ | ||
52 | static 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 | |||
64 | define_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 | ||
7 | config PPC_MPC5121 | 9 | config 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 | ||
28 | static void __init mpc5121_ads_setup_arch(void) | 30 | static 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 | ||
37 | static void __init mpc5121_ads_init_IRQ(void) | 47 | static 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 | ||
41 | config 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 | |||
41 | endif | 49 | endif |
42 | 50 | ||
43 | config PQ2ADS | 51 | config 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 | |||
6 | obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o | 6 | obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o |
7 | obj-$(CONFIG_PQ2FADS) += pq2fads.o | 7 | obj-$(CONFIG_PQ2FADS) += pq2fads.o |
8 | obj-$(CONFIG_EP8248E) += ep8248e.o | 8 | obj-$(CONFIG_EP8248E) += ep8248e.o |
9 | obj-$(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 | |||
34 | static 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 | |||
46 | struct cpm_pin { | ||
47 | int port, pin, flags; | ||
48 | }; | ||
49 | |||
50 | static __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 | |||
65 | static 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 | |||
79 | static 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 | |||
97 | static __initdata struct of_device_id of_bus_ids[] = { | ||
98 | { .compatible = "simple-bus", }, | ||
99 | {}, | ||
100 | }; | ||
101 | |||
102 | static int __init declare_of_platform_devices(void) | ||
103 | { | ||
104 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | machine_device_initcall(mgcoge, declare_of_platform_devices); | ||
109 | |||
110 | /* | ||
111 | * Called very early, device-tree isn't unflattened | ||
112 | */ | ||
113 | static 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 | |||
119 | define_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 | |||
19 | config MPC832x_MDS | 19 | config 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 | |||
27 | config MPC832x_RDB | 26 | config 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 | |||
57 | config MPC836x_MDS | 55 | config 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 | ||
64 | config MPC836x_RDK | 61 | config 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 | |||
33 | config MPC85xx_MDS | 33 | config 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 | ||
34 | config 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 | |||
34 | endif | 41 | endif |
35 | 42 | ||
36 | config MPC8641 | 43 | config 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 | ||
44 | config MPC8610 | 51 | config 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 | |||
7 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o | 7 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o |
8 | obj-$(CONFIG_SBC8641D) += sbc8641d.o | 8 | obj-$(CONFIG_SBC8641D) += sbc8641d.o |
9 | obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o | 9 | obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o |
10 | obj-$(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 | |||
52 | static DEFINE_SPINLOCK(gef_pic_lock); | ||
53 | |||
54 | static void __iomem *gef_pic_irq_reg_base; | ||
55 | static struct irq_host *gef_pic_irq_host; | ||
56 | static 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 | |||
96 | void 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 | |||
113 | static 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 | |||
128 | static 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 | |||
136 | static 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 | |||
151 | static 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 | */ | ||
162 | static 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 | |||
172 | static 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 | |||
186 | static 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 | */ | ||
195 | void __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 | */ | ||
235 | unsigned 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 | |||
6 | void gef_pic_cascade(unsigned int, struct irq_desc *); | ||
7 | unsigned int gef_pic_get_irq(void); | ||
8 | void 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 | |||
52 | void __iomem *sbc610_regs; | ||
53 | |||
54 | static 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 | |||
74 | static 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 */ | ||
102 | static 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 */ | ||
111 | static 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 */ | ||
120 | static 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 | |||
128 | static 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 | |||
143 | static 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 | } | ||
156 | DECLARE_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 | */ | ||
167 | static 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 | |||
177 | static 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 | |||
193 | static __initdata struct of_device_id of_bus_ids[] = { | ||
194 | { .compatible = "simple-bus", }, | ||
195 | {}, | ||
196 | }; | ||
197 | |||
198 | static 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 | } | ||
205 | machine_device_initcall(gef_sbc610, declare_of_platform_devices); | ||
206 | |||
207 | define_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) | |||
101 | static void | 101 | static void |
102 | mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) | 102 | mpc86xx_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) | |||
63 | static void | 63 | static void |
64 | sbc8641_show_cpuinfo(struct seq_file *m) | 64 | sbc8641_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 | ||
52 | config PPC_MGSUVD | ||
53 | bool "MGSUVD" | ||
54 | select CPM1 | ||
55 | help | ||
56 | This enables support for the Keymile MGSUVD board. | ||
57 | |||
52 | endchoice | 58 | endchoice |
53 | 59 | ||
54 | menu "Freescale Ethernet driver platform-specific options" | 60 | menu "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 | |||
6 | obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o | 6 | obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o |
7 | obj-$(CONFIG_PPC_EP88XC) += ep88xc.o | 7 | obj-$(CONFIG_PPC_EP88XC) += ep88xc.o |
8 | obj-$(CONFIG_PPC_ADDER875) += adder875.o | 8 | obj-$(CONFIG_PPC_ADDER875) += adder875.o |
9 | obj-$(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 | |||
26 | struct cpm_pin { | ||
27 | int port, pin, flags; | ||
28 | }; | ||
29 | |||
30 | static __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 | |||
43 | static 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 | |||
58 | static void __init mgsuvd_setup_arch(void) | ||
59 | { | ||
60 | cpm_reset(); | ||
61 | init_ioports(); | ||
62 | } | ||
63 | |||
64 | static __initdata struct of_device_id of_bus_ids[] = { | ||
65 | { .compatible = "simple-bus" }, | ||
66 | {}, | ||
67 | }; | ||
68 | |||
69 | static int __init declare_of_platform_devices(void) | ||
70 | { | ||
71 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
72 | return 0; | ||
73 | } | ||
74 | machine_device_initcall(mgsuvd, declare_of_platform_devices); | ||
75 | |||
76 | static 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 | |||
82 | define_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 | ||
241 | config QUICC_ENGINE | 241 | config 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 | ||
252 | config 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 | |||
251 | config CPM2 | 261 | config 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 | ||
294 | source "arch/powerpc/sysdev/bestcomm/Kconfig" | 304 | source "arch/powerpc/sysdev/bestcomm/Kconfig" |
295 | 305 | ||
306 | config 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 | |||
296 | endmenu | 315 | endmenu |
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 | ||
54 | config E200 | 55 | config E200 |
55 | bool "Freescale e200" | 56 | bool "Freescale e200" |
@@ -128,18 +129,20 @@ config FSL_EMB_PERFMON | |||
128 | 129 | ||
129 | config PTE_64BIT | 130 | config 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 | ||
135 | config PHYS_64BIT | 135 | config 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 | ||
305 | out_free_ctx: | 305 | out_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 | ||
545 | out_iput: | 547 | out_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) | |||
164 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) | 164 | void 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 | ||
170 | void mpc7448_hpc2_restart(char *cmd) | 169 | void 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 |
40 | system_reset_iSeries: | 40 | system_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 |
65 | 1: | 66 | 1: |
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) | |||
267 | 3: stdu r0,8(r8) | 268 | 3: stdu r0,8(r8) |
268 | bdnz 3b | 269 | bdnz 3b |
269 | 4: | 270 | 4: |
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) | ||
96 | static unsigned long from_rtc_time(struct rtc_time *tm) | 98 | static 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 |
103 | static unsigned long cuda_get_time(void) | 106 | static 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 |
45 | static void print_device_node_tree(struct pci_dn *pdn, int dent) | 45 | static 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 |
108 | static 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 | |||
115 | static 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 | |||
131 | static int __init smp_xics_probe(void) | ||
132 | { | ||
133 | xics_request_IPIs(); | ||
134 | |||
135 | return cpus_weight(cpu_possible_map); | ||
136 | } | ||
137 | |||
138 | static void __devinit smp_xics_setup_cpu(int cpu) | 108 | static 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 | ||
34 | static 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 | ||
48 | static unsigned int default_server = 0xFF; | ||
49 | static unsigned int default_distrib_server = 0; | ||
50 | static unsigned int interrupt_server_size = 8; | ||
51 | |||
52 | /* RTAS service tokens */ | ||
53 | static int ibm_get_xive; | ||
54 | static int ibm_set_xive; | ||
55 | static int ibm_int_on; | ||
56 | static 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 */ | ||
50 | struct xics_ipl { | 62 | struct xics_ipl { |
51 | union { | 63 | union { |
52 | u32 word; | 64 | u32 word; |
@@ -65,27 +77,6 @@ struct xics_ipl { | |||
65 | 77 | ||
66 | static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; | 78 | static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; |
67 | 79 | ||
68 | static unsigned int default_server = 0xFF; | ||
69 | static unsigned int default_distrib_server = 0; | ||
70 | static unsigned int interrupt_server_size = 8; | ||
71 | |||
72 | static struct irq_host *xics_host; | ||
73 | |||
74 | /* | ||
75 | * XICS only has a single IPI, so encode the messages per CPU | ||
76 | */ | ||
77 | struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | ||
78 | |||
79 | /* RTAS service tokens */ | ||
80 | static int ibm_get_xive; | ||
81 | static int ibm_set_xive; | ||
82 | static int ibm_int_on; | ||
83 | static int ibm_int_off; | ||
84 | |||
85 | |||
86 | /* Direct HW low level accessors */ | ||
87 | |||
88 | |||
89 | static inline unsigned int direct_xirr_info_get(void) | 80 | static 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 | ||
96 | static inline void direct_xirr_info_set(int value) | 87 | static 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 | |||
119 | static inline unsigned int lpar_xirr_info_get(void) | 109 | static 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 | ||
130 | static inline void lpar_xirr_info_set(int value) | 120 | static 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 | ||
141 | static inline void lpar_cppr_info(u8 value) | 130 | static 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 | |||
162 | static 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 |
204 | static int get_irq_server(unsigned int virq, unsigned int strict_check) | 152 | static 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 | |||
242 | static void xics_unmask_irq(unsigned int virq) | 186 | static 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 | ||
219 | static unsigned int xics_startup(unsigned int virq) | ||
220 | { | ||
221 | /* unmask it */ | ||
222 | xics_unmask_irq(virq); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
275 | static void xics_mask_real_irq(unsigned int irq) | 226 | static 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 | ||
311 | static unsigned int xics_startup(unsigned int virq) | 262 | static 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 | |||
324 | static 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 | 268 | static inline unsigned int xics_xirr_vector(unsigned int xirr) | |
333 | static 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 | ||
341 | static inline unsigned int xics_remap_irq(unsigned int vec) | 277 | static 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 | ||
359 | static 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 | ||
364 | static unsigned int xics_get_irq_lpar(void) | 298 | static 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 | |||
371 | static 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 | ||
402 | static 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 | ||
411 | static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id) | 319 | static 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 | ||
420 | void xics_cause_IPI(int cpu) | 327 | static 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 | ||
430 | static 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 | ||
439 | static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | 335 | static 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 | ||
481 | void 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 | |||
497 | static struct irq_chip xics_pic_direct = { | 378 | static 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 | |||
507 | static struct irq_chip xics_pic_lpar = { | 387 | static 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 */ |
517 | static struct irq_chip *xics_irq_chip; | 400 | static 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 | */ | ||
465 | struct xics_ipi_struct { | ||
466 | unsigned long value; | ||
467 | } ____cacheline_aligned; | ||
468 | |||
469 | static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | ||
470 | |||
471 | static 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 | |||
481 | void 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 | |||
497 | static 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 | |||
525 | static 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 | |||
534 | static 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 | |||
543 | static 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 | |||
565 | int __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 | |||
577 | static 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 | |||
572 | static void __init xics_map_one_cpu(int hw_id, unsigned long addr, | 618 | static 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 | ||
596 | static void __init xics_init_one_node(struct device_node *np, | 636 | static 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 | 719 | static void xics_set_cpu_priority(unsigned char cppr) |
677 | void 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 */ | ||
729 | static 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 | |||
736 | void 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 | ||
700 | void xics_teardown_cpu(void) | 743 | void 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 | ||
715 | void xics_kexec_teardown_cpu(int secondary) | 756 | void 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. */ |
750 | void xics_migrate_irqs_away(void) | 785 | void 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 | |||
17 | extern void xics_init_IRQ(void); | 15 | extern void xics_init_IRQ(void); |
18 | extern void xics_setup_cpu(void); | 16 | extern void xics_setup_cpu(void); |
19 | extern void xics_teardown_cpu(void); | 17 | extern void xics_teardown_cpu(void); |
20 | extern void xics_kexec_teardown_cpu(int secondary); | 18 | extern void xics_kexec_teardown_cpu(int secondary); |
21 | extern void xics_cause_IPI(int cpu); | ||
22 | extern void xics_request_IPIs(void); | ||
23 | extern void xics_migrate_irqs_away(void); | 19 | extern void xics_migrate_irqs_away(void); |
24 | 20 | extern int smp_xics_probe(void); | |
25 | struct xics_ipi_struct { | 21 | extern void smp_xics_message_pass(int target, int msg); |
26 | volatile unsigned long value; | ||
27 | } ____cacheline_aligned; | ||
28 | |||
29 | extern 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 */ |