diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-06 20:58:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-06 20:58:22 -0500 |
commit | e4e88f31bcb5f05f24b9ae518d4ecb44e1a7774d (patch) | |
tree | 9eef6998f5bbd1a2c999011d9e0151f00c6e7297 /arch/powerpc/platforms | |
parent | 9753dfe19a85e7e45a34a56f4cb2048bb4f50e27 (diff) | |
parent | ef88e3911c0e0301e73fa3b3b2567aabdbe17cc4 (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: (185 commits)
powerpc: fix compile error with 85xx/p1010rdb.c
powerpc: fix compile error with 85xx/p1023_rds.c
powerpc/fsl: add MSI support for the Freescale hypervisor
arch/powerpc/sysdev/fsl_rmu.c: introduce missing kfree
powerpc/fsl: Add support for Integrated Flash Controller
powerpc/fsl: update compatiable on fsl 16550 uart nodes
powerpc/85xx: fix PCI and localbus properties in p1022ds.dts
powerpc/85xx: re-enable ePAPR byte channel driver in corenet32_smp_defconfig
powerpc/fsl: Update defconfigs to enable some standard FSL HW features
powerpc: Add TBI PHY node to first MDIO bus
sbc834x: put full compat string in board match check
powerpc/fsl-pci: Allow 64-bit PCIe devices to DMA to any memory address
powerpc: Fix unpaired probe_hcall_entry and probe_hcall_exit
offb: Fix setting of the pseudo-palette for >8bpp
offb: Add palette hack for qemu "standard vga" framebuffer
offb: Fix bug in calculating requested vram size
powerpc/boot: Change the WARN to INFO for boot wrapper overlap message
powerpc/44x: Fix build error on currituck platform
powerpc/boot: Change the load address for the wrapper to fit the kernel
powerpc/44x: Enable CRASH_DUMP for 440x
...
Fix up a trivial conflict in arch/powerpc/include/asm/cputime.h due to
the additional sparse-checking code for cputime_t.
Diffstat (limited to 'arch/powerpc/platforms')
90 files changed, 3258 insertions, 1839 deletions
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index 153022971daa..baae85584b1c 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig | |||
@@ -100,6 +100,16 @@ config XILINX_VIRTEX_GENERIC_BOARD | |||
100 | Most Virtex designs should use this unless it needs to do some | 100 | Most Virtex designs should use this unless it needs to do some |
101 | special configuration at board probe time. | 101 | special configuration at board probe time. |
102 | 102 | ||
103 | config OBS600 | ||
104 | bool "OpenBlockS 600" | ||
105 | depends on 40x | ||
106 | default n | ||
107 | select 405EX | ||
108 | select PPC40x_SIMPLE | ||
109 | help | ||
110 | This option enables support for PlatHome OpenBlockS 600 server | ||
111 | |||
112 | |||
103 | config PPC40x_SIMPLE | 113 | config PPC40x_SIMPLE |
104 | bool "Simple PowerPC 40x board support" | 114 | bool "Simple PowerPC 40x board support" |
105 | depends on 40x | 115 | depends on 40x |
@@ -186,3 +196,14 @@ config IBM405_ERR51 | |||
186 | # bool | 196 | # bool |
187 | # depends on !STB03xxx && PPC4xx_DMA | 197 | # depends on !STB03xxx && PPC4xx_DMA |
188 | # default y | 198 | # default y |
199 | # | ||
200 | |||
201 | config APM8018X | ||
202 | bool "APM8018X" | ||
203 | depends on 40x | ||
204 | default n | ||
205 | select PPC40x_SIMPLE | ||
206 | help | ||
207 | This option enables support for the AppliedMicro APM8018X evaluation | ||
208 | board. | ||
209 | |||
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c index e8dd5c5df7d9..97612068fae3 100644 --- a/arch/powerpc/platforms/40x/ppc40x_simple.c +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c | |||
@@ -55,7 +55,9 @@ static const char *board[] __initdata = { | |||
55 | "amcc,haleakala", | 55 | "amcc,haleakala", |
56 | "amcc,kilauea", | 56 | "amcc,kilauea", |
57 | "amcc,makalu", | 57 | "amcc,makalu", |
58 | "est,hotfoot" | 58 | "apm,klondike", |
59 | "est,hotfoot", | ||
60 | "plathome,obs600" | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static int __init ppc40x_probe(void) | 63 | static int __init ppc40x_probe(void) |
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 762322ce24a9..5d5aaf6c91aa 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -186,6 +186,16 @@ config ISS4xx | |||
186 | help | 186 | help |
187 | This option enables support for the IBM ISS simulation environment | 187 | This option enables support for the IBM ISS simulation environment |
188 | 188 | ||
189 | config CURRITUCK | ||
190 | bool "IBM Currituck (476fpe) Support" | ||
191 | depends on PPC_47x | ||
192 | default n | ||
193 | select SWIOTLB | ||
194 | select 476FPE | ||
195 | select PPC4xx_PCI_EXPRESS | ||
196 | help | ||
197 | This option enables support for the IBM Currituck (476fpe) evaluation board | ||
198 | |||
189 | config ICON | 199 | config ICON |
190 | bool "Icon" | 200 | bool "Icon" |
191 | depends on 44x | 201 | depends on 44x |
@@ -308,6 +318,10 @@ config 460SX | |||
308 | select IBM_EMAC_ZMII | 318 | select IBM_EMAC_ZMII |
309 | select IBM_EMAC_TAH | 319 | select IBM_EMAC_TAH |
310 | 320 | ||
321 | config 476FPE | ||
322 | bool | ||
323 | select PPC_FPU | ||
324 | |||
311 | config APM821xx | 325 | config APM821xx |
312 | bool | 326 | bool |
313 | select PPC_FPU | 327 | select PPC_FPU |
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 553db6007217..d03833abec09 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile | |||
@@ -10,3 +10,4 @@ obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o | |||
10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o | 10 | obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o |
11 | obj-$(CONFIG_ISS4xx) += iss4xx.o | 11 | obj-$(CONFIG_ISS4xx) += iss4xx.o |
12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o | 12 | obj-$(CONFIG_CANYONLANDS)+= canyonlands.o |
13 | obj-$(CONFIG_CURRITUCK) += currituck.o | ||
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/currituck.c new file mode 100644 index 000000000000..3f6229b5dee0 --- /dev/null +++ b/arch/powerpc/platforms/44x/currituck.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Currituck board specific routines | ||
3 | * | ||
4 | * Copyright © 2011 Tony Breeds IBM Corporation | ||
5 | * | ||
6 | * Based on earlier code: | ||
7 | * Matt Porter <mporter@kernel.crashing.org> | ||
8 | * Copyright 2002-2005 MontaVista Software Inc. | ||
9 | * | ||
10 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | ||
11 | * Copyright (c) 2003-2005 Zultys Technologies | ||
12 | * | ||
13 | * Rewritten and ported to the merged powerpc tree: | ||
14 | * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation. | ||
15 | * Copyright © 2011 David Kliekamp 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/memblock.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/of_platform.h> | ||
27 | #include <linux/rtc.h> | ||
28 | |||
29 | #include <asm/machdep.h> | ||
30 | #include <asm/prom.h> | ||
31 | #include <asm/udbg.h> | ||
32 | #include <asm/time.h> | ||
33 | #include <asm/uic.h> | ||
34 | #include <asm/ppc4xx.h> | ||
35 | #include <asm/mpic.h> | ||
36 | #include <asm/mmu.h> | ||
37 | |||
38 | #include <linux/pci.h> | ||
39 | |||
40 | static __initdata struct of_device_id ppc47x_of_bus[] = { | ||
41 | { .compatible = "ibm,plb4", }, | ||
42 | { .compatible = "ibm,plb6", }, | ||
43 | { .compatible = "ibm,opb", }, | ||
44 | { .compatible = "ibm,ebc", }, | ||
45 | {}, | ||
46 | }; | ||
47 | |||
48 | /* The EEPROM is missing and the default values are bogus. This forces USB in | ||
49 | * to EHCI mode */ | ||
50 | static void __devinit quirk_ppc_currituck_usb_fixup(struct pci_dev *dev) | ||
51 | { | ||
52 | if (of_machine_is_compatible("ibm,currituck")) { | ||
53 | pci_write_config_dword(dev, 0xe0, 0x0114231f); | ||
54 | pci_write_config_dword(dev, 0xe4, 0x00006c40); | ||
55 | } | ||
56 | } | ||
57 | DECLARE_PCI_FIXUP_HEADER(0x1033, 0x0035, quirk_ppc_currituck_usb_fixup); | ||
58 | |||
59 | static int __init ppc47x_device_probe(void) | ||
60 | { | ||
61 | of_platform_bus_probe(NULL, ppc47x_of_bus, NULL); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | machine_device_initcall(ppc47x, ppc47x_device_probe); | ||
66 | |||
67 | /* We can have either UICs or MPICs */ | ||
68 | static void __init ppc47x_init_irq(void) | ||
69 | { | ||
70 | struct device_node *np; | ||
71 | |||
72 | /* Find top level interrupt controller */ | ||
73 | for_each_node_with_property(np, "interrupt-controller") { | ||
74 | if (of_get_property(np, "interrupts", NULL) == NULL) | ||
75 | break; | ||
76 | } | ||
77 | if (np == NULL) | ||
78 | panic("Can't find top level interrupt controller"); | ||
79 | |||
80 | /* Check type and do appropriate initialization */ | ||
81 | if (of_device_is_compatible(np, "chrp,open-pic")) { | ||
82 | /* The MPIC driver will get everything it needs from the | ||
83 | * device-tree, just pass 0 to all arguments | ||
84 | */ | ||
85 | struct mpic *mpic = | ||
86 | mpic_alloc(np, 0, 0, 0, 0, " MPIC "); | ||
87 | BUG_ON(mpic == NULL); | ||
88 | mpic_init(mpic); | ||
89 | ppc_md.get_irq = mpic_get_irq; | ||
90 | } else | ||
91 | panic("Unrecognized top level interrupt controller"); | ||
92 | } | ||
93 | |||
94 | #ifdef CONFIG_SMP | ||
95 | static void __cpuinit smp_ppc47x_setup_cpu(int cpu) | ||
96 | { | ||
97 | mpic_setup_this_cpu(); | ||
98 | } | ||
99 | |||
100 | static int __cpuinit smp_ppc47x_kick_cpu(int cpu) | ||
101 | { | ||
102 | struct device_node *cpunode = of_get_cpu_node(cpu, NULL); | ||
103 | const u64 *spin_table_addr_prop; | ||
104 | u32 *spin_table; | ||
105 | extern void start_secondary_47x(void); | ||
106 | |||
107 | BUG_ON(cpunode == NULL); | ||
108 | |||
109 | /* Assume spin table. We could test for the enable-method in | ||
110 | * the device-tree but currently there's little point as it's | ||
111 | * our only supported method | ||
112 | */ | ||
113 | spin_table_addr_prop = | ||
114 | of_get_property(cpunode, "cpu-release-addr", NULL); | ||
115 | |||
116 | if (spin_table_addr_prop == NULL) { | ||
117 | pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", | ||
118 | cpu); | ||
119 | return 1; | ||
120 | } | ||
121 | |||
122 | /* Assume it's mapped as part of the linear mapping. This is a bit | ||
123 | * fishy but will work fine for now | ||
124 | * | ||
125 | * XXX: Is there any reason to assume differently? | ||
126 | */ | ||
127 | spin_table = (u32 *)__va(*spin_table_addr_prop); | ||
128 | pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table); | ||
129 | |||
130 | spin_table[3] = cpu; | ||
131 | smp_wmb(); | ||
132 | spin_table[1] = __pa(start_secondary_47x); | ||
133 | mb(); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static struct smp_ops_t ppc47x_smp_ops = { | ||
139 | .probe = smp_mpic_probe, | ||
140 | .message_pass = smp_mpic_message_pass, | ||
141 | .setup_cpu = smp_ppc47x_setup_cpu, | ||
142 | .kick_cpu = smp_ppc47x_kick_cpu, | ||
143 | .give_timebase = smp_generic_give_timebase, | ||
144 | .take_timebase = smp_generic_take_timebase, | ||
145 | }; | ||
146 | |||
147 | static void __init ppc47x_smp_init(void) | ||
148 | { | ||
149 | if (mmu_has_feature(MMU_FTR_TYPE_47x)) | ||
150 | smp_ops = &ppc47x_smp_ops; | ||
151 | } | ||
152 | |||
153 | #else /* CONFIG_SMP */ | ||
154 | static void __init ppc47x_smp_init(void) { } | ||
155 | #endif /* CONFIG_SMP */ | ||
156 | |||
157 | static void __init ppc47x_setup_arch(void) | ||
158 | { | ||
159 | |||
160 | /* No need to check the DMA config as we /know/ our windows are all of | ||
161 | * RAM. Lets hope that doesn't change */ | ||
162 | #ifdef CONFIG_SWIOTLB | ||
163 | if (memblock_end_of_DRAM() > 0xffffffff) { | ||
164 | ppc_swiotlb_enable = 1; | ||
165 | set_pci_dma_ops(&swiotlb_dma_ops); | ||
166 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | ||
167 | } | ||
168 | #endif | ||
169 | ppc47x_smp_init(); | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Called very early, MMU is off, device-tree isn't unflattened | ||
174 | */ | ||
175 | static int __init ppc47x_probe(void) | ||
176 | { | ||
177 | unsigned long root = of_get_flat_dt_root(); | ||
178 | |||
179 | if (!of_flat_dt_is_compatible(root, "ibm,currituck")) | ||
180 | return 0; | ||
181 | |||
182 | return 1; | ||
183 | } | ||
184 | |||
185 | /* Use USB controller should have been hardware swizzled but it wasn't :( */ | ||
186 | static void ppc47x_pci_irq_fixup(struct pci_dev *dev) | ||
187 | { | ||
188 | if (dev->vendor == 0x1033 && (dev->device == 0x0035 || | ||
189 | dev->device == 0x00e0)) { | ||
190 | dev->irq = irq_create_mapping(NULL, 47); | ||
191 | pr_info("%s: Mapping irq 47 %d\n", __func__, dev->irq); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | define_machine(ppc47x) { | ||
196 | .name = "PowerPC 47x", | ||
197 | .probe = ppc47x_probe, | ||
198 | .progress = udbg_progress, | ||
199 | .init_IRQ = ppc47x_init_irq, | ||
200 | .setup_arch = ppc47x_setup_arch, | ||
201 | .pci_irq_fixup = ppc47x_pci_irq_fixup, | ||
202 | .restart = ppc4xx_reset_system, | ||
203 | .calibrate_decr = generic_calibrate_decr, | ||
204 | }; | ||
diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c index 19395f18b1db..5b8cdbb82f80 100644 --- a/arch/powerpc/platforms/44x/iss4xx.c +++ b/arch/powerpc/platforms/44x/iss4xx.c | |||
@@ -71,7 +71,7 @@ static void __init iss4xx_init_irq(void) | |||
71 | /* The MPIC driver will get everything it needs from the | 71 | /* The MPIC driver will get everything it needs from the |
72 | * device-tree, just pass 0 to all arguments | 72 | * device-tree, just pass 0 to all arguments |
73 | */ | 73 | */ |
74 | struct mpic *mpic = mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0, | 74 | struct mpic *mpic = mpic_alloc(np, 0, 0, 0, 0, |
75 | " MPIC "); | 75 | " MPIC "); |
76 | BUG_ON(mpic == NULL); | 76 | BUG_ON(mpic == NULL); |
77 | mpic_init(mpic); | 77 | mpic_init(mpic); |
diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c index aa0d84d22585..464ea8e0292d 100644 --- a/arch/powerpc/platforms/83xx/asp834x.c +++ b/arch/powerpc/platforms/83xx/asp834x.c | |||
@@ -36,38 +36,7 @@ static void __init asp834x_setup_arch(void) | |||
36 | mpc834x_usb_cfg(); | 36 | mpc834x_usb_cfg(); |
37 | } | 37 | } |
38 | 38 | ||
39 | static void __init asp834x_init_IRQ(void) | 39 | machine_device_initcall(asp834x, mpc83xx_declare_of_platform_devices); |
40 | { | ||
41 | struct device_node *np; | ||
42 | |||
43 | np = of_find_node_by_type(NULL, "ipic"); | ||
44 | if (!np) | ||
45 | return; | ||
46 | |||
47 | ipic_init(np, 0); | ||
48 | |||
49 | of_node_put(np); | ||
50 | |||
51 | /* Initialize the default interrupt mapping priorities, | ||
52 | * in case the boot rom changed something on us. | ||
53 | */ | ||
54 | ipic_set_default_priority(); | ||
55 | } | ||
56 | |||
57 | static struct __initdata of_device_id asp8347_ids[] = { | ||
58 | { .type = "soc", }, | ||
59 | { .compatible = "soc", }, | ||
60 | { .compatible = "simple-bus", }, | ||
61 | { .compatible = "gianfar", }, | ||
62 | {}, | ||
63 | }; | ||
64 | |||
65 | static int __init asp8347_declare_of_platform_devices(void) | ||
66 | { | ||
67 | of_platform_bus_probe(NULL, asp8347_ids, NULL); | ||
68 | return 0; | ||
69 | } | ||
70 | machine_device_initcall(asp834x, asp8347_declare_of_platform_devices); | ||
71 | 40 | ||
72 | /* | 41 | /* |
73 | * Called very early, MMU is off, device-tree isn't unflattened | 42 | * Called very early, MMU is off, device-tree isn't unflattened |
@@ -82,7 +51,7 @@ define_machine(asp834x) { | |||
82 | .name = "ASP8347E", | 51 | .name = "ASP8347E", |
83 | .probe = asp834x_probe, | 52 | .probe = asp834x_probe, |
84 | .setup_arch = asp834x_setup_arch, | 53 | .setup_arch = asp834x_setup_arch, |
85 | .init_IRQ = asp834x_init_IRQ, | 54 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
86 | .get_irq = ipic_get_irq, | 55 | .get_irq = ipic_get_irq, |
87 | .restart = mpc83xx_restart, | 56 | .restart = mpc83xx_restart, |
88 | .time_init = mpc83xx_time_init, | 57 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index c55129f5760a..65eb792a0d00 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c | |||
@@ -51,15 +51,14 @@ | |||
51 | */ | 51 | */ |
52 | static void __init mpc83xx_km_setup_arch(void) | 52 | static void __init mpc83xx_km_setup_arch(void) |
53 | { | 53 | { |
54 | #ifdef CONFIG_QUICC_ENGINE | ||
54 | struct device_node *np; | 55 | struct device_node *np; |
56 | #endif | ||
55 | 57 | ||
56 | if (ppc_md.progress) | 58 | if (ppc_md.progress) |
57 | ppc_md.progress("kmpbec83xx_setup_arch()", 0); | 59 | ppc_md.progress("kmpbec83xx_setup_arch()", 0); |
58 | 60 | ||
59 | #ifdef CONFIG_PCI | 61 | mpc83xx_setup_pci(); |
60 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
61 | mpc83xx_add_bridge(np); | ||
62 | #endif | ||
63 | 62 | ||
64 | #ifdef CONFIG_QUICC_ENGINE | 63 | #ifdef CONFIG_QUICC_ENGINE |
65 | qe_reset(); | 64 | qe_reset(); |
@@ -122,54 +121,7 @@ static void __init mpc83xx_km_setup_arch(void) | |||
122 | #endif /* CONFIG_QUICC_ENGINE */ | 121 | #endif /* CONFIG_QUICC_ENGINE */ |
123 | } | 122 | } |
124 | 123 | ||
125 | static struct of_device_id kmpbec83xx_ids[] = { | 124 | machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); |
126 | { .type = "soc", }, | ||
127 | { .compatible = "soc", }, | ||
128 | { .compatible = "simple-bus", }, | ||
129 | { .type = "qe", }, | ||
130 | { .compatible = "fsl,qe", }, | ||
131 | {}, | ||
132 | }; | ||
133 | |||
134 | static int __init kmeter_declare_of_platform_devices(void) | ||
135 | { | ||
136 | /* Publish the QE devices */ | ||
137 | of_platform_bus_probe(NULL, kmpbec83xx_ids, NULL); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | machine_device_initcall(mpc83xx_km, kmeter_declare_of_platform_devices); | ||
142 | |||
143 | static void __init mpc83xx_km_init_IRQ(void) | ||
144 | { | ||
145 | struct device_node *np; | ||
146 | |||
147 | np = of_find_compatible_node(NULL, NULL, "fsl,pq2pro-pic"); | ||
148 | if (!np) { | ||
149 | np = of_find_node_by_type(NULL, "ipic"); | ||
150 | if (!np) | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | ipic_init(np, 0); | ||
155 | |||
156 | /* Initialize the default interrupt mapping priorities, | ||
157 | * in case the boot rom changed something on us. | ||
158 | */ | ||
159 | ipic_set_default_priority(); | ||
160 | of_node_put(np); | ||
161 | |||
162 | #ifdef CONFIG_QUICC_ENGINE | ||
163 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
164 | if (!np) { | ||
165 | np = of_find_node_by_type(NULL, "qeic"); | ||
166 | if (!np) | ||
167 | return; | ||
168 | } | ||
169 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
170 | of_node_put(np); | ||
171 | #endif /* CONFIG_QUICC_ENGINE */ | ||
172 | } | ||
173 | 125 | ||
174 | /* list of the supported boards */ | 126 | /* list of the supported boards */ |
175 | static char *board[] __initdata = { | 127 | static char *board[] __initdata = { |
@@ -198,7 +150,7 @@ define_machine(mpc83xx_km) { | |||
198 | .name = "mpc83xx-km-platform", | 150 | .name = "mpc83xx-km-platform", |
199 | .probe = mpc83xx_km_probe, | 151 | .probe = mpc83xx_km_probe, |
200 | .setup_arch = mpc83xx_km_setup_arch, | 152 | .setup_arch = mpc83xx_km_setup_arch, |
201 | .init_IRQ = mpc83xx_km_init_IRQ, | 153 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
202 | .get_irq = ipic_get_irq, | 154 | .get_irq = ipic_get_irq, |
203 | .restart = mpc83xx_restart, | 155 | .restart = mpc83xx_restart, |
204 | .time_init = mpc83xx_time_init, | 156 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index f01806c940e1..125336f750c6 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c | |||
@@ -11,10 +11,15 @@ | |||
11 | 11 | ||
12 | #include <linux/stddef.h> | 12 | #include <linux/stddef.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/pci.h> | ||
14 | 16 | ||
15 | #include <asm/io.h> | 17 | #include <asm/io.h> |
16 | #include <asm/hw_irq.h> | 18 | #include <asm/hw_irq.h> |
19 | #include <asm/ipic.h> | ||
20 | #include <asm/qe_ic.h> | ||
17 | #include <sysdev/fsl_soc.h> | 21 | #include <sysdev/fsl_soc.h> |
22 | #include <sysdev/fsl_pci.h> | ||
18 | 23 | ||
19 | #include "mpc83xx.h" | 24 | #include "mpc83xx.h" |
20 | 25 | ||
@@ -65,3 +70,75 @@ long __init mpc83xx_time_init(void) | |||
65 | 70 | ||
66 | return 0; | 71 | return 0; |
67 | } | 72 | } |
73 | |||
74 | void __init mpc83xx_ipic_init_IRQ(void) | ||
75 | { | ||
76 | struct device_node *np; | ||
77 | |||
78 | /* looking for fsl,pq2pro-pic which is asl compatible with fsl,ipic */ | ||
79 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
80 | if (!np) | ||
81 | np = of_find_node_by_type(NULL, "ipic"); | ||
82 | if (!np) | ||
83 | return; | ||
84 | |||
85 | ipic_init(np, 0); | ||
86 | |||
87 | of_node_put(np); | ||
88 | |||
89 | /* Initialize the default interrupt mapping priorities, | ||
90 | * in case the boot rom changed something on us. | ||
91 | */ | ||
92 | ipic_set_default_priority(); | ||
93 | } | ||
94 | |||
95 | #ifdef CONFIG_QUICC_ENGINE | ||
96 | void __init mpc83xx_qe_init_IRQ(void) | ||
97 | { | ||
98 | struct device_node *np; | ||
99 | |||
100 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
101 | if (!np) { | ||
102 | np = of_find_node_by_type(NULL, "qeic"); | ||
103 | if (!np) | ||
104 | return; | ||
105 | } | ||
106 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
107 | of_node_put(np); | ||
108 | } | ||
109 | |||
110 | void __init mpc83xx_ipic_and_qe_init_IRQ(void) | ||
111 | { | ||
112 | mpc83xx_ipic_init_IRQ(); | ||
113 | mpc83xx_qe_init_IRQ(); | ||
114 | } | ||
115 | #endif /* CONFIG_QUICC_ENGINE */ | ||
116 | |||
117 | static struct of_device_id __initdata of_bus_ids[] = { | ||
118 | { .type = "soc", }, | ||
119 | { .compatible = "soc", }, | ||
120 | { .compatible = "simple-bus" }, | ||
121 | { .compatible = "gianfar" }, | ||
122 | { .compatible = "gpio-leds", }, | ||
123 | { .type = "qe", }, | ||
124 | { .compatible = "fsl,qe", }, | ||
125 | {}, | ||
126 | }; | ||
127 | |||
128 | int __init mpc83xx_declare_of_platform_devices(void) | ||
129 | { | ||
130 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_PCI | ||
135 | void __init mpc83xx_setup_pci(void) | ||
136 | { | ||
137 | struct device_node *np; | ||
138 | |||
139 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
140 | mpc83xx_add_bridge(np); | ||
141 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
142 | mpc83xx_add_bridge(np); | ||
143 | } | ||
144 | #endif | ||
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c index d0c4e15b7794..4f2d9fea77b7 100644 --- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c | |||
@@ -27,36 +27,13 @@ | |||
27 | */ | 27 | */ |
28 | static void __init mpc830x_rdb_setup_arch(void) | 28 | static void __init mpc830x_rdb_setup_arch(void) |
29 | { | 29 | { |
30 | #ifdef CONFIG_PCI | ||
31 | struct device_node *np; | ||
32 | #endif | ||
33 | |||
34 | if (ppc_md.progress) | 30 | if (ppc_md.progress) |
35 | ppc_md.progress("mpc830x_rdb_setup_arch()", 0); | 31 | ppc_md.progress("mpc830x_rdb_setup_arch()", 0); |
36 | 32 | ||
37 | #ifdef CONFIG_PCI | 33 | mpc83xx_setup_pci(); |
38 | for_each_compatible_node(np, "pci", "fsl,mpc8308-pcie") | ||
39 | mpc83xx_add_bridge(np); | ||
40 | #endif | ||
41 | mpc831x_usb_cfg(); | 34 | mpc831x_usb_cfg(); |
42 | } | 35 | } |
43 | 36 | ||
44 | static void __init mpc830x_rdb_init_IRQ(void) | ||
45 | { | ||
46 | struct device_node *np; | ||
47 | |||
48 | np = of_find_node_by_type(NULL, "ipic"); | ||
49 | if (!np) | ||
50 | return; | ||
51 | |||
52 | ipic_init(np, 0); | ||
53 | |||
54 | /* Initialize the default interrupt mapping priorities, | ||
55 | * in case the boot rom changed something on us. | ||
56 | */ | ||
57 | ipic_set_default_priority(); | ||
58 | } | ||
59 | |||
60 | static const char *board[] __initdata = { | 37 | static const char *board[] __initdata = { |
61 | "MPC8308RDB", | 38 | "MPC8308RDB", |
62 | "fsl,mpc8308rdb", | 39 | "fsl,mpc8308rdb", |
@@ -72,24 +49,13 @@ static int __init mpc830x_rdb_probe(void) | |||
72 | return of_flat_dt_match(of_get_flat_dt_root(), board); | 49 | return of_flat_dt_match(of_get_flat_dt_root(), board); |
73 | } | 50 | } |
74 | 51 | ||
75 | static struct of_device_id __initdata of_bus_ids[] = { | 52 | machine_device_initcall(mpc830x_rdb, mpc83xx_declare_of_platform_devices); |
76 | { .compatible = "simple-bus" }, | ||
77 | { .compatible = "gianfar" }, | ||
78 | {}, | ||
79 | }; | ||
80 | |||
81 | static int __init declare_of_platform_devices(void) | ||
82 | { | ||
83 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
84 | return 0; | ||
85 | } | ||
86 | machine_device_initcall(mpc830x_rdb, declare_of_platform_devices); | ||
87 | 53 | ||
88 | define_machine(mpc830x_rdb) { | 54 | define_machine(mpc830x_rdb) { |
89 | .name = "MPC830x RDB", | 55 | .name = "MPC830x RDB", |
90 | .probe = mpc830x_rdb_probe, | 56 | .probe = mpc830x_rdb_probe, |
91 | .setup_arch = mpc830x_rdb_setup_arch, | 57 | .setup_arch = mpc830x_rdb_setup_arch, |
92 | .init_IRQ = mpc830x_rdb_init_IRQ, | 58 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
93 | .get_irq = ipic_get_irq, | 59 | .get_irq = ipic_get_irq, |
94 | .restart = mpc83xx_restart, | 60 | .restart = mpc83xx_restart, |
95 | .time_init = mpc83xx_time_init, | 61 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index f859ead49a8d..fa25977c52de 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c | |||
@@ -28,38 +28,13 @@ | |||
28 | */ | 28 | */ |
29 | static void __init mpc831x_rdb_setup_arch(void) | 29 | static void __init mpc831x_rdb_setup_arch(void) |
30 | { | 30 | { |
31 | #ifdef CONFIG_PCI | ||
32 | struct device_node *np; | ||
33 | #endif | ||
34 | |||
35 | if (ppc_md.progress) | 31 | if (ppc_md.progress) |
36 | ppc_md.progress("mpc831x_rdb_setup_arch()", 0); | 32 | ppc_md.progress("mpc831x_rdb_setup_arch()", 0); |
37 | 33 | ||
38 | #ifdef CONFIG_PCI | 34 | mpc83xx_setup_pci(); |
39 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
40 | mpc83xx_add_bridge(np); | ||
41 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
42 | mpc83xx_add_bridge(np); | ||
43 | #endif | ||
44 | mpc831x_usb_cfg(); | 35 | mpc831x_usb_cfg(); |
45 | } | 36 | } |
46 | 37 | ||
47 | static void __init mpc831x_rdb_init_IRQ(void) | ||
48 | { | ||
49 | struct device_node *np; | ||
50 | |||
51 | np = of_find_node_by_type(NULL, "ipic"); | ||
52 | if (!np) | ||
53 | return; | ||
54 | |||
55 | ipic_init(np, 0); | ||
56 | |||
57 | /* Initialize the default interrupt mapping priorities, | ||
58 | * in case the boot rom changed something on us. | ||
59 | */ | ||
60 | ipic_set_default_priority(); | ||
61 | } | ||
62 | |||
63 | static const char *board[] __initdata = { | 38 | static const char *board[] __initdata = { |
64 | "MPC8313ERDB", | 39 | "MPC8313ERDB", |
65 | "fsl,mpc8315erdb", | 40 | "fsl,mpc8315erdb", |
@@ -74,25 +49,13 @@ static int __init mpc831x_rdb_probe(void) | |||
74 | return of_flat_dt_match(of_get_flat_dt_root(), board); | 49 | return of_flat_dt_match(of_get_flat_dt_root(), board); |
75 | } | 50 | } |
76 | 51 | ||
77 | static struct of_device_id __initdata of_bus_ids[] = { | 52 | machine_device_initcall(mpc831x_rdb, mpc83xx_declare_of_platform_devices); |
78 | { .compatible = "simple-bus" }, | ||
79 | { .compatible = "gianfar" }, | ||
80 | { .compatible = "gpio-leds", }, | ||
81 | {}, | ||
82 | }; | ||
83 | |||
84 | static int __init declare_of_platform_devices(void) | ||
85 | { | ||
86 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
87 | return 0; | ||
88 | } | ||
89 | machine_device_initcall(mpc831x_rdb, declare_of_platform_devices); | ||
90 | 53 | ||
91 | define_machine(mpc831x_rdb) { | 54 | define_machine(mpc831x_rdb) { |
92 | .name = "MPC831x RDB", | 55 | .name = "MPC831x RDB", |
93 | .probe = mpc831x_rdb_probe, | 56 | .probe = mpc831x_rdb_probe, |
94 | .setup_arch = mpc831x_rdb_setup_arch, | 57 | .setup_arch = mpc831x_rdb_setup_arch, |
95 | .init_IRQ = mpc831x_rdb_init_IRQ, | 58 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
96 | .get_irq = ipic_get_irq, | 59 | .get_irq = ipic_get_irq, |
97 | .restart = mpc83xx_restart, | 60 | .restart = mpc83xx_restart, |
98 | .time_init = mpc83xx_time_init, | 61 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 32a52896822f..e36bc611dd6e 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c | |||
@@ -72,10 +72,7 @@ static void __init mpc832x_sys_setup_arch(void) | |||
72 | of_node_put(np); | 72 | of_node_put(np); |
73 | } | 73 | } |
74 | 74 | ||
75 | #ifdef CONFIG_PCI | 75 | mpc83xx_setup_pci(); |
76 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
77 | mpc83xx_add_bridge(np); | ||
78 | #endif | ||
79 | 76 | ||
80 | #ifdef CONFIG_QUICC_ENGINE | 77 | #ifdef CONFIG_QUICC_ENGINE |
81 | qe_reset(); | 78 | qe_reset(); |
@@ -101,51 +98,7 @@ static void __init mpc832x_sys_setup_arch(void) | |||
101 | #endif /* CONFIG_QUICC_ENGINE */ | 98 | #endif /* CONFIG_QUICC_ENGINE */ |
102 | } | 99 | } |
103 | 100 | ||
104 | static struct of_device_id mpc832x_ids[] = { | 101 | machine_device_initcall(mpc832x_mds, mpc83xx_declare_of_platform_devices); |
105 | { .type = "soc", }, | ||
106 | { .compatible = "soc", }, | ||
107 | { .compatible = "simple-bus", }, | ||
108 | { .type = "qe", }, | ||
109 | { .compatible = "fsl,qe", }, | ||
110 | {}, | ||
111 | }; | ||
112 | |||
113 | static int __init mpc832x_declare_of_platform_devices(void) | ||
114 | { | ||
115 | /* Publish the QE devices */ | ||
116 | of_platform_bus_probe(NULL, mpc832x_ids, NULL); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | machine_device_initcall(mpc832x_mds, mpc832x_declare_of_platform_devices); | ||
121 | |||
122 | static void __init mpc832x_sys_init_IRQ(void) | ||
123 | { | ||
124 | struct device_node *np; | ||
125 | |||
126 | np = of_find_node_by_type(NULL, "ipic"); | ||
127 | if (!np) | ||
128 | return; | ||
129 | |||
130 | ipic_init(np, 0); | ||
131 | |||
132 | /* Initialize the default interrupt mapping priorities, | ||
133 | * in case the boot rom changed something on us. | ||
134 | */ | ||
135 | ipic_set_default_priority(); | ||
136 | of_node_put(np); | ||
137 | |||
138 | #ifdef CONFIG_QUICC_ENGINE | ||
139 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
140 | if (!np) { | ||
141 | np = of_find_node_by_type(NULL, "qeic"); | ||
142 | if (!np) | ||
143 | return; | ||
144 | } | ||
145 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
146 | of_node_put(np); | ||
147 | #endif /* CONFIG_QUICC_ENGINE */ | ||
148 | } | ||
149 | 102 | ||
150 | /* | 103 | /* |
151 | * Called very early, MMU is off, device-tree isn't unflattened | 104 | * Called very early, MMU is off, device-tree isn't unflattened |
@@ -161,7 +114,7 @@ define_machine(mpc832x_mds) { | |||
161 | .name = "MPC832x MDS", | 114 | .name = "MPC832x MDS", |
162 | .probe = mpc832x_sys_probe, | 115 | .probe = mpc832x_sys_probe, |
163 | .setup_arch = mpc832x_sys_setup_arch, | 116 | .setup_arch = mpc832x_sys_setup_arch, |
164 | .init_IRQ = mpc832x_sys_init_IRQ, | 117 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
165 | .get_irq = ipic_get_irq, | 118 | .get_irq = ipic_get_irq, |
166 | .restart = mpc83xx_restart, | 119 | .restart = mpc83xx_restart, |
167 | .time_init = mpc83xx_time_init, | 120 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 17f99745f0e4..eff5baabc3fb 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c | |||
@@ -193,17 +193,14 @@ machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); | |||
193 | */ | 193 | */ |
194 | static void __init mpc832x_rdb_setup_arch(void) | 194 | static void __init mpc832x_rdb_setup_arch(void) |
195 | { | 195 | { |
196 | #if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE) | 196 | #if defined(CONFIG_QUICC_ENGINE) |
197 | struct device_node *np; | 197 | struct device_node *np; |
198 | #endif | 198 | #endif |
199 | 199 | ||
200 | if (ppc_md.progress) | 200 | if (ppc_md.progress) |
201 | ppc_md.progress("mpc832x_rdb_setup_arch()", 0); | 201 | ppc_md.progress("mpc832x_rdb_setup_arch()", 0); |
202 | 202 | ||
203 | #ifdef CONFIG_PCI | 203 | mpc83xx_setup_pci(); |
204 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
205 | mpc83xx_add_bridge(np); | ||
206 | #endif | ||
207 | 204 | ||
208 | #ifdef CONFIG_QUICC_ENGINE | 205 | #ifdef CONFIG_QUICC_ENGINE |
209 | qe_reset(); | 206 | qe_reset(); |
@@ -218,52 +215,7 @@ static void __init mpc832x_rdb_setup_arch(void) | |||
218 | #endif /* CONFIG_QUICC_ENGINE */ | 215 | #endif /* CONFIG_QUICC_ENGINE */ |
219 | } | 216 | } |
220 | 217 | ||
221 | static struct of_device_id mpc832x_ids[] = { | 218 | machine_device_initcall(mpc832x_rdb, mpc83xx_declare_of_platform_devices); |
222 | { .type = "soc", }, | ||
223 | { .compatible = "soc", }, | ||
224 | { .compatible = "simple-bus", }, | ||
225 | { .type = "qe", }, | ||
226 | { .compatible = "fsl,qe", }, | ||
227 | {}, | ||
228 | }; | ||
229 | |||
230 | static int __init mpc832x_declare_of_platform_devices(void) | ||
231 | { | ||
232 | /* Publish the QE devices */ | ||
233 | of_platform_bus_probe(NULL, mpc832x_ids, NULL); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices); | ||
238 | |||
239 | static void __init mpc832x_rdb_init_IRQ(void) | ||
240 | { | ||
241 | |||
242 | struct device_node *np; | ||
243 | |||
244 | np = of_find_node_by_type(NULL, "ipic"); | ||
245 | if (!np) | ||
246 | return; | ||
247 | |||
248 | ipic_init(np, 0); | ||
249 | |||
250 | /* Initialize the default interrupt mapping priorities, | ||
251 | * in case the boot rom changed something on us. | ||
252 | */ | ||
253 | ipic_set_default_priority(); | ||
254 | of_node_put(np); | ||
255 | |||
256 | #ifdef CONFIG_QUICC_ENGINE | ||
257 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
258 | if (!np) { | ||
259 | np = of_find_node_by_type(NULL, "qeic"); | ||
260 | if (!np) | ||
261 | return; | ||
262 | } | ||
263 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
264 | of_node_put(np); | ||
265 | #endif /* CONFIG_QUICC_ENGINE */ | ||
266 | } | ||
267 | 219 | ||
268 | /* | 220 | /* |
269 | * Called very early, MMU is off, device-tree isn't unflattened | 221 | * Called very early, MMU is off, device-tree isn't unflattened |
@@ -279,7 +231,7 @@ define_machine(mpc832x_rdb) { | |||
279 | .name = "MPC832x RDB", | 231 | .name = "MPC832x RDB", |
280 | .probe = mpc832x_rdb_probe, | 232 | .probe = mpc832x_rdb_probe, |
281 | .setup_arch = mpc832x_rdb_setup_arch, | 233 | .setup_arch = mpc832x_rdb_setup_arch, |
282 | .init_IRQ = mpc832x_rdb_init_IRQ, | 234 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
283 | .get_irq = ipic_get_irq, | 235 | .get_irq = ipic_get_irq, |
284 | .restart = mpc83xx_restart, | 236 | .restart = mpc83xx_restart, |
285 | .time_init = mpc83xx_time_init, | 237 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 6b45969567d4..39849dd1b5bb 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c | |||
@@ -41,13 +41,12 @@ | |||
41 | 41 | ||
42 | static struct of_device_id __initdata mpc834x_itx_ids[] = { | 42 | static struct of_device_id __initdata mpc834x_itx_ids[] = { |
43 | { .compatible = "fsl,pq2pro-localbus", }, | 43 | { .compatible = "fsl,pq2pro-localbus", }, |
44 | { .compatible = "simple-bus", }, | ||
45 | { .compatible = "gianfar", }, | ||
46 | {}, | 44 | {}, |
47 | }; | 45 | }; |
48 | 46 | ||
49 | static int __init mpc834x_itx_declare_of_platform_devices(void) | 47 | static int __init mpc834x_itx_declare_of_platform_devices(void) |
50 | { | 48 | { |
49 | mpc83xx_declare_of_platform_devices(); | ||
51 | return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL); | 50 | return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL); |
52 | } | 51 | } |
53 | machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); | 52 | machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); |
@@ -59,37 +58,14 @@ machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); | |||
59 | */ | 58 | */ |
60 | static void __init mpc834x_itx_setup_arch(void) | 59 | static void __init mpc834x_itx_setup_arch(void) |
61 | { | 60 | { |
62 | #ifdef CONFIG_PCI | ||
63 | struct device_node *np; | ||
64 | #endif | ||
65 | |||
66 | if (ppc_md.progress) | 61 | if (ppc_md.progress) |
67 | ppc_md.progress("mpc834x_itx_setup_arch()", 0); | 62 | ppc_md.progress("mpc834x_itx_setup_arch()", 0); |
68 | 63 | ||
69 | #ifdef CONFIG_PCI | 64 | mpc83xx_setup_pci(); |
70 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
71 | mpc83xx_add_bridge(np); | ||
72 | #endif | ||
73 | 65 | ||
74 | mpc834x_usb_cfg(); | 66 | mpc834x_usb_cfg(); |
75 | } | 67 | } |
76 | 68 | ||
77 | static void __init mpc834x_itx_init_IRQ(void) | ||
78 | { | ||
79 | struct device_node *np; | ||
80 | |||
81 | np = of_find_node_by_type(NULL, "ipic"); | ||
82 | if (!np) | ||
83 | return; | ||
84 | |||
85 | ipic_init(np, 0); | ||
86 | |||
87 | /* Initialize the default interrupt mapping priorities, | ||
88 | * in case the boot rom changed something on us. | ||
89 | */ | ||
90 | ipic_set_default_priority(); | ||
91 | } | ||
92 | |||
93 | /* | 69 | /* |
94 | * Called very early, MMU is off, device-tree isn't unflattened | 70 | * Called very early, MMU is off, device-tree isn't unflattened |
95 | */ | 71 | */ |
@@ -104,7 +80,7 @@ define_machine(mpc834x_itx) { | |||
104 | .name = "MPC834x ITX", | 80 | .name = "MPC834x ITX", |
105 | .probe = mpc834x_itx_probe, | 81 | .probe = mpc834x_itx_probe, |
106 | .setup_arch = mpc834x_itx_setup_arch, | 82 | .setup_arch = mpc834x_itx_setup_arch, |
107 | .init_IRQ = mpc834x_itx_init_IRQ, | 83 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
108 | .get_irq = ipic_get_irq, | 84 | .get_irq = ipic_get_irq, |
109 | .restart = mpc83xx_restart, | 85 | .restart = mpc83xx_restart, |
110 | .time_init = mpc83xx_time_init, | 86 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c index 041c5177e737..5828d8e97c37 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c | |||
@@ -77,51 +77,15 @@ static int mpc834xemds_usb_cfg(void) | |||
77 | */ | 77 | */ |
78 | static void __init mpc834x_mds_setup_arch(void) | 78 | static void __init mpc834x_mds_setup_arch(void) |
79 | { | 79 | { |
80 | #ifdef CONFIG_PCI | ||
81 | struct device_node *np; | ||
82 | #endif | ||
83 | |||
84 | if (ppc_md.progress) | 80 | if (ppc_md.progress) |
85 | ppc_md.progress("mpc834x_mds_setup_arch()", 0); | 81 | ppc_md.progress("mpc834x_mds_setup_arch()", 0); |
86 | 82 | ||
87 | #ifdef CONFIG_PCI | 83 | mpc83xx_setup_pci(); |
88 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
89 | mpc83xx_add_bridge(np); | ||
90 | #endif | ||
91 | 84 | ||
92 | mpc834xemds_usb_cfg(); | 85 | mpc834xemds_usb_cfg(); |
93 | } | 86 | } |
94 | 87 | ||
95 | static void __init mpc834x_mds_init_IRQ(void) | 88 | machine_device_initcall(mpc834x_mds, mpc83xx_declare_of_platform_devices); |
96 | { | ||
97 | struct device_node *np; | ||
98 | |||
99 | np = of_find_node_by_type(NULL, "ipic"); | ||
100 | if (!np) | ||
101 | return; | ||
102 | |||
103 | ipic_init(np, 0); | ||
104 | |||
105 | /* Initialize the default interrupt mapping priorities, | ||
106 | * in case the boot rom changed something on us. | ||
107 | */ | ||
108 | ipic_set_default_priority(); | ||
109 | } | ||
110 | |||
111 | static struct of_device_id mpc834x_ids[] = { | ||
112 | { .type = "soc", }, | ||
113 | { .compatible = "soc", }, | ||
114 | { .compatible = "simple-bus", }, | ||
115 | { .compatible = "gianfar", }, | ||
116 | {}, | ||
117 | }; | ||
118 | |||
119 | static int __init mpc834x_declare_of_platform_devices(void) | ||
120 | { | ||
121 | of_platform_bus_probe(NULL, mpc834x_ids, NULL); | ||
122 | return 0; | ||
123 | } | ||
124 | machine_device_initcall(mpc834x_mds, mpc834x_declare_of_platform_devices); | ||
125 | 89 | ||
126 | /* | 90 | /* |
127 | * Called very early, MMU is off, device-tree isn't unflattened | 91 | * Called very early, MMU is off, device-tree isn't unflattened |
@@ -137,7 +101,7 @@ define_machine(mpc834x_mds) { | |||
137 | .name = "MPC834x MDS", | 101 | .name = "MPC834x MDS", |
138 | .probe = mpc834x_mds_probe, | 102 | .probe = mpc834x_mds_probe, |
139 | .setup_arch = mpc834x_mds_setup_arch, | 103 | .setup_arch = mpc834x_mds_setup_arch, |
140 | .init_IRQ = mpc834x_mds_init_IRQ, | 104 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
141 | .get_irq = ipic_get_irq, | 105 | .get_irq = ipic_get_irq, |
142 | .restart = mpc83xx_restart, | 106 | .restart = mpc83xx_restart, |
143 | .time_init = mpc83xx_time_init, | 107 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c index 934cc8c46bbc..ad8e4bcd7d55 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c | |||
@@ -80,10 +80,7 @@ static void __init mpc836x_mds_setup_arch(void) | |||
80 | of_node_put(np); | 80 | of_node_put(np); |
81 | } | 81 | } |
82 | 82 | ||
83 | #ifdef CONFIG_PCI | 83 | mpc83xx_setup_pci(); |
84 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
85 | mpc83xx_add_bridge(np); | ||
86 | #endif | ||
87 | 84 | ||
88 | #ifdef CONFIG_QUICC_ENGINE | 85 | #ifdef CONFIG_QUICC_ENGINE |
89 | qe_reset(); | 86 | qe_reset(); |
@@ -144,23 +141,7 @@ static void __init mpc836x_mds_setup_arch(void) | |||
144 | #endif /* CONFIG_QUICC_ENGINE */ | 141 | #endif /* CONFIG_QUICC_ENGINE */ |
145 | } | 142 | } |
146 | 143 | ||
147 | static struct of_device_id mpc836x_ids[] = { | 144 | machine_device_initcall(mpc836x_mds, mpc83xx_declare_of_platform_devices); |
148 | { .type = "soc", }, | ||
149 | { .compatible = "soc", }, | ||
150 | { .compatible = "simple-bus", }, | ||
151 | { .type = "qe", }, | ||
152 | { .compatible = "fsl,qe", }, | ||
153 | {}, | ||
154 | }; | ||
155 | |||
156 | static int __init mpc836x_declare_of_platform_devices(void) | ||
157 | { | ||
158 | /* Publish the QE devices */ | ||
159 | of_platform_bus_probe(NULL, mpc836x_ids, NULL); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | machine_device_initcall(mpc836x_mds, mpc836x_declare_of_platform_devices); | ||
164 | 145 | ||
165 | #ifdef CONFIG_QE_USB | 146 | #ifdef CONFIG_QE_USB |
166 | static int __init mpc836x_usb_cfg(void) | 147 | static int __init mpc836x_usb_cfg(void) |
@@ -226,34 +207,6 @@ err: | |||
226 | machine_arch_initcall(mpc836x_mds, mpc836x_usb_cfg); | 207 | machine_arch_initcall(mpc836x_mds, mpc836x_usb_cfg); |
227 | #endif /* CONFIG_QE_USB */ | 208 | #endif /* CONFIG_QE_USB */ |
228 | 209 | ||
229 | static void __init mpc836x_mds_init_IRQ(void) | ||
230 | { | ||
231 | struct device_node *np; | ||
232 | |||
233 | np = of_find_node_by_type(NULL, "ipic"); | ||
234 | if (!np) | ||
235 | return; | ||
236 | |||
237 | ipic_init(np, 0); | ||
238 | |||
239 | /* Initialize the default interrupt mapping priorities, | ||
240 | * in case the boot rom changed something on us. | ||
241 | */ | ||
242 | ipic_set_default_priority(); | ||
243 | of_node_put(np); | ||
244 | |||
245 | #ifdef CONFIG_QUICC_ENGINE | ||
246 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
247 | if (!np) { | ||
248 | np = of_find_node_by_type(NULL, "qeic"); | ||
249 | if (!np) | ||
250 | return; | ||
251 | } | ||
252 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
253 | of_node_put(np); | ||
254 | #endif /* CONFIG_QUICC_ENGINE */ | ||
255 | } | ||
256 | |||
257 | /* | 210 | /* |
258 | * Called very early, MMU is off, device-tree isn't unflattened | 211 | * Called very early, MMU is off, device-tree isn't unflattened |
259 | */ | 212 | */ |
@@ -268,7 +221,7 @@ define_machine(mpc836x_mds) { | |||
268 | .name = "MPC836x MDS", | 221 | .name = "MPC836x MDS", |
269 | .probe = mpc836x_mds_probe, | 222 | .probe = mpc836x_mds_probe, |
270 | .setup_arch = mpc836x_mds_setup_arch, | 223 | .setup_arch = mpc836x_mds_setup_arch, |
271 | .init_IRQ = mpc836x_mds_init_IRQ, | 224 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
272 | .get_irq = ipic_get_irq, | 225 | .get_irq = ipic_get_irq, |
273 | .restart = mpc83xx_restart, | 226 | .restart = mpc83xx_restart, |
274 | .time_init = mpc83xx_time_init, | 227 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c index b0090aac9642..f8769d713d61 100644 --- a/arch/powerpc/platforms/83xx/mpc836x_rdk.c +++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c | |||
@@ -27,61 +27,19 @@ | |||
27 | 27 | ||
28 | #include "mpc83xx.h" | 28 | #include "mpc83xx.h" |
29 | 29 | ||
30 | static struct of_device_id __initdata mpc836x_rdk_ids[] = { | 30 | machine_device_initcall(mpc836x_rdk, mpc83xx_declare_of_platform_devices); |
31 | { .compatible = "simple-bus", }, | ||
32 | {}, | ||
33 | }; | ||
34 | |||
35 | static int __init mpc836x_rdk_declare_of_platform_devices(void) | ||
36 | { | ||
37 | return of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL); | ||
38 | } | ||
39 | machine_device_initcall(mpc836x_rdk, mpc836x_rdk_declare_of_platform_devices); | ||
40 | 31 | ||
41 | static void __init mpc836x_rdk_setup_arch(void) | 32 | static void __init mpc836x_rdk_setup_arch(void) |
42 | { | 33 | { |
43 | #ifdef CONFIG_PCI | ||
44 | struct device_node *np; | ||
45 | #endif | ||
46 | |||
47 | if (ppc_md.progress) | 34 | if (ppc_md.progress) |
48 | ppc_md.progress("mpc836x_rdk_setup_arch()", 0); | 35 | ppc_md.progress("mpc836x_rdk_setup_arch()", 0); |
49 | 36 | ||
50 | #ifdef CONFIG_PCI | 37 | mpc83xx_setup_pci(); |
51 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
52 | mpc83xx_add_bridge(np); | ||
53 | #endif | ||
54 | #ifdef CONFIG_QUICC_ENGINE | 38 | #ifdef CONFIG_QUICC_ENGINE |
55 | qe_reset(); | 39 | qe_reset(); |
56 | #endif | 40 | #endif |
57 | } | 41 | } |
58 | 42 | ||
59 | static void __init mpc836x_rdk_init_IRQ(void) | ||
60 | { | ||
61 | struct device_node *np; | ||
62 | |||
63 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
64 | if (!np) | ||
65 | return; | ||
66 | |||
67 | ipic_init(np, 0); | ||
68 | |||
69 | /* | ||
70 | * Initialize the default interrupt mapping priorities, | ||
71 | * in case the boot rom changed something on us. | ||
72 | */ | ||
73 | ipic_set_default_priority(); | ||
74 | of_node_put(np); | ||
75 | #ifdef CONFIG_QUICC_ENGINE | ||
76 | np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | ||
77 | if (!np) | ||
78 | return; | ||
79 | |||
80 | qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic); | ||
81 | of_node_put(np); | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | /* | 43 | /* |
86 | * Called very early, MMU is off, device-tree isn't unflattened. | 44 | * Called very early, MMU is off, device-tree isn't unflattened. |
87 | */ | 45 | */ |
@@ -96,7 +54,7 @@ define_machine(mpc836x_rdk) { | |||
96 | .name = "MPC836x RDK", | 54 | .name = "MPC836x RDK", |
97 | .probe = mpc836x_rdk_probe, | 55 | .probe = mpc836x_rdk_probe, |
98 | .setup_arch = mpc836x_rdk_setup_arch, | 56 | .setup_arch = mpc836x_rdk_setup_arch, |
99 | .init_IRQ = mpc836x_rdk_init_IRQ, | 57 | .init_IRQ = mpc83xx_ipic_and_qe_init_IRQ, |
100 | .get_irq = ipic_get_irq, | 58 | .get_irq = ipic_get_irq, |
101 | .restart = mpc83xx_restart, | 59 | .restart = mpc83xx_restart, |
102 | .time_init = mpc83xx_time_init, | 60 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 83068322abd1..e53a60b6c863 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c | |||
@@ -79,54 +79,14 @@ out: | |||
79 | */ | 79 | */ |
80 | static void __init mpc837x_mds_setup_arch(void) | 80 | static void __init mpc837x_mds_setup_arch(void) |
81 | { | 81 | { |
82 | #ifdef CONFIG_PCI | ||
83 | struct device_node *np; | ||
84 | #endif | ||
85 | |||
86 | if (ppc_md.progress) | 82 | if (ppc_md.progress) |
87 | ppc_md.progress("mpc837x_mds_setup_arch()", 0); | 83 | ppc_md.progress("mpc837x_mds_setup_arch()", 0); |
88 | 84 | ||
89 | #ifdef CONFIG_PCI | 85 | mpc83xx_setup_pci(); |
90 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
91 | mpc83xx_add_bridge(np); | ||
92 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
93 | mpc83xx_add_bridge(np); | ||
94 | #endif | ||
95 | mpc837xmds_usb_cfg(); | 86 | mpc837xmds_usb_cfg(); |
96 | } | 87 | } |
97 | 88 | ||
98 | static struct of_device_id mpc837x_ids[] = { | 89 | machine_device_initcall(mpc837x_mds, mpc83xx_declare_of_platform_devices); |
99 | { .type = "soc", }, | ||
100 | { .compatible = "soc", }, | ||
101 | { .compatible = "simple-bus", }, | ||
102 | { .compatible = "gianfar", }, | ||
103 | {}, | ||
104 | }; | ||
105 | |||
106 | static int __init mpc837x_declare_of_platform_devices(void) | ||
107 | { | ||
108 | /* Publish platform_device */ | ||
109 | of_platform_bus_probe(NULL, mpc837x_ids, NULL); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices); | ||
114 | |||
115 | static void __init mpc837x_mds_init_IRQ(void) | ||
116 | { | ||
117 | struct device_node *np; | ||
118 | |||
119 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
120 | if (!np) | ||
121 | return; | ||
122 | |||
123 | ipic_init(np, 0); | ||
124 | |||
125 | /* Initialize the default interrupt mapping priorities, | ||
126 | * in case the boot rom changed something on us. | ||
127 | */ | ||
128 | ipic_set_default_priority(); | ||
129 | } | ||
130 | 90 | ||
131 | /* | 91 | /* |
132 | * Called very early, MMU is off, device-tree isn't unflattened | 92 | * Called very early, MMU is off, device-tree isn't unflattened |
@@ -142,7 +102,7 @@ define_machine(mpc837x_mds) { | |||
142 | .name = "MPC837x MDS", | 102 | .name = "MPC837x MDS", |
143 | .probe = mpc837x_mds_probe, | 103 | .probe = mpc837x_mds_probe, |
144 | .setup_arch = mpc837x_mds_setup_arch, | 104 | .setup_arch = mpc837x_mds_setup_arch, |
145 | .init_IRQ = mpc837x_mds_init_IRQ, | 105 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
146 | .get_irq = ipic_get_irq, | 106 | .get_irq = ipic_get_irq, |
147 | .restart = mpc83xx_restart, | 107 | .restart = mpc83xx_restart, |
148 | .time_init = mpc83xx_time_init, | 108 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 7bafbf2ec0f9..16c9c9cbbb7f 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c | |||
@@ -50,56 +50,15 @@ static void mpc837x_rdb_sd_cfg(void) | |||
50 | */ | 50 | */ |
51 | static void __init mpc837x_rdb_setup_arch(void) | 51 | static void __init mpc837x_rdb_setup_arch(void) |
52 | { | 52 | { |
53 | #ifdef CONFIG_PCI | ||
54 | struct device_node *np; | ||
55 | #endif | ||
56 | |||
57 | if (ppc_md.progress) | 53 | if (ppc_md.progress) |
58 | ppc_md.progress("mpc837x_rdb_setup_arch()", 0); | 54 | ppc_md.progress("mpc837x_rdb_setup_arch()", 0); |
59 | 55 | ||
60 | #ifdef CONFIG_PCI | 56 | mpc83xx_setup_pci(); |
61 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
62 | mpc83xx_add_bridge(np); | ||
63 | for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie") | ||
64 | mpc83xx_add_bridge(np); | ||
65 | #endif | ||
66 | mpc837x_usb_cfg(); | 57 | mpc837x_usb_cfg(); |
67 | mpc837x_rdb_sd_cfg(); | 58 | mpc837x_rdb_sd_cfg(); |
68 | } | 59 | } |
69 | 60 | ||
70 | static struct of_device_id mpc837x_ids[] = { | 61 | machine_device_initcall(mpc837x_rdb, mpc83xx_declare_of_platform_devices); |
71 | { .type = "soc", }, | ||
72 | { .compatible = "soc", }, | ||
73 | { .compatible = "simple-bus", }, | ||
74 | { .compatible = "gianfar", }, | ||
75 | { .compatible = "gpio-leds", }, | ||
76 | {}, | ||
77 | }; | ||
78 | |||
79 | static int __init mpc837x_declare_of_platform_devices(void) | ||
80 | { | ||
81 | /* Publish platform_device */ | ||
82 | of_platform_bus_probe(NULL, mpc837x_ids, NULL); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | machine_device_initcall(mpc837x_rdb, mpc837x_declare_of_platform_devices); | ||
87 | |||
88 | static void __init mpc837x_rdb_init_IRQ(void) | ||
89 | { | ||
90 | struct device_node *np; | ||
91 | |||
92 | np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); | ||
93 | if (!np) | ||
94 | return; | ||
95 | |||
96 | ipic_init(np, 0); | ||
97 | |||
98 | /* Initialize the default interrupt mapping priorities, | ||
99 | * in case the boot rom changed something on us. | ||
100 | */ | ||
101 | ipic_set_default_priority(); | ||
102 | } | ||
103 | 62 | ||
104 | static const char *board[] __initdata = { | 63 | static const char *board[] __initdata = { |
105 | "fsl,mpc8377rdb", | 64 | "fsl,mpc8377rdb", |
@@ -121,7 +80,7 @@ define_machine(mpc837x_rdb) { | |||
121 | .name = "MPC837x RDB/WLAN", | 80 | .name = "MPC837x RDB/WLAN", |
122 | .probe = mpc837x_rdb_probe, | 81 | .probe = mpc837x_rdb_probe, |
123 | .setup_arch = mpc837x_rdb_setup_arch, | 82 | .setup_arch = mpc837x_rdb_setup_arch, |
124 | .init_IRQ = mpc837x_rdb_init_IRQ, | 83 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
125 | .get_irq = ipic_get_irq, | 84 | .get_irq = ipic_get_irq, |
126 | .restart = mpc83xx_restart, | 85 | .restart = mpc83xx_restart, |
127 | .time_init = mpc83xx_time_init, | 86 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 82a434510d83..0cf74d7ea1c5 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h | |||
@@ -70,5 +70,21 @@ extern long mpc83xx_time_init(void); | |||
70 | extern int mpc837x_usb_cfg(void); | 70 | extern int mpc837x_usb_cfg(void); |
71 | extern int mpc834x_usb_cfg(void); | 71 | extern int mpc834x_usb_cfg(void); |
72 | extern int mpc831x_usb_cfg(void); | 72 | extern int mpc831x_usb_cfg(void); |
73 | extern void mpc83xx_ipic_init_IRQ(void); | ||
74 | #ifdef CONFIG_QUICC_ENGINE | ||
75 | extern void mpc83xx_qe_init_IRQ(void); | ||
76 | extern void mpc83xx_ipic_and_qe_init_IRQ(void); | ||
77 | #else | ||
78 | static inline void __init mpc83xx_qe_init_IRQ(void) {} | ||
79 | #define mpc83xx_ipic_and_qe_init_IRQ mpc83xx_ipic_init_IRQ | ||
80 | #endif /* CONFIG_QUICC_ENGINE */ | ||
81 | |||
82 | #ifdef CONFIG_PCI | ||
83 | extern void mpc83xx_setup_pci(void); | ||
84 | #else | ||
85 | #define mpc83xx_setup_pci() do {} while (0) | ||
86 | #endif | ||
87 | |||
88 | extern int mpc83xx_declare_of_platform_devices(void); | ||
73 | 89 | ||
74 | #endif /* __MPC83XX_H__ */ | 90 | #endif /* __MPC83XX_H__ */ |
diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c index af41d8c810a8..8a81d7640b1f 100644 --- a/arch/powerpc/platforms/83xx/sbc834x.c +++ b/arch/powerpc/platforms/83xx/sbc834x.c | |||
@@ -48,52 +48,13 @@ | |||
48 | */ | 48 | */ |
49 | static void __init sbc834x_setup_arch(void) | 49 | static void __init sbc834x_setup_arch(void) |
50 | { | 50 | { |
51 | #ifdef CONFIG_PCI | ||
52 | struct device_node *np; | ||
53 | #endif | ||
54 | |||
55 | if (ppc_md.progress) | 51 | if (ppc_md.progress) |
56 | ppc_md.progress("sbc834x_setup_arch()", 0); | 52 | ppc_md.progress("sbc834x_setup_arch()", 0); |
57 | 53 | ||
58 | #ifdef CONFIG_PCI | 54 | mpc83xx_setup_pci(); |
59 | for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") | ||
60 | mpc83xx_add_bridge(np); | ||
61 | #endif | ||
62 | |||
63 | } | 55 | } |
64 | 56 | ||
65 | static void __init sbc834x_init_IRQ(void) | 57 | machine_device_initcall(sbc834x, mpc83xx_declare_of_platform_devices); |
66 | { | ||
67 | struct device_node *np; | ||
68 | |||
69 | np = of_find_node_by_type(NULL, "ipic"); | ||
70 | if (!np) | ||
71 | return; | ||
72 | |||
73 | ipic_init(np, 0); | ||
74 | |||
75 | /* Initialize the default interrupt mapping priorities, | ||
76 | * in case the boot rom changed something on us. | ||
77 | */ | ||
78 | ipic_set_default_priority(); | ||
79 | |||
80 | of_node_put(np); | ||
81 | } | ||
82 | |||
83 | static struct __initdata of_device_id sbc834x_ids[] = { | ||
84 | { .type = "soc", }, | ||
85 | { .compatible = "soc", }, | ||
86 | { .compatible = "simple-bus", }, | ||
87 | { .compatible = "gianfar", }, | ||
88 | {}, | ||
89 | }; | ||
90 | |||
91 | static int __init sbc834x_declare_of_platform_devices(void) | ||
92 | { | ||
93 | of_platform_bus_probe(NULL, sbc834x_ids, NULL); | ||
94 | return 0; | ||
95 | } | ||
96 | machine_device_initcall(sbc834x, sbc834x_declare_of_platform_devices); | ||
97 | 58 | ||
98 | /* | 59 | /* |
99 | * Called very early, MMU is off, device-tree isn't unflattened | 60 | * Called very early, MMU is off, device-tree isn't unflattened |
@@ -102,14 +63,14 @@ static int __init sbc834x_probe(void) | |||
102 | { | 63 | { |
103 | unsigned long root = of_get_flat_dt_root(); | 64 | unsigned long root = of_get_flat_dt_root(); |
104 | 65 | ||
105 | return of_flat_dt_is_compatible(root, "SBC834x"); | 66 | return of_flat_dt_is_compatible(root, "SBC834xE"); |
106 | } | 67 | } |
107 | 68 | ||
108 | define_machine(sbc834x) { | 69 | define_machine(sbc834x) { |
109 | .name = "SBC834x", | 70 | .name = "SBC834xE", |
110 | .probe = sbc834x_probe, | 71 | .probe = sbc834x_probe, |
111 | .setup_arch = sbc834x_setup_arch, | 72 | .setup_arch = sbc834x_setup_arch, |
112 | .init_IRQ = sbc834x_init_IRQ, | 73 | .init_IRQ = mpc83xx_ipic_init_IRQ, |
113 | .get_irq = ipic_get_irq, | 74 | .get_irq = ipic_get_irq, |
114 | .restart = mpc83xx_restart, | 75 | .restart = mpc83xx_restart, |
115 | .time_init = mpc83xx_time_init, | 76 | .time_init = mpc83xx_time_init, |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index bc5acb95917a..9cb2d4320dcc 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -3,6 +3,8 @@ | |||
3 | # | 3 | # |
4 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
5 | 5 | ||
6 | obj-y += common.o | ||
7 | |||
6 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 8 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
7 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o | 9 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o |
8 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o | 10 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o |
diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c new file mode 100644 index 000000000000..9fef5302adc1 --- /dev/null +++ b/arch/powerpc/platforms/85xx/common.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * Routines common to most mpc85xx-based boards. | ||
3 | * | ||
4 | * This is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | #include <linux/of_platform.h> | ||
9 | |||
10 | #include <sysdev/cpm2_pic.h> | ||
11 | |||
12 | #include "mpc85xx.h" | ||
13 | |||
14 | static struct of_device_id __initdata mpc85xx_common_ids[] = { | ||
15 | { .type = "soc", }, | ||
16 | { .compatible = "soc", }, | ||
17 | { .compatible = "simple-bus", }, | ||
18 | { .name = "cpm", }, | ||
19 | { .name = "localbus", }, | ||
20 | { .compatible = "gianfar", }, | ||
21 | { .compatible = "fsl,qe", }, | ||
22 | { .compatible = "fsl,cpm2", }, | ||
23 | { .compatible = "fsl,srio", }, | ||
24 | {}, | ||
25 | }; | ||
26 | |||
27 | int __init mpc85xx_common_publish_devices(void) | ||
28 | { | ||
29 | return of_platform_bus_probe(NULL, mpc85xx_common_ids, NULL); | ||
30 | } | ||
31 | #ifdef CONFIG_CPM2 | ||
32 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
33 | { | ||
34 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
35 | int cascade_irq; | ||
36 | |||
37 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
38 | generic_handle_irq(cascade_irq); | ||
39 | |||
40 | chip->irq_eoi(&desc->irq_data); | ||
41 | } | ||
42 | |||
43 | |||
44 | void __init mpc85xx_cpm2_pic_init(void) | ||
45 | { | ||
46 | struct device_node *np; | ||
47 | int irq; | ||
48 | |||
49 | /* Setup CPM2 PIC */ | ||
50 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
51 | if (np == NULL) { | ||
52 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
53 | return; | ||
54 | } | ||
55 | irq = irq_of_parse_and_map(np, 0); | ||
56 | if (irq == NO_IRQ) { | ||
57 | of_node_put(np); | ||
58 | printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n"); | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | cpm2_pic_init(np); | ||
63 | of_node_put(np); | ||
64 | irq_set_chained_handler(irq, cpm2_cascade); | ||
65 | } | ||
66 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c index 802ad110b757..07e3e6c47371 100644 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/arch/powerpc/platforms/85xx/corenet_ds.c | |||
@@ -31,32 +31,18 @@ | |||
31 | #include <linux/of_platform.h> | 31 | #include <linux/of_platform.h> |
32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
33 | #include <sysdev/fsl_pci.h> | 33 | #include <sysdev/fsl_pci.h> |
34 | #include "smp.h" | ||
34 | 35 | ||
35 | void __init corenet_ds_pic_init(void) | 36 | void __init corenet_ds_pic_init(void) |
36 | { | 37 | { |
37 | struct mpic *mpic; | 38 | struct mpic *mpic; |
38 | struct resource r; | 39 | unsigned int flags = MPIC_BIG_ENDIAN | |
39 | struct device_node *np = NULL; | ||
40 | unsigned int flags = MPIC_PRIMARY | MPIC_BIG_ENDIAN | | ||
41 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU; | 40 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU; |
42 | 41 | ||
43 | np = of_find_node_by_type(np, "open-pic"); | ||
44 | |||
45 | if (np == NULL) { | ||
46 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
47 | return; | ||
48 | } | ||
49 | |||
50 | if (of_address_to_resource(np, 0, &r)) { | ||
51 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
52 | of_node_put(np); | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | if (ppc_md.get_irq == mpic_get_coreint_irq) | 42 | if (ppc_md.get_irq == mpic_get_coreint_irq) |
57 | flags |= MPIC_ENABLE_COREINT; | 43 | flags |= MPIC_ENABLE_COREINT; |
58 | 44 | ||
59 | mpic = mpic_alloc(np, r.start, flags, 0, 256, " OpenPIC "); | 45 | mpic = mpic_alloc(NULL, 0, flags, 0, 256, " OpenPIC "); |
60 | BUG_ON(mpic == NULL); | 46 | BUG_ON(mpic == NULL); |
61 | 47 | ||
62 | mpic_init(mpic); | 48 | mpic_init(mpic); |
@@ -65,10 +51,6 @@ void __init corenet_ds_pic_init(void) | |||
65 | /* | 51 | /* |
66 | * Setup the architecture | 52 | * Setup the architecture |
67 | */ | 53 | */ |
68 | #ifdef CONFIG_SMP | ||
69 | void __init mpc85xx_smp_init(void); | ||
70 | #endif | ||
71 | |||
72 | void __init corenet_ds_setup_arch(void) | 54 | void __init corenet_ds_setup_arch(void) |
73 | { | 55 | { |
74 | #ifdef CONFIG_PCI | 56 | #ifdef CONFIG_PCI |
@@ -77,9 +59,7 @@ void __init corenet_ds_setup_arch(void) | |||
77 | #endif | 59 | #endif |
78 | dma_addr_t max = 0xffffffff; | 60 | dma_addr_t max = 0xffffffff; |
79 | 61 | ||
80 | #ifdef CONFIG_SMP | ||
81 | mpc85xx_smp_init(); | 62 | mpc85xx_smp_init(); |
82 | #endif | ||
83 | 63 | ||
84 | #ifdef CONFIG_PCI | 64 | #ifdef CONFIG_PCI |
85 | for_each_node_by_type(np, "pci") { | 65 | for_each_node_by_type(np, "pci") { |
@@ -112,7 +92,7 @@ static const struct of_device_id of_device_ids[] __devinitconst = { | |||
112 | .compatible = "simple-bus" | 92 | .compatible = "simple-bus" |
113 | }, | 93 | }, |
114 | { | 94 | { |
115 | .compatible = "fsl,rapidio-delta", | 95 | .compatible = "fsl,srio", |
116 | }, | 96 | }, |
117 | { | 97 | { |
118 | .compatible = "fsl,p4080-pcie", | 98 | .compatible = "fsl,p4080-pcie", |
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index c46f9359be15..20f75d7819c6 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/cpm2.h> | 35 | #include <asm/cpm2.h> |
36 | #include <sysdev/cpm2_pic.h> | 36 | #include <sysdev/cpm2_pic.h> |
37 | 37 | ||
38 | #include "mpc85xx.h" | ||
38 | 39 | ||
39 | #define KSI8560_CPLD_HVR 0x04 /* Hardware Version Register */ | 40 | #define KSI8560_CPLD_HVR 0x04 /* Hardware Version Register */ |
40 | #define KSI8560_CPLD_PVR 0x08 /* PLD Version Register */ | 41 | #define KSI8560_CPLD_PVR 0x08 /* PLD Version Register */ |
@@ -54,60 +55,15 @@ static void machine_restart(char *cmd) | |||
54 | for (;;); | 55 | for (;;); |
55 | } | 56 | } |
56 | 57 | ||
57 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
58 | { | ||
59 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
60 | int cascade_irq; | ||
61 | |||
62 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
63 | generic_handle_irq(cascade_irq); | ||
64 | |||
65 | chip->irq_eoi(&desc->irq_data); | ||
66 | } | ||
67 | |||
68 | static void __init ksi8560_pic_init(void) | 58 | static void __init ksi8560_pic_init(void) |
69 | { | 59 | { |
70 | struct mpic *mpic; | 60 | struct mpic *mpic = mpic_alloc(NULL, 0, |
71 | struct resource r; | 61 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
72 | struct device_node *np; | ||
73 | #ifdef CONFIG_CPM2 | ||
74 | int irq; | ||
75 | #endif | ||
76 | |||
77 | np = of_find_node_by_type(NULL, "open-pic"); | ||
78 | |||
79 | if (np == NULL) { | ||
80 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | if (of_address_to_resource(np, 0, &r)) { | ||
85 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
86 | of_node_put(np); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | mpic = mpic_alloc(np, r.start, | ||
91 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
92 | 0, 256, " OpenPIC "); | 62 | 0, 256, " OpenPIC "); |
93 | BUG_ON(mpic == NULL); | 63 | BUG_ON(mpic == NULL); |
94 | of_node_put(np); | ||
95 | |||
96 | mpic_init(mpic); | 64 | mpic_init(mpic); |
97 | 65 | ||
98 | #ifdef CONFIG_CPM2 | 66 | mpc85xx_cpm2_pic_init(); |
99 | /* Setup CPM2 PIC */ | ||
100 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
101 | if (np == NULL) { | ||
102 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
103 | return; | ||
104 | } | ||
105 | irq = irq_of_parse_and_map(np, 0); | ||
106 | |||
107 | cpm2_pic_init(np); | ||
108 | of_node_put(np); | ||
109 | irq_set_chained_handler(irq, cpm2_cascade); | ||
110 | #endif | ||
111 | } | 67 | } |
112 | 68 | ||
113 | #ifdef CONFIG_CPM2 | 69 | #ifdef CONFIG_CPM2 |
@@ -215,22 +171,7 @@ static void ksi8560_show_cpuinfo(struct seq_file *m) | |||
215 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 171 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
216 | } | 172 | } |
217 | 173 | ||
218 | static struct of_device_id __initdata of_bus_ids[] = { | 174 | machine_device_initcall(ksi8560, mpc85xx_common_publish_devices); |
219 | { .type = "soc", }, | ||
220 | { .type = "simple-bus", }, | ||
221 | { .name = "cpm", }, | ||
222 | { .name = "localbus", }, | ||
223 | { .compatible = "gianfar", }, | ||
224 | {}, | ||
225 | }; | ||
226 | |||
227 | static int __init declare_of_platform_devices(void) | ||
228 | { | ||
229 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | machine_device_initcall(ksi8560, declare_of_platform_devices); | ||
234 | 175 | ||
235 | /* | 176 | /* |
236 | * Called very early, device-tree isn't unflattened | 177 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index f79f2f102141..cf266826682e 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c | |||
@@ -32,31 +32,15 @@ | |||
32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
33 | #include <sysdev/fsl_pci.h> | 33 | #include <sysdev/fsl_pci.h> |
34 | 34 | ||
35 | #include "mpc85xx.h" | ||
36 | |||
35 | void __init mpc8536_ds_pic_init(void) | 37 | void __init mpc8536_ds_pic_init(void) |
36 | { | 38 | { |
37 | struct mpic *mpic; | 39 | struct mpic *mpic = mpic_alloc(NULL, 0, |
38 | struct resource r; | 40 | MPIC_WANTS_RESET | |
39 | struct device_node *np; | ||
40 | |||
41 | np = of_find_node_by_type(NULL, "open-pic"); | ||
42 | if (np == NULL) { | ||
43 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
44 | return; | ||
45 | } | ||
46 | |||
47 | if (of_address_to_resource(np, 0, &r)) { | ||
48 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
49 | of_node_put(np); | ||
50 | return; | ||
51 | } | ||
52 | |||
53 | mpic = mpic_alloc(np, r.start, | ||
54 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
55 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, | 41 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, |
56 | 0, 256, " OpenPIC "); | 42 | 0, 256, " OpenPIC "); |
57 | BUG_ON(mpic == NULL); | 43 | BUG_ON(mpic == NULL); |
58 | of_node_put(np); | ||
59 | |||
60 | mpic_init(mpic); | 44 | mpic_init(mpic); |
61 | } | 45 | } |
62 | 46 | ||
@@ -104,19 +88,7 @@ static void __init mpc8536_ds_setup_arch(void) | |||
104 | printk("MPC8536 DS board from Freescale Semiconductor\n"); | 88 | printk("MPC8536 DS board from Freescale Semiconductor\n"); |
105 | } | 89 | } |
106 | 90 | ||
107 | static struct of_device_id __initdata mpc8536_ds_ids[] = { | 91 | machine_device_initcall(mpc8536_ds, mpc85xx_common_publish_devices); |
108 | { .type = "soc", }, | ||
109 | { .compatible = "soc", }, | ||
110 | { .compatible = "simple-bus", }, | ||
111 | { .compatible = "gianfar", }, | ||
112 | {}, | ||
113 | }; | ||
114 | |||
115 | static int __init mpc8536_ds_publish_devices(void) | ||
116 | { | ||
117 | return of_platform_bus_probe(NULL, mpc8536_ds_ids, NULL); | ||
118 | } | ||
119 | machine_device_initcall(mpc8536_ds, mpc8536_ds_publish_devices); | ||
120 | 92 | ||
121 | machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier); | 93 | machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier); |
122 | 94 | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h new file mode 100644 index 000000000000..2aa7c5dc2c7f --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef MPC85xx_H | ||
2 | #define MPC85xx_H | ||
3 | extern int mpc85xx_common_publish_devices(void); | ||
4 | |||
5 | #ifdef CONFIG_CPM2 | ||
6 | extern void mpc85xx_cpm2_pic_init(void); | ||
7 | #else | ||
8 | static inline void __init mpc85xx_cpm2_pic_init(void) {} | ||
9 | #endif /* CONFIG_CPM2 */ | ||
10 | |||
11 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 3b2c9bb66199..3bebb5173bfc 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <sysdev/cpm2_pic.h> | 35 | #include <sysdev/cpm2_pic.h> |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #include "mpc85xx.h" | ||
39 | |||
38 | #ifdef CONFIG_PCI | 40 | #ifdef CONFIG_PCI |
39 | static int mpc85xx_exclude_device(struct pci_controller *hose, | 41 | static int mpc85xx_exclude_device(struct pci_controller *hose, |
40 | u_char bus, u_char devfn) | 42 | u_char bus, u_char devfn) |
@@ -46,63 +48,15 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, | |||
46 | } | 48 | } |
47 | #endif /* CONFIG_PCI */ | 49 | #endif /* CONFIG_PCI */ |
48 | 50 | ||
49 | #ifdef CONFIG_CPM2 | ||
50 | |||
51 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
52 | { | ||
53 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
54 | int cascade_irq; | ||
55 | |||
56 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
57 | generic_handle_irq(cascade_irq); | ||
58 | |||
59 | chip->irq_eoi(&desc->irq_data); | ||
60 | } | ||
61 | |||
62 | #endif /* CONFIG_CPM2 */ | ||
63 | |||
64 | static void __init mpc85xx_ads_pic_init(void) | 51 | static void __init mpc85xx_ads_pic_init(void) |
65 | { | 52 | { |
66 | struct mpic *mpic; | 53 | struct mpic *mpic = mpic_alloc(NULL, 0, |
67 | struct resource r; | 54 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
68 | struct device_node *np = NULL; | ||
69 | #ifdef CONFIG_CPM2 | ||
70 | int irq; | ||
71 | #endif | ||
72 | |||
73 | np = of_find_node_by_type(np, "open-pic"); | ||
74 | if (!np) { | ||
75 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | if (of_address_to_resource(np, 0, &r)) { | ||
80 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
81 | of_node_put(np); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | mpic = mpic_alloc(np, r.start, | ||
86 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
87 | 0, 256, " OpenPIC "); | 55 | 0, 256, " OpenPIC "); |
88 | BUG_ON(mpic == NULL); | 56 | BUG_ON(mpic == NULL); |
89 | of_node_put(np); | ||
90 | |||
91 | mpic_init(mpic); | 57 | mpic_init(mpic); |
92 | 58 | ||
93 | #ifdef CONFIG_CPM2 | 59 | mpc85xx_cpm2_pic_init(); |
94 | /* Setup CPM2 PIC */ | ||
95 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
96 | if (np == NULL) { | ||
97 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
98 | return; | ||
99 | } | ||
100 | irq = irq_of_parse_and_map(np, 0); | ||
101 | |||
102 | cpm2_pic_init(np); | ||
103 | of_node_put(np); | ||
104 | irq_set_chained_handler(irq, cpm2_cascade); | ||
105 | #endif | ||
106 | } | 60 | } |
107 | 61 | ||
108 | /* | 62 | /* |
@@ -221,23 +175,7 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) | |||
221 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 175 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
222 | } | 176 | } |
223 | 177 | ||
224 | static struct of_device_id __initdata of_bus_ids[] = { | 178 | machine_device_initcall(mpc85xx_ads, mpc85xx_common_publish_devices); |
225 | { .name = "soc", }, | ||
226 | { .type = "soc", }, | ||
227 | { .name = "cpm", }, | ||
228 | { .name = "localbus", }, | ||
229 | { .compatible = "simple-bus", }, | ||
230 | { .compatible = "gianfar", }, | ||
231 | {}, | ||
232 | }; | ||
233 | |||
234 | static int __init declare_of_platform_devices(void) | ||
235 | { | ||
236 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | machine_device_initcall(mpc85xx_ads, declare_of_platform_devices); | ||
241 | 179 | ||
242 | /* | 180 | /* |
243 | * Called very early, device-tree isn't unflattened | 181 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 66cb8d64079f..40f03da616a9 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <sysdev/fsl_soc.h> | 46 | #include <sysdev/fsl_soc.h> |
47 | #include <sysdev/fsl_pci.h> | 47 | #include <sysdev/fsl_pci.h> |
48 | 48 | ||
49 | #include "mpc85xx.h" | ||
50 | |||
49 | /* CADMUS info */ | 51 | /* CADMUS info */ |
50 | /* xxx - galak, move into device tree */ | 52 | /* xxx - galak, move into device tree */ |
51 | #define CADMUS_BASE (0xf8004000) | 53 | #define CADMUS_BASE (0xf8004000) |
@@ -177,7 +179,7 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) | |||
177 | 179 | ||
178 | static struct irqaction mpc85xxcds_8259_irqaction = { | 180 | static struct irqaction mpc85xxcds_8259_irqaction = { |
179 | .handler = mpc85xx_8259_cascade_action, | 181 | .handler = mpc85xx_8259_cascade_action, |
180 | .flags = IRQF_SHARED, | 182 | .flags = IRQF_SHARED | IRQF_NO_THREAD, |
181 | .name = "8259 cascade", | 183 | .name = "8259 cascade", |
182 | }; | 184 | }; |
183 | #endif /* PPC_I8259 */ | 185 | #endif /* PPC_I8259 */ |
@@ -186,30 +188,10 @@ static struct irqaction mpc85xxcds_8259_irqaction = { | |||
186 | static void __init mpc85xx_cds_pic_init(void) | 188 | static void __init mpc85xx_cds_pic_init(void) |
187 | { | 189 | { |
188 | struct mpic *mpic; | 190 | struct mpic *mpic; |
189 | struct resource r; | 191 | mpic = mpic_alloc(NULL, 0, |
190 | struct device_node *np = NULL; | 192 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
191 | |||
192 | np = of_find_node_by_type(np, "open-pic"); | ||
193 | |||
194 | if (np == NULL) { | ||
195 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | if (of_address_to_resource(np, 0, &r)) { | ||
200 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
201 | of_node_put(np); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | mpic = mpic_alloc(np, r.start, | ||
206 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
207 | 0, 256, " OpenPIC "); | 193 | 0, 256, " OpenPIC "); |
208 | BUG_ON(mpic == NULL); | 194 | BUG_ON(mpic == NULL); |
209 | |||
210 | /* Return the mpic node */ | ||
211 | of_node_put(np); | ||
212 | |||
213 | mpic_init(mpic); | 195 | mpic_init(mpic); |
214 | } | 196 | } |
215 | 197 | ||
@@ -330,19 +312,7 @@ static int __init mpc85xx_cds_probe(void) | |||
330 | return of_flat_dt_is_compatible(root, "MPC85xxCDS"); | 312 | return of_flat_dt_is_compatible(root, "MPC85xxCDS"); |
331 | } | 313 | } |
332 | 314 | ||
333 | static struct of_device_id __initdata of_bus_ids[] = { | 315 | machine_device_initcall(mpc85xx_cds, mpc85xx_common_publish_devices); |
334 | { .type = "soc", }, | ||
335 | { .compatible = "soc", }, | ||
336 | { .compatible = "simple-bus", }, | ||
337 | { .compatible = "gianfar", }, | ||
338 | {}, | ||
339 | }; | ||
340 | |||
341 | static int __init declare_of_platform_devices(void) | ||
342 | { | ||
343 | return of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
344 | } | ||
345 | machine_device_initcall(mpc85xx_cds, declare_of_platform_devices); | ||
346 | 316 | ||
347 | define_machine(mpc85xx_cds) { | 317 | define_machine(mpc85xx_cds) { |
348 | .name = "MPC85xx CDS", | 318 | .name = "MPC85xx CDS", |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 1b9a8cf1873a..eefbb91e1d61 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c | |||
@@ -35,6 +35,9 @@ | |||
35 | 35 | ||
36 | #include <sysdev/fsl_soc.h> | 36 | #include <sysdev/fsl_soc.h> |
37 | #include <sysdev/fsl_pci.h> | 37 | #include <sysdev/fsl_pci.h> |
38 | #include "smp.h" | ||
39 | |||
40 | #include "mpc85xx.h" | ||
38 | 41 | ||
39 | #undef DEBUG | 42 | #undef DEBUG |
40 | 43 | ||
@@ -60,43 +63,27 @@ static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc) | |||
60 | void __init mpc85xx_ds_pic_init(void) | 63 | void __init mpc85xx_ds_pic_init(void) |
61 | { | 64 | { |
62 | struct mpic *mpic; | 65 | struct mpic *mpic; |
63 | struct resource r; | ||
64 | struct device_node *np; | ||
65 | #ifdef CONFIG_PPC_I8259 | 66 | #ifdef CONFIG_PPC_I8259 |
67 | struct device_node *np; | ||
66 | struct device_node *cascade_node = NULL; | 68 | struct device_node *cascade_node = NULL; |
67 | int cascade_irq; | 69 | int cascade_irq; |
68 | #endif | 70 | #endif |
69 | unsigned long root = of_get_flat_dt_root(); | 71 | unsigned long root = of_get_flat_dt_root(); |
70 | 72 | ||
71 | np = of_find_node_by_type(NULL, "open-pic"); | ||
72 | if (np == NULL) { | ||
73 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
74 | return; | ||
75 | } | ||
76 | |||
77 | if (of_address_to_resource(np, 0, &r)) { | ||
78 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
79 | of_node_put(np); | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) { | 73 | if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) { |
84 | mpic = mpic_alloc(np, r.start, | 74 | mpic = mpic_alloc(NULL, 0, |
85 | MPIC_PRIMARY | | ||
86 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 75 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
87 | MPIC_SINGLE_DEST_CPU, | 76 | MPIC_SINGLE_DEST_CPU, |
88 | 0, 256, " OpenPIC "); | 77 | 0, 256, " OpenPIC "); |
89 | } else { | 78 | } else { |
90 | mpic = mpic_alloc(np, r.start, | 79 | mpic = mpic_alloc(NULL, 0, |
91 | MPIC_PRIMARY | MPIC_WANTS_RESET | | 80 | MPIC_WANTS_RESET | |
92 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 81 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
93 | MPIC_SINGLE_DEST_CPU, | 82 | MPIC_SINGLE_DEST_CPU, |
94 | 0, 256, " OpenPIC "); | 83 | 0, 256, " OpenPIC "); |
95 | } | 84 | } |
96 | 85 | ||
97 | BUG_ON(mpic == NULL); | 86 | BUG_ON(mpic == NULL); |
98 | of_node_put(np); | ||
99 | |||
100 | mpic_init(mpic); | 87 | mpic_init(mpic); |
101 | 88 | ||
102 | #ifdef CONFIG_PPC_I8259 | 89 | #ifdef CONFIG_PPC_I8259 |
@@ -152,9 +139,6 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, | |||
152 | /* | 139 | /* |
153 | * Setup the architecture | 140 | * Setup the architecture |
154 | */ | 141 | */ |
155 | #ifdef CONFIG_SMP | ||
156 | extern void __init mpc85xx_smp_init(void); | ||
157 | #endif | ||
158 | static void __init mpc85xx_ds_setup_arch(void) | 142 | static void __init mpc85xx_ds_setup_arch(void) |
159 | { | 143 | { |
160 | #ifdef CONFIG_PCI | 144 | #ifdef CONFIG_PCI |
@@ -187,9 +171,7 @@ static void __init mpc85xx_ds_setup_arch(void) | |||
187 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | 171 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; |
188 | #endif | 172 | #endif |
189 | 173 | ||
190 | #ifdef CONFIG_SMP | ||
191 | mpc85xx_smp_init(); | 174 | mpc85xx_smp_init(); |
192 | #endif | ||
193 | 175 | ||
194 | #ifdef CONFIG_SWIOTLB | 176 | #ifdef CONFIG_SWIOTLB |
195 | if (memblock_end_of_DRAM() > max) { | 177 | if (memblock_end_of_DRAM() > max) { |
@@ -219,21 +201,9 @@ static int __init mpc8544_ds_probe(void) | |||
219 | return 0; | 201 | return 0; |
220 | } | 202 | } |
221 | 203 | ||
222 | static struct of_device_id __initdata mpc85xxds_ids[] = { | 204 | machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices); |
223 | { .type = "soc", }, | 205 | machine_device_initcall(mpc8572_ds, mpc85xx_common_publish_devices); |
224 | { .compatible = "soc", }, | 206 | machine_device_initcall(p2020_ds, mpc85xx_common_publish_devices); |
225 | { .compatible = "simple-bus", }, | ||
226 | { .compatible = "gianfar", }, | ||
227 | {}, | ||
228 | }; | ||
229 | |||
230 | static int __init mpc85xxds_publish_devices(void) | ||
231 | { | ||
232 | return of_platform_bus_probe(NULL, mpc85xxds_ids, NULL); | ||
233 | } | ||
234 | machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices); | ||
235 | machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices); | ||
236 | machine_device_initcall(p2020_ds, mpc85xxds_publish_devices); | ||
237 | 207 | ||
238 | machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier); | 208 | machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier); |
239 | machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier); | 209 | machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier); |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index a23a3ff634c5..1d15a0cd2c82 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -51,6 +51,9 @@ | |||
51 | #include <asm/qe_ic.h> | 51 | #include <asm/qe_ic.h> |
52 | #include <asm/mpic.h> | 52 | #include <asm/mpic.h> |
53 | #include <asm/swiotlb.h> | 53 | #include <asm/swiotlb.h> |
54 | #include "smp.h" | ||
55 | |||
56 | #include "mpc85xx.h" | ||
54 | 57 | ||
55 | #undef DEBUG | 58 | #undef DEBUG |
56 | #ifdef DEBUG | 59 | #ifdef DEBUG |
@@ -153,30 +156,7 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) | |||
153 | * Setup the architecture | 156 | * Setup the architecture |
154 | * | 157 | * |
155 | */ | 158 | */ |
156 | #ifdef CONFIG_SMP | ||
157 | extern void __init mpc85xx_smp_init(void); | ||
158 | #endif | ||
159 | |||
160 | #ifdef CONFIG_QUICC_ENGINE | 159 | #ifdef CONFIG_QUICC_ENGINE |
161 | static struct of_device_id mpc85xx_qe_ids[] __initdata = { | ||
162 | { .type = "qe", }, | ||
163 | { .compatible = "fsl,qe", }, | ||
164 | { }, | ||
165 | }; | ||
166 | |||
167 | static void __init mpc85xx_publish_qe_devices(void) | ||
168 | { | ||
169 | struct device_node *np; | ||
170 | |||
171 | np = of_find_compatible_node(NULL, NULL, "fsl,qe"); | ||
172 | if (!of_device_is_available(np)) { | ||
173 | of_node_put(np); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | of_platform_bus_probe(NULL, mpc85xx_qe_ids, NULL); | ||
178 | } | ||
179 | |||
180 | static void __init mpc85xx_mds_reset_ucc_phys(void) | 160 | static void __init mpc85xx_mds_reset_ucc_phys(void) |
181 | { | 161 | { |
182 | struct device_node *np; | 162 | struct device_node *np; |
@@ -347,7 +327,6 @@ static void __init mpc85xx_mds_qeic_init(void) | |||
347 | of_node_put(np); | 327 | of_node_put(np); |
348 | } | 328 | } |
349 | #else | 329 | #else |
350 | static void __init mpc85xx_publish_qe_devices(void) { } | ||
351 | static void __init mpc85xx_mds_qe_init(void) { } | 330 | static void __init mpc85xx_mds_qe_init(void) { } |
352 | static void __init mpc85xx_mds_qeic_init(void) { } | 331 | static void __init mpc85xx_mds_qeic_init(void) { } |
353 | #endif /* CONFIG_QUICC_ENGINE */ | 332 | #endif /* CONFIG_QUICC_ENGINE */ |
@@ -381,9 +360,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
381 | } | 360 | } |
382 | #endif | 361 | #endif |
383 | 362 | ||
384 | #ifdef CONFIG_SMP | ||
385 | mpc85xx_smp_init(); | 363 | mpc85xx_smp_init(); |
386 | #endif | ||
387 | 364 | ||
388 | mpc85xx_mds_qe_init(); | 365 | mpc85xx_mds_qe_init(); |
389 | 366 | ||
@@ -429,24 +406,11 @@ machine_arch_initcall(mpc8568_mds, board_fixups); | |||
429 | machine_arch_initcall(mpc8569_mds, board_fixups); | 406 | machine_arch_initcall(mpc8569_mds, board_fixups); |
430 | 407 | ||
431 | static struct of_device_id mpc85xx_ids[] = { | 408 | static struct of_device_id mpc85xx_ids[] = { |
432 | { .type = "soc", }, | ||
433 | { .compatible = "soc", }, | ||
434 | { .compatible = "simple-bus", }, | ||
435 | { .compatible = "gianfar", }, | ||
436 | { .compatible = "fsl,rapidio-delta", }, | ||
437 | { .compatible = "fsl,mpc8548-guts", }, | 409 | { .compatible = "fsl,mpc8548-guts", }, |
438 | { .compatible = "gpio-leds", }, | 410 | { .compatible = "gpio-leds", }, |
439 | {}, | 411 | {}, |
440 | }; | 412 | }; |
441 | 413 | ||
442 | static struct of_device_id p1021_ids[] = { | ||
443 | { .type = "soc", }, | ||
444 | { .compatible = "soc", }, | ||
445 | { .compatible = "simple-bus", }, | ||
446 | { .compatible = "gianfar", }, | ||
447 | {}, | ||
448 | }; | ||
449 | |||
450 | static int __init mpc85xx_publish_devices(void) | 414 | static int __init mpc85xx_publish_devices(void) |
451 | { | 415 | { |
452 | if (machine_is(mpc8568_mds)) | 416 | if (machine_is(mpc8568_mds)) |
@@ -454,23 +418,15 @@ static int __init mpc85xx_publish_devices(void) | |||
454 | if (machine_is(mpc8569_mds)) | 418 | if (machine_is(mpc8569_mds)) |
455 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); | 419 | simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); |
456 | 420 | ||
421 | mpc85xx_common_publish_devices(); | ||
457 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); | 422 | of_platform_bus_probe(NULL, mpc85xx_ids, NULL); |
458 | mpc85xx_publish_qe_devices(); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | static int __init p1021_publish_devices(void) | ||
464 | { | ||
465 | of_platform_bus_probe(NULL, p1021_ids, NULL); | ||
466 | mpc85xx_publish_qe_devices(); | ||
467 | 423 | ||
468 | return 0; | 424 | return 0; |
469 | } | 425 | } |
470 | 426 | ||
471 | machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); | 427 | machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); |
472 | machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); | 428 | machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); |
473 | machine_device_initcall(p1021_mds, p1021_publish_devices); | 429 | machine_device_initcall(p1021_mds, mpc85xx_common_publish_devices); |
474 | 430 | ||
475 | machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); | 431 | machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); |
476 | machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); | 432 | machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); |
@@ -478,26 +434,11 @@ machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier); | |||
478 | 434 | ||
479 | static void __init mpc85xx_mds_pic_init(void) | 435 | static void __init mpc85xx_mds_pic_init(void) |
480 | { | 436 | { |
481 | struct mpic *mpic; | 437 | struct mpic *mpic = mpic_alloc(NULL, 0, |
482 | struct resource r; | 438 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
483 | struct device_node *np = NULL; | ||
484 | |||
485 | np = of_find_node_by_type(NULL, "open-pic"); | ||
486 | if (!np) | ||
487 | return; | ||
488 | |||
489 | if (of_address_to_resource(np, 0, &r)) { | ||
490 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
491 | of_node_put(np); | ||
492 | return; | ||
493 | } | ||
494 | |||
495 | mpic = mpic_alloc(np, r.start, | ||
496 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | | ||
497 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | 439 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
498 | 0, 256, " OpenPIC "); | 440 | 0, 256, " OpenPIC "); |
499 | BUG_ON(mpic == NULL); | 441 | BUG_ON(mpic == NULL); |
500 | of_node_put(np); | ||
501 | 442 | ||
502 | mpic_init(mpic); | 443 | mpic_init(mpic); |
503 | mpc85xx_mds_qeic_init(); | 444 | mpc85xx_mds_qeic_init(); |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index f5ff9110c97e..ccf520e890be 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c | |||
@@ -29,6 +29,9 @@ | |||
29 | 29 | ||
30 | #include <sysdev/fsl_soc.h> | 30 | #include <sysdev/fsl_soc.h> |
31 | #include <sysdev/fsl_pci.h> | 31 | #include <sysdev/fsl_pci.h> |
32 | #include "smp.h" | ||
33 | |||
34 | #include "mpc85xx.h" | ||
32 | 35 | ||
33 | #undef DEBUG | 36 | #undef DEBUG |
34 | 37 | ||
@@ -42,49 +45,28 @@ | |||
42 | void __init mpc85xx_rdb_pic_init(void) | 45 | void __init mpc85xx_rdb_pic_init(void) |
43 | { | 46 | { |
44 | struct mpic *mpic; | 47 | struct mpic *mpic; |
45 | struct resource r; | ||
46 | struct device_node *np; | ||
47 | unsigned long root = of_get_flat_dt_root(); | 48 | unsigned long root = of_get_flat_dt_root(); |
48 | 49 | ||
49 | np = of_find_node_by_type(NULL, "open-pic"); | ||
50 | if (np == NULL) { | ||
51 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | if (of_address_to_resource(np, 0, &r)) { | ||
56 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
57 | of_node_put(np); | ||
58 | return; | ||
59 | } | ||
60 | |||
61 | if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) { | 50 | if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) { |
62 | mpic = mpic_alloc(np, r.start, | 51 | mpic = mpic_alloc(NULL, 0, |
63 | MPIC_PRIMARY | | ||
64 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 52 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
65 | MPIC_SINGLE_DEST_CPU, | 53 | MPIC_SINGLE_DEST_CPU, |
66 | 0, 256, " OpenPIC "); | 54 | 0, 256, " OpenPIC "); |
67 | } else { | 55 | } else { |
68 | mpic = mpic_alloc(np, r.start, | 56 | mpic = mpic_alloc(NULL, 0, |
69 | MPIC_PRIMARY | MPIC_WANTS_RESET | | 57 | MPIC_WANTS_RESET | |
70 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 58 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
71 | MPIC_SINGLE_DEST_CPU, | 59 | MPIC_SINGLE_DEST_CPU, |
72 | 0, 256, " OpenPIC "); | 60 | 0, 256, " OpenPIC "); |
73 | } | 61 | } |
74 | 62 | ||
75 | BUG_ON(mpic == NULL); | 63 | BUG_ON(mpic == NULL); |
76 | of_node_put(np); | ||
77 | |||
78 | mpic_init(mpic); | 64 | mpic_init(mpic); |
79 | |||
80 | } | 65 | } |
81 | 66 | ||
82 | /* | 67 | /* |
83 | * Setup the architecture | 68 | * Setup the architecture |
84 | */ | 69 | */ |
85 | #ifdef CONFIG_SMP | ||
86 | extern void __init mpc85xx_smp_init(void); | ||
87 | #endif | ||
88 | static void __init mpc85xx_rdb_setup_arch(void) | 70 | static void __init mpc85xx_rdb_setup_arch(void) |
89 | { | 71 | { |
90 | #ifdef CONFIG_PCI | 72 | #ifdef CONFIG_PCI |
@@ -102,27 +84,12 @@ static void __init mpc85xx_rdb_setup_arch(void) | |||
102 | 84 | ||
103 | #endif | 85 | #endif |
104 | 86 | ||
105 | #ifdef CONFIG_SMP | ||
106 | mpc85xx_smp_init(); | 87 | mpc85xx_smp_init(); |
107 | #endif | ||
108 | |||
109 | printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); | 88 | printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); |
110 | } | 89 | } |
111 | 90 | ||
112 | static struct of_device_id __initdata mpc85xxrdb_ids[] = { | 91 | machine_device_initcall(p2020_rdb, mpc85xx_common_publish_devices); |
113 | { .type = "soc", }, | 92 | machine_device_initcall(p1020_rdb, mpc85xx_common_publish_devices); |
114 | { .compatible = "soc", }, | ||
115 | { .compatible = "simple-bus", }, | ||
116 | { .compatible = "gianfar", }, | ||
117 | {}, | ||
118 | }; | ||
119 | |||
120 | static int __init mpc85xxrdb_publish_devices(void) | ||
121 | { | ||
122 | return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL); | ||
123 | } | ||
124 | machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices); | ||
125 | machine_device_initcall(p1020_rdb, mpc85xxrdb_publish_devices); | ||
126 | 93 | ||
127 | /* | 94 | /* |
128 | * Called very early, device-tree isn't unflattened | 95 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c index d7387fa7f534..538bc3f57e9d 100644 --- a/arch/powerpc/platforms/85xx/p1010rdb.c +++ b/arch/powerpc/platforms/85xx/p1010rdb.c | |||
@@ -28,33 +28,18 @@ | |||
28 | #include <sysdev/fsl_soc.h> | 28 | #include <sysdev/fsl_soc.h> |
29 | #include <sysdev/fsl_pci.h> | 29 | #include <sysdev/fsl_pci.h> |
30 | 30 | ||
31 | #include "mpc85xx.h" | ||
32 | |||
31 | void __init p1010_rdb_pic_init(void) | 33 | void __init p1010_rdb_pic_init(void) |
32 | { | 34 | { |
33 | struct mpic *mpic; | 35 | struct mpic *mpic = mpic_alloc(NULL, 0, |
34 | struct resource r; | 36 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
35 | struct device_node *np; | 37 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
36 | |||
37 | np = of_find_node_by_type(NULL, "open-pic"); | ||
38 | if (np == NULL) { | ||
39 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
40 | return; | ||
41 | } | ||
42 | |||
43 | if (of_address_to_resource(np, 0, &r)) { | ||
44 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
45 | of_node_put(np); | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | mpic = mpic_alloc(np, r.start, MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
50 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | ||
51 | 0, 256, " OpenPIC "); | 38 | 0, 256, " OpenPIC "); |
52 | 39 | ||
53 | BUG_ON(mpic == NULL); | 40 | BUG_ON(mpic == NULL); |
54 | of_node_put(np); | ||
55 | 41 | ||
56 | mpic_init(mpic); | 42 | mpic_init(mpic); |
57 | |||
58 | } | 43 | } |
59 | 44 | ||
60 | 45 | ||
@@ -81,18 +66,7 @@ static void __init p1010_rdb_setup_arch(void) | |||
81 | printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n"); | 66 | printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n"); |
82 | } | 67 | } |
83 | 68 | ||
84 | static struct of_device_id __initdata p1010rdb_ids[] = { | 69 | machine_device_initcall(p1010_rdb, mpc85xx_common_publish_devices); |
85 | { .type = "soc", }, | ||
86 | { .compatible = "soc", }, | ||
87 | { .compatible = "simple-bus", }, | ||
88 | {}, | ||
89 | }; | ||
90 | |||
91 | static int __init p1010rdb_publish_devices(void) | ||
92 | { | ||
93 | return of_platform_bus_probe(NULL, p1010rdb_ids, NULL); | ||
94 | } | ||
95 | machine_device_initcall(p1010_rdb, p1010rdb_publish_devices); | ||
96 | machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier); | 70 | machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier); |
97 | 71 | ||
98 | /* | 72 | /* |
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index fda15716fada..bb3d84f4046f 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -26,6 +26,9 @@ | |||
26 | #include <sysdev/fsl_soc.h> | 26 | #include <sysdev/fsl_soc.h> |
27 | #include <sysdev/fsl_pci.h> | 27 | #include <sysdev/fsl_pci.h> |
28 | #include <asm/fsl_guts.h> | 28 | #include <asm/fsl_guts.h> |
29 | #include "smp.h" | ||
30 | |||
31 | #include "mpc85xx.h" | ||
29 | 32 | ||
30 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) | 33 | #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) |
31 | 34 | ||
@@ -238,38 +241,15 @@ p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port) | |||
238 | 241 | ||
239 | void __init p1022_ds_pic_init(void) | 242 | void __init p1022_ds_pic_init(void) |
240 | { | 243 | { |
241 | struct mpic *mpic; | 244 | struct mpic *mpic = mpic_alloc(NULL, 0, |
242 | struct resource r; | 245 | MPIC_WANTS_RESET | |
243 | struct device_node *np; | ||
244 | |||
245 | np = of_find_node_by_type(NULL, "open-pic"); | ||
246 | if (!np) { | ||
247 | pr_err("Could not find open-pic node\n"); | ||
248 | return; | ||
249 | } | ||
250 | |||
251 | if (of_address_to_resource(np, 0, &r)) { | ||
252 | pr_err("Failed to map mpic register space\n"); | ||
253 | of_node_put(np); | ||
254 | return; | ||
255 | } | ||
256 | |||
257 | mpic = mpic_alloc(np, r.start, | ||
258 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
259 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | 246 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | |
260 | MPIC_SINGLE_DEST_CPU, | 247 | MPIC_SINGLE_DEST_CPU, |
261 | 0, 256, " OpenPIC "); | 248 | 0, 256, " OpenPIC "); |
262 | |||
263 | BUG_ON(mpic == NULL); | 249 | BUG_ON(mpic == NULL); |
264 | of_node_put(np); | ||
265 | |||
266 | mpic_init(mpic); | 250 | mpic_init(mpic); |
267 | } | 251 | } |
268 | 252 | ||
269 | #ifdef CONFIG_SMP | ||
270 | void __init mpc85xx_smp_init(void); | ||
271 | #endif | ||
272 | |||
273 | /* | 253 | /* |
274 | * Setup the architecture | 254 | * Setup the architecture |
275 | */ | 255 | */ |
@@ -309,9 +289,7 @@ static void __init p1022_ds_setup_arch(void) | |||
309 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; | 289 | diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; |
310 | #endif | 290 | #endif |
311 | 291 | ||
312 | #ifdef CONFIG_SMP | ||
313 | mpc85xx_smp_init(); | 292 | mpc85xx_smp_init(); |
314 | #endif | ||
315 | 293 | ||
316 | #ifdef CONFIG_SWIOTLB | 294 | #ifdef CONFIG_SWIOTLB |
317 | if (memblock_end_of_DRAM() > max) { | 295 | if (memblock_end_of_DRAM() > max) { |
@@ -325,10 +303,6 @@ static void __init p1022_ds_setup_arch(void) | |||
325 | } | 303 | } |
326 | 304 | ||
327 | static struct of_device_id __initdata p1022_ds_ids[] = { | 305 | static struct of_device_id __initdata p1022_ds_ids[] = { |
328 | { .type = "soc", }, | ||
329 | { .compatible = "soc", }, | ||
330 | { .compatible = "simple-bus", }, | ||
331 | { .compatible = "gianfar", }, | ||
332 | /* So that the DMA channel nodes can be probed individually: */ | 306 | /* So that the DMA channel nodes can be probed individually: */ |
333 | { .compatible = "fsl,eloplus-dma", }, | 307 | { .compatible = "fsl,eloplus-dma", }, |
334 | {}, | 308 | {}, |
@@ -336,6 +310,7 @@ static struct of_device_id __initdata p1022_ds_ids[] = { | |||
336 | 310 | ||
337 | static int __init p1022_ds_publish_devices(void) | 311 | static int __init p1022_ds_publish_devices(void) |
338 | { | 312 | { |
313 | mpc85xx_common_publish_devices(); | ||
339 | return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); | 314 | return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); |
340 | } | 315 | } |
341 | machine_device_initcall(p1022_ds, p1022_ds_publish_devices); | 316 | machine_device_initcall(p1022_ds, p1022_ds_publish_devices); |
diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c index 835e0b335bfa..d951e7027bb6 100644 --- a/arch/powerpc/platforms/85xx/p1023_rds.c +++ b/arch/powerpc/platforms/85xx/p1023_rds.c | |||
@@ -30,19 +30,18 @@ | |||
30 | #include <asm/prom.h> | 30 | #include <asm/prom.h> |
31 | #include <asm/udbg.h> | 31 | #include <asm/udbg.h> |
32 | #include <asm/mpic.h> | 32 | #include <asm/mpic.h> |
33 | #include "smp.h" | ||
33 | 34 | ||
34 | #include <sysdev/fsl_soc.h> | 35 | #include <sysdev/fsl_soc.h> |
35 | #include <sysdev/fsl_pci.h> | 36 | #include <sysdev/fsl_pci.h> |
36 | 37 | ||
38 | #include "mpc85xx.h" | ||
39 | |||
37 | /* ************************************************************************ | 40 | /* ************************************************************************ |
38 | * | 41 | * |
39 | * Setup the architecture | 42 | * Setup the architecture |
40 | * | 43 | * |
41 | */ | 44 | */ |
42 | #ifdef CONFIG_SMP | ||
43 | void __init mpc85xx_smp_init(void); | ||
44 | #endif | ||
45 | |||
46 | static void __init mpc85xx_rds_setup_arch(void) | 45 | static void __init mpc85xx_rds_setup_arch(void) |
47 | { | 46 | { |
48 | struct device_node *np; | 47 | struct device_node *np; |
@@ -87,53 +86,19 @@ static void __init mpc85xx_rds_setup_arch(void) | |||
87 | fsl_add_bridge(np, 0); | 86 | fsl_add_bridge(np, 0); |
88 | #endif | 87 | #endif |
89 | 88 | ||
90 | #ifdef CONFIG_SMP | ||
91 | mpc85xx_smp_init(); | 89 | mpc85xx_smp_init(); |
92 | #endif | ||
93 | } | ||
94 | |||
95 | static struct of_device_id p1023_ids[] = { | ||
96 | { .type = "soc", }, | ||
97 | { .compatible = "soc", }, | ||
98 | { .compatible = "simple-bus", }, | ||
99 | {}, | ||
100 | }; | ||
101 | |||
102 | |||
103 | static int __init p1023_publish_devices(void) | ||
104 | { | ||
105 | of_platform_bus_probe(NULL, p1023_ids, NULL); | ||
106 | |||
107 | return 0; | ||
108 | } | 90 | } |
109 | 91 | ||
110 | machine_device_initcall(p1023_rds, p1023_publish_devices); | 92 | machine_device_initcall(p1023_rds, mpc85xx_common_publish_devices); |
111 | 93 | ||
112 | static void __init mpc85xx_rds_pic_init(void) | 94 | static void __init mpc85xx_rds_pic_init(void) |
113 | { | 95 | { |
114 | struct mpic *mpic; | 96 | struct mpic *mpic = mpic_alloc(NULL, 0, |
115 | struct resource r; | 97 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
116 | struct device_node *np = NULL; | ||
117 | |||
118 | np = of_find_node_by_type(NULL, "open-pic"); | ||
119 | if (!np) { | ||
120 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
121 | return; | ||
122 | } | ||
123 | |||
124 | if (of_address_to_resource(np, 0, &r)) { | ||
125 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
126 | of_node_put(np); | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | mpic = mpic_alloc(np, r.start, | ||
131 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | | ||
132 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, | 98 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
133 | 0, 256, " OpenPIC "); | 99 | 0, 256, " OpenPIC "); |
134 | 100 | ||
135 | BUG_ON(mpic == NULL); | 101 | BUG_ON(mpic == NULL); |
136 | of_node_put(np); | ||
137 | 102 | ||
138 | mpic_init(mpic); | 103 | mpic_init(mpic); |
139 | } | 104 | } |
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index 14632a971225..184a50784617 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c | |||
@@ -48,35 +48,16 @@ | |||
48 | #include <sysdev/fsl_soc.h> | 48 | #include <sysdev/fsl_soc.h> |
49 | #include <sysdev/fsl_pci.h> | 49 | #include <sysdev/fsl_pci.h> |
50 | 50 | ||
51 | #include "mpc85xx.h" | ||
52 | |||
51 | static int sbc_rev; | 53 | static int sbc_rev; |
52 | 54 | ||
53 | static void __init sbc8548_pic_init(void) | 55 | static void __init sbc8548_pic_init(void) |
54 | { | 56 | { |
55 | struct mpic *mpic; | 57 | struct mpic *mpic = mpic_alloc(NULL, 0, |
56 | struct resource r; | 58 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
57 | struct device_node *np = NULL; | ||
58 | |||
59 | np = of_find_node_by_type(np, "open-pic"); | ||
60 | |||
61 | if (np == NULL) { | ||
62 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | if (of_address_to_resource(np, 0, &r)) { | ||
67 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
68 | of_node_put(np); | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | mpic = mpic_alloc(np, r.start, | ||
73 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
74 | 0, 256, " OpenPIC "); | 59 | 0, 256, " OpenPIC "); |
75 | BUG_ON(mpic == NULL); | 60 | BUG_ON(mpic == NULL); |
76 | |||
77 | /* Return the mpic node */ | ||
78 | of_node_put(np); | ||
79 | |||
80 | mpic_init(mpic); | 61 | mpic_init(mpic); |
81 | } | 62 | } |
82 | 63 | ||
@@ -149,21 +130,7 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) | |||
149 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 130 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
150 | } | 131 | } |
151 | 132 | ||
152 | static struct of_device_id __initdata of_bus_ids[] = { | 133 | machine_device_initcall(sbc8548, mpc85xx_common_publish_devices); |
153 | { .name = "soc", }, | ||
154 | { .type = "soc", }, | ||
155 | { .compatible = "simple-bus", }, | ||
156 | { .compatible = "gianfar", }, | ||
157 | {}, | ||
158 | }; | ||
159 | |||
160 | static int __init declare_of_platform_devices(void) | ||
161 | { | ||
162 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | machine_device_initcall(sbc8548, declare_of_platform_devices); | ||
167 | 134 | ||
168 | /* | 135 | /* |
169 | * Called very early, device-tree isn't unflattened | 136 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index cebd786dc334..940752e93051 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c | |||
@@ -32,68 +32,22 @@ | |||
32 | #include <sysdev/fsl_soc.h> | 32 | #include <sysdev/fsl_soc.h> |
33 | #include <sysdev/fsl_pci.h> | 33 | #include <sysdev/fsl_pci.h> |
34 | 34 | ||
35 | #include "mpc85xx.h" | ||
36 | |||
35 | #ifdef CONFIG_CPM2 | 37 | #ifdef CONFIG_CPM2 |
36 | #include <asm/cpm2.h> | 38 | #include <asm/cpm2.h> |
37 | #include <sysdev/cpm2_pic.h> | 39 | #include <sysdev/cpm2_pic.h> |
38 | #endif | 40 | #endif |
39 | 41 | ||
40 | #ifdef CONFIG_CPM2 | ||
41 | |||
42 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
43 | { | ||
44 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
45 | int cascade_irq; | ||
46 | |||
47 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
48 | generic_handle_irq(cascade_irq); | ||
49 | |||
50 | chip->irq_eoi(&desc->irq_data); | ||
51 | } | ||
52 | |||
53 | #endif /* CONFIG_CPM2 */ | ||
54 | |||
55 | static void __init sbc8560_pic_init(void) | 42 | static void __init sbc8560_pic_init(void) |
56 | { | 43 | { |
57 | struct mpic *mpic; | 44 | struct mpic *mpic = mpic_alloc(NULL, 0, |
58 | struct resource r; | 45 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
59 | struct device_node *np = NULL; | ||
60 | #ifdef CONFIG_CPM2 | ||
61 | int irq; | ||
62 | #endif | ||
63 | |||
64 | np = of_find_node_by_type(np, "open-pic"); | ||
65 | if (!np) { | ||
66 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
67 | return; | ||
68 | } | ||
69 | |||
70 | if (of_address_to_resource(np, 0, &r)) { | ||
71 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
72 | of_node_put(np); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | mpic = mpic_alloc(np, r.start, | ||
77 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
78 | 0, 256, " OpenPIC "); | 46 | 0, 256, " OpenPIC "); |
79 | BUG_ON(mpic == NULL); | 47 | BUG_ON(mpic == NULL); |
80 | of_node_put(np); | ||
81 | |||
82 | mpic_init(mpic); | 48 | mpic_init(mpic); |
83 | 49 | ||
84 | #ifdef CONFIG_CPM2 | 50 | mpc85xx_cpm2_pic_init(); |
85 | /* Setup CPM2 PIC */ | ||
86 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
87 | if (np == NULL) { | ||
88 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
89 | return; | ||
90 | } | ||
91 | irq = irq_of_parse_and_map(np, 0); | ||
92 | |||
93 | cpm2_pic_init(np); | ||
94 | of_node_put(np); | ||
95 | irq_set_chained_handler(irq, cpm2_cascade); | ||
96 | #endif | ||
97 | } | 51 | } |
98 | 52 | ||
99 | /* | 53 | /* |
@@ -208,23 +162,7 @@ static void sbc8560_show_cpuinfo(struct seq_file *m) | |||
208 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 162 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
209 | } | 163 | } |
210 | 164 | ||
211 | static struct of_device_id __initdata of_bus_ids[] = { | 165 | machine_device_initcall(sbc8560, mpc85xx_common_publish_devices); |
212 | { .name = "soc", }, | ||
213 | { .type = "soc", }, | ||
214 | { .name = "cpm", }, | ||
215 | { .name = "localbus", }, | ||
216 | { .compatible = "simple-bus", }, | ||
217 | { .compatible = "gianfar", }, | ||
218 | {}, | ||
219 | }; | ||
220 | |||
221 | static int __init declare_of_platform_devices(void) | ||
222 | { | ||
223 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | machine_device_initcall(sbc8560, declare_of_platform_devices); | ||
228 | 166 | ||
229 | /* | 167 | /* |
230 | * Called very early, device-tree isn't unflattened | 168 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 2df4785ffd4e..ff4249044a3c 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include <sysdev/fsl_soc.h> | 28 | #include <sysdev/fsl_soc.h> |
29 | #include <sysdev/mpic.h> | 29 | #include <sysdev/mpic.h> |
30 | #include "smp.h" | ||
30 | 31 | ||
31 | extern void __early_start(void); | 32 | extern void __early_start(void); |
32 | 33 | ||
diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h new file mode 100644 index 000000000000..e2b44933ff19 --- /dev/null +++ b/arch/powerpc/platforms/85xx/smp.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef POWERPC_85XX_SMP_H_ | ||
2 | #define POWERPC_85XX_SMP_H_ 1 | ||
3 | |||
4 | #include <linux/init.h> | ||
5 | |||
6 | #ifdef CONFIG_SMP | ||
7 | void __init mpc85xx_smp_init(void); | ||
8 | #else | ||
9 | static inline void mpc85xx_smp_init(void) | ||
10 | { | ||
11 | /* Nothing to do */ | ||
12 | } | ||
13 | #endif | ||
14 | |||
15 | #endif /* not POWERPC_85XX_SMP_H_ */ | ||
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c index 747d8fb3ab82..18f635906b27 100644 --- a/arch/powerpc/platforms/85xx/socrates.c +++ b/arch/powerpc/platforms/85xx/socrates.c | |||
@@ -41,32 +41,17 @@ | |||
41 | #include <sysdev/fsl_soc.h> | 41 | #include <sysdev/fsl_soc.h> |
42 | #include <sysdev/fsl_pci.h> | 42 | #include <sysdev/fsl_pci.h> |
43 | 43 | ||
44 | #include "mpc85xx.h" | ||
44 | #include "socrates_fpga_pic.h" | 45 | #include "socrates_fpga_pic.h" |
45 | 46 | ||
46 | static void __init socrates_pic_init(void) | 47 | static void __init socrates_pic_init(void) |
47 | { | 48 | { |
48 | struct mpic *mpic; | ||
49 | struct resource r; | ||
50 | struct device_node *np; | 49 | struct device_node *np; |
51 | 50 | ||
52 | np = of_find_node_by_type(NULL, "open-pic"); | 51 | struct mpic *mpic = mpic_alloc(NULL, 0, |
53 | if (!np) { | 52 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
54 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | if (of_address_to_resource(np, 0, &r)) { | ||
59 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
60 | of_node_put(np); | ||
61 | return; | ||
62 | } | ||
63 | |||
64 | mpic = mpic_alloc(np, r.start, | ||
65 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
66 | 0, 256, " OpenPIC "); | 53 | 0, 256, " OpenPIC "); |
67 | BUG_ON(mpic == NULL); | 54 | BUG_ON(mpic == NULL); |
68 | of_node_put(np); | ||
69 | |||
70 | mpic_init(mpic); | 55 | mpic_init(mpic); |
71 | 56 | ||
72 | np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); | 57 | np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); |
@@ -96,17 +81,7 @@ static void __init socrates_setup_arch(void) | |||
96 | #endif | 81 | #endif |
97 | } | 82 | } |
98 | 83 | ||
99 | static struct of_device_id __initdata socrates_of_bus_ids[] = { | 84 | machine_device_initcall(socrates, mpc85xx_common_publish_devices); |
100 | { .compatible = "simple-bus", }, | ||
101 | { .compatible = "gianfar", }, | ||
102 | {}, | ||
103 | }; | ||
104 | |||
105 | static int __init socrates_publish_devices(void) | ||
106 | { | ||
107 | return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); | ||
108 | } | ||
109 | machine_device_initcall(socrates, socrates_publish_devices); | ||
110 | 85 | ||
111 | /* | 86 | /* |
112 | * Called very early, device-tree isn't unflattened | 87 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index 5387e9f06bdb..e9e5234b4e76 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c | |||
@@ -40,70 +40,21 @@ | |||
40 | #include <sysdev/fsl_soc.h> | 40 | #include <sysdev/fsl_soc.h> |
41 | #include <sysdev/fsl_pci.h> | 41 | #include <sysdev/fsl_pci.h> |
42 | 42 | ||
43 | #include "mpc85xx.h" | ||
44 | |||
43 | #ifdef CONFIG_CPM2 | 45 | #ifdef CONFIG_CPM2 |
44 | #include <asm/cpm2.h> | 46 | #include <asm/cpm2.h> |
45 | #include <sysdev/cpm2_pic.h> | ||
46 | |||
47 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
48 | { | ||
49 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
50 | int cascade_irq; | ||
51 | |||
52 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
53 | generic_handle_irq(cascade_irq); | ||
54 | |||
55 | chip->irq_eoi(&desc->irq_data); | ||
56 | } | ||
57 | #endif /* CONFIG_CPM2 */ | 47 | #endif /* CONFIG_CPM2 */ |
58 | 48 | ||
59 | static void __init stx_gp3_pic_init(void) | 49 | static void __init stx_gp3_pic_init(void) |
60 | { | 50 | { |
61 | struct mpic *mpic; | 51 | struct mpic *mpic = mpic_alloc(NULL, 0, |
62 | struct resource r; | 52 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
63 | struct device_node *np; | ||
64 | #ifdef CONFIG_CPM2 | ||
65 | int irq; | ||
66 | #endif | ||
67 | |||
68 | np = of_find_node_by_type(NULL, "open-pic"); | ||
69 | if (!np) { | ||
70 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | if (of_address_to_resource(np, 0, &r)) { | ||
75 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
76 | of_node_put(np); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | mpic = mpic_alloc(np, r.start, | ||
81 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
82 | 0, 256, " OpenPIC "); | 53 | 0, 256, " OpenPIC "); |
83 | BUG_ON(mpic == NULL); | 54 | BUG_ON(mpic == NULL); |
84 | of_node_put(np); | ||
85 | |||
86 | mpic_init(mpic); | 55 | mpic_init(mpic); |
87 | 56 | ||
88 | #ifdef CONFIG_CPM2 | 57 | mpc85xx_cpm2_pic_init(); |
89 | /* Setup CPM2 PIC */ | ||
90 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
91 | if (np == NULL) { | ||
92 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
93 | return; | ||
94 | } | ||
95 | irq = irq_of_parse_and_map(np, 0); | ||
96 | |||
97 | if (irq == NO_IRQ) { | ||
98 | of_node_put(np); | ||
99 | printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n"); | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | cpm2_pic_init(np); | ||
104 | of_node_put(np); | ||
105 | irq_set_chained_handler(irq, cpm2_cascade); | ||
106 | #endif | ||
107 | } | 58 | } |
108 | 59 | ||
109 | /* | 60 | /* |
@@ -144,19 +95,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) | |||
144 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | 95 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); |
145 | } | 96 | } |
146 | 97 | ||
147 | static struct of_device_id __initdata of_bus_ids[] = { | 98 | machine_device_initcall(stx_gp3, mpc85xx_common_publish_devices); |
148 | { .compatible = "simple-bus", }, | ||
149 | { .compatible = "gianfar", }, | ||
150 | {}, | ||
151 | }; | ||
152 | |||
153 | static int __init declare_of_platform_devices(void) | ||
154 | { | ||
155 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | machine_device_initcall(stx_gp3, declare_of_platform_devices); | ||
160 | 99 | ||
161 | /* | 100 | /* |
162 | * Called very early, device-tree isn't unflattened | 101 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 325de772725a..bf7c89fb75bb 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
@@ -38,70 +38,21 @@ | |||
38 | #include <sysdev/fsl_soc.h> | 38 | #include <sysdev/fsl_soc.h> |
39 | #include <sysdev/fsl_pci.h> | 39 | #include <sysdev/fsl_pci.h> |
40 | 40 | ||
41 | #include "mpc85xx.h" | ||
42 | |||
41 | #ifdef CONFIG_CPM2 | 43 | #ifdef CONFIG_CPM2 |
42 | #include <asm/cpm2.h> | 44 | #include <asm/cpm2.h> |
43 | #include <sysdev/cpm2_pic.h> | ||
44 | |||
45 | static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) | ||
46 | { | ||
47 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
48 | int cascade_irq; | ||
49 | |||
50 | while ((cascade_irq = cpm2_get_irq()) >= 0) | ||
51 | generic_handle_irq(cascade_irq); | ||
52 | |||
53 | chip->irq_eoi(&desc->irq_data); | ||
54 | } | ||
55 | #endif /* CONFIG_CPM2 */ | 45 | #endif /* CONFIG_CPM2 */ |
56 | 46 | ||
57 | static void __init tqm85xx_pic_init(void) | 47 | static void __init tqm85xx_pic_init(void) |
58 | { | 48 | { |
59 | struct mpic *mpic; | 49 | struct mpic *mpic = mpic_alloc(NULL, 0, |
60 | struct resource r; | 50 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, |
61 | struct device_node *np; | ||
62 | #ifdef CONFIG_CPM2 | ||
63 | int irq; | ||
64 | #endif | ||
65 | |||
66 | np = of_find_node_by_type(NULL, "open-pic"); | ||
67 | if (!np) { | ||
68 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | if (of_address_to_resource(np, 0, &r)) { | ||
73 | printk(KERN_ERR "Could not map mpic register space\n"); | ||
74 | of_node_put(np); | ||
75 | return; | ||
76 | } | ||
77 | |||
78 | mpic = mpic_alloc(np, r.start, | ||
79 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
80 | 0, 256, " OpenPIC "); | 51 | 0, 256, " OpenPIC "); |
81 | BUG_ON(mpic == NULL); | 52 | BUG_ON(mpic == NULL); |
82 | of_node_put(np); | ||
83 | |||
84 | mpic_init(mpic); | 53 | mpic_init(mpic); |
85 | 54 | ||
86 | #ifdef CONFIG_CPM2 | 55 | mpc85xx_cpm2_pic_init(); |
87 | /* Setup CPM2 PIC */ | ||
88 | np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); | ||
89 | if (np == NULL) { | ||
90 | printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); | ||
91 | return; | ||
92 | } | ||
93 | irq = irq_of_parse_and_map(np, 0); | ||
94 | |||
95 | if (irq == NO_IRQ) { | ||
96 | of_node_put(np); | ||
97 | printk(KERN_ERR "PIC init: got no IRQ for cpm cascade\n"); | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | cpm2_pic_init(np); | ||
102 | of_node_put(np); | ||
103 | irq_set_chained_handler(irq, cpm2_cascade); | ||
104 | #endif | ||
105 | } | 56 | } |
106 | 57 | ||
107 | /* | 58 | /* |
@@ -173,19 +124,7 @@ static void __init tqm85xx_ti1520_fixup(struct pci_dev *pdev) | |||
173 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, | 124 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, |
174 | tqm85xx_ti1520_fixup); | 125 | tqm85xx_ti1520_fixup); |
175 | 126 | ||
176 | static struct of_device_id __initdata of_bus_ids[] = { | 127 | machine_device_initcall(tqm85xx, mpc85xx_common_publish_devices); |
177 | { .compatible = "simple-bus", }, | ||
178 | { .compatible = "gianfar", }, | ||
179 | {}, | ||
180 | }; | ||
181 | |||
182 | static int __init declare_of_platform_devices(void) | ||
183 | { | ||
184 | of_platform_bus_probe(NULL, of_bus_ids, NULL); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | machine_device_initcall(tqm85xx, declare_of_platform_devices); | ||
189 | 128 | ||
190 | static const char *board[] __initdata = { | 129 | static const char *board[] __initdata = { |
191 | "tqc,tqm8540", | 130 | "tqc,tqm8540", |
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index a9dc5e795123..3a69f8b77de6 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c | |||
@@ -32,6 +32,9 @@ | |||
32 | 32 | ||
33 | #include <sysdev/fsl_soc.h> | 33 | #include <sysdev/fsl_soc.h> |
34 | #include <sysdev/fsl_pci.h> | 34 | #include <sysdev/fsl_pci.h> |
35 | #include "smp.h" | ||
36 | |||
37 | #include "mpc85xx.h" | ||
35 | 38 | ||
36 | /* A few bit definitions needed for fixups on some boards */ | 39 | /* A few bit definitions needed for fixups on some boards */ |
37 | #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ | 40 | #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ |
@@ -40,29 +43,11 @@ | |||
40 | 43 | ||
41 | void __init xes_mpc85xx_pic_init(void) | 44 | void __init xes_mpc85xx_pic_init(void) |
42 | { | 45 | { |
43 | struct mpic *mpic; | 46 | struct mpic *mpic = mpic_alloc(NULL, 0, |
44 | struct resource r; | 47 | MPIC_WANTS_RESET | |
45 | struct device_node *np; | ||
46 | |||
47 | np = of_find_node_by_type(NULL, "open-pic"); | ||
48 | if (np == NULL) { | ||
49 | printk(KERN_ERR "Could not find open-pic node\n"); | ||
50 | return; | ||
51 | } | ||
52 | |||
53 | if (of_address_to_resource(np, 0, &r)) { | ||
54 | printk(KERN_ERR "Failed to map mpic register space\n"); | ||
55 | of_node_put(np); | ||
56 | return; | ||
57 | } | ||
58 | |||
59 | mpic = mpic_alloc(np, r.start, | ||
60 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
61 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, | 48 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, |
62 | 0, 256, " OpenPIC "); | 49 | 0, 256, " OpenPIC "); |
63 | BUG_ON(mpic == NULL); | 50 | BUG_ON(mpic == NULL); |
64 | of_node_put(np); | ||
65 | |||
66 | mpic_init(mpic); | 51 | mpic_init(mpic); |
67 | } | 52 | } |
68 | 53 | ||
@@ -136,9 +121,6 @@ static int primary_phb_addr; | |||
136 | /* | 121 | /* |
137 | * Setup the architecture | 122 | * Setup the architecture |
138 | */ | 123 | */ |
139 | #ifdef CONFIG_SMP | ||
140 | extern void __init mpc85xx_smp_init(void); | ||
141 | #endif | ||
142 | static void __init xes_mpc85xx_setup_arch(void) | 124 | static void __init xes_mpc85xx_setup_arch(void) |
143 | { | 125 | { |
144 | #ifdef CONFIG_PCI | 126 | #ifdef CONFIG_PCI |
@@ -172,26 +154,12 @@ static void __init xes_mpc85xx_setup_arch(void) | |||
172 | } | 154 | } |
173 | #endif | 155 | #endif |
174 | 156 | ||
175 | #ifdef CONFIG_SMP | ||
176 | mpc85xx_smp_init(); | 157 | mpc85xx_smp_init(); |
177 | #endif | ||
178 | } | 158 | } |
179 | 159 | ||
180 | static struct of_device_id __initdata xes_mpc85xx_ids[] = { | 160 | machine_device_initcall(xes_mpc8572, mpc85xx_common_publish_devices); |
181 | { .type = "soc", }, | 161 | machine_device_initcall(xes_mpc8548, mpc85xx_common_publish_devices); |
182 | { .compatible = "soc", }, | 162 | machine_device_initcall(xes_mpc8540, mpc85xx_common_publish_devices); |
183 | { .compatible = "simple-bus", }, | ||
184 | { .compatible = "gianfar", }, | ||
185 | {}, | ||
186 | }; | ||
187 | |||
188 | static int __init xes_mpc85xx_publish_devices(void) | ||
189 | { | ||
190 | return of_platform_bus_probe(NULL, xes_mpc85xx_ids, NULL); | ||
191 | } | ||
192 | machine_device_initcall(xes_mpc8572, xes_mpc85xx_publish_devices); | ||
193 | machine_device_initcall(xes_mpc8548, xes_mpc85xx_publish_devices); | ||
194 | machine_device_initcall(xes_mpc8540, xes_mpc85xx_publish_devices); | ||
195 | 163 | ||
196 | /* | 164 | /* |
197 | * Called very early, device-tree isn't unflattened | 165 | * Called very early, device-tree isn't unflattened |
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index b11c3535f350..569262ca499a 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -161,7 +161,7 @@ mpc86xx_time_init(void) | |||
161 | 161 | ||
162 | static __initdata struct of_device_id of_bus_ids[] = { | 162 | static __initdata struct of_device_id of_bus_ids[] = { |
163 | { .compatible = "simple-bus", }, | 163 | { .compatible = "simple-bus", }, |
164 | { .compatible = "fsl,rapidio-delta", }, | 164 | { .compatible = "fsl,srio", }, |
165 | { .compatible = "gianfar", }, | 165 | { .compatible = "gianfar", }, |
166 | {}, | 166 | {}, |
167 | }; | 167 | }; |
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c index 8ef8960abda6..52bbfa031531 100644 --- a/arch/powerpc/platforms/86xx/pic.c +++ b/arch/powerpc/platforms/86xx/pic.c | |||
@@ -31,26 +31,16 @@ static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) | |||
31 | 31 | ||
32 | void __init mpc86xx_init_irq(void) | 32 | void __init mpc86xx_init_irq(void) |
33 | { | 33 | { |
34 | struct mpic *mpic; | ||
35 | struct device_node *np; | ||
36 | struct resource res; | ||
37 | #ifdef CONFIG_PPC_I8259 | 34 | #ifdef CONFIG_PPC_I8259 |
35 | struct device_node *np; | ||
38 | struct device_node *cascade_node = NULL; | 36 | struct device_node *cascade_node = NULL; |
39 | int cascade_irq; | 37 | int cascade_irq; |
40 | #endif | 38 | #endif |
41 | 39 | ||
42 | /* Determine PIC address. */ | 40 | struct mpic *mpic = mpic_alloc(NULL, 0, |
43 | np = of_find_node_by_type(NULL, "open-pic"); | 41 | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | |
44 | if (np == NULL) | 42 | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, |
45 | return; | ||
46 | of_address_to_resource(np, 0, &res); | ||
47 | |||
48 | mpic = mpic_alloc(np, res.start, | ||
49 | MPIC_PRIMARY | MPIC_WANTS_RESET | | ||
50 | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | | ||
51 | MPIC_SINGLE_DEST_CPU, | ||
52 | 0, 256, " MPIC "); | 43 | 0, 256, " MPIC "); |
53 | of_node_put(np); | ||
54 | BUG_ON(mpic == NULL); | 44 | BUG_ON(mpic == NULL); |
55 | 45 | ||
56 | mpic_init(mpic); | 46 | mpic_init(mpic); |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 3fe6d927ad70..31e1adeaa92a 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -211,6 +211,12 @@ config PPC_PASEMI_CPUFREQ | |||
211 | 211 | ||
212 | endmenu | 212 | endmenu |
213 | 213 | ||
214 | menu "CPUIdle driver" | ||
215 | |||
216 | source "drivers/cpuidle/Kconfig" | ||
217 | |||
218 | endmenu | ||
219 | |||
214 | config PPC601_SYNC_FIX | 220 | config PPC601_SYNC_FIX |
215 | bool "Workarounds for PPC601 bugs" | 221 | bool "Workarounds for PPC601 bugs" |
216 | depends on 6xx && (PPC_PREP || PPC_PMAC) | 222 | depends on 6xx && (PPC_PREP || PPC_PMAC) |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index fbecae0fbb49..425db18580a2 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -174,7 +174,6 @@ config BOOKE | |||
174 | config FSL_BOOKE | 174 | config FSL_BOOKE |
175 | bool | 175 | bool |
176 | depends on (E200 || E500) && PPC32 | 176 | depends on (E200 || E500) && PPC32 |
177 | select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT | ||
178 | default y | 177 | default y |
179 | 178 | ||
180 | # this is for common code between PPC32 & PPC64 FSL BOOKE | 179 | # this is for common code between PPC32 & PPC64 FSL BOOKE |
@@ -182,6 +181,7 @@ config PPC_FSL_BOOK3E | |||
182 | bool | 181 | bool |
183 | select FSL_EMB_PERFMON | 182 | select FSL_EMB_PERFMON |
184 | select PPC_SMP_MUXED_IPI | 183 | select PPC_SMP_MUXED_IPI |
184 | select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64 | ||
185 | default y if FSL_BOOKE | 185 | default y if FSL_BOOKE |
186 | 186 | ||
187 | config PTE_64BIT | 187 | config PTE_64BIT |
@@ -236,7 +236,7 @@ config VSX | |||
236 | 236 | ||
237 | config PPC_ICSWX | 237 | config PPC_ICSWX |
238 | bool "Support for PowerPC icswx coprocessor instruction" | 238 | bool "Support for PowerPC icswx coprocessor instruction" |
239 | depends on POWER4 | 239 | depends on POWER4 || PPC_A2 |
240 | default n | 240 | default n |
241 | ---help--- | 241 | ---help--- |
242 | 242 | ||
@@ -252,6 +252,25 @@ config PPC_ICSWX | |||
252 | 252 | ||
253 | If in doubt, say N here. | 253 | If in doubt, say N here. |
254 | 254 | ||
255 | config PPC_ICSWX_PID | ||
256 | bool "icswx requires direct PID management" | ||
257 | depends on PPC_ICSWX && POWER4 | ||
258 | default y | ||
259 | ---help--- | ||
260 | The PID register in server is used explicitly for ICSWX. In | ||
261 | embedded systems PID managment is done by the system. | ||
262 | |||
263 | config PPC_ICSWX_USE_SIGILL | ||
264 | bool "Should a bad CT cause a SIGILL?" | ||
265 | depends on PPC_ICSWX | ||
266 | default n | ||
267 | ---help--- | ||
268 | Should a bad CT used for "non-record form ICSWX" cause an | ||
269 | illegal intruction signal or should it be silent as | ||
270 | architected. | ||
271 | |||
272 | If in doubt, say N here. | ||
273 | |||
255 | config SPE | 274 | config SPE |
256 | bool "SPE Support" | 275 | bool "SPE Support" |
257 | depends on E200 || (E500 && !PPC_E500MC) | 276 | depends on E200 || (E500 && !PPC_E500MC) |
@@ -290,7 +309,7 @@ config PPC_BOOK3E_MMU | |||
290 | 309 | ||
291 | config PPC_MM_SLICES | 310 | config PPC_MM_SLICES |
292 | bool | 311 | bool |
293 | default y if (PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) | 312 | default y if (!PPC_FSL_BOOK3E && PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) |
294 | default n | 313 | default n |
295 | 314 | ||
296 | config VIRT_CPU_ACCOUNTING | 315 | config VIRT_CPU_ACCOUNTING |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 592c3d51b817..ae9fc7bc17d6 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -1037,6 +1037,8 @@ static int __init cell_iommu_fixed_mapping_init(void) | |||
1037 | 1037 | ||
1038 | /* The fixed mapping is only supported on axon machines */ | 1038 | /* The fixed mapping is only supported on axon machines */ |
1039 | np = of_find_node_by_name(NULL, "axon"); | 1039 | np = of_find_node_by_name(NULL, "axon"); |
1040 | of_node_put(np); | ||
1041 | |||
1040 | if (!np) { | 1042 | if (!np) { |
1041 | pr_debug("iommu: fixed mapping disabled, no axons found\n"); | 1043 | pr_debug("iommu: fixed mapping disabled, no axons found\n"); |
1042 | return -1; | 1044 | return -1; |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 0fc9b7256126..62002a7edfed 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -184,24 +184,10 @@ static int __init cell_publish_devices(void) | |||
184 | } | 184 | } |
185 | machine_subsys_initcall(cell, cell_publish_devices); | 185 | machine_subsys_initcall(cell, cell_publish_devices); |
186 | 186 | ||
187 | static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) | ||
188 | { | ||
189 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
190 | struct mpic *mpic = irq_desc_get_handler_data(desc); | ||
191 | unsigned int virq; | ||
192 | |||
193 | virq = mpic_get_one_irq(mpic); | ||
194 | if (virq != NO_IRQ) | ||
195 | generic_handle_irq(virq); | ||
196 | |||
197 | chip->irq_eoi(&desc->irq_data); | ||
198 | } | ||
199 | |||
200 | static void __init mpic_init_IRQ(void) | 187 | static void __init mpic_init_IRQ(void) |
201 | { | 188 | { |
202 | struct device_node *dn; | 189 | struct device_node *dn; |
203 | struct mpic *mpic; | 190 | struct mpic *mpic; |
204 | unsigned int virq; | ||
205 | 191 | ||
206 | for (dn = NULL; | 192 | for (dn = NULL; |
207 | (dn = of_find_node_by_name(dn, "interrupt-controller"));) { | 193 | (dn = of_find_node_by_name(dn, "interrupt-controller"));) { |
@@ -211,19 +197,10 @@ static void __init mpic_init_IRQ(void) | |||
211 | /* The MPIC driver will get everything it needs from the | 197 | /* The MPIC driver will get everything it needs from the |
212 | * device-tree, just pass 0 to all arguments | 198 | * device-tree, just pass 0 to all arguments |
213 | */ | 199 | */ |
214 | mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC "); | 200 | mpic = mpic_alloc(dn, 0, MPIC_SECONDARY, 0, 0, " MPIC "); |
215 | if (mpic == NULL) | 201 | if (mpic == NULL) |
216 | continue; | 202 | continue; |
217 | mpic_init(mpic); | 203 | mpic_init(mpic); |
218 | |||
219 | virq = irq_of_parse_and_map(dn, 0); | ||
220 | if (virq == NO_IRQ) | ||
221 | continue; | ||
222 | |||
223 | printk(KERN_INFO "%s : hooking up to IRQ %d\n", | ||
224 | dn->full_name, virq); | ||
225 | irq_set_handler_data(virq, mpic); | ||
226 | irq_set_chained_handler(virq, cell_mpic_cascade); | ||
227 | } | 204 | } |
228 | } | 205 | } |
229 | 206 | ||
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 122786498419..f1f17bb2c33c 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -435,8 +435,7 @@ static void __init chrp_find_openpic(void) | |||
435 | if (len > 1) | 435 | if (len > 1) |
436 | isu_size = iranges[3]; | 436 | isu_size = iranges[3]; |
437 | 437 | ||
438 | chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY, | 438 | chrp_mpic = mpic_alloc(np, opaddr, 0, isu_size, 0, " MPIC "); |
439 | isu_size, 0, " MPIC "); | ||
440 | if (chrp_mpic == NULL) { | 439 | if (chrp_mpic == NULL) { |
441 | printk(KERN_ERR "Failed to allocate MPIC structure\n"); | 440 | printk(KERN_ERR "Failed to allocate MPIC structure\n"); |
442 | goto bail; | 441 | goto bail; |
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index 2e9bcf6444c8..9cfcf20c0560 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c | |||
@@ -148,30 +148,14 @@ static void __init holly_setup_arch(void) | |||
148 | static void __init holly_init_IRQ(void) | 148 | static void __init holly_init_IRQ(void) |
149 | { | 149 | { |
150 | struct mpic *mpic; | 150 | struct mpic *mpic; |
151 | phys_addr_t mpic_paddr = 0; | ||
152 | struct device_node *tsi_pic; | ||
153 | #ifdef CONFIG_PCI | 151 | #ifdef CONFIG_PCI |
154 | unsigned int cascade_pci_irq; | 152 | unsigned int cascade_pci_irq; |
155 | struct device_node *tsi_pci; | 153 | struct device_node *tsi_pci; |
156 | struct device_node *cascade_node = NULL; | 154 | struct device_node *cascade_node = NULL; |
157 | #endif | 155 | #endif |
158 | 156 | ||
159 | tsi_pic = of_find_node_by_type(NULL, "open-pic"); | 157 | mpic = mpic_alloc(NULL, 0, |
160 | if (tsi_pic) { | 158 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | |
161 | unsigned int size; | ||
162 | const void *prop = of_get_property(tsi_pic, "reg", &size); | ||
163 | mpic_paddr = of_translate_address(tsi_pic, prop); | ||
164 | } | ||
165 | |||
166 | if (mpic_paddr == 0) { | ||
167 | printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__); | ||
168 | return; | ||
169 | } | ||
170 | |||
171 | pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr); | ||
172 | |||
173 | mpic = mpic_alloc(tsi_pic, mpic_paddr, | ||
174 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | ||
175 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, | 159 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, |
176 | 24, | 160 | 24, |
177 | NR_IRQS-4, /* num_sources used */ | 161 | NR_IRQS-4, /* num_sources used */ |
@@ -179,7 +163,7 @@ static void __init holly_init_IRQ(void) | |||
179 | 163 | ||
180 | BUG_ON(mpic == NULL); | 164 | BUG_ON(mpic == NULL); |
181 | 165 | ||
182 | mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); | 166 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x100); |
183 | 167 | ||
184 | mpic_init(mpic); | 168 | mpic_init(mpic); |
185 | 169 | ||
@@ -204,7 +188,6 @@ static void __init holly_init_IRQ(void) | |||
204 | #endif | 188 | #endif |
205 | /* Configure MPIC outputs to CPU0 */ | 189 | /* Configure MPIC outputs to CPU0 */ |
206 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); | 190 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); |
207 | of_node_put(tsi_pic); | ||
208 | } | 191 | } |
209 | 192 | ||
210 | void holly_show_cpuinfo(struct seq_file *m) | 193 | void holly_show_cpuinfo(struct seq_file *m) |
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index 244f997de791..bcfad92c9cec 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c | |||
@@ -81,29 +81,19 @@ static void __init linkstation_setup_arch(void) | |||
81 | static void __init linkstation_init_IRQ(void) | 81 | static void __init linkstation_init_IRQ(void) |
82 | { | 82 | { |
83 | struct mpic *mpic; | 83 | struct mpic *mpic; |
84 | struct device_node *dnp; | ||
85 | const u32 *prop; | ||
86 | int size; | ||
87 | phys_addr_t paddr; | ||
88 | 84 | ||
89 | dnp = of_find_node_by_type(NULL, "open-pic"); | 85 | mpic = mpic_alloc(NULL, 0, MPIC_WANTS_RESET, |
90 | if (dnp == NULL) | 86 | 4, 32, " EPIC "); |
91 | return; | ||
92 | |||
93 | prop = of_get_property(dnp, "reg", &size); | ||
94 | paddr = (phys_addr_t)of_translate_address(dnp, prop); | ||
95 | |||
96 | mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC "); | ||
97 | BUG_ON(mpic == NULL); | 87 | BUG_ON(mpic == NULL); |
98 | 88 | ||
99 | /* PCI IRQs */ | 89 | /* PCI IRQs */ |
100 | mpic_assign_isu(mpic, 0, paddr + 0x10200); | 90 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x10200); |
101 | 91 | ||
102 | /* I2C */ | 92 | /* I2C */ |
103 | mpic_assign_isu(mpic, 1, paddr + 0x11000); | 93 | mpic_assign_isu(mpic, 1, mpic->paddr + 0x11000); |
104 | 94 | ||
105 | /* ttyS0, ttyS1 */ | 95 | /* ttyS0, ttyS1 */ |
106 | mpic_assign_isu(mpic, 2, paddr + 0x11100); | 96 | mpic_assign_isu(mpic, 2, mpic->paddr + 0x11100); |
107 | 97 | ||
108 | mpic_init(mpic); | 98 | mpic_init(mpic); |
109 | } | 99 | } |
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index f8f33e16c6b6..f3350d786f5b 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | |||
@@ -102,31 +102,14 @@ static void __init mpc7448_hpc2_setup_arch(void) | |||
102 | static void __init mpc7448_hpc2_init_IRQ(void) | 102 | static void __init mpc7448_hpc2_init_IRQ(void) |
103 | { | 103 | { |
104 | struct mpic *mpic; | 104 | struct mpic *mpic; |
105 | phys_addr_t mpic_paddr = 0; | ||
106 | struct device_node *tsi_pic; | ||
107 | #ifdef CONFIG_PCI | 105 | #ifdef CONFIG_PCI |
108 | unsigned int cascade_pci_irq; | 106 | unsigned int cascade_pci_irq; |
109 | struct device_node *tsi_pci; | 107 | struct device_node *tsi_pci; |
110 | struct device_node *cascade_node = NULL; | 108 | struct device_node *cascade_node = NULL; |
111 | #endif | 109 | #endif |
112 | 110 | ||
113 | tsi_pic = of_find_node_by_type(NULL, "open-pic"); | 111 | mpic = mpic_alloc(NULL, 0, |
114 | if (tsi_pic) { | 112 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | |
115 | unsigned int size; | ||
116 | const void *prop = of_get_property(tsi_pic, "reg", &size); | ||
117 | mpic_paddr = of_translate_address(tsi_pic, prop); | ||
118 | } | ||
119 | |||
120 | if (mpic_paddr == 0) { | ||
121 | printk("%s: No tsi108 PIC found !\n", __func__); | ||
122 | return; | ||
123 | } | ||
124 | |||
125 | DBG("%s: tsi108 pic phys_addr = 0x%x\n", __func__, | ||
126 | (u32) mpic_paddr); | ||
127 | |||
128 | mpic = mpic_alloc(tsi_pic, mpic_paddr, | ||
129 | MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | | ||
130 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, | 113 | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, |
131 | 24, | 114 | 24, |
132 | NR_IRQS-4, /* num_sources used */ | 115 | NR_IRQS-4, /* num_sources used */ |
@@ -134,7 +117,7 @@ static void __init mpc7448_hpc2_init_IRQ(void) | |||
134 | 117 | ||
135 | BUG_ON(mpic == NULL); | 118 | BUG_ON(mpic == NULL); |
136 | 119 | ||
137 | mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); | 120 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x100); |
138 | 121 | ||
139 | mpic_init(mpic); | 122 | mpic_init(mpic); |
140 | 123 | ||
@@ -159,7 +142,6 @@ static void __init mpc7448_hpc2_init_IRQ(void) | |||
159 | #endif | 142 | #endif |
160 | /* Configure MPIC outputs to CPU0 */ | 143 | /* Configure MPIC outputs to CPU0 */ |
161 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); | 144 | tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); |
162 | of_node_put(tsi_pic); | ||
163 | } | 145 | } |
164 | 146 | ||
165 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) | 147 | void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) |
diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index f1eebcae9bf0..afa638834965 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c | |||
@@ -83,35 +83,17 @@ static void __init storcenter_setup_arch(void) | |||
83 | static void __init storcenter_init_IRQ(void) | 83 | static void __init storcenter_init_IRQ(void) |
84 | { | 84 | { |
85 | struct mpic *mpic; | 85 | struct mpic *mpic; |
86 | struct device_node *dnp; | ||
87 | const void *prop; | ||
88 | int size; | ||
89 | phys_addr_t paddr; | ||
90 | |||
91 | dnp = of_find_node_by_type(NULL, "open-pic"); | ||
92 | if (dnp == NULL) | ||
93 | return; | ||
94 | |||
95 | prop = of_get_property(dnp, "reg", &size); | ||
96 | if (prop == NULL) { | ||
97 | of_node_put(dnp); | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | paddr = (phys_addr_t)of_translate_address(dnp, prop); | ||
102 | mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, | ||
103 | 16, 32, " OpenPIC "); | ||
104 | |||
105 | of_node_put(dnp); | ||
106 | 86 | ||
87 | mpic = mpic_alloc(NULL, 0, MPIC_WANTS_RESET, | ||
88 | 16, 32, " OpenPIC "); | ||
107 | BUG_ON(mpic == NULL); | 89 | BUG_ON(mpic == NULL); |
108 | 90 | ||
109 | /* | 91 | /* |
110 | * 16 Serial Interrupts followed by 16 Internal Interrupts. | 92 | * 16 Serial Interrupts followed by 16 Internal Interrupts. |
111 | * I2C is the second internal, so it is at 17, 0x11020. | 93 | * I2C is the second internal, so it is at 17, 0x11020. |
112 | */ | 94 | */ |
113 | mpic_assign_isu(mpic, 0, paddr + 0x10200); | 95 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x10200); |
114 | mpic_assign_isu(mpic, 1, paddr + 0x11000); | 96 | mpic_assign_isu(mpic, 1, mpic->paddr + 0x11000); |
115 | 97 | ||
116 | mpic_init(mpic); | 98 | mpic_init(mpic); |
117 | } | 99 | } |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index dd2e48b28508..401e3f3f74c8 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -207,6 +207,54 @@ static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, | |||
207 | return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset); | 207 | return hose->cfg_data + u3_ht_cfa1(bus, devfn, offset); |
208 | } | 208 | } |
209 | 209 | ||
210 | static int u3_ht_root_read_config(struct pci_controller *hose, u8 offset, | ||
211 | int len, u32 *val) | ||
212 | { | ||
213 | volatile void __iomem *addr; | ||
214 | |||
215 | addr = hose->cfg_addr; | ||
216 | addr += ((offset & ~3) << 2) + (4 - len - (offset & 3)); | ||
217 | |||
218 | switch (len) { | ||
219 | case 1: | ||
220 | *val = in_8(addr); | ||
221 | break; | ||
222 | case 2: | ||
223 | *val = in_be16(addr); | ||
224 | break; | ||
225 | default: | ||
226 | *val = in_be32(addr); | ||
227 | break; | ||
228 | } | ||
229 | |||
230 | return PCIBIOS_SUCCESSFUL; | ||
231 | } | ||
232 | |||
233 | static int u3_ht_root_write_config(struct pci_controller *hose, u8 offset, | ||
234 | int len, u32 val) | ||
235 | { | ||
236 | volatile void __iomem *addr; | ||
237 | |||
238 | addr = hose->cfg_addr + ((offset & ~3) << 2) + (4 - len - (offset & 3)); | ||
239 | |||
240 | if (offset >= PCI_BASE_ADDRESS_0 && offset < PCI_CAPABILITY_LIST) | ||
241 | return PCIBIOS_SUCCESSFUL; | ||
242 | |||
243 | switch (len) { | ||
244 | case 1: | ||
245 | out_8(addr, val); | ||
246 | break; | ||
247 | case 2: | ||
248 | out_be16(addr, val); | ||
249 | break; | ||
250 | default: | ||
251 | out_be32(addr, val); | ||
252 | break; | ||
253 | } | ||
254 | |||
255 | return PCIBIOS_SUCCESSFUL; | ||
256 | } | ||
257 | |||
210 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | 258 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, |
211 | int offset, int len, u32 *val) | 259 | int offset, int len, u32 *val) |
212 | { | 260 | { |
@@ -217,6 +265,9 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | |||
217 | if (hose == NULL) | 265 | if (hose == NULL) |
218 | return PCIBIOS_DEVICE_NOT_FOUND; | 266 | return PCIBIOS_DEVICE_NOT_FOUND; |
219 | 267 | ||
268 | if (bus->number == hose->first_busno && devfn == PCI_DEVFN(0, 0)) | ||
269 | return u3_ht_root_read_config(hose, offset, len, val); | ||
270 | |||
220 | if (offset > 0xff) | 271 | if (offset > 0xff) |
221 | return PCIBIOS_BAD_REGISTER_NUMBER; | 272 | return PCIBIOS_BAD_REGISTER_NUMBER; |
222 | 273 | ||
@@ -252,6 +303,9 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | |||
252 | if (hose == NULL) | 303 | if (hose == NULL) |
253 | return PCIBIOS_DEVICE_NOT_FOUND; | 304 | return PCIBIOS_DEVICE_NOT_FOUND; |
254 | 305 | ||
306 | if (bus->number == hose->first_busno && devfn == PCI_DEVFN(0, 0)) | ||
307 | return u3_ht_root_write_config(hose, offset, len, val); | ||
308 | |||
255 | if (offset > 0xff) | 309 | if (offset > 0xff) |
256 | return PCIBIOS_BAD_REGISTER_NUMBER; | 310 | return PCIBIOS_BAD_REGISTER_NUMBER; |
257 | 311 | ||
@@ -428,6 +482,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
428 | * reg_property and using some accessor functions instead | 482 | * reg_property and using some accessor functions instead |
429 | */ | 483 | */ |
430 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); | 484 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); |
485 | hose->cfg_addr = ioremap(0xf8070000, 0x1000); | ||
431 | 486 | ||
432 | hose->first_busno = 0; | 487 | hose->first_busno = 0; |
433 | hose->last_busno = 0xef; | 488 | hose->last_busno = 0xef; |
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 4c372047c94e..0bcbfe7b2c55 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
@@ -221,7 +221,7 @@ static void __init maple_init_IRQ(void) | |||
221 | unsigned long openpic_addr = 0; | 221 | unsigned long openpic_addr = 0; |
222 | int naddr, n, i, opplen, has_isus = 0; | 222 | int naddr, n, i, opplen, has_isus = 0; |
223 | struct mpic *mpic; | 223 | struct mpic *mpic; |
224 | unsigned int flags = MPIC_PRIMARY; | 224 | unsigned int flags = 0; |
225 | 225 | ||
226 | /* Locate MPIC in the device-tree. Note that there is a bug | 226 | /* Locate MPIC in the device-tree. Note that there is a bug |
227 | * in Maple device-tree where the type of the controller is | 227 | * in Maple device-tree where the type of the controller is |
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 6f3558210554..98b7a7c13176 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c | |||
@@ -224,7 +224,7 @@ static __init void pas_init_IRQ(void) | |||
224 | openpic_addr = of_read_number(opprop, naddr); | 224 | openpic_addr = of_read_number(opprop, naddr); |
225 | printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); | 225 | printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); |
226 | 226 | ||
227 | mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS; | 227 | mpic_flags = MPIC_LARGE_VECTORS | MPIC_NO_BIAS; |
228 | 228 | ||
229 | nmiprop = of_get_property(mpic_node, "nmi-source", NULL); | 229 | nmiprop = of_get_property(mpic_node, "nmi-source", NULL); |
230 | if (nmiprop) | 230 | if (nmiprop) |
@@ -234,7 +234,7 @@ static __init void pas_init_IRQ(void) | |||
234 | mpic_flags, 0, 0, "PASEMI-OPIC"); | 234 | mpic_flags, 0, 0, "PASEMI-OPIC"); |
235 | BUG_ON(!mpic); | 235 | BUG_ON(!mpic); |
236 | 236 | ||
237 | mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); | 237 | mpic_assign_isu(mpic, 0, mpic->paddr + 0x10000); |
238 | mpic_init(mpic); | 238 | mpic_init(mpic); |
239 | /* The NMI/MCK source needs to be prio 15 */ | 239 | /* The NMI/MCK source needs to be prio 15 */ |
240 | if (nmiprop) { | 240 | if (nmiprop) { |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 901bfbddc3dd..7761aabfc293 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
@@ -52,13 +52,8 @@ struct device_node *of_irq_dflt_pic; | |||
52 | /* Default addresses */ | 52 | /* Default addresses */ |
53 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; | 53 | static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; |
54 | 54 | ||
55 | #define GC_LEVEL_MASK 0x3ff00000 | ||
56 | #define OHARE_LEVEL_MASK 0x1ff00000 | ||
57 | #define HEATHROW_LEVEL_MASK 0x1ff00000 | ||
58 | |||
59 | static int max_irqs; | 55 | static int max_irqs; |
60 | static int max_real_irqs; | 56 | static int max_real_irqs; |
61 | static u32 level_mask[4]; | ||
62 | 57 | ||
63 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); | 58 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); |
64 | 59 | ||
@@ -217,8 +212,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) | |||
217 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { | 212 | for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { |
218 | int i = irq >> 5; | 213 | int i = irq >> 5; |
219 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | 214 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; |
220 | /* We must read level interrupts from the level register */ | 215 | bits |= in_le32(&pmac_irq_hw[i]->level); |
221 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
222 | bits &= ppc_cached_irq_mask[i]; | 216 | bits &= ppc_cached_irq_mask[i]; |
223 | if (bits == 0) | 217 | if (bits == 0) |
224 | continue; | 218 | continue; |
@@ -248,8 +242,7 @@ static unsigned int pmac_pic_get_irq(void) | |||
248 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { | 242 | for (irq = max_real_irqs; (irq -= 32) >= 0; ) { |
249 | int i = irq >> 5; | 243 | int i = irq >> 5; |
250 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; | 244 | bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; |
251 | /* We must read level interrupts from the level register */ | 245 | bits |= in_le32(&pmac_irq_hw[i]->level); |
252 | bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); | ||
253 | bits &= ppc_cached_irq_mask[i]; | 246 | bits &= ppc_cached_irq_mask[i]; |
254 | if (bits == 0) | 247 | if (bits == 0) |
255 | continue; | 248 | continue; |
@@ -284,19 +277,14 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) | |||
284 | static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, | 277 | static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, |
285 | irq_hw_number_t hw) | 278 | irq_hw_number_t hw) |
286 | { | 279 | { |
287 | int level; | ||
288 | |||
289 | if (hw >= max_irqs) | 280 | if (hw >= max_irqs) |
290 | return -EINVAL; | 281 | return -EINVAL; |
291 | 282 | ||
292 | /* Mark level interrupts, set delayed disable for edge ones and set | 283 | /* Mark level interrupts, set delayed disable for edge ones and set |
293 | * handlers | 284 | * handlers |
294 | */ | 285 | */ |
295 | level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f))); | 286 | irq_set_status_flags(virq, IRQ_LEVEL); |
296 | if (level) | 287 | irq_set_chip_and_handler(virq, &pmac_pic, handle_level_irq); |
297 | irq_set_status_flags(virq, IRQ_LEVEL); | ||
298 | irq_set_chip_and_handler(virq, &pmac_pic, | ||
299 | level ? handle_level_irq : handle_edge_irq); | ||
300 | return 0; | 288 | return 0; |
301 | } | 289 | } |
302 | 290 | ||
@@ -334,21 +322,14 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
334 | 322 | ||
335 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { | 323 | if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { |
336 | max_irqs = max_real_irqs = 32; | 324 | max_irqs = max_real_irqs = 32; |
337 | level_mask[0] = GC_LEVEL_MASK; | ||
338 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { | 325 | } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { |
339 | max_irqs = max_real_irqs = 32; | 326 | max_irqs = max_real_irqs = 32; |
340 | level_mask[0] = OHARE_LEVEL_MASK; | ||
341 | |||
342 | /* We might have a second cascaded ohare */ | 327 | /* We might have a second cascaded ohare */ |
343 | slave = of_find_node_by_name(NULL, "pci106b,7"); | 328 | slave = of_find_node_by_name(NULL, "pci106b,7"); |
344 | if (slave) { | 329 | if (slave) |
345 | max_irqs = 64; | 330 | max_irqs = 64; |
346 | level_mask[1] = OHARE_LEVEL_MASK; | ||
347 | } | ||
348 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { | 331 | } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { |
349 | max_irqs = max_real_irqs = 64; | 332 | max_irqs = max_real_irqs = 64; |
350 | level_mask[0] = HEATHROW_LEVEL_MASK; | ||
351 | level_mask[1] = 0; | ||
352 | 333 | ||
353 | /* We might have a second cascaded heathrow */ | 334 | /* We might have a second cascaded heathrow */ |
354 | slave = of_find_node_by_name(master, "mac-io"); | 335 | slave = of_find_node_by_name(master, "mac-io"); |
@@ -363,11 +344,8 @@ static void __init pmac_pic_probe_oldstyle(void) | |||
363 | } | 344 | } |
364 | 345 | ||
365 | /* We found a slave */ | 346 | /* We found a slave */ |
366 | if (slave) { | 347 | if (slave) |
367 | max_irqs = 128; | 348 | max_irqs = 128; |
368 | level_mask[2] = HEATHROW_LEVEL_MASK; | ||
369 | level_mask[3] = 0; | ||
370 | } | ||
371 | } | 349 | } |
372 | BUG_ON(master == NULL); | 350 | BUG_ON(master == NULL); |
373 | 351 | ||
@@ -464,18 +442,6 @@ int of_irq_map_oldworld(struct device_node *device, int index, | |||
464 | } | 442 | } |
465 | #endif /* CONFIG_PPC32 */ | 443 | #endif /* CONFIG_PPC32 */ |
466 | 444 | ||
467 | static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) | ||
468 | { | ||
469 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
470 | struct mpic *mpic = irq_desc_get_handler_data(desc); | ||
471 | unsigned int cascade_irq = mpic_get_one_irq(mpic); | ||
472 | |||
473 | if (cascade_irq != NO_IRQ) | ||
474 | generic_handle_irq(cascade_irq); | ||
475 | |||
476 | chip->irq_eoi(&desc->irq_data); | ||
477 | } | ||
478 | |||
479 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) | 445 | static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) |
480 | { | 446 | { |
481 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) | 447 | #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) |
@@ -498,14 +464,8 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | |||
498 | int master) | 464 | int master) |
499 | { | 465 | { |
500 | const char *name = master ? " MPIC 1 " : " MPIC 2 "; | 466 | const char *name = master ? " MPIC 1 " : " MPIC 2 "; |
501 | struct resource r; | ||
502 | struct mpic *mpic; | 467 | struct mpic *mpic; |
503 | unsigned int flags = master ? MPIC_PRIMARY : 0; | 468 | unsigned int flags = master ? 0 : MPIC_SECONDARY; |
504 | int rc; | ||
505 | |||
506 | rc = of_address_to_resource(np, 0, &r); | ||
507 | if (rc) | ||
508 | return NULL; | ||
509 | 469 | ||
510 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); | 470 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); |
511 | 471 | ||
@@ -519,7 +479,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, | |||
519 | if (master && (flags & MPIC_BIG_ENDIAN)) | 479 | if (master && (flags & MPIC_BIG_ENDIAN)) |
520 | flags |= MPIC_U3_HT_IRQS; | 480 | flags |= MPIC_U3_HT_IRQS; |
521 | 481 | ||
522 | mpic = mpic_alloc(np, r.start, flags, 0, 0, name); | 482 | mpic = mpic_alloc(np, 0, flags, 0, 0, name); |
523 | if (mpic == NULL) | 483 | if (mpic == NULL) |
524 | return NULL; | 484 | return NULL; |
525 | 485 | ||
@@ -532,7 +492,6 @@ static int __init pmac_pic_probe_mpic(void) | |||
532 | { | 492 | { |
533 | struct mpic *mpic1, *mpic2; | 493 | struct mpic *mpic1, *mpic2; |
534 | struct device_node *np, *master = NULL, *slave = NULL; | 494 | struct device_node *np, *master = NULL, *slave = NULL; |
535 | unsigned int cascade; | ||
536 | 495 | ||
537 | /* We can have up to 2 MPICs cascaded */ | 496 | /* We can have up to 2 MPICs cascaded */ |
538 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) | 497 | for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) |
@@ -568,27 +527,14 @@ static int __init pmac_pic_probe_mpic(void) | |||
568 | 527 | ||
569 | of_node_put(master); | 528 | of_node_put(master); |
570 | 529 | ||
571 | /* No slave, let's go out */ | 530 | /* Set up a cascaded controller, if present */ |
572 | if (slave == NULL) | 531 | if (slave) { |
573 | return 0; | 532 | mpic2 = pmac_setup_one_mpic(slave, 0); |
574 | 533 | if (mpic2 == NULL) | |
575 | /* Get/Map slave interrupt */ | 534 | printk(KERN_ERR "Failed to setup slave MPIC\n"); |
576 | cascade = irq_of_parse_and_map(slave, 0); | ||
577 | if (cascade == NO_IRQ) { | ||
578 | printk(KERN_ERR "Failed to map cascade IRQ\n"); | ||
579 | return 0; | ||
580 | } | ||
581 | |||
582 | mpic2 = pmac_setup_one_mpic(slave, 0); | ||
583 | if (mpic2 == NULL) { | ||
584 | printk(KERN_ERR "Failed to setup slave MPIC\n"); | ||
585 | of_node_put(slave); | 535 | of_node_put(slave); |
586 | return 0; | ||
587 | } | 536 | } |
588 | irq_set_handler_data(cascade, mpic2); | ||
589 | irq_set_chained_handler(cascade, pmac_u3_cascade); | ||
590 | 537 | ||
591 | of_node_put(slave); | ||
592 | return 0; | 538 | return 0; |
593 | } | 539 | } |
594 | 540 | ||
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 96580b189ec2..970ea1de4298 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -494,11 +494,15 @@ static int __init pmac_declare_of_platform_devices(void) | |||
494 | return -1; | 494 | return -1; |
495 | 495 | ||
496 | np = of_find_node_by_name(NULL, "valkyrie"); | 496 | np = of_find_node_by_name(NULL, "valkyrie"); |
497 | if (np) | 497 | if (np) { |
498 | of_platform_device_create(np, "valkyrie", NULL); | 498 | of_platform_device_create(np, "valkyrie", NULL); |
499 | of_node_put(np); | ||
500 | } | ||
499 | np = of_find_node_by_name(NULL, "platinum"); | 501 | np = of_find_node_by_name(NULL, "platinum"); |
500 | if (np) | 502 | if (np) { |
501 | of_platform_device_create(np, "platinum", NULL); | 503 | of_platform_device_create(np, "platinum", NULL); |
504 | of_node_put(np); | ||
505 | } | ||
502 | np = of_find_node_by_type(NULL, "smu"); | 506 | np = of_find_node_by_type(NULL, "smu"); |
503 | if (np) { | 507 | if (np) { |
504 | of_platform_device_create(np, "smu", NULL); | 508 | of_platform_device_create(np, "smu", NULL); |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 9b6a820bdd7d..44d769258ebf 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
@@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void) | |||
200 | 200 | ||
201 | if (psurge_secondary_virq) | 201 | if (psurge_secondary_virq) |
202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, | 202 | rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, |
203 | IRQF_PERCPU, "IPI", NULL); | 203 | IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL); |
204 | 204 | ||
205 | if (rc) | 205 | if (rc) |
206 | pr_err("Failed to setup secondary cpu IPI\n"); | 206 | pr_err("Failed to setup secondary cpu IPI\n"); |
@@ -408,13 +408,13 @@ static int __init smp_psurge_kick_cpu(int nr) | |||
408 | 408 | ||
409 | static struct irqaction psurge_irqaction = { | 409 | static struct irqaction psurge_irqaction = { |
410 | .handler = psurge_ipi_intr, | 410 | .handler = psurge_ipi_intr, |
411 | .flags = IRQF_PERCPU, | 411 | .flags = IRQF_PERCPU | IRQF_NO_THREAD, |
412 | .name = "primary IPI", | 412 | .name = "primary IPI", |
413 | }; | 413 | }; |
414 | 414 | ||
415 | static void __init smp_psurge_setup_cpu(int cpu_nr) | 415 | static void __init smp_psurge_setup_cpu(int cpu_nr) |
416 | { | 416 | { |
417 | if (cpu_nr != 0) | 417 | if (cpu_nr != 0 || !psurge_start) |
418 | return; | 418 | return; |
419 | 419 | ||
420 | /* reset the entry point so if we get another intr we won't | 420 | /* reset the entry point so if we get another intr we won't |
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 31853008b418..bcc3cb48a44e 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile | |||
@@ -2,4 +2,4 @@ obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o | |||
2 | obj-y += opal-rtc.o opal-nvram.o | 2 | obj-y += opal-rtc.o opal-nvram.o |
3 | 3 | ||
4 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
5 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o | 5 | obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 4a3f46d8533e..3bb07e5e43cd 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -99,3 +99,11 @@ OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); | |||
99 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); | 99 | OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); |
100 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); | 100 | OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); |
101 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); | 101 | OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); |
102 | OPAL_CALL(opal_pci_get_hub_diag_data, OPAL_PCI_GET_HUB_DIAG_DATA); | ||
103 | OPAL_CALL(opal_pci_get_phb_diag_data, OPAL_PCI_GET_PHB_DIAG_DATA); | ||
104 | OPAL_CALL(opal_pci_fence_phb, OPAL_PCI_FENCE_PHB); | ||
105 | OPAL_CALL(opal_pci_reinit, OPAL_PCI_REINIT); | ||
106 | OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | ||
107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | ||
108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | ||
109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c new file mode 100644 index 000000000000..f31162cfdaa9 --- /dev/null +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -0,0 +1,1330 @@ | |||
1 | /* | ||
2 | * Support PCI/PCIe on PowerNV platforms | ||
3 | * | ||
4 | * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #undef DEBUG | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/bootmem.h> | ||
20 | #include <linux/irq.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/msi.h> | ||
23 | |||
24 | #include <asm/sections.h> | ||
25 | #include <asm/io.h> | ||
26 | #include <asm/prom.h> | ||
27 | #include <asm/pci-bridge.h> | ||
28 | #include <asm/machdep.h> | ||
29 | #include <asm/ppc-pci.h> | ||
30 | #include <asm/opal.h> | ||
31 | #include <asm/iommu.h> | ||
32 | #include <asm/tce.h> | ||
33 | #include <asm/abs_addr.h> | ||
34 | |||
35 | #include "powernv.h" | ||
36 | #include "pci.h" | ||
37 | |||
38 | struct resource_wrap { | ||
39 | struct list_head link; | ||
40 | resource_size_t size; | ||
41 | resource_size_t align; | ||
42 | struct pci_dev *dev; /* Set if it's a device */ | ||
43 | struct pci_bus *bus; /* Set if it's a bridge */ | ||
44 | }; | ||
45 | |||
46 | static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe, | ||
47 | struct va_format *vaf) | ||
48 | { | ||
49 | char pfix[32]; | ||
50 | |||
51 | if (pe->pdev) | ||
52 | strlcpy(pfix, dev_name(&pe->pdev->dev), sizeof(pfix)); | ||
53 | else | ||
54 | sprintf(pfix, "%04x:%02x ", | ||
55 | pci_domain_nr(pe->pbus), pe->pbus->number); | ||
56 | return printk("pci %s%s: [PE# %.3d] %pV", level, pfix, pe->pe_number, vaf); | ||
57 | } | ||
58 | |||
59 | #define define_pe_printk_level(func, kern_level) \ | ||
60 | static int func(const struct pnv_ioda_pe *pe, const char *fmt, ...) \ | ||
61 | { \ | ||
62 | struct va_format vaf; \ | ||
63 | va_list args; \ | ||
64 | int r; \ | ||
65 | \ | ||
66 | va_start(args, fmt); \ | ||
67 | \ | ||
68 | vaf.fmt = fmt; \ | ||
69 | vaf.va = &args; \ | ||
70 | \ | ||
71 | r = __pe_printk(kern_level, pe, &vaf); \ | ||
72 | va_end(args); \ | ||
73 | \ | ||
74 | return r; \ | ||
75 | } \ | ||
76 | |||
77 | define_pe_printk_level(pe_err, KERN_ERR); | ||
78 | define_pe_printk_level(pe_warn, KERN_WARNING); | ||
79 | define_pe_printk_level(pe_info, KERN_INFO); | ||
80 | |||
81 | |||
82 | /* Calculate resource usage & alignment requirement of a single | ||
83 | * device. This will also assign all resources within the device | ||
84 | * for a given type starting at 0 for the biggest one and then | ||
85 | * assigning in decreasing order of size. | ||
86 | */ | ||
87 | static void __devinit pnv_ioda_calc_dev(struct pci_dev *dev, unsigned int flags, | ||
88 | resource_size_t *size, | ||
89 | resource_size_t *align) | ||
90 | { | ||
91 | resource_size_t start; | ||
92 | struct resource *r; | ||
93 | int i; | ||
94 | |||
95 | pr_devel(" -> CDR %s\n", pci_name(dev)); | ||
96 | |||
97 | *size = *align = 0; | ||
98 | |||
99 | /* Clear the resources out and mark them all unset */ | ||
100 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
101 | r = &dev->resource[i]; | ||
102 | if (!(r->flags & flags)) | ||
103 | continue; | ||
104 | if (r->start) { | ||
105 | r->end -= r->start; | ||
106 | r->start = 0; | ||
107 | } | ||
108 | r->flags |= IORESOURCE_UNSET; | ||
109 | } | ||
110 | |||
111 | /* We currently keep all memory resources together, we | ||
112 | * will handle prefetch & 64-bit separately in the future | ||
113 | * but for now we stick everybody in M32 | ||
114 | */ | ||
115 | start = 0; | ||
116 | for (;;) { | ||
117 | resource_size_t max_size = 0; | ||
118 | int max_no = -1; | ||
119 | |||
120 | /* Find next biggest resource */ | ||
121 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
122 | r = &dev->resource[i]; | ||
123 | if (!(r->flags & IORESOURCE_UNSET) || | ||
124 | !(r->flags & flags)) | ||
125 | continue; | ||
126 | if (resource_size(r) > max_size) { | ||
127 | max_size = resource_size(r); | ||
128 | max_no = i; | ||
129 | } | ||
130 | } | ||
131 | if (max_no < 0) | ||
132 | break; | ||
133 | r = &dev->resource[max_no]; | ||
134 | if (max_size > *align) | ||
135 | *align = max_size; | ||
136 | *size += max_size; | ||
137 | r->start = start; | ||
138 | start += max_size; | ||
139 | r->end = r->start + max_size - 1; | ||
140 | r->flags &= ~IORESOURCE_UNSET; | ||
141 | pr_devel(" -> R%d %016llx..%016llx\n", | ||
142 | max_no, r->start, r->end); | ||
143 | } | ||
144 | pr_devel(" <- CDR %s size=%llx align=%llx\n", | ||
145 | pci_name(dev), *size, *align); | ||
146 | } | ||
147 | |||
148 | /* Allocate a resource "wrap" for a given device or bridge and | ||
149 | * insert it at the right position in the sorted list | ||
150 | */ | ||
151 | static void __devinit pnv_ioda_add_wrap(struct list_head *list, | ||
152 | struct pci_bus *bus, | ||
153 | struct pci_dev *dev, | ||
154 | resource_size_t size, | ||
155 | resource_size_t align) | ||
156 | { | ||
157 | struct resource_wrap *w1, *w = kzalloc(sizeof(*w), GFP_KERNEL); | ||
158 | |||
159 | w->size = size; | ||
160 | w->align = align; | ||
161 | w->dev = dev; | ||
162 | w->bus = bus; | ||
163 | |||
164 | list_for_each_entry(w1, list, link) { | ||
165 | if (w1->align < align) { | ||
166 | list_add_tail(&w->link, &w1->link); | ||
167 | return; | ||
168 | } | ||
169 | } | ||
170 | list_add_tail(&w->link, list); | ||
171 | } | ||
172 | |||
173 | /* Offset device resources of a given type */ | ||
174 | static void __devinit pnv_ioda_offset_dev(struct pci_dev *dev, | ||
175 | unsigned int flags, | ||
176 | resource_size_t offset) | ||
177 | { | ||
178 | struct resource *r; | ||
179 | int i; | ||
180 | |||
181 | pr_devel(" -> ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); | ||
182 | |||
183 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
184 | r = &dev->resource[i]; | ||
185 | if (r->flags & flags) { | ||
186 | dev->resource[i].start += offset; | ||
187 | dev->resource[i].end += offset; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | pr_devel(" <- ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); | ||
192 | } | ||
193 | |||
194 | /* Offset bus resources (& all children) of a given type */ | ||
195 | static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus, | ||
196 | unsigned int flags, | ||
197 | resource_size_t offset) | ||
198 | { | ||
199 | struct resource *r; | ||
200 | struct pci_dev *dev; | ||
201 | struct pci_bus *cbus; | ||
202 | int i; | ||
203 | |||
204 | pr_devel(" -> OBR %s [%x] +%016llx\n", | ||
205 | bus->self ? pci_name(bus->self) : "root", flags, offset); | ||
206 | |||
207 | for (i = 0; i < 2; i++) { | ||
208 | r = bus->resource[i]; | ||
209 | if (r && (r->flags & flags)) { | ||
210 | bus->resource[i]->start += offset; | ||
211 | bus->resource[i]->end += offset; | ||
212 | } | ||
213 | } | ||
214 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
215 | pnv_ioda_offset_dev(dev, flags, offset); | ||
216 | list_for_each_entry(cbus, &bus->children, node) | ||
217 | pnv_ioda_offset_bus(cbus, flags, offset); | ||
218 | |||
219 | pr_devel(" <- OBR %s [%x]\n", | ||
220 | bus->self ? pci_name(bus->self) : "root", flags); | ||
221 | } | ||
222 | |||
223 | /* This is the guts of our IODA resource allocation. This is called | ||
224 | * recursively for each bus in the system. It calculates all the | ||
225 | * necessary size and requirements for children and assign them | ||
226 | * resources such that: | ||
227 | * | ||
228 | * - Each function fits in it's own contiguous set of IO/M32 | ||
229 | * segment | ||
230 | * | ||
231 | * - All segments behind a P2P bridge are contiguous and obey | ||
232 | * alignment constraints of those bridges | ||
233 | */ | ||
234 | static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags, | ||
235 | resource_size_t *size, | ||
236 | resource_size_t *align) | ||
237 | { | ||
238 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
239 | struct pnv_phb *phb = hose->private_data; | ||
240 | resource_size_t dev_size, dev_align, start; | ||
241 | resource_size_t min_align, min_balign; | ||
242 | struct pci_dev *cdev; | ||
243 | struct pci_bus *cbus; | ||
244 | struct list_head head; | ||
245 | struct resource_wrap *w; | ||
246 | unsigned int bres; | ||
247 | |||
248 | *size = *align = 0; | ||
249 | |||
250 | pr_devel("-> CBR %s [%x]\n", | ||
251 | bus->self ? pci_name(bus->self) : "root", flags); | ||
252 | |||
253 | /* Calculate alignment requirements based on the type | ||
254 | * of resource we are working on | ||
255 | */ | ||
256 | if (flags & IORESOURCE_IO) { | ||
257 | bres = 0; | ||
258 | min_align = phb->ioda.io_segsize; | ||
259 | min_balign = 0x1000; | ||
260 | } else { | ||
261 | bres = 1; | ||
262 | min_align = phb->ioda.m32_segsize; | ||
263 | min_balign = 0x100000; | ||
264 | } | ||
265 | |||
266 | /* Gather all our children resources ordered by alignment */ | ||
267 | INIT_LIST_HEAD(&head); | ||
268 | |||
269 | /* - Busses */ | ||
270 | list_for_each_entry(cbus, &bus->children, node) { | ||
271 | pnv_ioda_calc_bus(cbus, flags, &dev_size, &dev_align); | ||
272 | pnv_ioda_add_wrap(&head, cbus, NULL, dev_size, dev_align); | ||
273 | } | ||
274 | |||
275 | /* - Devices */ | ||
276 | list_for_each_entry(cdev, &bus->devices, bus_list) { | ||
277 | pnv_ioda_calc_dev(cdev, flags, &dev_size, &dev_align); | ||
278 | /* Align them to segment size */ | ||
279 | if (dev_align < min_align) | ||
280 | dev_align = min_align; | ||
281 | pnv_ioda_add_wrap(&head, NULL, cdev, dev_size, dev_align); | ||
282 | } | ||
283 | if (list_empty(&head)) | ||
284 | goto empty; | ||
285 | |||
286 | /* Now we can do two things: assign offsets to them within that | ||
287 | * level and get our total alignment & size requirements. The | ||
288 | * assignment algorithm is going to be uber-trivial for now, we | ||
289 | * can try to be smarter later at filling out holes. | ||
290 | */ | ||
291 | start = bus->self ? 0 : bus->resource[bres]->start; | ||
292 | |||
293 | /* Don't hand out IO 0 */ | ||
294 | if ((flags & IORESOURCE_IO) && !bus->self) | ||
295 | start += 0x1000; | ||
296 | |||
297 | while(!list_empty(&head)) { | ||
298 | w = list_first_entry(&head, struct resource_wrap, link); | ||
299 | list_del(&w->link); | ||
300 | if (w->size) { | ||
301 | if (start) { | ||
302 | start = ALIGN(start, w->align); | ||
303 | if (w->dev) | ||
304 | pnv_ioda_offset_dev(w->dev,flags,start); | ||
305 | else if (w->bus) | ||
306 | pnv_ioda_offset_bus(w->bus,flags,start); | ||
307 | } | ||
308 | if (w->align > *align) | ||
309 | *align = w->align; | ||
310 | } | ||
311 | start += w->size; | ||
312 | kfree(w); | ||
313 | } | ||
314 | *size = start; | ||
315 | |||
316 | /* Align and setup bridge resources */ | ||
317 | *align = max_t(resource_size_t, *align, | ||
318 | max_t(resource_size_t, min_align, min_balign)); | ||
319 | *size = ALIGN(*size, | ||
320 | max_t(resource_size_t, min_align, min_balign)); | ||
321 | empty: | ||
322 | /* Only setup P2P's, not the PHB itself */ | ||
323 | if (bus->self) { | ||
324 | WARN_ON(bus->resource[bres] == NULL); | ||
325 | bus->resource[bres]->start = 0; | ||
326 | bus->resource[bres]->flags = (*size) ? flags : 0; | ||
327 | bus->resource[bres]->end = (*size) ? (*size - 1) : 0; | ||
328 | |||
329 | /* Clear prefetch bus resources for now */ | ||
330 | bus->resource[2]->flags = 0; | ||
331 | } | ||
332 | |||
333 | pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n", | ||
334 | bus->self ? pci_name(bus->self) : "root", flags,*size,*align); | ||
335 | } | ||
336 | |||
337 | static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) | ||
338 | { | ||
339 | struct device_node *np; | ||
340 | |||
341 | np = pci_device_to_OF_node(dev); | ||
342 | if (!np) | ||
343 | return NULL; | ||
344 | return PCI_DN(np); | ||
345 | } | ||
346 | |||
347 | static void __devinit pnv_ioda_setup_pe_segments(struct pci_dev *dev) | ||
348 | { | ||
349 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
350 | struct pnv_phb *phb = hose->private_data; | ||
351 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
352 | unsigned int pe, i; | ||
353 | resource_size_t pos; | ||
354 | struct resource io_res; | ||
355 | struct resource m32_res; | ||
356 | struct pci_bus_region region; | ||
357 | int rc; | ||
358 | |||
359 | /* Anything not referenced in the device-tree gets PE#0 */ | ||
360 | pe = pdn ? pdn->pe_number : 0; | ||
361 | |||
362 | /* Calculate the device min/max */ | ||
363 | io_res.start = m32_res.start = (resource_size_t)-1; | ||
364 | io_res.end = m32_res.end = 0; | ||
365 | io_res.flags = IORESOURCE_IO; | ||
366 | m32_res.flags = IORESOURCE_MEM; | ||
367 | |||
368 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
369 | struct resource *r = NULL; | ||
370 | if (dev->resource[i].flags & IORESOURCE_IO) | ||
371 | r = &io_res; | ||
372 | if (dev->resource[i].flags & IORESOURCE_MEM) | ||
373 | r = &m32_res; | ||
374 | if (!r) | ||
375 | continue; | ||
376 | if (dev->resource[i].start < r->start) | ||
377 | r->start = dev->resource[i].start; | ||
378 | if (dev->resource[i].end > r->end) | ||
379 | r->end = dev->resource[i].end; | ||
380 | } | ||
381 | |||
382 | /* Setup IO segments */ | ||
383 | if (io_res.start < io_res.end) { | ||
384 | pcibios_resource_to_bus(dev, ®ion, &io_res); | ||
385 | pos = region.start; | ||
386 | i = pos / phb->ioda.io_segsize; | ||
387 | while(i < phb->ioda.total_pe && pos <= region.end) { | ||
388 | if (phb->ioda.io_segmap[i]) { | ||
389 | pr_err("%s: Trying to use IO seg #%d which is" | ||
390 | " already used by PE# %d\n", | ||
391 | pci_name(dev), i, | ||
392 | phb->ioda.io_segmap[i]); | ||
393 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
394 | break; | ||
395 | } | ||
396 | phb->ioda.io_segmap[i] = pe; | ||
397 | rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, | ||
398 | OPAL_IO_WINDOW_TYPE, | ||
399 | 0, i); | ||
400 | if (rc != OPAL_SUCCESS) { | ||
401 | pr_err("%s: OPAL error %d setting up mapping" | ||
402 | " for IO seg# %d\n", | ||
403 | pci_name(dev), rc, i); | ||
404 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
405 | break; | ||
406 | } | ||
407 | pos += phb->ioda.io_segsize; | ||
408 | i++; | ||
409 | }; | ||
410 | } | ||
411 | |||
412 | /* Setup M32 segments */ | ||
413 | if (m32_res.start < m32_res.end) { | ||
414 | pcibios_resource_to_bus(dev, ®ion, &m32_res); | ||
415 | pos = region.start; | ||
416 | i = pos / phb->ioda.m32_segsize; | ||
417 | while(i < phb->ioda.total_pe && pos <= region.end) { | ||
418 | if (phb->ioda.m32_segmap[i]) { | ||
419 | pr_err("%s: Trying to use M32 seg #%d which is" | ||
420 | " already used by PE# %d\n", | ||
421 | pci_name(dev), i, | ||
422 | phb->ioda.m32_segmap[i]); | ||
423 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
424 | break; | ||
425 | } | ||
426 | phb->ioda.m32_segmap[i] = pe; | ||
427 | rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, | ||
428 | OPAL_M32_WINDOW_TYPE, | ||
429 | 0, i); | ||
430 | if (rc != OPAL_SUCCESS) { | ||
431 | pr_err("%s: OPAL error %d setting up mapping" | ||
432 | " for M32 seg# %d\n", | ||
433 | pci_name(dev), rc, i); | ||
434 | /* XXX DO SOMETHING TO DISABLE DEVICE ? */ | ||
435 | break; | ||
436 | } | ||
437 | pos += phb->ioda.m32_segsize; | ||
438 | i++; | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | |||
443 | /* Check if a resource still fits in the total IO or M32 range | ||
444 | * for a given PHB | ||
445 | */ | ||
446 | static int __devinit pnv_ioda_resource_fit(struct pci_controller *hose, | ||
447 | struct resource *r) | ||
448 | { | ||
449 | struct resource *bounds; | ||
450 | |||
451 | if (r->flags & IORESOURCE_IO) | ||
452 | bounds = &hose->io_resource; | ||
453 | else if (r->flags & IORESOURCE_MEM) | ||
454 | bounds = &hose->mem_resources[0]; | ||
455 | else | ||
456 | return 1; | ||
457 | |||
458 | if (r->start >= bounds->start && r->end <= bounds->end) | ||
459 | return 1; | ||
460 | r->flags = 0; | ||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static void __devinit pnv_ioda_update_resources(struct pci_bus *bus) | ||
465 | { | ||
466 | struct pci_controller *hose = pci_bus_to_host(bus); | ||
467 | struct pci_bus *cbus; | ||
468 | struct pci_dev *cdev; | ||
469 | unsigned int i; | ||
470 | |||
471 | /* We used to clear all device enables here. However it looks like | ||
472 | * clearing MEM enable causes Obsidian (IPR SCS) to go bonkers, | ||
473 | * and shoot fatal errors to the PHB which in turns fences itself | ||
474 | * and we can't recover from that ... yet. So for now, let's leave | ||
475 | * the enables as-is and hope for the best. | ||
476 | */ | ||
477 | |||
478 | /* Check if bus resources fit in our IO or M32 range */ | ||
479 | for (i = 0; bus->self && (i < 2); i++) { | ||
480 | struct resource *r = bus->resource[i]; | ||
481 | if (r && !pnv_ioda_resource_fit(hose, r)) | ||
482 | pr_err("%s: Bus %d resource %d disabled, no room\n", | ||
483 | pci_name(bus->self), bus->number, i); | ||
484 | } | ||
485 | |||
486 | /* Update self if it's not a PHB */ | ||
487 | if (bus->self) | ||
488 | pci_setup_bridge(bus); | ||
489 | |||
490 | /* Update child devices */ | ||
491 | list_for_each_entry(cdev, &bus->devices, bus_list) { | ||
492 | /* Check if resource fits, if not, disabled it */ | ||
493 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | ||
494 | struct resource *r = &cdev->resource[i]; | ||
495 | if (!pnv_ioda_resource_fit(hose, r)) | ||
496 | pr_err("%s: Resource %d disabled, no room\n", | ||
497 | pci_name(cdev), i); | ||
498 | } | ||
499 | |||
500 | /* Assign segments */ | ||
501 | pnv_ioda_setup_pe_segments(cdev); | ||
502 | |||
503 | /* Update HW BARs */ | ||
504 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) | ||
505 | pci_update_resource(cdev, i); | ||
506 | } | ||
507 | |||
508 | /* Update child busses */ | ||
509 | list_for_each_entry(cbus, &bus->children, node) | ||
510 | pnv_ioda_update_resources(cbus); | ||
511 | } | ||
512 | |||
513 | static int __devinit pnv_ioda_alloc_pe(struct pnv_phb *phb) | ||
514 | { | ||
515 | unsigned long pe; | ||
516 | |||
517 | do { | ||
518 | pe = find_next_zero_bit(phb->ioda.pe_alloc, | ||
519 | phb->ioda.total_pe, 0); | ||
520 | if (pe >= phb->ioda.total_pe) | ||
521 | return IODA_INVALID_PE; | ||
522 | } while(test_and_set_bit(pe, phb->ioda.pe_alloc)); | ||
523 | |||
524 | phb->ioda.pe_array[pe].pe_number = pe; | ||
525 | return pe; | ||
526 | } | ||
527 | |||
528 | static void __devinit pnv_ioda_free_pe(struct pnv_phb *phb, int pe) | ||
529 | { | ||
530 | WARN_ON(phb->ioda.pe_array[pe].pdev); | ||
531 | |||
532 | memset(&phb->ioda.pe_array[pe], 0, sizeof(struct pnv_ioda_pe)); | ||
533 | clear_bit(pe, phb->ioda.pe_alloc); | ||
534 | } | ||
535 | |||
536 | /* Currently those 2 are only used when MSIs are enabled, this will change | ||
537 | * but in the meantime, we need to protect them to avoid warnings | ||
538 | */ | ||
539 | #ifdef CONFIG_PCI_MSI | ||
540 | static struct pnv_ioda_pe * __devinit __pnv_ioda_get_one_pe(struct pci_dev *dev) | ||
541 | { | ||
542 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
543 | struct pnv_phb *phb = hose->private_data; | ||
544 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
545 | |||
546 | if (!pdn) | ||
547 | return NULL; | ||
548 | if (pdn->pe_number == IODA_INVALID_PE) | ||
549 | return NULL; | ||
550 | return &phb->ioda.pe_array[pdn->pe_number]; | ||
551 | } | ||
552 | |||
553 | static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev) | ||
554 | { | ||
555 | struct pnv_ioda_pe *pe = __pnv_ioda_get_one_pe(dev); | ||
556 | |||
557 | while (!pe && dev->bus->self) { | ||
558 | dev = dev->bus->self; | ||
559 | pe = __pnv_ioda_get_one_pe(dev); | ||
560 | if (pe) | ||
561 | pe = pe->bus_pe; | ||
562 | } | ||
563 | return pe; | ||
564 | } | ||
565 | #endif /* CONFIG_PCI_MSI */ | ||
566 | |||
567 | static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, | ||
568 | struct pnv_ioda_pe *pe) | ||
569 | { | ||
570 | struct pci_dev *parent; | ||
571 | uint8_t bcomp, dcomp, fcomp; | ||
572 | long rc, rid_end, rid; | ||
573 | |||
574 | /* Bus validation ? */ | ||
575 | if (pe->pbus) { | ||
576 | int count; | ||
577 | |||
578 | dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; | ||
579 | fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; | ||
580 | parent = pe->pbus->self; | ||
581 | count = pe->pbus->subordinate - pe->pbus->secondary + 1; | ||
582 | switch(count) { | ||
583 | case 1: bcomp = OpalPciBusAll; break; | ||
584 | case 2: bcomp = OpalPciBus7Bits; break; | ||
585 | case 4: bcomp = OpalPciBus6Bits; break; | ||
586 | case 8: bcomp = OpalPciBus5Bits; break; | ||
587 | case 16: bcomp = OpalPciBus4Bits; break; | ||
588 | case 32: bcomp = OpalPciBus3Bits; break; | ||
589 | default: | ||
590 | pr_err("%s: Number of subordinate busses %d" | ||
591 | " unsupported\n", | ||
592 | pci_name(pe->pbus->self), count); | ||
593 | /* Do an exact match only */ | ||
594 | bcomp = OpalPciBusAll; | ||
595 | } | ||
596 | rid_end = pe->rid + (count << 8); | ||
597 | } else { | ||
598 | parent = pe->pdev->bus->self; | ||
599 | bcomp = OpalPciBusAll; | ||
600 | dcomp = OPAL_COMPARE_RID_DEVICE_NUMBER; | ||
601 | fcomp = OPAL_COMPARE_RID_FUNCTION_NUMBER; | ||
602 | rid_end = pe->rid + 1; | ||
603 | } | ||
604 | |||
605 | /* Associate PE in PELT */ | ||
606 | rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid, | ||
607 | bcomp, dcomp, fcomp, OPAL_MAP_PE); | ||
608 | if (rc) { | ||
609 | pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc); | ||
610 | return -ENXIO; | ||
611 | } | ||
612 | opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, | ||
613 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
614 | |||
615 | /* Add to all parents PELT-V */ | ||
616 | while (parent) { | ||
617 | struct pci_dn *pdn = pnv_ioda_get_pdn(parent); | ||
618 | if (pdn && pdn->pe_number != IODA_INVALID_PE) { | ||
619 | rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, | ||
620 | pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); | ||
621 | /* XXX What to do in case of error ? */ | ||
622 | } | ||
623 | parent = parent->bus->self; | ||
624 | } | ||
625 | /* Setup reverse map */ | ||
626 | for (rid = pe->rid; rid < rid_end; rid++) | ||
627 | phb->ioda.pe_rmap[rid] = pe->pe_number; | ||
628 | |||
629 | /* Setup one MVTs on IODA1 */ | ||
630 | if (phb->type == PNV_PHB_IODA1) { | ||
631 | pe->mve_number = pe->pe_number; | ||
632 | rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, | ||
633 | pe->pe_number); | ||
634 | if (rc) { | ||
635 | pe_err(pe, "OPAL error %ld setting up MVE %d\n", | ||
636 | rc, pe->mve_number); | ||
637 | pe->mve_number = -1; | ||
638 | } else { | ||
639 | rc = opal_pci_set_mve_enable(phb->opal_id, | ||
640 | pe->mve_number, OPAL_ENABLE_MVE); | ||
641 | if (rc) { | ||
642 | pe_err(pe, "OPAL error %ld enabling MVE %d\n", | ||
643 | rc, pe->mve_number); | ||
644 | pe->mve_number = -1; | ||
645 | } | ||
646 | } | ||
647 | } else if (phb->type == PNV_PHB_IODA2) | ||
648 | pe->mve_number = 0; | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static void __devinit pnv_ioda_link_pe_by_weight(struct pnv_phb *phb, | ||
654 | struct pnv_ioda_pe *pe) | ||
655 | { | ||
656 | struct pnv_ioda_pe *lpe; | ||
657 | |||
658 | list_for_each_entry(lpe, &phb->ioda.pe_list, link) { | ||
659 | if (lpe->dma_weight < pe->dma_weight) { | ||
660 | list_add_tail(&pe->link, &lpe->link); | ||
661 | return; | ||
662 | } | ||
663 | } | ||
664 | list_add_tail(&pe->link, &phb->ioda.pe_list); | ||
665 | } | ||
666 | |||
667 | static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev) | ||
668 | { | ||
669 | /* This is quite simplistic. The "base" weight of a device | ||
670 | * is 10. 0 means no DMA is to be accounted for it. | ||
671 | */ | ||
672 | |||
673 | /* If it's a bridge, no DMA */ | ||
674 | if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) | ||
675 | return 0; | ||
676 | |||
677 | /* Reduce the weight of slow USB controllers */ | ||
678 | if (dev->class == PCI_CLASS_SERIAL_USB_UHCI || | ||
679 | dev->class == PCI_CLASS_SERIAL_USB_OHCI || | ||
680 | dev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
681 | return 3; | ||
682 | |||
683 | /* Increase the weight of RAID (includes Obsidian) */ | ||
684 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) | ||
685 | return 15; | ||
686 | |||
687 | /* Default */ | ||
688 | return 10; | ||
689 | } | ||
690 | |||
691 | static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev) | ||
692 | { | ||
693 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
694 | struct pnv_phb *phb = hose->private_data; | ||
695 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
696 | struct pnv_ioda_pe *pe; | ||
697 | int pe_num; | ||
698 | |||
699 | if (!pdn) { | ||
700 | pr_err("%s: Device tree node not associated properly\n", | ||
701 | pci_name(dev)); | ||
702 | return NULL; | ||
703 | } | ||
704 | if (pdn->pe_number != IODA_INVALID_PE) | ||
705 | return NULL; | ||
706 | |||
707 | /* PE#0 has been pre-set */ | ||
708 | if (dev->bus->number == 0) | ||
709 | pe_num = 0; | ||
710 | else | ||
711 | pe_num = pnv_ioda_alloc_pe(phb); | ||
712 | if (pe_num == IODA_INVALID_PE) { | ||
713 | pr_warning("%s: Not enough PE# available, disabling device\n", | ||
714 | pci_name(dev)); | ||
715 | return NULL; | ||
716 | } | ||
717 | |||
718 | /* NOTE: We get only one ref to the pci_dev for the pdn, not for the | ||
719 | * pointer in the PE data structure, both should be destroyed at the | ||
720 | * same time. However, this needs to be looked at more closely again | ||
721 | * once we actually start removing things (Hotplug, SR-IOV, ...) | ||
722 | * | ||
723 | * At some point we want to remove the PDN completely anyways | ||
724 | */ | ||
725 | pe = &phb->ioda.pe_array[pe_num]; | ||
726 | pci_dev_get(dev); | ||
727 | pdn->pcidev = dev; | ||
728 | pdn->pe_number = pe_num; | ||
729 | pe->pdev = dev; | ||
730 | pe->pbus = NULL; | ||
731 | pe->tce32_seg = -1; | ||
732 | pe->mve_number = -1; | ||
733 | pe->rid = dev->bus->number << 8 | pdn->devfn; | ||
734 | |||
735 | pe_info(pe, "Associated device to PE\n"); | ||
736 | |||
737 | if (pnv_ioda_configure_pe(phb, pe)) { | ||
738 | /* XXX What do we do here ? */ | ||
739 | if (pe_num) | ||
740 | pnv_ioda_free_pe(phb, pe_num); | ||
741 | pdn->pe_number = IODA_INVALID_PE; | ||
742 | pe->pdev = NULL; | ||
743 | pci_dev_put(dev); | ||
744 | return NULL; | ||
745 | } | ||
746 | |||
747 | /* Assign a DMA weight to the device */ | ||
748 | pe->dma_weight = pnv_ioda_dma_weight(dev); | ||
749 | if (pe->dma_weight != 0) { | ||
750 | phb->ioda.dma_weight += pe->dma_weight; | ||
751 | phb->ioda.dma_pe_count++; | ||
752 | } | ||
753 | |||
754 | /* Link the PE */ | ||
755 | pnv_ioda_link_pe_by_weight(phb, pe); | ||
756 | |||
757 | return pe; | ||
758 | } | ||
759 | |||
760 | static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) | ||
761 | { | ||
762 | struct pci_dev *dev; | ||
763 | |||
764 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
765 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
766 | |||
767 | if (pdn == NULL) { | ||
768 | pr_warn("%s: No device node associated with device !\n", | ||
769 | pci_name(dev)); | ||
770 | continue; | ||
771 | } | ||
772 | pci_dev_get(dev); | ||
773 | pdn->pcidev = dev; | ||
774 | pdn->pe_number = pe->pe_number; | ||
775 | pe->dma_weight += pnv_ioda_dma_weight(dev); | ||
776 | if (dev->subordinate) | ||
777 | pnv_ioda_setup_same_PE(dev->subordinate, pe); | ||
778 | } | ||
779 | } | ||
780 | |||
781 | static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev, | ||
782 | struct pnv_ioda_pe *ppe) | ||
783 | { | ||
784 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
785 | struct pnv_phb *phb = hose->private_data; | ||
786 | struct pci_bus *bus = dev->subordinate; | ||
787 | struct pnv_ioda_pe *pe; | ||
788 | int pe_num; | ||
789 | |||
790 | if (!bus) { | ||
791 | pr_warning("%s: Bridge without a subordinate bus !\n", | ||
792 | pci_name(dev)); | ||
793 | return; | ||
794 | } | ||
795 | pe_num = pnv_ioda_alloc_pe(phb); | ||
796 | if (pe_num == IODA_INVALID_PE) { | ||
797 | pr_warning("%s: Not enough PE# available, disabling bus\n", | ||
798 | pci_name(dev)); | ||
799 | return; | ||
800 | } | ||
801 | |||
802 | pe = &phb->ioda.pe_array[pe_num]; | ||
803 | ppe->bus_pe = pe; | ||
804 | pe->pbus = bus; | ||
805 | pe->pdev = NULL; | ||
806 | pe->tce32_seg = -1; | ||
807 | pe->mve_number = -1; | ||
808 | pe->rid = bus->secondary << 8; | ||
809 | pe->dma_weight = 0; | ||
810 | |||
811 | pe_info(pe, "Secondary busses %d..%d associated with PE\n", | ||
812 | bus->secondary, bus->subordinate); | ||
813 | |||
814 | if (pnv_ioda_configure_pe(phb, pe)) { | ||
815 | /* XXX What do we do here ? */ | ||
816 | if (pe_num) | ||
817 | pnv_ioda_free_pe(phb, pe_num); | ||
818 | pe->pbus = NULL; | ||
819 | return; | ||
820 | } | ||
821 | |||
822 | /* Associate it with all child devices */ | ||
823 | pnv_ioda_setup_same_PE(bus, pe); | ||
824 | |||
825 | /* Account for one DMA PE if at least one DMA capable device exist | ||
826 | * below the bridge | ||
827 | */ | ||
828 | if (pe->dma_weight != 0) { | ||
829 | phb->ioda.dma_weight += pe->dma_weight; | ||
830 | phb->ioda.dma_pe_count++; | ||
831 | } | ||
832 | |||
833 | /* Link the PE */ | ||
834 | pnv_ioda_link_pe_by_weight(phb, pe); | ||
835 | } | ||
836 | |||
837 | static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus) | ||
838 | { | ||
839 | struct pci_dev *dev; | ||
840 | struct pnv_ioda_pe *pe; | ||
841 | |||
842 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
843 | pe = pnv_ioda_setup_dev_PE(dev); | ||
844 | if (pe == NULL) | ||
845 | continue; | ||
846 | /* Leaving the PCIe domain ... single PE# */ | ||
847 | if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | ||
848 | pnv_ioda_setup_bus_PE(dev, pe); | ||
849 | else if (dev->subordinate) | ||
850 | pnv_ioda_setup_PEs(dev->subordinate); | ||
851 | } | ||
852 | } | ||
853 | |||
854 | static void __devinit pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, | ||
855 | struct pci_dev *dev) | ||
856 | { | ||
857 | /* We delay DMA setup after we have assigned all PE# */ | ||
858 | } | ||
859 | |||
860 | static void __devinit pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, | ||
861 | struct pci_bus *bus) | ||
862 | { | ||
863 | struct pci_dev *dev; | ||
864 | |||
865 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
866 | set_iommu_table_base(&dev->dev, &pe->tce32_table); | ||
867 | if (dev->subordinate) | ||
868 | pnv_ioda_setup_bus_dma(pe, dev->subordinate); | ||
869 | } | ||
870 | } | ||
871 | |||
872 | static void __devinit pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | ||
873 | struct pnv_ioda_pe *pe, | ||
874 | unsigned int base, | ||
875 | unsigned int segs) | ||
876 | { | ||
877 | |||
878 | struct page *tce_mem = NULL; | ||
879 | const __be64 *swinvp; | ||
880 | struct iommu_table *tbl; | ||
881 | unsigned int i; | ||
882 | int64_t rc; | ||
883 | void *addr; | ||
884 | |||
885 | /* 256M DMA window, 4K TCE pages, 8 bytes TCE */ | ||
886 | #define TCE32_TABLE_SIZE ((0x10000000 / 0x1000) * 8) | ||
887 | |||
888 | /* XXX FIXME: Handle 64-bit only DMA devices */ | ||
889 | /* XXX FIXME: Provide 64-bit DMA facilities & non-4K TCE tables etc.. */ | ||
890 | /* XXX FIXME: Allocate multi-level tables on PHB3 */ | ||
891 | |||
892 | /* We shouldn't already have a 32-bit DMA associated */ | ||
893 | if (WARN_ON(pe->tce32_seg >= 0)) | ||
894 | return; | ||
895 | |||
896 | /* Grab a 32-bit TCE table */ | ||
897 | pe->tce32_seg = base; | ||
898 | pe_info(pe, " Setting up 32-bit TCE table at %08x..%08x\n", | ||
899 | (base << 28), ((base + segs) << 28) - 1); | ||
900 | |||
901 | /* XXX Currently, we allocate one big contiguous table for the | ||
902 | * TCEs. We only really need one chunk per 256M of TCE space | ||
903 | * (ie per segment) but that's an optimization for later, it | ||
904 | * requires some added smarts with our get/put_tce implementation | ||
905 | */ | ||
906 | tce_mem = alloc_pages_node(phb->hose->node, GFP_KERNEL, | ||
907 | get_order(TCE32_TABLE_SIZE * segs)); | ||
908 | if (!tce_mem) { | ||
909 | pe_err(pe, " Failed to allocate a 32-bit TCE memory\n"); | ||
910 | goto fail; | ||
911 | } | ||
912 | addr = page_address(tce_mem); | ||
913 | memset(addr, 0, TCE32_TABLE_SIZE * segs); | ||
914 | |||
915 | /* Configure HW */ | ||
916 | for (i = 0; i < segs; i++) { | ||
917 | rc = opal_pci_map_pe_dma_window(phb->opal_id, | ||
918 | pe->pe_number, | ||
919 | base + i, 1, | ||
920 | __pa(addr) + TCE32_TABLE_SIZE * i, | ||
921 | TCE32_TABLE_SIZE, 0x1000); | ||
922 | if (rc) { | ||
923 | pe_err(pe, " Failed to configure 32-bit TCE table," | ||
924 | " err %ld\n", rc); | ||
925 | goto fail; | ||
926 | } | ||
927 | } | ||
928 | |||
929 | /* Setup linux iommu table */ | ||
930 | tbl = &pe->tce32_table; | ||
931 | pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs, | ||
932 | base << 28); | ||
933 | |||
934 | /* OPAL variant of P7IOC SW invalidated TCEs */ | ||
935 | swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL); | ||
936 | if (swinvp) { | ||
937 | /* We need a couple more fields -- an address and a data | ||
938 | * to or. Since the bus is only printed out on table free | ||
939 | * errors, and on the first pass the data will be a relative | ||
940 | * bus number, print that out instead. | ||
941 | */ | ||
942 | tbl->it_busno = 0; | ||
943 | tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); | ||
944 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE | ||
945 | | TCE_PCI_SWINV_PAIR; | ||
946 | } | ||
947 | iommu_init_table(tbl, phb->hose->node); | ||
948 | |||
949 | if (pe->pdev) | ||
950 | set_iommu_table_base(&pe->pdev->dev, tbl); | ||
951 | else | ||
952 | pnv_ioda_setup_bus_dma(pe, pe->pbus); | ||
953 | |||
954 | return; | ||
955 | fail: | ||
956 | /* XXX Failure: Try to fallback to 64-bit only ? */ | ||
957 | if (pe->tce32_seg >= 0) | ||
958 | pe->tce32_seg = -1; | ||
959 | if (tce_mem) | ||
960 | __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); | ||
961 | } | ||
962 | |||
963 | static void __devinit pnv_ioda_setup_dma(struct pnv_phb *phb) | ||
964 | { | ||
965 | struct pci_controller *hose = phb->hose; | ||
966 | unsigned int residual, remaining, segs, tw, base; | ||
967 | struct pnv_ioda_pe *pe; | ||
968 | |||
969 | /* If we have more PE# than segments available, hand out one | ||
970 | * per PE until we run out and let the rest fail. If not, | ||
971 | * then we assign at least one segment per PE, plus more based | ||
972 | * on the amount of devices under that PE | ||
973 | */ | ||
974 | if (phb->ioda.dma_pe_count > phb->ioda.tce32_count) | ||
975 | residual = 0; | ||
976 | else | ||
977 | residual = phb->ioda.tce32_count - | ||
978 | phb->ioda.dma_pe_count; | ||
979 | |||
980 | pr_info("PCI: Domain %04x has %ld available 32-bit DMA segments\n", | ||
981 | hose->global_number, phb->ioda.tce32_count); | ||
982 | pr_info("PCI: %d PE# for a total weight of %d\n", | ||
983 | phb->ioda.dma_pe_count, phb->ioda.dma_weight); | ||
984 | |||
985 | /* Walk our PE list and configure their DMA segments, hand them | ||
986 | * out one base segment plus any residual segments based on | ||
987 | * weight | ||
988 | */ | ||
989 | remaining = phb->ioda.tce32_count; | ||
990 | tw = phb->ioda.dma_weight; | ||
991 | base = 0; | ||
992 | list_for_each_entry(pe, &phb->ioda.pe_list, link) { | ||
993 | if (!pe->dma_weight) | ||
994 | continue; | ||
995 | if (!remaining) { | ||
996 | pe_warn(pe, "No DMA32 resources available\n"); | ||
997 | continue; | ||
998 | } | ||
999 | segs = 1; | ||
1000 | if (residual) { | ||
1001 | segs += ((pe->dma_weight * residual) + (tw / 2)) / tw; | ||
1002 | if (segs > remaining) | ||
1003 | segs = remaining; | ||
1004 | } | ||
1005 | pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", | ||
1006 | pe->dma_weight, segs); | ||
1007 | pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); | ||
1008 | remaining -= segs; | ||
1009 | base += segs; | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | #ifdef CONFIG_PCI_MSI | ||
1014 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | ||
1015 | unsigned int hwirq, unsigned int is_64, | ||
1016 | struct msi_msg *msg) | ||
1017 | { | ||
1018 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); | ||
1019 | unsigned int xive_num = hwirq - phb->msi_base; | ||
1020 | uint64_t addr64; | ||
1021 | uint32_t addr32, data; | ||
1022 | int rc; | ||
1023 | |||
1024 | /* No PE assigned ? bail out ... no MSI for you ! */ | ||
1025 | if (pe == NULL) | ||
1026 | return -ENXIO; | ||
1027 | |||
1028 | /* Check if we have an MVE */ | ||
1029 | if (pe->mve_number < 0) | ||
1030 | return -ENXIO; | ||
1031 | |||
1032 | /* Assign XIVE to PE */ | ||
1033 | rc = opal_pci_set_xive_pe(phb->opal_id, pe->pe_number, xive_num); | ||
1034 | if (rc) { | ||
1035 | pr_warn("%s: OPAL error %d setting XIVE %d PE\n", | ||
1036 | pci_name(dev), rc, xive_num); | ||
1037 | return -EIO; | ||
1038 | } | ||
1039 | |||
1040 | if (is_64) { | ||
1041 | rc = opal_get_msi_64(phb->opal_id, pe->mve_number, xive_num, 1, | ||
1042 | &addr64, &data); | ||
1043 | if (rc) { | ||
1044 | pr_warn("%s: OPAL error %d getting 64-bit MSI data\n", | ||
1045 | pci_name(dev), rc); | ||
1046 | return -EIO; | ||
1047 | } | ||
1048 | msg->address_hi = addr64 >> 32; | ||
1049 | msg->address_lo = addr64 & 0xfffffffful; | ||
1050 | } else { | ||
1051 | rc = opal_get_msi_32(phb->opal_id, pe->mve_number, xive_num, 1, | ||
1052 | &addr32, &data); | ||
1053 | if (rc) { | ||
1054 | pr_warn("%s: OPAL error %d getting 32-bit MSI data\n", | ||
1055 | pci_name(dev), rc); | ||
1056 | return -EIO; | ||
1057 | } | ||
1058 | msg->address_hi = 0; | ||
1059 | msg->address_lo = addr32; | ||
1060 | } | ||
1061 | msg->data = data; | ||
1062 | |||
1063 | pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," | ||
1064 | " address=%x_%08x data=%x PE# %d\n", | ||
1065 | pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, | ||
1066 | msg->address_hi, msg->address_lo, data, pe->pe_number); | ||
1067 | |||
1068 | return 0; | ||
1069 | } | ||
1070 | |||
1071 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) | ||
1072 | { | ||
1073 | unsigned int bmap_size; | ||
1074 | const __be32 *prop = of_get_property(phb->hose->dn, | ||
1075 | "ibm,opal-msi-ranges", NULL); | ||
1076 | if (!prop) { | ||
1077 | /* BML Fallback */ | ||
1078 | prop = of_get_property(phb->hose->dn, "msi-ranges", NULL); | ||
1079 | } | ||
1080 | if (!prop) | ||
1081 | return; | ||
1082 | |||
1083 | phb->msi_base = be32_to_cpup(prop); | ||
1084 | phb->msi_count = be32_to_cpup(prop + 1); | ||
1085 | bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); | ||
1086 | phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL); | ||
1087 | if (!phb->msi_map) { | ||
1088 | pr_err("PCI %d: Failed to allocate MSI bitmap !\n", | ||
1089 | phb->hose->global_number); | ||
1090 | return; | ||
1091 | } | ||
1092 | phb->msi_setup = pnv_pci_ioda_msi_setup; | ||
1093 | phb->msi32_support = 1; | ||
1094 | pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", | ||
1095 | phb->msi_count, phb->msi_base); | ||
1096 | } | ||
1097 | #else | ||
1098 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } | ||
1099 | #endif /* CONFIG_PCI_MSI */ | ||
1100 | |||
1101 | /* This is the starting point of our IODA specific resource | ||
1102 | * allocation process | ||
1103 | */ | ||
1104 | static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose) | ||
1105 | { | ||
1106 | resource_size_t size, align; | ||
1107 | struct pci_bus *child; | ||
1108 | |||
1109 | /* Associate PEs per functions */ | ||
1110 | pnv_ioda_setup_PEs(hose->bus); | ||
1111 | |||
1112 | /* Calculate all resources */ | ||
1113 | pnv_ioda_calc_bus(hose->bus, IORESOURCE_IO, &size, &align); | ||
1114 | pnv_ioda_calc_bus(hose->bus, IORESOURCE_MEM, &size, &align); | ||
1115 | |||
1116 | /* Apply then to HW */ | ||
1117 | pnv_ioda_update_resources(hose->bus); | ||
1118 | |||
1119 | /* Setup DMA */ | ||
1120 | pnv_ioda_setup_dma(hose->private_data); | ||
1121 | |||
1122 | /* Configure PCI Express settings */ | ||
1123 | list_for_each_entry(child, &hose->bus->children, node) { | ||
1124 | struct pci_dev *self = child->self; | ||
1125 | if (!self) | ||
1126 | continue; | ||
1127 | pcie_bus_configure_settings(child, self->pcie_mpss); | ||
1128 | } | ||
1129 | } | ||
1130 | |||
1131 | /* Prevent enabling devices for which we couldn't properly | ||
1132 | * assign a PE | ||
1133 | */ | ||
1134 | static int __devinit pnv_pci_enable_device_hook(struct pci_dev *dev) | ||
1135 | { | ||
1136 | struct pci_dn *pdn = pnv_ioda_get_pdn(dev); | ||
1137 | |||
1138 | if (!pdn || pdn->pe_number == IODA_INVALID_PE) | ||
1139 | return -EINVAL; | ||
1140 | return 0; | ||
1141 | } | ||
1142 | |||
1143 | static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus, | ||
1144 | u32 devfn) | ||
1145 | { | ||
1146 | return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; | ||
1147 | } | ||
1148 | |||
1149 | void __init pnv_pci_init_ioda1_phb(struct device_node *np) | ||
1150 | { | ||
1151 | struct pci_controller *hose; | ||
1152 | static int primary = 1; | ||
1153 | struct pnv_phb *phb; | ||
1154 | unsigned long size, m32map_off, iomap_off, pemap_off; | ||
1155 | const u64 *prop64; | ||
1156 | u64 phb_id; | ||
1157 | void *aux; | ||
1158 | long rc; | ||
1159 | |||
1160 | pr_info(" Initializing IODA OPAL PHB %s\n", np->full_name); | ||
1161 | |||
1162 | prop64 = of_get_property(np, "ibm,opal-phbid", NULL); | ||
1163 | if (!prop64) { | ||
1164 | pr_err(" Missing \"ibm,opal-phbid\" property !\n"); | ||
1165 | return; | ||
1166 | } | ||
1167 | phb_id = be64_to_cpup(prop64); | ||
1168 | pr_debug(" PHB-ID : 0x%016llx\n", phb_id); | ||
1169 | |||
1170 | phb = alloc_bootmem(sizeof(struct pnv_phb)); | ||
1171 | if (phb) { | ||
1172 | memset(phb, 0, sizeof(struct pnv_phb)); | ||
1173 | phb->hose = hose = pcibios_alloc_controller(np); | ||
1174 | } | ||
1175 | if (!phb || !phb->hose) { | ||
1176 | pr_err("PCI: Failed to allocate PCI controller for %s\n", | ||
1177 | np->full_name); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1181 | spin_lock_init(&phb->lock); | ||
1182 | /* XXX Use device-tree */ | ||
1183 | hose->first_busno = 0; | ||
1184 | hose->last_busno = 0xff; | ||
1185 | hose->private_data = phb; | ||
1186 | phb->opal_id = phb_id; | ||
1187 | phb->type = PNV_PHB_IODA1; | ||
1188 | |||
1189 | /* Detect specific models for error handling */ | ||
1190 | if (of_device_is_compatible(np, "ibm,p7ioc-pciex")) | ||
1191 | phb->model = PNV_PHB_MODEL_P7IOC; | ||
1192 | else | ||
1193 | phb->model = PNV_PHB_MODEL_UNKNOWN; | ||
1194 | |||
1195 | /* We parse "ranges" now since we need to deduce the register base | ||
1196 | * from the IO base | ||
1197 | */ | ||
1198 | pci_process_bridge_OF_ranges(phb->hose, np, primary); | ||
1199 | primary = 0; | ||
1200 | |||
1201 | /* Magic formula from Milton */ | ||
1202 | phb->regs = of_iomap(np, 0); | ||
1203 | if (phb->regs == NULL) | ||
1204 | pr_err(" Failed to map registers !\n"); | ||
1205 | |||
1206 | |||
1207 | /* XXX This is hack-a-thon. This needs to be changed so that: | ||
1208 | * - we obtain stuff like PE# etc... from device-tree | ||
1209 | * - we properly re-allocate M32 ourselves | ||
1210 | * (the OFW one isn't very good) | ||
1211 | */ | ||
1212 | |||
1213 | /* Initialize more IODA stuff */ | ||
1214 | phb->ioda.total_pe = 128; | ||
1215 | |||
1216 | phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); | ||
1217 | /* OFW Has already off top 64k of M32 space (MSI space) */ | ||
1218 | phb->ioda.m32_size += 0x10000; | ||
1219 | |||
1220 | phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe; | ||
1221 | phb->ioda.m32_pci_base = hose->mem_resources[0].start - | ||
1222 | hose->pci_mem_offset; | ||
1223 | phb->ioda.io_size = hose->pci_io_size; | ||
1224 | phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe; | ||
1225 | phb->ioda.io_pci_base = 0; /* XXX calculate this ? */ | ||
1226 | |||
1227 | /* Allocate aux data & arrays */ | ||
1228 | size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); | ||
1229 | m32map_off = size; | ||
1230 | size += phb->ioda.total_pe; | ||
1231 | iomap_off = size; | ||
1232 | size += phb->ioda.total_pe; | ||
1233 | pemap_off = size; | ||
1234 | size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe); | ||
1235 | aux = alloc_bootmem(size); | ||
1236 | memset(aux, 0, size); | ||
1237 | phb->ioda.pe_alloc = aux; | ||
1238 | phb->ioda.m32_segmap = aux + m32map_off; | ||
1239 | phb->ioda.io_segmap = aux + iomap_off; | ||
1240 | phb->ioda.pe_array = aux + pemap_off; | ||
1241 | set_bit(0, phb->ioda.pe_alloc); | ||
1242 | |||
1243 | INIT_LIST_HEAD(&phb->ioda.pe_list); | ||
1244 | |||
1245 | /* Calculate how many 32-bit TCE segments we have */ | ||
1246 | phb->ioda.tce32_count = phb->ioda.m32_pci_base >> 28; | ||
1247 | |||
1248 | /* Clear unusable m64 */ | ||
1249 | hose->mem_resources[1].flags = 0; | ||
1250 | hose->mem_resources[1].start = 0; | ||
1251 | hose->mem_resources[1].end = 0; | ||
1252 | hose->mem_resources[2].flags = 0; | ||
1253 | hose->mem_resources[2].start = 0; | ||
1254 | hose->mem_resources[2].end = 0; | ||
1255 | |||
1256 | #if 0 | ||
1257 | rc = opal_pci_set_phb_mem_window(opal->phb_id, | ||
1258 | window_type, | ||
1259 | window_num, | ||
1260 | starting_real_address, | ||
1261 | starting_pci_address, | ||
1262 | segment_size); | ||
1263 | #endif | ||
1264 | |||
1265 | pr_info(" %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n", | ||
1266 | phb->ioda.total_pe, | ||
1267 | phb->ioda.m32_size, phb->ioda.m32_segsize, | ||
1268 | phb->ioda.io_size, phb->ioda.io_segsize); | ||
1269 | |||
1270 | if (phb->regs) { | ||
1271 | pr_devel(" BUID = 0x%016llx\n", in_be64(phb->regs + 0x100)); | ||
1272 | pr_devel(" PHB2_CR = 0x%016llx\n", in_be64(phb->regs + 0x160)); | ||
1273 | pr_devel(" IO_BAR = 0x%016llx\n", in_be64(phb->regs + 0x170)); | ||
1274 | pr_devel(" IO_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x178)); | ||
1275 | pr_devel(" IO_SAR = 0x%016llx\n", in_be64(phb->regs + 0x180)); | ||
1276 | pr_devel(" M32_BAR = 0x%016llx\n", in_be64(phb->regs + 0x190)); | ||
1277 | pr_devel(" M32_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x198)); | ||
1278 | pr_devel(" M32_SAR = 0x%016llx\n", in_be64(phb->regs + 0x1a0)); | ||
1279 | } | ||
1280 | phb->hose->ops = &pnv_pci_ops; | ||
1281 | |||
1282 | /* Setup RID -> PE mapping function */ | ||
1283 | phb->bdfn_to_pe = pnv_ioda_bdfn_to_pe; | ||
1284 | |||
1285 | /* Setup TCEs */ | ||
1286 | phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup; | ||
1287 | |||
1288 | /* Setup MSI support */ | ||
1289 | pnv_pci_init_ioda_msis(phb); | ||
1290 | |||
1291 | /* We set both probe_only and PCI_REASSIGN_ALL_RSRC. This is an | ||
1292 | * odd combination which essentially means that we skip all resource | ||
1293 | * fixups and assignments in the generic code, and do it all | ||
1294 | * ourselves here | ||
1295 | */ | ||
1296 | pci_probe_only = 1; | ||
1297 | ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; | ||
1298 | ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; | ||
1299 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); | ||
1300 | |||
1301 | /* Reset IODA tables to a clean state */ | ||
1302 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); | ||
1303 | if (rc) | ||
1304 | pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); | ||
1305 | opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); | ||
1306 | } | ||
1307 | |||
1308 | void __init pnv_pci_init_ioda_hub(struct device_node *np) | ||
1309 | { | ||
1310 | struct device_node *phbn; | ||
1311 | const u64 *prop64; | ||
1312 | u64 hub_id; | ||
1313 | |||
1314 | pr_info("Probing IODA IO-Hub %s\n", np->full_name); | ||
1315 | |||
1316 | prop64 = of_get_property(np, "ibm,opal-hubid", NULL); | ||
1317 | if (!prop64) { | ||
1318 | pr_err(" Missing \"ibm,opal-hubid\" property !\n"); | ||
1319 | return; | ||
1320 | } | ||
1321 | hub_id = be64_to_cpup(prop64); | ||
1322 | pr_devel(" HUB-ID : 0x%016llx\n", hub_id); | ||
1323 | |||
1324 | /* Count child PHBs */ | ||
1325 | for_each_child_of_node(np, phbn) { | ||
1326 | /* Look for IODA1 PHBs */ | ||
1327 | if (of_device_is_compatible(phbn, "ibm,ioda-phb")) | ||
1328 | pnv_pci_init_ioda1_phb(phbn); | ||
1329 | } | ||
1330 | } | ||
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 4c80f7c77d56..264967770c3a 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c | |||
@@ -137,6 +137,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, | |||
137 | phb->hose->private_data = phb; | 137 | phb->hose->private_data = phb; |
138 | phb->opal_id = phb_id; | 138 | phb->opal_id = phb_id; |
139 | phb->type = PNV_PHB_P5IOC2; | 139 | phb->type = PNV_PHB_P5IOC2; |
140 | phb->model = PNV_PHB_MODEL_P5IOC2; | ||
140 | 141 | ||
141 | phb->regs = of_iomap(np, 0); | 142 | phb->regs = of_iomap(np, 0); |
142 | 143 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 85bb66d7f933..a70bc1e385eb 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -144,6 +144,112 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev) | |||
144 | } | 144 | } |
145 | #endif /* CONFIG_PCI_MSI */ | 145 | #endif /* CONFIG_PCI_MSI */ |
146 | 146 | ||
147 | static void pnv_pci_dump_p7ioc_diag_data(struct pnv_phb *phb) | ||
148 | { | ||
149 | struct OpalIoP7IOCPhbErrorData *data = &phb->diag.p7ioc; | ||
150 | int i; | ||
151 | |||
152 | pr_info("PHB %d diagnostic data:\n", phb->hose->global_number); | ||
153 | |||
154 | pr_info(" brdgCtl = 0x%08x\n", data->brdgCtl); | ||
155 | |||
156 | pr_info(" portStatusReg = 0x%08x\n", data->portStatusReg); | ||
157 | pr_info(" rootCmplxStatus = 0x%08x\n", data->rootCmplxStatus); | ||
158 | pr_info(" busAgentStatus = 0x%08x\n", data->busAgentStatus); | ||
159 | |||
160 | pr_info(" deviceStatus = 0x%08x\n", data->deviceStatus); | ||
161 | pr_info(" slotStatus = 0x%08x\n", data->slotStatus); | ||
162 | pr_info(" linkStatus = 0x%08x\n", data->linkStatus); | ||
163 | pr_info(" devCmdStatus = 0x%08x\n", data->devCmdStatus); | ||
164 | pr_info(" devSecStatus = 0x%08x\n", data->devSecStatus); | ||
165 | |||
166 | pr_info(" rootErrorStatus = 0x%08x\n", data->rootErrorStatus); | ||
167 | pr_info(" uncorrErrorStatus = 0x%08x\n", data->uncorrErrorStatus); | ||
168 | pr_info(" corrErrorStatus = 0x%08x\n", data->corrErrorStatus); | ||
169 | pr_info(" tlpHdr1 = 0x%08x\n", data->tlpHdr1); | ||
170 | pr_info(" tlpHdr2 = 0x%08x\n", data->tlpHdr2); | ||
171 | pr_info(" tlpHdr3 = 0x%08x\n", data->tlpHdr3); | ||
172 | pr_info(" tlpHdr4 = 0x%08x\n", data->tlpHdr4); | ||
173 | pr_info(" sourceId = 0x%08x\n", data->sourceId); | ||
174 | |||
175 | pr_info(" errorClass = 0x%016llx\n", data->errorClass); | ||
176 | pr_info(" correlator = 0x%016llx\n", data->correlator); | ||
177 | |||
178 | pr_info(" p7iocPlssr = 0x%016llx\n", data->p7iocPlssr); | ||
179 | pr_info(" p7iocCsr = 0x%016llx\n", data->p7iocCsr); | ||
180 | pr_info(" lemFir = 0x%016llx\n", data->lemFir); | ||
181 | pr_info(" lemErrorMask = 0x%016llx\n", data->lemErrorMask); | ||
182 | pr_info(" lemWOF = 0x%016llx\n", data->lemWOF); | ||
183 | pr_info(" phbErrorStatus = 0x%016llx\n", data->phbErrorStatus); | ||
184 | pr_info(" phbFirstErrorStatus = 0x%016llx\n", data->phbFirstErrorStatus); | ||
185 | pr_info(" phbErrorLog0 = 0x%016llx\n", data->phbErrorLog0); | ||
186 | pr_info(" phbErrorLog1 = 0x%016llx\n", data->phbErrorLog1); | ||
187 | pr_info(" mmioErrorStatus = 0x%016llx\n", data->mmioErrorStatus); | ||
188 | pr_info(" mmioFirstErrorStatus = 0x%016llx\n", data->mmioFirstErrorStatus); | ||
189 | pr_info(" mmioErrorLog0 = 0x%016llx\n", data->mmioErrorLog0); | ||
190 | pr_info(" mmioErrorLog1 = 0x%016llx\n", data->mmioErrorLog1); | ||
191 | pr_info(" dma0ErrorStatus = 0x%016llx\n", data->dma0ErrorStatus); | ||
192 | pr_info(" dma0FirstErrorStatus = 0x%016llx\n", data->dma0FirstErrorStatus); | ||
193 | pr_info(" dma0ErrorLog0 = 0x%016llx\n", data->dma0ErrorLog0); | ||
194 | pr_info(" dma0ErrorLog1 = 0x%016llx\n", data->dma0ErrorLog1); | ||
195 | pr_info(" dma1ErrorStatus = 0x%016llx\n", data->dma1ErrorStatus); | ||
196 | pr_info(" dma1FirstErrorStatus = 0x%016llx\n", data->dma1FirstErrorStatus); | ||
197 | pr_info(" dma1ErrorLog0 = 0x%016llx\n", data->dma1ErrorLog0); | ||
198 | pr_info(" dma1ErrorLog1 = 0x%016llx\n", data->dma1ErrorLog1); | ||
199 | |||
200 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { | ||
201 | if ((data->pestA[i] >> 63) == 0 && | ||
202 | (data->pestB[i] >> 63) == 0) | ||
203 | continue; | ||
204 | pr_info(" PE[%3d] PESTA = 0x%016llx\n", i, data->pestA[i]); | ||
205 | pr_info(" PESTB = 0x%016llx\n", data->pestB[i]); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | static void pnv_pci_dump_phb_diag_data(struct pnv_phb *phb) | ||
210 | { | ||
211 | switch(phb->model) { | ||
212 | case PNV_PHB_MODEL_P7IOC: | ||
213 | pnv_pci_dump_p7ioc_diag_data(phb); | ||
214 | break; | ||
215 | default: | ||
216 | pr_warning("PCI %d: Can't decode this PHB diag data\n", | ||
217 | phb->hose->global_number); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) | ||
222 | { | ||
223 | unsigned long flags, rc; | ||
224 | int has_diag; | ||
225 | |||
226 | spin_lock_irqsave(&phb->lock, flags); | ||
227 | |||
228 | rc = opal_pci_get_phb_diag_data(phb->opal_id, phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); | ||
229 | has_diag = (rc == OPAL_SUCCESS); | ||
230 | |||
231 | rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, | ||
232 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
233 | if (rc) { | ||
234 | pr_warning("PCI %d: Failed to clear EEH freeze state" | ||
235 | " for PE#%d, err %ld\n", | ||
236 | phb->hose->global_number, pe_no, rc); | ||
237 | |||
238 | /* For now, let's only display the diag buffer when we fail to clear | ||
239 | * the EEH status. We'll do more sensible things later when we have | ||
240 | * proper EEH support. We need to make sure we don't pollute ourselves | ||
241 | * with the normal errors generated when probing empty slots | ||
242 | */ | ||
243 | if (has_diag) | ||
244 | pnv_pci_dump_phb_diag_data(phb); | ||
245 | else | ||
246 | pr_warning("PCI %d: No diag data available\n", | ||
247 | phb->hose->global_number); | ||
248 | } | ||
249 | |||
250 | spin_unlock_irqrestore(&phb->lock, flags); | ||
251 | } | ||
252 | |||
147 | static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, | 253 | static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, |
148 | u32 bdfn) | 254 | u32 bdfn) |
149 | { | 255 | { |
@@ -165,15 +271,8 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, | |||
165 | } | 271 | } |
166 | cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", | 272 | cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", |
167 | bdfn, pe_no, fstate); | 273 | bdfn, pe_no, fstate); |
168 | if (fstate != 0) { | 274 | if (fstate != 0) |
169 | rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, | 275 | pnv_pci_handle_eeh_config(phb, pe_no); |
170 | OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); | ||
171 | if (rc) { | ||
172 | pr_warning("PCI %d: Failed to clear EEH freeze state" | ||
173 | " for PE#%d, err %lld\n", | ||
174 | phb->hose->global_number, pe_no, rc); | ||
175 | } | ||
176 | } | ||
177 | } | 276 | } |
178 | 277 | ||
179 | static int pnv_pci_read_config(struct pci_bus *bus, | 278 | static int pnv_pci_read_config(struct pci_bus *bus, |
@@ -257,12 +356,54 @@ struct pci_ops pnv_pci_ops = { | |||
257 | .write = pnv_pci_write_config, | 356 | .write = pnv_pci_write_config, |
258 | }; | 357 | }; |
259 | 358 | ||
359 | |||
360 | static void pnv_tce_invalidate(struct iommu_table *tbl, | ||
361 | u64 *startp, u64 *endp) | ||
362 | { | ||
363 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; | ||
364 | unsigned long start, end, inc; | ||
365 | |||
366 | start = __pa(startp); | ||
367 | end = __pa(endp); | ||
368 | |||
369 | |||
370 | /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */ | ||
371 | if (tbl->it_busno) { | ||
372 | start <<= 12; | ||
373 | end <<= 12; | ||
374 | inc = 128 << 12; | ||
375 | start |= tbl->it_busno; | ||
376 | end |= tbl->it_busno; | ||
377 | } | ||
378 | /* p7ioc-style invalidation, 2 TCEs per write */ | ||
379 | else if (tbl->it_type & TCE_PCI_SWINV_PAIR) { | ||
380 | start |= (1ull << 63); | ||
381 | end |= (1ull << 63); | ||
382 | inc = 16; | ||
383 | } | ||
384 | /* Default (older HW) */ | ||
385 | else | ||
386 | inc = 128; | ||
387 | |||
388 | end |= inc - 1; /* round up end to be different than start */ | ||
389 | |||
390 | mb(); /* Ensure above stores are visible */ | ||
391 | while (start <= end) { | ||
392 | __raw_writeq(start, invalidate); | ||
393 | start += inc; | ||
394 | } | ||
395 | /* The iommu layer will do another mb() for us on build() and | ||
396 | * we don't care on free() | ||
397 | */ | ||
398 | } | ||
399 | |||
400 | |||
260 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | 401 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, |
261 | unsigned long uaddr, enum dma_data_direction direction, | 402 | unsigned long uaddr, enum dma_data_direction direction, |
262 | struct dma_attrs *attrs) | 403 | struct dma_attrs *attrs) |
263 | { | 404 | { |
264 | u64 proto_tce; | 405 | u64 proto_tce; |
265 | u64 *tcep; | 406 | u64 *tcep, *tces; |
266 | u64 rpn; | 407 | u64 rpn; |
267 | 408 | ||
268 | proto_tce = TCE_PCI_READ; // Read allowed | 409 | proto_tce = TCE_PCI_READ; // Read allowed |
@@ -270,25 +411,33 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | |||
270 | if (direction != DMA_TO_DEVICE) | 411 | if (direction != DMA_TO_DEVICE) |
271 | proto_tce |= TCE_PCI_WRITE; | 412 | proto_tce |= TCE_PCI_WRITE; |
272 | 413 | ||
273 | tcep = ((u64 *)tbl->it_base) + index; | 414 | tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset; |
415 | rpn = __pa(uaddr) >> TCE_SHIFT; | ||
274 | 416 | ||
275 | while (npages--) { | 417 | while (npages--) |
276 | /* can't move this out since we might cross LMB boundary */ | 418 | *(tcep++) = proto_tce | (rpn++ << TCE_RPN_SHIFT); |
277 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 419 | |
278 | *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | 420 | /* Some implementations won't cache invalid TCEs and thus may not |
421 | * need that flush. We'll probably turn it_type into a bit mask | ||
422 | * of flags if that becomes the case | ||
423 | */ | ||
424 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) | ||
425 | pnv_tce_invalidate(tbl, tces, tcep - 1); | ||
279 | 426 | ||
280 | uaddr += TCE_PAGE_SIZE; | ||
281 | tcep++; | ||
282 | } | ||
283 | return 0; | 427 | return 0; |
284 | } | 428 | } |
285 | 429 | ||
286 | static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) | 430 | static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) |
287 | { | 431 | { |
288 | u64 *tcep = ((u64 *)tbl->it_base) + index; | 432 | u64 *tcep, *tces; |
433 | |||
434 | tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset; | ||
289 | 435 | ||
290 | while (npages--) | 436 | while (npages--) |
291 | *(tcep++) = 0; | 437 | *(tcep++) = 0; |
438 | |||
439 | if (tbl->it_type & TCE_PCI_SWINV_FREE) | ||
440 | pnv_tce_invalidate(tbl, tces, tcep - 1); | ||
292 | } | 441 | } |
293 | 442 | ||
294 | void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | 443 | void pnv_pci_setup_iommu_table(struct iommu_table *tbl, |
@@ -308,13 +457,14 @@ static struct iommu_table * __devinit | |||
308 | pnv_pci_setup_bml_iommu(struct pci_controller *hose) | 457 | pnv_pci_setup_bml_iommu(struct pci_controller *hose) |
309 | { | 458 | { |
310 | struct iommu_table *tbl; | 459 | struct iommu_table *tbl; |
311 | const __be64 *basep; | 460 | const __be64 *basep, *swinvp; |
312 | const __be32 *sizep; | 461 | const __be32 *sizep; |
313 | 462 | ||
314 | basep = of_get_property(hose->dn, "linux,tce-base", NULL); | 463 | basep = of_get_property(hose->dn, "linux,tce-base", NULL); |
315 | sizep = of_get_property(hose->dn, "linux,tce-size", NULL); | 464 | sizep = of_get_property(hose->dn, "linux,tce-size", NULL); |
316 | if (basep == NULL || sizep == NULL) { | 465 | if (basep == NULL || sizep == NULL) { |
317 | pr_err("PCI: %s has missing tce entries !\n", hose->dn->full_name); | 466 | pr_err("PCI: %s has missing tce entries !\n", |
467 | hose->dn->full_name); | ||
318 | return NULL; | 468 | return NULL; |
319 | } | 469 | } |
320 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node); | 470 | tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, hose->node); |
@@ -323,6 +473,15 @@ pnv_pci_setup_bml_iommu(struct pci_controller *hose) | |||
323 | pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), | 473 | pnv_pci_setup_iommu_table(tbl, __va(be64_to_cpup(basep)), |
324 | be32_to_cpup(sizep), 0); | 474 | be32_to_cpup(sizep), 0); |
325 | iommu_init_table(tbl, hose->node); | 475 | iommu_init_table(tbl, hose->node); |
476 | |||
477 | /* Deal with SW invalidated TCEs when needed (BML way) */ | ||
478 | swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info", | ||
479 | NULL); | ||
480 | if (swinvp) { | ||
481 | tbl->it_busno = swinvp[1]; | ||
482 | tbl->it_index = (unsigned long)ioremap(swinvp[0], 8); | ||
483 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; | ||
484 | } | ||
326 | return tbl; | 485 | return tbl; |
327 | } | 486 | } |
328 | 487 | ||
@@ -356,6 +515,13 @@ static void __devinit pnv_pci_dma_dev_setup(struct pci_dev *pdev) | |||
356 | pnv_pci_dma_fallback_setup(hose, pdev); | 515 | pnv_pci_dma_fallback_setup(hose, pdev); |
357 | } | 516 | } |
358 | 517 | ||
518 | /* Fixup wrong class code in p7ioc root complex */ | ||
519 | static void __devinit pnv_p7ioc_rc_quirk(struct pci_dev *dev) | ||
520 | { | ||
521 | dev->class = PCI_CLASS_BRIDGE_PCI << 8; | ||
522 | } | ||
523 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); | ||
524 | |||
359 | static int pnv_pci_probe_mode(struct pci_bus *bus) | 525 | static int pnv_pci_probe_mode(struct pci_bus *bus) |
360 | { | 526 | { |
361 | struct pci_controller *hose = pci_bus_to_host(bus); | 527 | struct pci_controller *hose = pci_bus_to_host(bus); |
@@ -400,12 +566,24 @@ void __init pnv_pci_init(void) | |||
400 | init_pci_config_tokens(); | 566 | init_pci_config_tokens(); |
401 | find_and_init_phbs(); | 567 | find_and_init_phbs(); |
402 | #endif /* CONFIG_PPC_POWERNV_RTAS */ | 568 | #endif /* CONFIG_PPC_POWERNV_RTAS */ |
403 | } else { | 569 | } |
404 | /* OPAL is here, do our normal stuff */ | 570 | /* OPAL is here, do our normal stuff */ |
571 | else { | ||
572 | int found_ioda = 0; | ||
573 | |||
574 | /* Look for IODA IO-Hubs. We don't support mixing IODA | ||
575 | * and p5ioc2 due to the need to change some global | ||
576 | * probing flags | ||
577 | */ | ||
578 | for_each_compatible_node(np, NULL, "ibm,ioda-hub") { | ||
579 | pnv_pci_init_ioda_hub(np); | ||
580 | found_ioda = 1; | ||
581 | } | ||
405 | 582 | ||
406 | /* Look for p5ioc2 IO-Hubs */ | 583 | /* Look for p5ioc2 IO-Hubs */ |
407 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") | 584 | if (!found_ioda) |
408 | pnv_pci_init_p5ioc2_hub(np); | 585 | for_each_compatible_node(np, NULL, "ibm,p5ioc2") |
586 | pnv_pci_init_p5ioc2_hub(np); | ||
409 | } | 587 | } |
410 | 588 | ||
411 | /* Setup the linkage between OF nodes and PHBs */ | 589 | /* Setup the linkage between OF nodes and PHBs */ |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index d4dbc4950936..8bc479634643 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -9,9 +9,63 @@ enum pnv_phb_type { | |||
9 | PNV_PHB_IODA2, | 9 | PNV_PHB_IODA2, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | /* Precise PHB model for error management */ | ||
13 | enum pnv_phb_model { | ||
14 | PNV_PHB_MODEL_UNKNOWN, | ||
15 | PNV_PHB_MODEL_P5IOC2, | ||
16 | PNV_PHB_MODEL_P7IOC, | ||
17 | }; | ||
18 | |||
19 | #define PNV_PCI_DIAG_BUF_SIZE 4096 | ||
20 | |||
21 | /* Data associated with a PE, including IOMMU tracking etc.. */ | ||
22 | struct pnv_ioda_pe { | ||
23 | /* A PE can be associated with a single device or an | ||
24 | * entire bus (& children). In the former case, pdev | ||
25 | * is populated, in the later case, pbus is. | ||
26 | */ | ||
27 | struct pci_dev *pdev; | ||
28 | struct pci_bus *pbus; | ||
29 | |||
30 | /* Effective RID (device RID for a device PE and base bus | ||
31 | * RID with devfn 0 for a bus PE) | ||
32 | */ | ||
33 | unsigned int rid; | ||
34 | |||
35 | /* PE number */ | ||
36 | unsigned int pe_number; | ||
37 | |||
38 | /* "Weight" assigned to the PE for the sake of DMA resource | ||
39 | * allocations | ||
40 | */ | ||
41 | unsigned int dma_weight; | ||
42 | |||
43 | /* This is a PCI-E -> PCI-X bridge, this points to the | ||
44 | * corresponding bus PE | ||
45 | */ | ||
46 | struct pnv_ioda_pe *bus_pe; | ||
47 | |||
48 | /* "Base" iommu table, ie, 4K TCEs, 32-bit DMA */ | ||
49 | int tce32_seg; | ||
50 | int tce32_segcount; | ||
51 | struct iommu_table tce32_table; | ||
52 | |||
53 | /* XXX TODO: Add support for additional 64-bit iommus */ | ||
54 | |||
55 | /* MSIs. MVE index is identical for for 32 and 64 bit MSI | ||
56 | * and -1 if not supported. (It's actually identical to the | ||
57 | * PE number) | ||
58 | */ | ||
59 | int mve_number; | ||
60 | |||
61 | /* Link in list of PE#s */ | ||
62 | struct list_head link; | ||
63 | }; | ||
64 | |||
12 | struct pnv_phb { | 65 | struct pnv_phb { |
13 | struct pci_controller *hose; | 66 | struct pci_controller *hose; |
14 | enum pnv_phb_type type; | 67 | enum pnv_phb_type type; |
68 | enum pnv_phb_model model; | ||
15 | u64 opal_id; | 69 | u64 opal_id; |
16 | void __iomem *regs; | 70 | void __iomem *regs; |
17 | spinlock_t lock; | 71 | spinlock_t lock; |
@@ -34,7 +88,52 @@ struct pnv_phb { | |||
34 | struct { | 88 | struct { |
35 | struct iommu_table iommu_table; | 89 | struct iommu_table iommu_table; |
36 | } p5ioc2; | 90 | } p5ioc2; |
91 | |||
92 | struct { | ||
93 | /* Global bridge info */ | ||
94 | unsigned int total_pe; | ||
95 | unsigned int m32_size; | ||
96 | unsigned int m32_segsize; | ||
97 | unsigned int m32_pci_base; | ||
98 | unsigned int io_size; | ||
99 | unsigned int io_segsize; | ||
100 | unsigned int io_pci_base; | ||
101 | |||
102 | /* PE allocation bitmap */ | ||
103 | unsigned long *pe_alloc; | ||
104 | |||
105 | /* M32 & IO segment maps */ | ||
106 | unsigned int *m32_segmap; | ||
107 | unsigned int *io_segmap; | ||
108 | struct pnv_ioda_pe *pe_array; | ||
109 | |||
110 | /* Reverse map of PEs, will have to extend if | ||
111 | * we are to support more than 256 PEs, indexed | ||
112 | * bus { bus, devfn } | ||
113 | */ | ||
114 | unsigned char pe_rmap[0x10000]; | ||
115 | |||
116 | /* 32-bit TCE tables allocation */ | ||
117 | unsigned long tce32_count; | ||
118 | |||
119 | /* Total "weight" for the sake of DMA resources | ||
120 | * allocation | ||
121 | */ | ||
122 | unsigned int dma_weight; | ||
123 | unsigned int dma_pe_count; | ||
124 | |||
125 | /* Sorted list of used PE's, sorted at | ||
126 | * boot for resource allocation purposes | ||
127 | */ | ||
128 | struct list_head pe_list; | ||
129 | } ioda; | ||
37 | }; | 130 | }; |
131 | |||
132 | /* PHB status structure */ | ||
133 | union { | ||
134 | unsigned char blob[PNV_PCI_DIAG_BUF_SIZE]; | ||
135 | struct OpalIoP7IOCPhbErrorData p7ioc; | ||
136 | } diag; | ||
38 | }; | 137 | }; |
39 | 138 | ||
40 | extern struct pci_ops pnv_pci_ops; | 139 | extern struct pci_ops pnv_pci_ops; |
@@ -43,6 +142,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | |||
43 | void *tce_mem, u64 tce_size, | 142 | void *tce_mem, u64 tce_size, |
44 | u64 dma_offset); | 143 | u64 dma_offset); |
45 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); | 144 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); |
145 | extern void pnv_pci_init_ioda_hub(struct device_node *np); | ||
46 | 146 | ||
47 | 147 | ||
48 | #endif /* __POWERNV_PCI_H */ | 148 | #endif /* __POWERNV_PCI_H */ |
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index e87736685243..17210c526c52 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c | |||
@@ -75,7 +75,7 @@ int __devinit pnv_smp_kick_cpu(int nr) | |||
75 | /* On OPAL v2 the CPU are still spinning inside OPAL itself, | 75 | /* On OPAL v2 the CPU are still spinning inside OPAL itself, |
76 | * get them back now | 76 | * get them back now |
77 | */ | 77 | */ |
78 | if (firmware_has_feature(FW_FEATURE_OPALv2)) { | 78 | if (!paca[nr].cpu_start && firmware_has_feature(FW_FEATURE_OPALv2)) { |
79 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); | 79 | pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); |
80 | rc = opal_start_cpu(pcpu, start_here); | 80 | rc = opal_start_cpu(pcpu, start_here); |
81 | if (rc != OPAL_SUCCESS) | 81 | if (rc != OPAL_SUCCESS) |
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 1d6f4f478fe2..617efa12a3a5 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
@@ -31,18 +31,18 @@ | |||
31 | 31 | ||
32 | #if defined(DEBUG) | 32 | #if defined(DEBUG) |
33 | #define DBG udbg_printf | 33 | #define DBG udbg_printf |
34 | #define FAIL udbg_printf | ||
34 | #else | 35 | #else |
35 | #define DBG pr_debug | 36 | #define DBG pr_devel |
37 | #define FAIL pr_debug | ||
36 | #endif | 38 | #endif |
37 | 39 | ||
38 | /** | 40 | /** |
39 | * struct ps3_bmp - a per cpu irq status and mask bitmap structure | 41 | * struct ps3_bmp - a per cpu irq status and mask bitmap structure |
40 | * @status: 256 bit status bitmap indexed by plug | 42 | * @status: 256 bit status bitmap indexed by plug |
41 | * @unused_1: | 43 | * @unused_1: Alignment |
42 | * @mask: 256 bit mask bitmap indexed by plug | 44 | * @mask: 256 bit mask bitmap indexed by plug |
43 | * @unused_2: | 45 | * @unused_2: Alignment |
44 | * @lock: | ||
45 | * @ipi_debug_brk_mask: | ||
46 | * | 46 | * |
47 | * The HV maintains per SMT thread mappings of HV outlet to HV plug on | 47 | * The HV maintains per SMT thread mappings of HV outlet to HV plug on |
48 | * behalf of the guest. These mappings are implemented as 256 bit guest | 48 | * behalf of the guest. These mappings are implemented as 256 bit guest |
@@ -73,21 +73,24 @@ struct ps3_bmp { | |||
73 | unsigned long mask; | 73 | unsigned long mask; |
74 | u64 unused_2[3]; | 74 | u64 unused_2[3]; |
75 | }; | 75 | }; |
76 | u64 ipi_debug_brk_mask; | ||
77 | spinlock_t lock; | ||
78 | }; | 76 | }; |
79 | 77 | ||
80 | /** | 78 | /** |
81 | * struct ps3_private - a per cpu data structure | 79 | * struct ps3_private - a per cpu data structure |
82 | * @bmp: ps3_bmp structure | 80 | * @bmp: ps3_bmp structure |
81 | * @bmp_lock: Syncronize access to bmp. | ||
82 | * @ipi_debug_brk_mask: Mask for debug break IPIs | ||
83 | * @ppe_id: HV logical_ppe_id | 83 | * @ppe_id: HV logical_ppe_id |
84 | * @thread_id: HV thread_id | 84 | * @thread_id: HV thread_id |
85 | * @ipi_mask: Mask of IPI virqs | ||
85 | */ | 86 | */ |
86 | 87 | ||
87 | struct ps3_private { | 88 | struct ps3_private { |
88 | struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); | 89 | struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); |
90 | spinlock_t bmp_lock; | ||
89 | u64 ppe_id; | 91 | u64 ppe_id; |
90 | u64 thread_id; | 92 | u64 thread_id; |
93 | unsigned long ipi_debug_brk_mask; | ||
91 | unsigned long ipi_mask; | 94 | unsigned long ipi_mask; |
92 | }; | 95 | }; |
93 | 96 | ||
@@ -105,7 +108,7 @@ static void ps3_chip_mask(struct irq_data *d) | |||
105 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); | 108 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); |
106 | unsigned long flags; | 109 | unsigned long flags; |
107 | 110 | ||
108 | pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, | 111 | DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, |
109 | pd->thread_id, d->irq); | 112 | pd->thread_id, d->irq); |
110 | 113 | ||
111 | local_irq_save(flags); | 114 | local_irq_save(flags); |
@@ -126,7 +129,7 @@ static void ps3_chip_unmask(struct irq_data *d) | |||
126 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); | 129 | struct ps3_private *pd = irq_data_get_irq_chip_data(d); |
127 | unsigned long flags; | 130 | unsigned long flags; |
128 | 131 | ||
129 | pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, | 132 | DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, |
130 | pd->thread_id, d->irq); | 133 | pd->thread_id, d->irq); |
131 | 134 | ||
132 | local_irq_save(flags); | 135 | local_irq_save(flags); |
@@ -190,19 +193,19 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
190 | *virq = irq_create_mapping(NULL, outlet); | 193 | *virq = irq_create_mapping(NULL, outlet); |
191 | 194 | ||
192 | if (*virq == NO_IRQ) { | 195 | if (*virq == NO_IRQ) { |
193 | pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", | 196 | FAIL("%s:%d: irq_create_mapping failed: outlet %lu\n", |
194 | __func__, __LINE__, outlet); | 197 | __func__, __LINE__, outlet); |
195 | result = -ENOMEM; | 198 | result = -ENOMEM; |
196 | goto fail_create; | 199 | goto fail_create; |
197 | } | 200 | } |
198 | 201 | ||
199 | pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, | 202 | DBG("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, |
200 | outlet, cpu, *virq); | 203 | outlet, cpu, *virq); |
201 | 204 | ||
202 | result = irq_set_chip_data(*virq, pd); | 205 | result = irq_set_chip_data(*virq, pd); |
203 | 206 | ||
204 | if (result) { | 207 | if (result) { |
205 | pr_debug("%s:%d: irq_set_chip_data failed\n", | 208 | FAIL("%s:%d: irq_set_chip_data failed\n", |
206 | __func__, __LINE__); | 209 | __func__, __LINE__); |
207 | goto fail_set; | 210 | goto fail_set; |
208 | } | 211 | } |
@@ -228,13 +231,13 @@ static int ps3_virq_destroy(unsigned int virq) | |||
228 | { | 231 | { |
229 | const struct ps3_private *pd = irq_get_chip_data(virq); | 232 | const struct ps3_private *pd = irq_get_chip_data(virq); |
230 | 233 | ||
231 | pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, | 234 | DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, |
232 | __LINE__, pd->ppe_id, pd->thread_id, virq); | 235 | __LINE__, pd->ppe_id, pd->thread_id, virq); |
233 | 236 | ||
234 | irq_set_chip_data(virq, NULL); | 237 | irq_set_chip_data(virq, NULL); |
235 | irq_dispose_mapping(virq); | 238 | irq_dispose_mapping(virq); |
236 | 239 | ||
237 | pr_debug("%s:%d <-\n", __func__, __LINE__); | 240 | DBG("%s:%d <-\n", __func__, __LINE__); |
238 | return 0; | 241 | return 0; |
239 | } | 242 | } |
240 | 243 | ||
@@ -257,7 +260,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
257 | result = ps3_virq_setup(cpu, outlet, virq); | 260 | result = ps3_virq_setup(cpu, outlet, virq); |
258 | 261 | ||
259 | if (result) { | 262 | if (result) { |
260 | pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); | 263 | FAIL("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); |
261 | goto fail_setup; | 264 | goto fail_setup; |
262 | } | 265 | } |
263 | 266 | ||
@@ -269,7 +272,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
269 | outlet, 0); | 272 | outlet, 0); |
270 | 273 | ||
271 | if (result) { | 274 | if (result) { |
272 | pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", | 275 | FAIL("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", |
273 | __func__, __LINE__, ps3_result(result)); | 276 | __func__, __LINE__, ps3_result(result)); |
274 | result = -EPERM; | 277 | result = -EPERM; |
275 | goto fail_connect; | 278 | goto fail_connect; |
@@ -298,7 +301,7 @@ int ps3_irq_plug_destroy(unsigned int virq) | |||
298 | int result; | 301 | int result; |
299 | const struct ps3_private *pd = irq_get_chip_data(virq); | 302 | const struct ps3_private *pd = irq_get_chip_data(virq); |
300 | 303 | ||
301 | pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, | 304 | DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, |
302 | __LINE__, pd->ppe_id, pd->thread_id, virq); | 305 | __LINE__, pd->ppe_id, pd->thread_id, virq); |
303 | 306 | ||
304 | ps3_chip_mask(irq_get_irq_data(virq)); | 307 | ps3_chip_mask(irq_get_irq_data(virq)); |
@@ -306,7 +309,7 @@ int ps3_irq_plug_destroy(unsigned int virq) | |||
306 | result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); | 309 | result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); |
307 | 310 | ||
308 | if (result) | 311 | if (result) |
309 | pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", | 312 | FAIL("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", |
310 | __func__, __LINE__, ps3_result(result)); | 313 | __func__, __LINE__, ps3_result(result)); |
311 | 314 | ||
312 | ps3_virq_destroy(virq); | 315 | ps3_virq_destroy(virq); |
@@ -334,7 +337,7 @@ int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) | |||
334 | result = lv1_construct_event_receive_port(&outlet); | 337 | result = lv1_construct_event_receive_port(&outlet); |
335 | 338 | ||
336 | if (result) { | 339 | if (result) { |
337 | pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", | 340 | FAIL("%s:%d: lv1_construct_event_receive_port failed: %s\n", |
338 | __func__, __LINE__, ps3_result(result)); | 341 | __func__, __LINE__, ps3_result(result)); |
339 | *virq = NO_IRQ; | 342 | *virq = NO_IRQ; |
340 | return result; | 343 | return result; |
@@ -360,14 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq) | |||
360 | { | 363 | { |
361 | int result; | 364 | int result; |
362 | 365 | ||
363 | pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq); | 366 | DBG(" -> %s:%d virq %u\n", __func__, __LINE__, virq); |
364 | 367 | ||
365 | ps3_chip_mask(irq_get_irq_data(virq)); | 368 | ps3_chip_mask(irq_get_irq_data(virq)); |
366 | 369 | ||
367 | result = lv1_destruct_event_receive_port(virq_to_hw(virq)); | 370 | result = lv1_destruct_event_receive_port(virq_to_hw(virq)); |
368 | 371 | ||
369 | if (result) | 372 | if (result) |
370 | pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", | 373 | FAIL("%s:%d: lv1_destruct_event_receive_port failed: %s\n", |
371 | __func__, __LINE__, ps3_result(result)); | 374 | __func__, __LINE__, ps3_result(result)); |
372 | 375 | ||
373 | /* | 376 | /* |
@@ -375,7 +378,7 @@ int ps3_event_receive_port_destroy(unsigned int virq) | |||
375 | * calls from interrupt context (smp_call_function) when kexecing. | 378 | * calls from interrupt context (smp_call_function) when kexecing. |
376 | */ | 379 | */ |
377 | 380 | ||
378 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 381 | DBG(" <- %s:%d\n", __func__, __LINE__); |
379 | return result; | 382 | return result; |
380 | } | 383 | } |
381 | 384 | ||
@@ -411,7 +414,7 @@ int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, | |||
411 | dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); | 414 | dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); |
412 | 415 | ||
413 | if (result) { | 416 | if (result) { |
414 | pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" | 417 | FAIL("%s:%d: lv1_connect_interrupt_event_receive_port" |
415 | " failed: %s\n", __func__, __LINE__, | 418 | " failed: %s\n", __func__, __LINE__, |
416 | ps3_result(result)); | 419 | ps3_result(result)); |
417 | ps3_event_receive_port_destroy(*virq); | 420 | ps3_event_receive_port_destroy(*virq); |
@@ -419,7 +422,7 @@ int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, | |||
419 | return result; | 422 | return result; |
420 | } | 423 | } |
421 | 424 | ||
422 | pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, | 425 | DBG("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, |
423 | dev->interrupt_id, *virq); | 426 | dev->interrupt_id, *virq); |
424 | 427 | ||
425 | return 0; | 428 | return 0; |
@@ -433,14 +436,14 @@ int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, | |||
433 | 436 | ||
434 | int result; | 437 | int result; |
435 | 438 | ||
436 | pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, | 439 | DBG(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, |
437 | dev->interrupt_id, virq); | 440 | dev->interrupt_id, virq); |
438 | 441 | ||
439 | result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, | 442 | result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, |
440 | dev->dev_id, virq_to_hw(virq), dev->interrupt_id); | 443 | dev->dev_id, virq_to_hw(virq), dev->interrupt_id); |
441 | 444 | ||
442 | if (result) | 445 | if (result) |
443 | pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" | 446 | FAIL("%s:%d: lv1_disconnect_interrupt_event_receive_port" |
444 | " failed: %s\n", __func__, __LINE__, | 447 | " failed: %s\n", __func__, __LINE__, |
445 | ps3_result(result)); | 448 | ps3_result(result)); |
446 | 449 | ||
@@ -455,7 +458,7 @@ int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, | |||
455 | result = ps3_virq_destroy(virq); | 458 | result = ps3_virq_destroy(virq); |
456 | BUG_ON(result); | 459 | BUG_ON(result); |
457 | 460 | ||
458 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 461 | DBG(" <- %s:%d\n", __func__, __LINE__); |
459 | return result; | 462 | return result; |
460 | } | 463 | } |
461 | EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); | 464 | EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); |
@@ -480,7 +483,7 @@ int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, | |||
480 | result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); | 483 | result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); |
481 | 484 | ||
482 | if (result) { | 485 | if (result) { |
483 | pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", | 486 | FAIL("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", |
484 | __func__, __LINE__, ps3_result(result)); | 487 | __func__, __LINE__, ps3_result(result)); |
485 | return result; | 488 | return result; |
486 | } | 489 | } |
@@ -510,7 +513,7 @@ int ps3_io_irq_destroy(unsigned int virq) | |||
510 | result = lv1_destruct_io_irq_outlet(outlet); | 513 | result = lv1_destruct_io_irq_outlet(outlet); |
511 | 514 | ||
512 | if (result) | 515 | if (result) |
513 | pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", | 516 | FAIL("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", |
514 | __func__, __LINE__, ps3_result(result)); | 517 | __func__, __LINE__, ps3_result(result)); |
515 | 518 | ||
516 | return result; | 519 | return result; |
@@ -542,7 +545,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, | |||
542 | result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); | 545 | result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); |
543 | 546 | ||
544 | if (result) { | 547 | if (result) { |
545 | pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", | 548 | FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", |
546 | __func__, __LINE__, ps3_result(result)); | 549 | __func__, __LINE__, ps3_result(result)); |
547 | return result; | 550 | return result; |
548 | } | 551 | } |
@@ -562,7 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq) | |||
562 | result = lv1_deconfigure_virtual_uart_irq(); | 565 | result = lv1_deconfigure_virtual_uart_irq(); |
563 | 566 | ||
564 | if (result) { | 567 | if (result) { |
565 | pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", | 568 | FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", |
566 | __func__, __LINE__, ps3_result(result)); | 569 | __func__, __LINE__, ps3_result(result)); |
567 | return result; | 570 | return result; |
568 | } | 571 | } |
@@ -595,7 +598,7 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, | |||
595 | result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); | 598 | result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); |
596 | 599 | ||
597 | if (result) { | 600 | if (result) { |
598 | pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", | 601 | FAIL("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", |
599 | __func__, __LINE__, ps3_result(result)); | 602 | __func__, __LINE__, ps3_result(result)); |
600 | return result; | 603 | return result; |
601 | } | 604 | } |
@@ -626,7 +629,7 @@ int ps3_spe_irq_destroy(unsigned int virq) | |||
626 | static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, | 629 | static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, |
627 | const char* func, int line) | 630 | const char* func, int line) |
628 | { | 631 | { |
629 | pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", | 632 | pr_debug("%s:%d: %s %u {%04llx_%04llx_%04llx_%04llx}\n", |
630 | func, line, header, cpu, | 633 | func, line, header, cpu, |
631 | *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, | 634 | *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, |
632 | *p & 0xffff); | 635 | *p & 0xffff); |
@@ -635,7 +638,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, | |||
635 | static void __maybe_unused _dump_256_bmp(const char *header, | 638 | static void __maybe_unused _dump_256_bmp(const char *header, |
636 | const u64 *p, unsigned cpu, const char* func, int line) | 639 | const u64 *p, unsigned cpu, const char* func, int line) |
637 | { | 640 | { |
638 | pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", | 641 | pr_debug("%s:%d: %s %u {%016llx:%016llx:%016llx:%016llx}\n", |
639 | func, line, header, cpu, p[0], p[1], p[2], p[3]); | 642 | func, line, header, cpu, p[0], p[1], p[2], p[3]); |
640 | } | 643 | } |
641 | 644 | ||
@@ -644,10 +647,10 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line) | |||
644 | { | 647 | { |
645 | unsigned long flags; | 648 | unsigned long flags; |
646 | 649 | ||
647 | spin_lock_irqsave(&pd->bmp.lock, flags); | 650 | spin_lock_irqsave(&pd->bmp_lock, flags); |
648 | _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); | 651 | _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); |
649 | _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); | 652 | _dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line); |
650 | spin_unlock_irqrestore(&pd->bmp.lock, flags); | 653 | spin_unlock_irqrestore(&pd->bmp_lock, flags); |
651 | } | 654 | } |
652 | 655 | ||
653 | #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) | 656 | #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) |
@@ -656,9 +659,9 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd, | |||
656 | { | 659 | { |
657 | unsigned long flags; | 660 | unsigned long flags; |
658 | 661 | ||
659 | spin_lock_irqsave(&pd->bmp.lock, flags); | 662 | spin_lock_irqsave(&pd->bmp_lock, flags); |
660 | _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); | 663 | _dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line); |
661 | spin_unlock_irqrestore(&pd->bmp.lock, flags); | 664 | spin_unlock_irqrestore(&pd->bmp_lock, flags); |
662 | } | 665 | } |
663 | #else | 666 | #else |
664 | static void dump_bmp(struct ps3_private* pd) {}; | 667 | static void dump_bmp(struct ps3_private* pd) {}; |
@@ -667,7 +670,7 @@ static void dump_bmp(struct ps3_private* pd) {}; | |||
667 | static int ps3_host_map(struct irq_host *h, unsigned int virq, | 670 | static int ps3_host_map(struct irq_host *h, unsigned int virq, |
668 | irq_hw_number_t hwirq) | 671 | irq_hw_number_t hwirq) |
669 | { | 672 | { |
670 | pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, | 673 | DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, |
671 | virq); | 674 | virq); |
672 | 675 | ||
673 | irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); | 676 | irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); |
@@ -690,10 +693,10 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) | |||
690 | { | 693 | { |
691 | struct ps3_private *pd = &per_cpu(ps3_private, cpu); | 694 | struct ps3_private *pd = &per_cpu(ps3_private, cpu); |
692 | 695 | ||
693 | pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; | 696 | set_bit(63 - virq, &pd->ipi_debug_brk_mask); |
694 | 697 | ||
695 | pr_debug("%s:%d: cpu %u, virq %u, mask %llxh\n", __func__, __LINE__, | 698 | DBG("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__, |
696 | cpu, virq, pd->bmp.ipi_debug_brk_mask); | 699 | cpu, virq, pd->ipi_debug_brk_mask); |
697 | } | 700 | } |
698 | 701 | ||
699 | void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) | 702 | void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) |
@@ -714,14 +717,14 @@ static unsigned int ps3_get_irq(void) | |||
714 | 717 | ||
715 | /* check for ipi break first to stop this cpu ASAP */ | 718 | /* check for ipi break first to stop this cpu ASAP */ |
716 | 719 | ||
717 | if (x & pd->bmp.ipi_debug_brk_mask) | 720 | if (x & pd->ipi_debug_brk_mask) |
718 | x &= pd->bmp.ipi_debug_brk_mask; | 721 | x &= pd->ipi_debug_brk_mask; |
719 | 722 | ||
720 | asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); | 723 | asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); |
721 | plug &= 0x3f; | 724 | plug &= 0x3f; |
722 | 725 | ||
723 | if (unlikely(plug == NO_IRQ)) { | 726 | if (unlikely(plug == NO_IRQ)) { |
724 | pr_debug("%s:%d: no plug found: thread_id %llu\n", __func__, | 727 | DBG("%s:%d: no plug found: thread_id %llu\n", __func__, |
725 | __LINE__, pd->thread_id); | 728 | __LINE__, pd->thread_id); |
726 | dump_bmp(&per_cpu(ps3_private, 0)); | 729 | dump_bmp(&per_cpu(ps3_private, 0)); |
727 | dump_bmp(&per_cpu(ps3_private, 1)); | 730 | dump_bmp(&per_cpu(ps3_private, 1)); |
@@ -760,9 +763,9 @@ void __init ps3_init_IRQ(void) | |||
760 | 763 | ||
761 | lv1_get_logical_ppe_id(&pd->ppe_id); | 764 | lv1_get_logical_ppe_id(&pd->ppe_id); |
762 | pd->thread_id = get_hard_smp_processor_id(cpu); | 765 | pd->thread_id = get_hard_smp_processor_id(cpu); |
763 | spin_lock_init(&pd->bmp.lock); | 766 | spin_lock_init(&pd->bmp_lock); |
764 | 767 | ||
765 | pr_debug("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", | 768 | DBG("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", |
766 | __func__, __LINE__, pd->ppe_id, pd->thread_id, | 769 | __func__, __LINE__, pd->ppe_id, pd->thread_id, |
767 | ps3_mm_phys_to_lpar(__pa(&pd->bmp))); | 770 | ps3_mm_phys_to_lpar(__pa(&pd->bmp))); |
768 | 771 | ||
@@ -770,7 +773,7 @@ void __init ps3_init_IRQ(void) | |||
770 | pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); | 773 | pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); |
771 | 774 | ||
772 | if (result) | 775 | if (result) |
773 | pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" | 776 | FAIL("%s:%d: lv1_configure_irq_state_bitmap failed:" |
774 | " %s\n", __func__, __LINE__, | 777 | " %s\n", __func__, __LINE__, |
775 | ps3_result(result)); | 778 | ps3_result(result)); |
776 | } | 779 | } |
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index ca40f6afd35d..7bdfea336f5e 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c | |||
@@ -44,7 +44,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) | |||
44 | s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; | 44 | s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; |
45 | s[i] = 0; | 45 | s[i] = 0; |
46 | 46 | ||
47 | pr_debug("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); | 47 | pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); |
48 | #endif | 48 | #endif |
49 | } | 49 | } |
50 | 50 | ||
@@ -53,7 +53,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) | |||
53 | static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, | 53 | static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, |
54 | u64 n4, const char *func, int line) | 54 | u64 n4, const char *func, int line) |
55 | { | 55 | { |
56 | pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); | 56 | pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id); |
57 | _dump_field("n1: ", n1, func, line); | 57 | _dump_field("n1: ", n1, func, line); |
58 | _dump_field("n2: ", n2, func, line); | 58 | _dump_field("n2: ", n2, func, line); |
59 | _dump_field("n3: ", n3, func, line); | 59 | _dump_field("n3: ", n3, func, line); |
@@ -65,13 +65,13 @@ static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, | |||
65 | static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | 65 | static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, |
66 | u64 v1, u64 v2, const char *func, int line) | 66 | u64 v1, u64 v2, const char *func, int line) |
67 | { | 67 | { |
68 | pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); | 68 | pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id); |
69 | _dump_field("n1: ", n1, func, line); | 69 | _dump_field("n1: ", n1, func, line); |
70 | _dump_field("n2: ", n2, func, line); | 70 | _dump_field("n2: ", n2, func, line); |
71 | _dump_field("n3: ", n3, func, line); | 71 | _dump_field("n3: ", n3, func, line); |
72 | _dump_field("n4: ", n4, func, line); | 72 | _dump_field("n4: ", n4, func, line); |
73 | pr_debug("%s:%d: v1: %016llx\n", func, line, v1); | 73 | pr_devel("%s:%d: v1: %016llx\n", func, line, v1); |
74 | pr_debug("%s:%d: v2: %016llx\n", func, line, v2); | 74 | pr_devel("%s:%d: v2: %016llx\n", func, line, v2); |
75 | } | 75 | } |
76 | 76 | ||
77 | /** | 77 | /** |
@@ -131,11 +131,11 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | |||
131 | lpar_id = id; | 131 | lpar_id = id; |
132 | } | 132 | } |
133 | 133 | ||
134 | result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1, | 134 | result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1, |
135 | &v2); | 135 | &v2); |
136 | 136 | ||
137 | if (result) { | 137 | if (result) { |
138 | pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", | 138 | pr_warn("%s:%d: lv1_read_repository_node failed: %s\n", |
139 | __func__, __LINE__, ps3_result(result)); | 139 | __func__, __LINE__, ps3_result(result)); |
140 | dump_node_name(lpar_id, n1, n2, n3, n4); | 140 | dump_node_name(lpar_id, n1, n2, n3, n4); |
141 | return -ENOENT; | 141 | return -ENOENT; |
@@ -149,10 +149,10 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, | |||
149 | *_v2 = v2; | 149 | *_v2 = v2; |
150 | 150 | ||
151 | if (v1 && !_v1) | 151 | if (v1 && !_v1) |
152 | pr_debug("%s:%d: warning: discarding non-zero v1: %016llx\n", | 152 | pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n", |
153 | __func__, __LINE__, v1); | 153 | __func__, __LINE__, v1); |
154 | if (v2 && !_v2) | 154 | if (v2 && !_v2) |
155 | pr_debug("%s:%d: warning: discarding non-zero v2: %016llx\n", | 155 | pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n", |
156 | __func__, __LINE__, v2); | 156 | __func__, __LINE__, v2); |
157 | 157 | ||
158 | return 0; | 158 | return 0; |
@@ -323,16 +323,16 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) | |||
323 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); | 323 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); |
324 | 324 | ||
325 | if (result) { | 325 | if (result) { |
326 | pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); | 326 | pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); |
327 | return result; | 327 | return result; |
328 | } | 328 | } |
329 | 329 | ||
330 | pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", | 330 | pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", |
331 | __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, | 331 | __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, |
332 | num_dev); | 332 | num_dev); |
333 | 333 | ||
334 | if (tmp.dev_index >= num_dev) { | 334 | if (tmp.dev_index >= num_dev) { |
335 | pr_debug("%s:%d: no device found\n", __func__, __LINE__); | 335 | pr_devel("%s:%d: no device found\n", __func__, __LINE__); |
336 | return -ENODEV; | 336 | return -ENODEV; |
337 | } | 337 | } |
338 | 338 | ||
@@ -340,7 +340,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) | |||
340 | &tmp.dev_type); | 340 | &tmp.dev_type); |
341 | 341 | ||
342 | if (result) { | 342 | if (result) { |
343 | pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__); | 343 | pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__); |
344 | return result; | 344 | return result; |
345 | } | 345 | } |
346 | 346 | ||
@@ -348,12 +348,12 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) | |||
348 | &tmp.dev_id); | 348 | &tmp.dev_id); |
349 | 349 | ||
350 | if (result) { | 350 | if (result) { |
351 | pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, | 351 | pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__, |
352 | __LINE__); | 352 | __LINE__); |
353 | return result; | 353 | return result; |
354 | } | 354 | } |
355 | 355 | ||
356 | pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", | 356 | pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", |
357 | __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); | 357 | __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); |
358 | 358 | ||
359 | *repo = tmp; | 359 | *repo = tmp; |
@@ -367,14 +367,14 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, | |||
367 | struct ps3_repository_device tmp; | 367 | struct ps3_repository_device tmp; |
368 | unsigned int num_dev; | 368 | unsigned int num_dev; |
369 | 369 | ||
370 | pr_debug(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, | 370 | pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, |
371 | bus_id, dev_id); | 371 | bus_id, dev_id); |
372 | 372 | ||
373 | for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { | 373 | for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { |
374 | result = ps3_repository_read_bus_id(tmp.bus_index, | 374 | result = ps3_repository_read_bus_id(tmp.bus_index, |
375 | &tmp.bus_id); | 375 | &tmp.bus_id); |
376 | if (result) { | 376 | if (result) { |
377 | pr_debug("%s:%u read_bus_id(%u) failed\n", __func__, | 377 | pr_devel("%s:%u read_bus_id(%u) failed\n", __func__, |
378 | __LINE__, tmp.bus_index); | 378 | __LINE__, tmp.bus_index); |
379 | return result; | 379 | return result; |
380 | } | 380 | } |
@@ -382,23 +382,23 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, | |||
382 | if (tmp.bus_id == bus_id) | 382 | if (tmp.bus_id == bus_id) |
383 | goto found_bus; | 383 | goto found_bus; |
384 | 384 | ||
385 | pr_debug("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, | 385 | pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, |
386 | tmp.bus_id); | 386 | tmp.bus_id); |
387 | } | 387 | } |
388 | pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); | 388 | pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__); |
389 | return result; | 389 | return result; |
390 | 390 | ||
391 | found_bus: | 391 | found_bus: |
392 | result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); | 392 | result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); |
393 | if (result) { | 393 | if (result) { |
394 | pr_debug("%s:%u read_bus_type(%u) failed\n", __func__, | 394 | pr_devel("%s:%u read_bus_type(%u) failed\n", __func__, |
395 | __LINE__, tmp.bus_index); | 395 | __LINE__, tmp.bus_index); |
396 | return result; | 396 | return result; |
397 | } | 397 | } |
398 | 398 | ||
399 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); | 399 | result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); |
400 | if (result) { | 400 | if (result) { |
401 | pr_debug("%s:%u read_bus_num_dev failed\n", __func__, | 401 | pr_devel("%s:%u read_bus_num_dev failed\n", __func__, |
402 | __LINE__); | 402 | __LINE__); |
403 | return result; | 403 | return result; |
404 | } | 404 | } |
@@ -408,7 +408,7 @@ found_bus: | |||
408 | tmp.dev_index, | 408 | tmp.dev_index, |
409 | &tmp.dev_id); | 409 | &tmp.dev_id); |
410 | if (result) { | 410 | if (result) { |
411 | pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__, | 411 | pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__, |
412 | __LINE__, tmp.bus_index, tmp.dev_index); | 412 | __LINE__, tmp.bus_index, tmp.dev_index); |
413 | return result; | 413 | return result; |
414 | } | 414 | } |
@@ -416,21 +416,21 @@ found_bus: | |||
416 | if (tmp.dev_id == dev_id) | 416 | if (tmp.dev_id == dev_id) |
417 | goto found_dev; | 417 | goto found_dev; |
418 | 418 | ||
419 | pr_debug("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, | 419 | pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, |
420 | tmp.dev_id); | 420 | tmp.dev_id); |
421 | } | 421 | } |
422 | pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__); | 422 | pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__); |
423 | return result; | 423 | return result; |
424 | 424 | ||
425 | found_dev: | 425 | found_dev: |
426 | result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, | 426 | result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, |
427 | &tmp.dev_type); | 427 | &tmp.dev_type); |
428 | if (result) { | 428 | if (result) { |
429 | pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__); | 429 | pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__); |
430 | return result; | 430 | return result; |
431 | } | 431 | } |
432 | 432 | ||
433 | pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", | 433 | pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", |
434 | __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, | 434 | __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, |
435 | tmp.dev_index, tmp.bus_id, tmp.dev_id); | 435 | tmp.dev_index, tmp.bus_id, tmp.dev_id); |
436 | *repo = tmp; | 436 | *repo = tmp; |
@@ -443,18 +443,18 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, | |||
443 | int result = 0; | 443 | int result = 0; |
444 | struct ps3_repository_device repo; | 444 | struct ps3_repository_device repo; |
445 | 445 | ||
446 | pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); | 446 | pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); |
447 | 447 | ||
448 | repo.bus_type = bus_type; | 448 | repo.bus_type = bus_type; |
449 | result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); | 449 | result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); |
450 | if (result) { | 450 | if (result) { |
451 | pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); | 451 | pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__); |
452 | return result; | 452 | return result; |
453 | } | 453 | } |
454 | 454 | ||
455 | result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); | 455 | result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); |
456 | if (result) { | 456 | if (result) { |
457 | pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, | 457 | pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, |
458 | repo.bus_index); | 458 | repo.bus_index); |
459 | return result; | 459 | return result; |
460 | } | 460 | } |
@@ -469,13 +469,13 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, | |||
469 | 469 | ||
470 | result = callback(&repo); | 470 | result = callback(&repo); |
471 | if (result) { | 471 | if (result) { |
472 | pr_debug("%s:%d: abort at callback\n", __func__, | 472 | pr_devel("%s:%d: abort at callback\n", __func__, |
473 | __LINE__); | 473 | __LINE__); |
474 | break; | 474 | break; |
475 | } | 475 | } |
476 | } | 476 | } |
477 | 477 | ||
478 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 478 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
479 | return result; | 479 | return result; |
480 | } | 480 | } |
481 | 481 | ||
@@ -489,7 +489,7 @@ int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, | |||
489 | for (i = from; i < 10; i++) { | 489 | for (i = from; i < 10; i++) { |
490 | error = ps3_repository_read_bus_type(i, &type); | 490 | error = ps3_repository_read_bus_type(i, &type); |
491 | if (error) { | 491 | if (error) { |
492 | pr_debug("%s:%d read_bus_type failed\n", | 492 | pr_devel("%s:%d read_bus_type failed\n", |
493 | __func__, __LINE__); | 493 | __func__, __LINE__); |
494 | *bus_index = UINT_MAX; | 494 | *bus_index = UINT_MAX; |
495 | return error; | 495 | return error; |
@@ -509,7 +509,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | |||
509 | int result = 0; | 509 | int result = 0; |
510 | unsigned int res_index; | 510 | unsigned int res_index; |
511 | 511 | ||
512 | pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); | 512 | pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); |
513 | 513 | ||
514 | *interrupt_id = UINT_MAX; | 514 | *interrupt_id = UINT_MAX; |
515 | 515 | ||
@@ -521,7 +521,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | |||
521 | repo->dev_index, res_index, &t, &id); | 521 | repo->dev_index, res_index, &t, &id); |
522 | 522 | ||
523 | if (result) { | 523 | if (result) { |
524 | pr_debug("%s:%d read_dev_intr failed\n", | 524 | pr_devel("%s:%d read_dev_intr failed\n", |
525 | __func__, __LINE__); | 525 | __func__, __LINE__); |
526 | return result; | 526 | return result; |
527 | } | 527 | } |
@@ -535,7 +535,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, | |||
535 | if (res_index == 10) | 535 | if (res_index == 10) |
536 | return -ENODEV; | 536 | return -ENODEV; |
537 | 537 | ||
538 | pr_debug("%s:%d: found intr_type %u at res_index %u\n", | 538 | pr_devel("%s:%d: found intr_type %u at res_index %u\n", |
539 | __func__, __LINE__, intr_type, res_index); | 539 | __func__, __LINE__, intr_type, res_index); |
540 | 540 | ||
541 | return result; | 541 | return result; |
@@ -547,7 +547,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, | |||
547 | int result = 0; | 547 | int result = 0; |
548 | unsigned int res_index; | 548 | unsigned int res_index; |
549 | 549 | ||
550 | pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); | 550 | pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); |
551 | 551 | ||
552 | *bus_addr = *len = 0; | 552 | *bus_addr = *len = 0; |
553 | 553 | ||
@@ -560,7 +560,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, | |||
560 | repo->dev_index, res_index, &t, &a, &l); | 560 | repo->dev_index, res_index, &t, &a, &l); |
561 | 561 | ||
562 | if (result) { | 562 | if (result) { |
563 | pr_debug("%s:%d read_dev_reg failed\n", | 563 | pr_devel("%s:%d read_dev_reg failed\n", |
564 | __func__, __LINE__); | 564 | __func__, __LINE__); |
565 | return result; | 565 | return result; |
566 | } | 566 | } |
@@ -575,7 +575,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, | |||
575 | if (res_index == 10) | 575 | if (res_index == 10) |
576 | return -ENODEV; | 576 | return -ENODEV; |
577 | 577 | ||
578 | pr_debug("%s:%d: found reg_type %u at res_index %u\n", | 578 | pr_devel("%s:%d: found reg_type %u at res_index %u\n", |
579 | __func__, __LINE__, reg_type, res_index); | 579 | __func__, __LINE__, reg_type, res_index); |
580 | 580 | ||
581 | return result; | 581 | return result; |
@@ -1009,7 +1009,7 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | |||
1009 | int result = 0; | 1009 | int result = 0; |
1010 | unsigned int res_index; | 1010 | unsigned int res_index; |
1011 | 1011 | ||
1012 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | 1012 | pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, |
1013 | repo->bus_index, repo->dev_index); | 1013 | repo->bus_index, repo->dev_index); |
1014 | 1014 | ||
1015 | for (res_index = 0; res_index < 10; res_index++) { | 1015 | for (res_index = 0; res_index < 10; res_index++) { |
@@ -1021,13 +1021,13 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | |||
1021 | 1021 | ||
1022 | if (result) { | 1022 | if (result) { |
1023 | if (result != LV1_NO_ENTRY) | 1023 | if (result != LV1_NO_ENTRY) |
1024 | pr_debug("%s:%d ps3_repository_read_dev_intr" | 1024 | pr_devel("%s:%d ps3_repository_read_dev_intr" |
1025 | " (%u:%u) failed\n", __func__, __LINE__, | 1025 | " (%u:%u) failed\n", __func__, __LINE__, |
1026 | repo->bus_index, repo->dev_index); | 1026 | repo->bus_index, repo->dev_index); |
1027 | break; | 1027 | break; |
1028 | } | 1028 | } |
1029 | 1029 | ||
1030 | pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", | 1030 | pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", |
1031 | __func__, __LINE__, repo->bus_index, repo->dev_index, | 1031 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
1032 | intr_type, interrupt_id); | 1032 | intr_type, interrupt_id); |
1033 | } | 1033 | } |
@@ -1042,18 +1042,18 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) | |||
1042 | 1042 | ||
1043 | if (result) { | 1043 | if (result) { |
1044 | if (result != LV1_NO_ENTRY) | 1044 | if (result != LV1_NO_ENTRY) |
1045 | pr_debug("%s:%d ps3_repository_read_dev_reg" | 1045 | pr_devel("%s:%d ps3_repository_read_dev_reg" |
1046 | " (%u:%u) failed\n", __func__, __LINE__, | 1046 | " (%u:%u) failed\n", __func__, __LINE__, |
1047 | repo->bus_index, repo->dev_index); | 1047 | repo->bus_index, repo->dev_index); |
1048 | break; | 1048 | break; |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", | 1051 | pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n", |
1052 | __func__, __LINE__, repo->bus_index, repo->dev_index, | 1052 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
1053 | reg_type, bus_addr, len); | 1053 | reg_type, bus_addr, len); |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1056 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
1057 | return result; | 1057 | return result; |
1058 | } | 1058 | } |
1059 | 1059 | ||
@@ -1063,22 +1063,22 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo) | |||
1063 | unsigned int num_regions, region_index; | 1063 | unsigned int num_regions, region_index; |
1064 | u64 port, blk_size, num_blocks; | 1064 | u64 port, blk_size, num_blocks; |
1065 | 1065 | ||
1066 | pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, | 1066 | pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, |
1067 | repo->bus_index, repo->dev_index); | 1067 | repo->bus_index, repo->dev_index); |
1068 | 1068 | ||
1069 | result = ps3_repository_read_stor_dev_info(repo->bus_index, | 1069 | result = ps3_repository_read_stor_dev_info(repo->bus_index, |
1070 | repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); | 1070 | repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); |
1071 | if (result) { | 1071 | if (result) { |
1072 | pr_debug("%s:%d ps3_repository_read_stor_dev_info" | 1072 | pr_devel("%s:%d ps3_repository_read_stor_dev_info" |
1073 | " (%u:%u) failed\n", __func__, __LINE__, | 1073 | " (%u:%u) failed\n", __func__, __LINE__, |
1074 | repo->bus_index, repo->dev_index); | 1074 | repo->bus_index, repo->dev_index); |
1075 | goto out; | 1075 | goto out; |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " | 1078 | pr_devel("%s:%d (%u:%u): port %llu, blk_size %llu, num_blocks " |
1079 | "%lu, num_regions %u\n", | 1079 | "%llu, num_regions %u\n", |
1080 | __func__, __LINE__, repo->bus_index, repo->dev_index, port, | 1080 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
1081 | blk_size, num_blocks, num_regions); | 1081 | port, blk_size, num_blocks, num_regions); |
1082 | 1082 | ||
1083 | for (region_index = 0; region_index < num_regions; region_index++) { | 1083 | for (region_index = 0; region_index < num_regions; region_index++) { |
1084 | unsigned int region_id; | 1084 | unsigned int region_id; |
@@ -1088,19 +1088,20 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo) | |||
1088 | repo->dev_index, region_index, ®ion_id, | 1088 | repo->dev_index, region_index, ®ion_id, |
1089 | ®ion_start, ®ion_size); | 1089 | ®ion_start, ®ion_size); |
1090 | if (result) { | 1090 | if (result) { |
1091 | pr_debug("%s:%d ps3_repository_read_stor_dev_region" | 1091 | pr_devel("%s:%d ps3_repository_read_stor_dev_region" |
1092 | " (%u:%u) failed\n", __func__, __LINE__, | 1092 | " (%u:%u) failed\n", __func__, __LINE__, |
1093 | repo->bus_index, repo->dev_index); | 1093 | repo->bus_index, repo->dev_index); |
1094 | break; | 1094 | break; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", | 1097 | pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", |
1098 | __func__, __LINE__, repo->bus_index, repo->dev_index, | 1098 | __func__, __LINE__, repo->bus_index, repo->dev_index, |
1099 | region_id, region_start, region_size); | 1099 | region_id, (unsigned long)region_start, |
1100 | (unsigned long)region_size); | ||
1100 | } | 1101 | } |
1101 | 1102 | ||
1102 | out: | 1103 | out: |
1103 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1104 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
1104 | return result; | 1105 | return result; |
1105 | } | 1106 | } |
1106 | 1107 | ||
@@ -1109,7 +1110,7 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
1109 | { | 1110 | { |
1110 | int result = 0; | 1111 | int result = 0; |
1111 | 1112 | ||
1112 | pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); | 1113 | pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); |
1113 | 1114 | ||
1114 | for (repo->dev_index = 0; repo->dev_index < num_dev; | 1115 | for (repo->dev_index = 0; repo->dev_index < num_dev; |
1115 | repo->dev_index++) { | 1116 | repo->dev_index++) { |
@@ -1118,7 +1119,7 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
1118 | repo->dev_index, &repo->dev_type); | 1119 | repo->dev_index, &repo->dev_type); |
1119 | 1120 | ||
1120 | if (result) { | 1121 | if (result) { |
1121 | pr_debug("%s:%d ps3_repository_read_dev_type" | 1122 | pr_devel("%s:%d ps3_repository_read_dev_type" |
1122 | " (%u:%u) failed\n", __func__, __LINE__, | 1123 | " (%u:%u) failed\n", __func__, __LINE__, |
1123 | repo->bus_index, repo->dev_index); | 1124 | repo->bus_index, repo->dev_index); |
1124 | break; | 1125 | break; |
@@ -1128,15 +1129,15 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
1128 | repo->dev_index, &repo->dev_id); | 1129 | repo->dev_index, &repo->dev_id); |
1129 | 1130 | ||
1130 | if (result) { | 1131 | if (result) { |
1131 | pr_debug("%s:%d ps3_repository_read_dev_id" | 1132 | pr_devel("%s:%d ps3_repository_read_dev_id" |
1132 | " (%u:%u) failed\n", __func__, __LINE__, | 1133 | " (%u:%u) failed\n", __func__, __LINE__, |
1133 | repo->bus_index, repo->dev_index); | 1134 | repo->bus_index, repo->dev_index); |
1134 | continue; | 1135 | continue; |
1135 | } | 1136 | } |
1136 | 1137 | ||
1137 | pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, | 1138 | pr_devel("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, |
1138 | __LINE__, repo->bus_index, repo->dev_index, | 1139 | __LINE__, repo->bus_index, repo->dev_index, |
1139 | repo->dev_type, repo->dev_id); | 1140 | repo->dev_type, (unsigned long)repo->dev_id); |
1140 | 1141 | ||
1141 | ps3_repository_dump_resource_info(repo); | 1142 | ps3_repository_dump_resource_info(repo); |
1142 | 1143 | ||
@@ -1144,7 +1145,7 @@ static int dump_device_info(struct ps3_repository_device *repo, | |||
1144 | dump_stor_dev_info(repo); | 1145 | dump_stor_dev_info(repo); |
1145 | } | 1146 | } |
1146 | 1147 | ||
1147 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1148 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
1148 | return result; | 1149 | return result; |
1149 | } | 1150 | } |
1150 | 1151 | ||
@@ -1153,7 +1154,7 @@ int ps3_repository_dump_bus_info(void) | |||
1153 | int result = 0; | 1154 | int result = 0; |
1154 | struct ps3_repository_device repo; | 1155 | struct ps3_repository_device repo; |
1155 | 1156 | ||
1156 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | 1157 | pr_devel(" -> %s:%d\n", __func__, __LINE__); |
1157 | 1158 | ||
1158 | memset(&repo, 0, sizeof(repo)); | 1159 | memset(&repo, 0, sizeof(repo)); |
1159 | 1160 | ||
@@ -1164,7 +1165,7 @@ int ps3_repository_dump_bus_info(void) | |||
1164 | &repo.bus_type); | 1165 | &repo.bus_type); |
1165 | 1166 | ||
1166 | if (result) { | 1167 | if (result) { |
1167 | pr_debug("%s:%d read_bus_type(%u) failed\n", | 1168 | pr_devel("%s:%d read_bus_type(%u) failed\n", |
1168 | __func__, __LINE__, repo.bus_index); | 1169 | __func__, __LINE__, repo.bus_index); |
1169 | break; | 1170 | break; |
1170 | } | 1171 | } |
@@ -1173,32 +1174,32 @@ int ps3_repository_dump_bus_info(void) | |||
1173 | &repo.bus_id); | 1174 | &repo.bus_id); |
1174 | 1175 | ||
1175 | if (result) { | 1176 | if (result) { |
1176 | pr_debug("%s:%d read_bus_id(%u) failed\n", | 1177 | pr_devel("%s:%d read_bus_id(%u) failed\n", |
1177 | __func__, __LINE__, repo.bus_index); | 1178 | __func__, __LINE__, repo.bus_index); |
1178 | continue; | 1179 | continue; |
1179 | } | 1180 | } |
1180 | 1181 | ||
1181 | if (repo.bus_index != repo.bus_id) | 1182 | if (repo.bus_index != repo.bus_id) |
1182 | pr_debug("%s:%d bus_index != bus_id\n", | 1183 | pr_devel("%s:%d bus_index != bus_id\n", |
1183 | __func__, __LINE__); | 1184 | __func__, __LINE__); |
1184 | 1185 | ||
1185 | result = ps3_repository_read_bus_num_dev(repo.bus_index, | 1186 | result = ps3_repository_read_bus_num_dev(repo.bus_index, |
1186 | &num_dev); | 1187 | &num_dev); |
1187 | 1188 | ||
1188 | if (result) { | 1189 | if (result) { |
1189 | pr_debug("%s:%d read_bus_num_dev(%u) failed\n", | 1190 | pr_devel("%s:%d read_bus_num_dev(%u) failed\n", |
1190 | __func__, __LINE__, repo.bus_index); | 1191 | __func__, __LINE__, repo.bus_index); |
1191 | continue; | 1192 | continue; |
1192 | } | 1193 | } |
1193 | 1194 | ||
1194 | pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", | 1195 | pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", |
1195 | __func__, __LINE__, repo.bus_index, repo.bus_type, | 1196 | __func__, __LINE__, repo.bus_index, repo.bus_type, |
1196 | repo.bus_id, num_dev); | 1197 | (unsigned long)repo.bus_id, num_dev); |
1197 | 1198 | ||
1198 | dump_device_info(&repo, num_dev); | 1199 | dump_device_info(&repo, num_dev); |
1199 | } | 1200 | } |
1200 | 1201 | ||
1201 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 1202 | pr_devel(" <- %s:%d\n", __func__, __LINE__); |
1202 | return result; | 1203 | return result; |
1203 | } | 1204 | } |
1204 | 1205 | ||
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index e8ec1b2bfffd..2d664c5a83b0 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c | |||
@@ -193,10 +193,12 @@ static int ps3_set_dabr(unsigned long dabr) | |||
193 | 193 | ||
194 | static void __init ps3_setup_arch(void) | 194 | static void __init ps3_setup_arch(void) |
195 | { | 195 | { |
196 | u64 tmp; | ||
196 | 197 | ||
197 | DBG(" -> %s:%d\n", __func__, __LINE__); | 198 | DBG(" -> %s:%d\n", __func__, __LINE__); |
198 | 199 | ||
199 | lv1_get_version_info(&ps3_firmware_version.raw); | 200 | lv1_get_version_info(&ps3_firmware_version.raw, &tmp); |
201 | |||
200 | printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", | 202 | printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", |
201 | ps3_firmware_version.major, ps3_firmware_version.minor, | 203 | ps3_firmware_version.major, ps3_firmware_version.minor, |
202 | ps3_firmware_version.rev); | 204 | ps3_firmware_version.rev); |
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index efc1cd8c034a..4b35166229fe 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c | |||
@@ -57,7 +57,7 @@ static void ps3_smp_message_pass(int cpu, int msg) | |||
57 | " (%d)\n", __func__, __LINE__, cpu, msg, result); | 57 | " (%d)\n", __func__, __LINE__, cpu, msg, result); |
58 | } | 58 | } |
59 | 59 | ||
60 | static int ps3_smp_probe(void) | 60 | static int __init ps3_smp_probe(void) |
61 | { | 61 | { |
62 | int cpu; | 62 | int cpu; |
63 | 63 | ||
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 451fad1c92a8..e17fa1432d80 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c | |||
@@ -154,7 +154,7 @@ static unsigned long get_vas_id(void) | |||
154 | u64 id; | 154 | u64 id; |
155 | 155 | ||
156 | lv1_get_logical_ppe_id(&id); | 156 | lv1_get_logical_ppe_id(&id); |
157 | lv1_get_virtual_address_space_id_of_ppe(id, &id); | 157 | lv1_get_virtual_address_space_id_of_ppe(&id); |
158 | 158 | ||
159 | return id; | 159 | return id; |
160 | } | 160 | } |
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index c81f6bb9c10f..ae7b6d41fed3 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
@@ -120,3 +120,12 @@ config DTL | |||
120 | which are accessible through a debugfs file. | 120 | which are accessible through a debugfs file. |
121 | 121 | ||
122 | Say N if you are unsure. | 122 | Say N if you are unsure. |
123 | |||
124 | config PSERIES_IDLE | ||
125 | tristate "Cpuidle driver for pSeries platforms" | ||
126 | depends on CPU_IDLE | ||
127 | depends on PPC_PSERIES | ||
128 | default y | ||
129 | help | ||
130 | Select this option to enable processor idle state management | ||
131 | through cpuidle subsystem. | ||
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 3556e402cbf5..236db46b4078 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o | |||
22 | obj-$(CONFIG_CMM) += cmm.o | 22 | obj-$(CONFIG_CMM) += cmm.o |
23 | obj-$(CONFIG_DTL) += dtl.o | 23 | obj-$(CONFIG_DTL) += dtl.o |
24 | obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o | 24 | obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o |
25 | obj-$(CONFIG_PSERIES_IDLE) += processor_idle.o | ||
25 | 26 | ||
26 | ifeq ($(CONFIG_PPC_PSERIES),y) | 27 | ifeq ($(CONFIG_PPC_PSERIES),y) |
27 | obj-$(CONFIG_SUSPEND) += suspend.o | 28 | obj-$(CONFIG_SUSPEND) += suspend.o |
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index f106662f4381..c9311cfdfcac 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c | |||
@@ -109,7 +109,7 @@ static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long | |||
109 | if (opcode > MAX_HCALL_OPCODE) | 109 | if (opcode > MAX_HCALL_OPCODE) |
110 | return; | 110 | return; |
111 | 111 | ||
112 | h = &get_cpu_var(hcall_stats)[opcode / 4]; | 112 | h = &__get_cpu_var(hcall_stats)[opcode / 4]; |
113 | h->tb_start = mftb(); | 113 | h->tb_start = mftb(); |
114 | h->purr_start = mfspr(SPRN_PURR); | 114 | h->purr_start = mfspr(SPRN_PURR); |
115 | } | 115 | } |
@@ -126,8 +126,6 @@ static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long | |||
126 | h->num_calls++; | 126 | h->num_calls++; |
127 | h->tb_total += mftb() - h->tb_start; | 127 | h->tb_total += mftb() - h->tb_start; |
128 | h->purr_total += mfspr(SPRN_PURR) - h->purr_start; | 128 | h->purr_total += mfspr(SPRN_PURR) - h->purr_start; |
129 | |||
130 | put_cpu_var(hcall_stats); | ||
131 | } | 129 | } |
132 | 130 | ||
133 | static int __init hcall_inst_init(void) | 131 | static int __init hcall_inst_init(void) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index b719d9709730..c442f2b1980f 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -52,13 +52,42 @@ | |||
52 | #include "plpar_wrappers.h" | 52 | #include "plpar_wrappers.h" |
53 | 53 | ||
54 | 54 | ||
55 | static void tce_invalidate_pSeries_sw(struct iommu_table *tbl, | ||
56 | u64 *startp, u64 *endp) | ||
57 | { | ||
58 | u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index; | ||
59 | unsigned long start, end, inc; | ||
60 | |||
61 | start = __pa(startp); | ||
62 | end = __pa(endp); | ||
63 | inc = L1_CACHE_BYTES; /* invalidate a cacheline of TCEs at a time */ | ||
64 | |||
65 | /* If this is non-zero, change the format. We shift the | ||
66 | * address and or in the magic from the device tree. */ | ||
67 | if (tbl->it_busno) { | ||
68 | start <<= 12; | ||
69 | end <<= 12; | ||
70 | inc <<= 12; | ||
71 | start |= tbl->it_busno; | ||
72 | end |= tbl->it_busno; | ||
73 | } | ||
74 | |||
75 | end |= inc - 1; /* round up end to be different than start */ | ||
76 | |||
77 | mb(); /* Make sure TCEs in memory are written */ | ||
78 | while (start <= end) { | ||
79 | out_be64(invalidate, start); | ||
80 | start += inc; | ||
81 | } | ||
82 | } | ||
83 | |||
55 | static int tce_build_pSeries(struct iommu_table *tbl, long index, | 84 | static int tce_build_pSeries(struct iommu_table *tbl, long index, |
56 | long npages, unsigned long uaddr, | 85 | long npages, unsigned long uaddr, |
57 | enum dma_data_direction direction, | 86 | enum dma_data_direction direction, |
58 | struct dma_attrs *attrs) | 87 | struct dma_attrs *attrs) |
59 | { | 88 | { |
60 | u64 proto_tce; | 89 | u64 proto_tce; |
61 | u64 *tcep; | 90 | u64 *tcep, *tces; |
62 | u64 rpn; | 91 | u64 rpn; |
63 | 92 | ||
64 | proto_tce = TCE_PCI_READ; // Read allowed | 93 | proto_tce = TCE_PCI_READ; // Read allowed |
@@ -66,7 +95,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, | |||
66 | if (direction != DMA_TO_DEVICE) | 95 | if (direction != DMA_TO_DEVICE) |
67 | proto_tce |= TCE_PCI_WRITE; | 96 | proto_tce |= TCE_PCI_WRITE; |
68 | 97 | ||
69 | tcep = ((u64 *)tbl->it_base) + index; | 98 | tces = tcep = ((u64 *)tbl->it_base) + index; |
70 | 99 | ||
71 | while (npages--) { | 100 | while (npages--) { |
72 | /* can't move this out since we might cross MEMBLOCK boundary */ | 101 | /* can't move this out since we might cross MEMBLOCK boundary */ |
@@ -76,18 +105,24 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, | |||
76 | uaddr += TCE_PAGE_SIZE; | 105 | uaddr += TCE_PAGE_SIZE; |
77 | tcep++; | 106 | tcep++; |
78 | } | 107 | } |
108 | |||
109 | if (tbl->it_type == TCE_PCI_SWINV_CREATE) | ||
110 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); | ||
79 | return 0; | 111 | return 0; |
80 | } | 112 | } |
81 | 113 | ||
82 | 114 | ||
83 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | 115 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) |
84 | { | 116 | { |
85 | u64 *tcep; | 117 | u64 *tcep, *tces; |
86 | 118 | ||
87 | tcep = ((u64 *)tbl->it_base) + index; | 119 | tces = tcep = ((u64 *)tbl->it_base) + index; |
88 | 120 | ||
89 | while (npages--) | 121 | while (npages--) |
90 | *(tcep++) = 0; | 122 | *(tcep++) = 0; |
123 | |||
124 | if (tbl->it_type == TCE_PCI_SWINV_FREE) | ||
125 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); | ||
91 | } | 126 | } |
92 | 127 | ||
93 | static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) | 128 | static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) |
@@ -425,7 +460,7 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
425 | struct iommu_table *tbl) | 460 | struct iommu_table *tbl) |
426 | { | 461 | { |
427 | struct device_node *node; | 462 | struct device_node *node; |
428 | const unsigned long *basep; | 463 | const unsigned long *basep, *sw_inval; |
429 | const u32 *sizep; | 464 | const u32 *sizep; |
430 | 465 | ||
431 | node = phb->dn; | 466 | node = phb->dn; |
@@ -462,6 +497,22 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
462 | tbl->it_index = 0; | 497 | tbl->it_index = 0; |
463 | tbl->it_blocksize = 16; | 498 | tbl->it_blocksize = 16; |
464 | tbl->it_type = TCE_PCI; | 499 | tbl->it_type = TCE_PCI; |
500 | |||
501 | sw_inval = of_get_property(node, "linux,tce-sw-invalidate-info", NULL); | ||
502 | if (sw_inval) { | ||
503 | /* | ||
504 | * This property contains information on how to | ||
505 | * invalidate the TCE entry. The first property is | ||
506 | * the base MMIO address used to invalidate entries. | ||
507 | * The second property tells us the format of the TCE | ||
508 | * invalidate (whether it needs to be shifted) and | ||
509 | * some magic routing info to add to our invalidate | ||
510 | * command. | ||
511 | */ | ||
512 | tbl->it_index = (unsigned long) ioremap(sw_inval[0], 8); | ||
513 | tbl->it_busno = sw_inval[1]; /* overload this with magic */ | ||
514 | tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE; | ||
515 | } | ||
465 | } | 516 | } |
466 | 517 | ||
467 | /* | 518 | /* |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 52d429be6c76..948e0e3b3547 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -554,6 +554,7 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args) | |||
554 | goto out; | 554 | goto out; |
555 | 555 | ||
556 | (*depth)++; | 556 | (*depth)++; |
557 | preempt_disable(); | ||
557 | trace_hcall_entry(opcode, args); | 558 | trace_hcall_entry(opcode, args); |
558 | if (opcode == H_CEDE) | 559 | if (opcode == H_CEDE) |
559 | rcu_idle_enter(); | 560 | rcu_idle_enter(); |
@@ -580,6 +581,7 @@ void __trace_hcall_exit(long opcode, unsigned long retval, | |||
580 | if (opcode == H_CEDE) | 581 | if (opcode == H_CEDE) |
581 | rcu_idle_exit(); | 582 | rcu_idle_exit(); |
582 | trace_hcall_exit(opcode, retval, retbuf); | 583 | trace_hcall_exit(opcode, retval, retbuf); |
584 | preempt_enable(); | ||
583 | (*depth)--; | 585 | (*depth)--; |
584 | 586 | ||
585 | out: | 587 | out: |
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index a76b22844d18..330a57b7c17c 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
@@ -625,6 +625,8 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
625 | { | 625 | { |
626 | static unsigned int oops_count = 0; | 626 | static unsigned int oops_count = 0; |
627 | static bool panicking = false; | 627 | static bool panicking = false; |
628 | static DEFINE_SPINLOCK(lock); | ||
629 | unsigned long flags; | ||
628 | size_t text_len; | 630 | size_t text_len; |
629 | unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; | 631 | unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; |
630 | int rc = -1; | 632 | int rc = -1; |
@@ -655,6 +657,9 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
655 | if (clobbering_unread_rtas_event()) | 657 | if (clobbering_unread_rtas_event()) |
656 | return; | 658 | return; |
657 | 659 | ||
660 | if (!spin_trylock_irqsave(&lock, flags)) | ||
661 | return; | ||
662 | |||
658 | if (big_oops_buf) { | 663 | if (big_oops_buf) { |
659 | text_len = capture_last_msgs(old_msgs, old_len, | 664 | text_len = capture_last_msgs(old_msgs, old_len, |
660 | new_msgs, new_len, big_oops_buf, big_oops_buf_sz); | 665 | new_msgs, new_len, big_oops_buf, big_oops_buf_sz); |
@@ -670,4 +675,6 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
670 | 675 | ||
671 | (void) nvram_write_os_partition(&oops_log_partition, oops_buf, | 676 | (void) nvram_write_os_partition(&oops_log_partition, oops_buf, |
672 | (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count); | 677 | (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count); |
678 | |||
679 | spin_unlock_irqrestore(&lock, flags); | ||
673 | } | 680 | } |
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c new file mode 100644 index 000000000000..085fd3f45ad2 --- /dev/null +++ b/arch/powerpc/platforms/pseries/processor_idle.c | |||
@@ -0,0 +1,329 @@ | |||
1 | /* | ||
2 | * processor_idle - idle state cpuidle driver. | ||
3 | * Adapted from drivers/idle/intel_idle.c and | ||
4 | * drivers/acpi/processor_idle.c | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/moduleparam.h> | ||
12 | #include <linux/cpuidle.h> | ||
13 | #include <linux/cpu.h> | ||
14 | |||
15 | #include <asm/paca.h> | ||
16 | #include <asm/reg.h> | ||
17 | #include <asm/system.h> | ||
18 | #include <asm/machdep.h> | ||
19 | #include <asm/firmware.h> | ||
20 | |||
21 | #include "plpar_wrappers.h" | ||
22 | #include "pseries.h" | ||
23 | |||
24 | struct cpuidle_driver pseries_idle_driver = { | ||
25 | .name = "pseries_idle", | ||
26 | .owner = THIS_MODULE, | ||
27 | }; | ||
28 | |||
29 | #define MAX_IDLE_STATE_COUNT 2 | ||
30 | |||
31 | static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; | ||
32 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | ||
33 | static struct cpuidle_state *cpuidle_state_table; | ||
34 | |||
35 | void update_smt_snooze_delay(int snooze) | ||
36 | { | ||
37 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
38 | if (drv) | ||
39 | drv->states[0].target_residency = snooze; | ||
40 | } | ||
41 | |||
42 | static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) | ||
43 | { | ||
44 | |||
45 | *kt_before = ktime_get_real(); | ||
46 | *in_purr = mfspr(SPRN_PURR); | ||
47 | /* | ||
48 | * Indicate to the HV that we are idle. Now would be | ||
49 | * a good time to find other work to dispatch. | ||
50 | */ | ||
51 | get_lppaca()->idle = 1; | ||
52 | } | ||
53 | |||
54 | static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) | ||
55 | { | ||
56 | get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; | ||
57 | get_lppaca()->idle = 0; | ||
58 | |||
59 | return ktime_to_us(ktime_sub(ktime_get_real(), kt_before)); | ||
60 | } | ||
61 | |||
62 | static int snooze_loop(struct cpuidle_device *dev, | ||
63 | struct cpuidle_driver *drv, | ||
64 | int index) | ||
65 | { | ||
66 | unsigned long in_purr; | ||
67 | ktime_t kt_before; | ||
68 | unsigned long start_snooze; | ||
69 | long snooze = drv->states[0].target_residency; | ||
70 | |||
71 | idle_loop_prolog(&in_purr, &kt_before); | ||
72 | |||
73 | if (snooze) { | ||
74 | start_snooze = get_tb() + snooze * tb_ticks_per_usec; | ||
75 | local_irq_enable(); | ||
76 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
77 | |||
78 | while ((snooze < 0) || (get_tb() < start_snooze)) { | ||
79 | if (need_resched() || cpu_is_offline(dev->cpu)) | ||
80 | goto out; | ||
81 | ppc64_runlatch_off(); | ||
82 | HMT_low(); | ||
83 | HMT_very_low(); | ||
84 | } | ||
85 | |||
86 | HMT_medium(); | ||
87 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
88 | smp_mb(); | ||
89 | local_irq_disable(); | ||
90 | } | ||
91 | |||
92 | out: | ||
93 | HMT_medium(); | ||
94 | dev->last_residency = | ||
95 | (int)idle_loop_epilog(in_purr, kt_before); | ||
96 | return index; | ||
97 | } | ||
98 | |||
99 | static int dedicated_cede_loop(struct cpuidle_device *dev, | ||
100 | struct cpuidle_driver *drv, | ||
101 | int index) | ||
102 | { | ||
103 | unsigned long in_purr; | ||
104 | ktime_t kt_before; | ||
105 | |||
106 | idle_loop_prolog(&in_purr, &kt_before); | ||
107 | get_lppaca()->donate_dedicated_cpu = 1; | ||
108 | |||
109 | ppc64_runlatch_off(); | ||
110 | HMT_medium(); | ||
111 | cede_processor(); | ||
112 | |||
113 | get_lppaca()->donate_dedicated_cpu = 0; | ||
114 | dev->last_residency = | ||
115 | (int)idle_loop_epilog(in_purr, kt_before); | ||
116 | return index; | ||
117 | } | ||
118 | |||
119 | static int shared_cede_loop(struct cpuidle_device *dev, | ||
120 | struct cpuidle_driver *drv, | ||
121 | int index) | ||
122 | { | ||
123 | unsigned long in_purr; | ||
124 | ktime_t kt_before; | ||
125 | |||
126 | idle_loop_prolog(&in_purr, &kt_before); | ||
127 | |||
128 | /* | ||
129 | * Yield the processor to the hypervisor. We return if | ||
130 | * an external interrupt occurs (which are driven prior | ||
131 | * to returning here) or if a prod occurs from another | ||
132 | * processor. When returning here, external interrupts | ||
133 | * are enabled. | ||
134 | */ | ||
135 | cede_processor(); | ||
136 | |||
137 | dev->last_residency = | ||
138 | (int)idle_loop_epilog(in_purr, kt_before); | ||
139 | return index; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * States for dedicated partition case. | ||
144 | */ | ||
145 | static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = { | ||
146 | { /* Snooze */ | ||
147 | .name = "snooze", | ||
148 | .desc = "snooze", | ||
149 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
150 | .exit_latency = 0, | ||
151 | .target_residency = 0, | ||
152 | .enter = &snooze_loop }, | ||
153 | { /* CEDE */ | ||
154 | .name = "CEDE", | ||
155 | .desc = "CEDE", | ||
156 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
157 | .exit_latency = 1, | ||
158 | .target_residency = 10, | ||
159 | .enter = &dedicated_cede_loop }, | ||
160 | }; | ||
161 | |||
162 | /* | ||
163 | * States for shared partition case. | ||
164 | */ | ||
165 | static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { | ||
166 | { /* Shared Cede */ | ||
167 | .name = "Shared Cede", | ||
168 | .desc = "Shared Cede", | ||
169 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
170 | .exit_latency = 0, | ||
171 | .target_residency = 0, | ||
172 | .enter = &shared_cede_loop }, | ||
173 | }; | ||
174 | |||
175 | int pseries_notify_cpuidle_add_cpu(int cpu) | ||
176 | { | ||
177 | struct cpuidle_device *dev = | ||
178 | per_cpu_ptr(pseries_cpuidle_devices, cpu); | ||
179 | if (dev && cpuidle_get_driver()) { | ||
180 | cpuidle_disable_device(dev); | ||
181 | cpuidle_enable_device(dev); | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * pseries_cpuidle_driver_init() | ||
188 | */ | ||
189 | static int pseries_cpuidle_driver_init(void) | ||
190 | { | ||
191 | int idle_state; | ||
192 | struct cpuidle_driver *drv = &pseries_idle_driver; | ||
193 | |||
194 | drv->state_count = 0; | ||
195 | |||
196 | for (idle_state = 0; idle_state < MAX_IDLE_STATE_COUNT; ++idle_state) { | ||
197 | |||
198 | if (idle_state > max_idle_state) | ||
199 | break; | ||
200 | |||
201 | /* is the state not enabled? */ | ||
202 | if (cpuidle_state_table[idle_state].enter == NULL) | ||
203 | continue; | ||
204 | |||
205 | drv->states[drv->state_count] = /* structure copy */ | ||
206 | cpuidle_state_table[idle_state]; | ||
207 | |||
208 | if (cpuidle_state_table == dedicated_states) | ||
209 | drv->states[drv->state_count].target_residency = | ||
210 | __get_cpu_var(smt_snooze_delay); | ||
211 | |||
212 | drv->state_count += 1; | ||
213 | } | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | /* pseries_idle_devices_uninit(void) | ||
219 | * unregister cpuidle devices and de-allocate memory | ||
220 | */ | ||
221 | static void pseries_idle_devices_uninit(void) | ||
222 | { | ||
223 | int i; | ||
224 | struct cpuidle_device *dev; | ||
225 | |||
226 | for_each_possible_cpu(i) { | ||
227 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
228 | cpuidle_unregister_device(dev); | ||
229 | } | ||
230 | |||
231 | free_percpu(pseries_cpuidle_devices); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* pseries_idle_devices_init() | ||
236 | * allocate, initialize and register cpuidle device | ||
237 | */ | ||
238 | static int pseries_idle_devices_init(void) | ||
239 | { | ||
240 | int i; | ||
241 | struct cpuidle_driver *drv = &pseries_idle_driver; | ||
242 | struct cpuidle_device *dev; | ||
243 | |||
244 | pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device); | ||
245 | if (pseries_cpuidle_devices == NULL) | ||
246 | return -ENOMEM; | ||
247 | |||
248 | for_each_possible_cpu(i) { | ||
249 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
250 | dev->state_count = drv->state_count; | ||
251 | dev->cpu = i; | ||
252 | if (cpuidle_register_device(dev)) { | ||
253 | printk(KERN_DEBUG \ | ||
254 | "cpuidle_register_device %d failed!\n", i); | ||
255 | return -EIO; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * pseries_idle_probe() | ||
264 | * Choose state table for shared versus dedicated partition | ||
265 | */ | ||
266 | static int pseries_idle_probe(void) | ||
267 | { | ||
268 | |||
269 | if (!firmware_has_feature(FW_FEATURE_SPLPAR)) | ||
270 | return -ENODEV; | ||
271 | |||
272 | if (cpuidle_disable != IDLE_NO_OVERRIDE) | ||
273 | return -ENODEV; | ||
274 | |||
275 | if (max_idle_state == 0) { | ||
276 | printk(KERN_DEBUG "pseries processor idle disabled.\n"); | ||
277 | return -EPERM; | ||
278 | } | ||
279 | |||
280 | if (get_lppaca()->shared_proc) | ||
281 | cpuidle_state_table = shared_states; | ||
282 | else | ||
283 | cpuidle_state_table = dedicated_states; | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int __init pseries_processor_idle_init(void) | ||
289 | { | ||
290 | int retval; | ||
291 | |||
292 | retval = pseries_idle_probe(); | ||
293 | if (retval) | ||
294 | return retval; | ||
295 | |||
296 | pseries_cpuidle_driver_init(); | ||
297 | retval = cpuidle_register_driver(&pseries_idle_driver); | ||
298 | if (retval) { | ||
299 | printk(KERN_DEBUG "Registration of pseries driver failed.\n"); | ||
300 | return retval; | ||
301 | } | ||
302 | |||
303 | retval = pseries_idle_devices_init(); | ||
304 | if (retval) { | ||
305 | pseries_idle_devices_uninit(); | ||
306 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
307 | return retval; | ||
308 | } | ||
309 | |||
310 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static void __exit pseries_processor_idle_exit(void) | ||
316 | { | ||
317 | |||
318 | pseries_idle_devices_uninit(); | ||
319 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
320 | |||
321 | return; | ||
322 | } | ||
323 | |||
324 | module_init(pseries_processor_idle_init); | ||
325 | module_exit(pseries_processor_idle_exit); | ||
326 | |||
327 | MODULE_AUTHOR("Deepthi Dharwar <deepthi@linux.vnet.ibm.com>"); | ||
328 | MODULE_DESCRIPTION("Cpuidle driver for POWER"); | ||
329 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 24c7162f11d9..9a3dda07566f 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h | |||
@@ -57,4 +57,7 @@ extern struct device_node *dlpar_configure_connector(u32); | |||
57 | extern int dlpar_attach_node(struct device_node *); | 57 | extern int dlpar_attach_node(struct device_node *); |
58 | extern int dlpar_detach_node(struct device_node *); | 58 | extern int dlpar_detach_node(struct device_node *); |
59 | 59 | ||
60 | /* Snooze Delay, pseries_idle */ | ||
61 | DECLARE_PER_CPU(long, smt_snooze_delay); | ||
62 | |||
60 | #endif /* _PSERIES_PSERIES_H */ | 63 | #endif /* _PSERIES_PSERIES_H */ |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index c3408ca8855e..f79f1278dfca 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
40 | #include <linux/seq_file.h> | 40 | #include <linux/seq_file.h> |
41 | #include <linux/root_dev.h> | 41 | #include <linux/root_dev.h> |
42 | #include <linux/cpuidle.h> | ||
42 | 43 | ||
43 | #include <asm/mmu.h> | 44 | #include <asm/mmu.h> |
44 | #include <asm/processor.h> | 45 | #include <asm/processor.h> |
@@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize); | |||
74 | 75 | ||
75 | int fwnmi_active; /* TRUE if an FWNMI handler is present */ | 76 | int fwnmi_active; /* TRUE if an FWNMI handler is present */ |
76 | 77 | ||
77 | static void pseries_shared_idle_sleep(void); | ||
78 | static void pseries_dedicated_idle_sleep(void); | ||
79 | |||
80 | static struct device_node *pSeries_mpic_node; | 78 | static struct device_node *pSeries_mpic_node; |
81 | 79 | ||
82 | static void pSeries_show_cpuinfo(struct seq_file *m) | 80 | static void pSeries_show_cpuinfo(struct seq_file *m) |
@@ -192,8 +190,7 @@ static void __init pseries_mpic_init_IRQ(void) | |||
192 | BUG_ON(openpic_addr == 0); | 190 | BUG_ON(openpic_addr == 0); |
193 | 191 | ||
194 | /* Setup the openpic driver */ | 192 | /* Setup the openpic driver */ |
195 | mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, | 193 | mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, 0, |
196 | MPIC_PRIMARY, | ||
197 | 16, 250, /* isu size, irq count */ | 194 | 16, 250, /* isu size, irq count */ |
198 | " MPIC "); | 195 | " MPIC "); |
199 | BUG_ON(mpic == NULL); | 196 | BUG_ON(mpic == NULL); |
@@ -352,8 +349,25 @@ static int alloc_dispatch_log_kmem_cache(void) | |||
352 | } | 349 | } |
353 | early_initcall(alloc_dispatch_log_kmem_cache); | 350 | early_initcall(alloc_dispatch_log_kmem_cache); |
354 | 351 | ||
352 | static void pSeries_idle(void) | ||
353 | { | ||
354 | /* This would call on the cpuidle framework, and the back-end pseries | ||
355 | * driver to go to idle states | ||
356 | */ | ||
357 | if (cpuidle_idle_call()) { | ||
358 | /* On error, execute default handler | ||
359 | * to go into low thread priority and possibly | ||
360 | * low power mode. | ||
361 | */ | ||
362 | HMT_low(); | ||
363 | HMT_very_low(); | ||
364 | } | ||
365 | } | ||
366 | |||
355 | static void __init pSeries_setup_arch(void) | 367 | static void __init pSeries_setup_arch(void) |
356 | { | 368 | { |
369 | panic_timeout = 10; | ||
370 | |||
357 | /* Discover PIC type and setup ppc_md accordingly */ | 371 | /* Discover PIC type and setup ppc_md accordingly */ |
358 | pseries_discover_pic(); | 372 | pseries_discover_pic(); |
359 | 373 | ||
@@ -374,18 +388,9 @@ static void __init pSeries_setup_arch(void) | |||
374 | 388 | ||
375 | pSeries_nvram_init(); | 389 | pSeries_nvram_init(); |
376 | 390 | ||
377 | /* Choose an idle loop */ | ||
378 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 391 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
379 | vpa_init(boot_cpuid); | 392 | vpa_init(boot_cpuid); |
380 | if (get_lppaca()->shared_proc) { | 393 | ppc_md.power_save = pSeries_idle; |
381 | printk(KERN_DEBUG "Using shared processor idle loop\n"); | ||
382 | ppc_md.power_save = pseries_shared_idle_sleep; | ||
383 | } else { | ||
384 | printk(KERN_DEBUG "Using dedicated idle loop\n"); | ||
385 | ppc_md.power_save = pseries_dedicated_idle_sleep; | ||
386 | } | ||
387 | } else { | ||
388 | printk(KERN_DEBUG "Using default idle loop\n"); | ||
389 | } | 394 | } |
390 | 395 | ||
391 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 396 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
@@ -586,80 +591,6 @@ static int __init pSeries_probe(void) | |||
586 | return 1; | 591 | return 1; |
587 | } | 592 | } |
588 | 593 | ||
589 | |||
590 | DECLARE_PER_CPU(long, smt_snooze_delay); | ||
591 | |||
592 | static void pseries_dedicated_idle_sleep(void) | ||
593 | { | ||
594 | unsigned int cpu = smp_processor_id(); | ||
595 | unsigned long start_snooze; | ||
596 | unsigned long in_purr, out_purr; | ||
597 | long snooze = __get_cpu_var(smt_snooze_delay); | ||
598 | |||
599 | /* | ||
600 | * Indicate to the HV that we are idle. Now would be | ||
601 | * a good time to find other work to dispatch. | ||
602 | */ | ||
603 | get_lppaca()->idle = 1; | ||
604 | get_lppaca()->donate_dedicated_cpu = 1; | ||
605 | in_purr = mfspr(SPRN_PURR); | ||
606 | |||
607 | /* | ||
608 | * We come in with interrupts disabled, and need_resched() | ||
609 | * has been checked recently. If we should poll for a little | ||
610 | * while, do so. | ||
611 | */ | ||
612 | if (snooze) { | ||
613 | start_snooze = get_tb() + snooze * tb_ticks_per_usec; | ||
614 | local_irq_enable(); | ||
615 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
616 | |||
617 | while ((snooze < 0) || (get_tb() < start_snooze)) { | ||
618 | if (need_resched() || cpu_is_offline(cpu)) | ||
619 | goto out; | ||
620 | ppc64_runlatch_off(); | ||
621 | HMT_low(); | ||
622 | HMT_very_low(); | ||
623 | } | ||
624 | |||
625 | HMT_medium(); | ||
626 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
627 | smp_mb(); | ||
628 | local_irq_disable(); | ||
629 | if (need_resched() || cpu_is_offline(cpu)) | ||
630 | goto out; | ||
631 | } | ||
632 | |||
633 | cede_processor(); | ||
634 | |||
635 | out: | ||
636 | HMT_medium(); | ||
637 | out_purr = mfspr(SPRN_PURR); | ||
638 | get_lppaca()->wait_state_cycles += out_purr - in_purr; | ||
639 | get_lppaca()->donate_dedicated_cpu = 0; | ||
640 | get_lppaca()->idle = 0; | ||
641 | } | ||
642 | |||
643 | static void pseries_shared_idle_sleep(void) | ||
644 | { | ||
645 | /* | ||
646 | * Indicate to the HV that we are idle. Now would be | ||
647 | * a good time to find other work to dispatch. | ||
648 | */ | ||
649 | get_lppaca()->idle = 1; | ||
650 | |||
651 | /* | ||
652 | * Yield the processor to the hypervisor. We return if | ||
653 | * an external interrupt occurs (which are driven prior | ||
654 | * to returning here) or if a prod occurs from another | ||
655 | * processor. When returning here, external interrupts | ||
656 | * are enabled. | ||
657 | */ | ||
658 | cede_processor(); | ||
659 | |||
660 | get_lppaca()->idle = 0; | ||
661 | } | ||
662 | |||
663 | static int pSeries_pci_probe_mode(struct pci_bus *bus) | 594 | static int pSeries_pci_probe_mode(struct pci_bus *bus) |
664 | { | 595 | { |
665 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 596 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 26e93fd4c62b..bbc3c42f6730 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -148,6 +148,7 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
148 | set_cpu_current_state(cpu, CPU_STATE_ONLINE); | 148 | set_cpu_current_state(cpu, CPU_STATE_ONLINE); |
149 | set_default_offline_state(cpu); | 149 | set_default_offline_state(cpu); |
150 | #endif | 150 | #endif |
151 | pseries_notify_cpuidle_add_cpu(cpu); | ||
151 | } | 152 | } |
152 | 153 | ||
153 | static int __devinit smp_pSeries_kick_cpu(int nr) | 154 | static int __devinit smp_pSeries_kick_cpu(int nr) |
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig index bd560c786ed6..57d22a2f4ba9 100644 --- a/arch/powerpc/platforms/wsp/Kconfig +++ b/arch/powerpc/platforms/wsp/Kconfig | |||
@@ -1,20 +1,28 @@ | |||
1 | config PPC_WSP | 1 | config PPC_WSP |
2 | bool | 2 | bool |
3 | select PPC_A2 | 3 | select PPC_A2 |
4 | select GENERIC_TBSYNC | ||
5 | select PPC_ICSWX | ||
4 | select PPC_SCOM | 6 | select PPC_SCOM |
5 | select PPC_XICS | 7 | select PPC_XICS |
6 | select PPC_ICP_NATIVE | 8 | select PPC_ICP_NATIVE |
7 | select PCI | 9 | select PCI |
8 | select PPC_IO_WORKAROUNDS if PCI | 10 | select PPC_IO_WORKAROUNDS if PCI |
9 | select PPC_INDIRECT_PIO if PCI | 11 | select PPC_INDIRECT_PIO if PCI |
12 | select PPC_WSP_COPRO | ||
10 | default n | 13 | default n |
11 | 14 | ||
12 | menu "WSP platform selection" | 15 | menu "WSP platform selection" |
13 | depends on PPC_BOOK3E_64 | 16 | depends on PPC_BOOK3E_64 |
14 | 17 | ||
15 | config PPC_PSR2 | 18 | config PPC_PSR2 |
16 | bool "PSR-2 platform" | 19 | bool "PowerEN System Reference Platform 2" |
17 | select GENERIC_TBSYNC | 20 | select EPAPR_BOOT |
21 | select PPC_WSP | ||
22 | default y | ||
23 | |||
24 | config PPC_CHROMA | ||
25 | bool "PowerEN PCIe Chroma Card" | ||
18 | select EPAPR_BOOT | 26 | select EPAPR_BOOT |
19 | select PPC_WSP | 27 | select PPC_WSP |
20 | default y | 28 | default y |
diff --git a/arch/powerpc/platforms/wsp/Makefile b/arch/powerpc/platforms/wsp/Makefile index a1486b436f02..56817ac98fc9 100644 --- a/arch/powerpc/platforms/wsp/Makefile +++ b/arch/powerpc/platforms/wsp/Makefile | |||
@@ -1,8 +1,10 @@ | |||
1 | ccflags-y += -mno-minimal-toc | 1 | ccflags-y += -mno-minimal-toc |
2 | 2 | ||
3 | obj-y += setup.o ics.o | 3 | obj-y += setup.o ics.o wsp.o |
4 | obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o | 4 | obj-$(CONFIG_PPC_PSR2) += psr2.o |
5 | obj-$(CONFIG_PPC_CHROMA) += chroma.o h8.o | ||
6 | obj-$(CONFIG_PPC_WSP) += opb_pic.o | ||
5 | obj-$(CONFIG_PPC_WSP) += scom_wsp.o | 7 | obj-$(CONFIG_PPC_WSP) += scom_wsp.o |
6 | obj-$(CONFIG_SMP) += smp.o scom_smp.o | 8 | obj-$(CONFIG_SMP) += smp.o scom_smp.o |
7 | obj-$(CONFIG_PCI) += wsp_pci.o | 9 | obj-$(CONFIG_PCI) += wsp_pci.o |
8 | obj-$(CONFIG_PCI_MSI) += msi.o \ No newline at end of file | 10 | obj-$(CONFIG_PCI_MSI) += msi.o |
diff --git a/arch/powerpc/platforms/wsp/chroma.c b/arch/powerpc/platforms/wsp/chroma.c new file mode 100644 index 000000000000..ca6fa26f6e63 --- /dev/null +++ b/arch/powerpc/platforms/wsp/chroma.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2011, IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/delay.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/mm.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/smp.h> | ||
17 | #include <linux/time.h> | ||
18 | |||
19 | #include <asm/machdep.h> | ||
20 | #include <asm/system.h> | ||
21 | #include <asm/udbg.h> | ||
22 | |||
23 | #include "ics.h" | ||
24 | #include "wsp.h" | ||
25 | |||
26 | void __init chroma_setup_arch(void) | ||
27 | { | ||
28 | wsp_setup_arch(); | ||
29 | wsp_setup_h8(); | ||
30 | |||
31 | } | ||
32 | |||
33 | static int __init chroma_probe(void) | ||
34 | { | ||
35 | unsigned long root = of_get_flat_dt_root(); | ||
36 | |||
37 | if (!of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) | ||
38 | return 0; | ||
39 | |||
40 | return 1; | ||
41 | } | ||
42 | |||
43 | define_machine(chroma_md) { | ||
44 | .name = "Chroma PCIe", | ||
45 | .probe = chroma_probe, | ||
46 | .setup_arch = chroma_setup_arch, | ||
47 | .restart = wsp_h8_restart, | ||
48 | .power_off = wsp_h8_power_off, | ||
49 | .halt = wsp_halt, | ||
50 | .calibrate_decr = generic_calibrate_decr, | ||
51 | .init_IRQ = wsp_setup_irq, | ||
52 | .progress = udbg_progress, | ||
53 | .power_save = book3e_idle, | ||
54 | }; | ||
55 | |||
56 | machine_arch_initcall(chroma_md, wsp_probe_devices); | ||
diff --git a/arch/powerpc/platforms/wsp/h8.c b/arch/powerpc/platforms/wsp/h8.c new file mode 100644 index 000000000000..d18e6cc19df3 --- /dev/null +++ b/arch/powerpc/platforms/wsp/h8.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2011, IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/of.h> | ||
12 | #include <linux/io.h> | ||
13 | |||
14 | #include "wsp.h" | ||
15 | |||
16 | /* | ||
17 | * The UART connection to the H8 is over ttyS1 which is just a 16550. | ||
18 | * We assume that FW has it setup right and no one messes with it. | ||
19 | */ | ||
20 | |||
21 | |||
22 | static u8 __iomem *h8; | ||
23 | |||
24 | #define RBR 0 /* Receiver Buffer Register */ | ||
25 | #define THR 0 /* Transmitter Holding Register */ | ||
26 | #define LSR 5 /* Line Status Register */ | ||
27 | #define LSR_DR 0x01 /* LSR value for Data-Ready */ | ||
28 | #define LSR_THRE 0x20 /* LSR value for Transmitter-Holding-Register-Empty */ | ||
29 | static void wsp_h8_putc(int c) | ||
30 | { | ||
31 | u8 lsr; | ||
32 | |||
33 | do { | ||
34 | lsr = readb(h8 + LSR); | ||
35 | } while ((lsr & LSR_THRE) != LSR_THRE); | ||
36 | writeb(c, h8 + THR); | ||
37 | } | ||
38 | |||
39 | static int wsp_h8_getc(void) | ||
40 | { | ||
41 | u8 lsr; | ||
42 | |||
43 | do { | ||
44 | lsr = readb(h8 + LSR); | ||
45 | } while ((lsr & LSR_DR) != LSR_DR); | ||
46 | |||
47 | return readb(h8 + RBR); | ||
48 | } | ||
49 | |||
50 | static void wsp_h8_puts(const char *s, int sz) | ||
51 | { | ||
52 | int i; | ||
53 | |||
54 | for (i = 0; i < sz; i++) { | ||
55 | wsp_h8_putc(s[i]); | ||
56 | |||
57 | /* no flow control so wait for echo */ | ||
58 | wsp_h8_getc(); | ||
59 | } | ||
60 | wsp_h8_putc('\r'); | ||
61 | wsp_h8_putc('\n'); | ||
62 | } | ||
63 | |||
64 | static void wsp_h8_terminal_cmd(const char *cmd, int sz) | ||
65 | { | ||
66 | hard_irq_disable(); | ||
67 | wsp_h8_puts(cmd, sz); | ||
68 | /* should never return, but just in case */ | ||
69 | for (;;) | ||
70 | continue; | ||
71 | } | ||
72 | |||
73 | |||
74 | void wsp_h8_restart(char *cmd) | ||
75 | { | ||
76 | static const char restart[] = "warm-reset"; | ||
77 | |||
78 | (void)cmd; | ||
79 | wsp_h8_terminal_cmd(restart, sizeof(restart) - 1); | ||
80 | } | ||
81 | |||
82 | void wsp_h8_power_off(void) | ||
83 | { | ||
84 | static const char off[] = "power-off"; | ||
85 | |||
86 | wsp_h8_terminal_cmd(off, sizeof(off) - 1); | ||
87 | } | ||
88 | |||
89 | static void __iomem *wsp_h8_getaddr(void) | ||
90 | { | ||
91 | struct device_node *aliases; | ||
92 | struct device_node *uart; | ||
93 | struct property *path; | ||
94 | void __iomem *va = NULL; | ||
95 | |||
96 | /* | ||
97 | * there is nothing in the devtree to tell us which is mapped | ||
98 | * to the H8, but se know it is the second serial port. | ||
99 | */ | ||
100 | |||
101 | aliases = of_find_node_by_path("/aliases"); | ||
102 | if (aliases == NULL) | ||
103 | return NULL; | ||
104 | |||
105 | path = of_find_property(aliases, "serial1", NULL); | ||
106 | if (path == NULL) | ||
107 | goto out; | ||
108 | |||
109 | uart = of_find_node_by_path(path->value); | ||
110 | if (uart == NULL) | ||
111 | goto out; | ||
112 | |||
113 | va = of_iomap(uart, 0); | ||
114 | |||
115 | /* remove it so no one messes with it */ | ||
116 | of_detach_node(uart); | ||
117 | of_node_put(uart); | ||
118 | |||
119 | out: | ||
120 | of_node_put(aliases); | ||
121 | |||
122 | return va; | ||
123 | } | ||
124 | |||
125 | void __init wsp_setup_h8(void) | ||
126 | { | ||
127 | h8 = wsp_h8_getaddr(); | ||
128 | |||
129 | /* Devtree change? lets hard map it anyway */ | ||
130 | if (h8 == NULL) { | ||
131 | pr_warn("UART to H8 could not be found"); | ||
132 | h8 = ioremap(0xffc0008000ULL, 0x100); | ||
133 | } | ||
134 | } | ||
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c index be05631a3c1c..19f353dfcd03 100644 --- a/arch/powerpc/platforms/wsp/opb_pic.c +++ b/arch/powerpc/platforms/wsp/opb_pic.c | |||
@@ -320,7 +320,8 @@ void __init opb_pic_init(void) | |||
320 | } | 320 | } |
321 | 321 | ||
322 | /* Attach opb interrupt handler to new virtual IRQ */ | 322 | /* Attach opb interrupt handler to new virtual IRQ */ |
323 | rc = request_irq(virq, opb_irq_handler, 0, "OPB LS Cascade", opb); | 323 | rc = request_irq(virq, opb_irq_handler, IRQF_NO_THREAD, |
324 | "OPB LS Cascade", opb); | ||
324 | if (rc) { | 325 | if (rc) { |
325 | printk("opb: request_irq failed: %d\n", rc); | 326 | printk("opb: request_irq failed: %d\n", rc); |
326 | continue; | 327 | continue; |
diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c index 166f2e4b4bee..0c1ae06d0be1 100644 --- a/arch/powerpc/platforms/wsp/psr2.c +++ b/arch/powerpc/platforms/wsp/psr2.c | |||
@@ -14,10 +14,10 @@ | |||
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/smp.h> | 16 | #include <linux/smp.h> |
17 | #include <linux/time.h> | ||
17 | 18 | ||
18 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
19 | #include <asm/system.h> | 20 | #include <asm/system.h> |
20 | #include <asm/time.h> | ||
21 | #include <asm/udbg.h> | 21 | #include <asm/udbg.h> |
22 | 22 | ||
23 | #include "ics.h" | 23 | #include "ics.h" |
@@ -27,7 +27,8 @@ | |||
27 | static void psr2_spin(void) | 27 | static void psr2_spin(void) |
28 | { | 28 | { |
29 | hard_irq_disable(); | 29 | hard_irq_disable(); |
30 | for (;;) ; | 30 | for (;;) |
31 | continue; | ||
31 | } | 32 | } |
32 | 33 | ||
33 | static void psr2_restart(char *cmd) | 34 | static void psr2_restart(char *cmd) |
@@ -35,65 +36,32 @@ static void psr2_restart(char *cmd) | |||
35 | psr2_spin(); | 36 | psr2_spin(); |
36 | } | 37 | } |
37 | 38 | ||
38 | static int psr2_probe_devices(void) | ||
39 | { | ||
40 | struct device_node *np; | ||
41 | |||
42 | /* Our RTC is a ds1500. It seems to be programatically compatible | ||
43 | * with the ds1511 for which we have a driver so let's use that | ||
44 | */ | ||
45 | np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); | ||
46 | if (np != NULL) { | ||
47 | struct resource res; | ||
48 | if (of_address_to_resource(np, 0, &res) == 0) | ||
49 | platform_device_register_simple("ds1511", 0, &res, 1); | ||
50 | } | ||
51 | return 0; | ||
52 | } | ||
53 | machine_arch_initcall(psr2_md, psr2_probe_devices); | ||
54 | |||
55 | static void __init psr2_setup_arch(void) | ||
56 | { | ||
57 | /* init to some ~sane value until calibrate_delay() runs */ | ||
58 | loops_per_jiffy = 50000000; | ||
59 | |||
60 | scom_init_wsp(); | ||
61 | |||
62 | /* Setup SMP callback */ | ||
63 | #ifdef CONFIG_SMP | ||
64 | a2_setup_smp(); | ||
65 | #endif | ||
66 | #ifdef CONFIG_PCI | ||
67 | wsp_setup_pci(); | ||
68 | #endif | ||
69 | |||
70 | } | ||
71 | |||
72 | static int __init psr2_probe(void) | 39 | static int __init psr2_probe(void) |
73 | { | 40 | { |
74 | unsigned long root = of_get_flat_dt_root(); | 41 | unsigned long root = of_get_flat_dt_root(); |
75 | 42 | ||
43 | if (of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) { | ||
44 | /* chroma systems also claim they are psr2s */ | ||
45 | return 0; | ||
46 | } | ||
47 | |||
76 | if (!of_flat_dt_is_compatible(root, "ibm,psr2")) | 48 | if (!of_flat_dt_is_compatible(root, "ibm,psr2")) |
77 | return 0; | 49 | return 0; |
78 | 50 | ||
79 | return 1; | 51 | return 1; |
80 | } | 52 | } |
81 | 53 | ||
82 | static void __init psr2_init_irq(void) | ||
83 | { | ||
84 | wsp_init_irq(); | ||
85 | opb_pic_init(); | ||
86 | } | ||
87 | |||
88 | define_machine(psr2_md) { | 54 | define_machine(psr2_md) { |
89 | .name = "PSR2 A2", | 55 | .name = "PSR2 A2", |
90 | .probe = psr2_probe, | 56 | .probe = psr2_probe, |
91 | .setup_arch = psr2_setup_arch, | 57 | .setup_arch = wsp_setup_arch, |
92 | .restart = psr2_restart, | 58 | .restart = psr2_restart, |
93 | .power_off = psr2_spin, | 59 | .power_off = psr2_spin, |
94 | .halt = psr2_spin, | 60 | .halt = psr2_spin, |
95 | .calibrate_decr = generic_calibrate_decr, | 61 | .calibrate_decr = generic_calibrate_decr, |
96 | .init_IRQ = psr2_init_irq, | 62 | .init_IRQ = wsp_setup_irq, |
97 | .progress = udbg_progress, | 63 | .progress = udbg_progress, |
98 | .power_save = book3e_idle, | 64 | .power_save = book3e_idle, |
99 | }; | 65 | }; |
66 | |||
67 | machine_arch_initcall(psr2_md, wsp_probe_devices); | ||
diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c new file mode 100644 index 000000000000..d25cc96c21b8 --- /dev/null +++ b/arch/powerpc/platforms/wsp/wsp.c | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2011, IBM Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/of.h> | ||
12 | #include <linux/of_device.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/time.h> | ||
16 | |||
17 | #include <asm/scom.h> | ||
18 | |||
19 | #include "wsp.h" | ||
20 | #include "ics.h" | ||
21 | |||
22 | #define WSP_SOC_COMPATIBLE "ibm,wsp-soc" | ||
23 | #define PBIC_COMPATIBLE "ibm,wsp-pbic" | ||
24 | #define COPRO_COMPATIBLE "ibm,wsp-coprocessor" | ||
25 | |||
26 | static int __init wsp_probe_buses(void) | ||
27 | { | ||
28 | static __initdata struct of_device_id bus_ids[] = { | ||
29 | /* | ||
30 | * every node in between needs to be here or you won't | ||
31 | * find it | ||
32 | */ | ||
33 | { .compatible = WSP_SOC_COMPATIBLE, }, | ||
34 | { .compatible = PBIC_COMPATIBLE, }, | ||
35 | { .compatible = COPRO_COMPATIBLE, }, | ||
36 | {}, | ||
37 | }; | ||
38 | of_platform_bus_probe(NULL, bus_ids, NULL); | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | void __init wsp_setup_arch(void) | ||
44 | { | ||
45 | /* init to some ~sane value until calibrate_delay() runs */ | ||
46 | loops_per_jiffy = 50000000; | ||
47 | |||
48 | scom_init_wsp(); | ||
49 | |||
50 | /* Setup SMP callback */ | ||
51 | #ifdef CONFIG_SMP | ||
52 | a2_setup_smp(); | ||
53 | #endif | ||
54 | #ifdef CONFIG_PCI | ||
55 | wsp_setup_pci(); | ||
56 | #endif | ||
57 | } | ||
58 | |||
59 | void __init wsp_setup_irq(void) | ||
60 | { | ||
61 | wsp_init_irq(); | ||
62 | opb_pic_init(); | ||
63 | } | ||
64 | |||
65 | |||
66 | int __init wsp_probe_devices(void) | ||
67 | { | ||
68 | struct device_node *np; | ||
69 | |||
70 | /* Our RTC is a ds1500. It seems to be programatically compatible | ||
71 | * with the ds1511 for which we have a driver so let's use that | ||
72 | */ | ||
73 | np = of_find_compatible_node(NULL, NULL, "dallas,ds1500"); | ||
74 | if (np != NULL) { | ||
75 | struct resource res; | ||
76 | if (of_address_to_resource(np, 0, &res) == 0) | ||
77 | platform_device_register_simple("ds1511", 0, &res, 1); | ||
78 | } | ||
79 | |||
80 | wsp_probe_buses(); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | void wsp_halt(void) | ||
86 | { | ||
87 | u64 val; | ||
88 | scom_map_t m; | ||
89 | struct device_node *dn; | ||
90 | struct device_node *mine; | ||
91 | struct device_node *me; | ||
92 | |||
93 | me = of_get_cpu_node(smp_processor_id(), NULL); | ||
94 | mine = scom_find_parent(me); | ||
95 | |||
96 | /* This will halt all the A2s but not power off the chip */ | ||
97 | for_each_node_with_property(dn, "scom-controller") { | ||
98 | if (dn == mine) | ||
99 | continue; | ||
100 | m = scom_map(dn, 0, 1); | ||
101 | |||
102 | /* read-modify-write it so the HW probe does not get | ||
103 | * confused */ | ||
104 | val = scom_read(m, 0); | ||
105 | val |= 1; | ||
106 | scom_write(m, 0, val); | ||
107 | scom_unmap(m); | ||
108 | } | ||
109 | m = scom_map(mine, 0, 1); | ||
110 | val = scom_read(m, 0); | ||
111 | val |= 1; | ||
112 | scom_write(m, 0, val); | ||
113 | /* should never return */ | ||
114 | scom_unmap(m); | ||
115 | } | ||
diff --git a/arch/powerpc/platforms/wsp/wsp.h b/arch/powerpc/platforms/wsp/wsp.h index 33479818f62a..10c1d1fff362 100644 --- a/arch/powerpc/platforms/wsp/wsp.h +++ b/arch/powerpc/platforms/wsp/wsp.h | |||
@@ -6,15 +6,25 @@ | |||
6 | /* Devtree compatible strings for major devices */ | 6 | /* Devtree compatible strings for major devices */ |
7 | #define PCIE_COMPATIBLE "ibm,wsp-pciex" | 7 | #define PCIE_COMPATIBLE "ibm,wsp-pciex" |
8 | 8 | ||
9 | extern void wsp_setup_arch(void); | ||
10 | extern void wsp_setup_irq(void); | ||
11 | extern int wsp_probe_devices(void); | ||
12 | extern void wsp_halt(void); | ||
13 | |||
9 | extern void wsp_setup_pci(void); | 14 | extern void wsp_setup_pci(void); |
10 | extern void scom_init_wsp(void); | 15 | extern void scom_init_wsp(void); |
11 | 16 | ||
12 | extern void a2_setup_smp(void); | 17 | extern void a2_setup_smp(void); |
13 | extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, | 18 | extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, |
14 | struct device_node *np); | 19 | struct device_node *np); |
15 | int smp_a2_cpu_bootable(unsigned int nr); | 20 | extern int smp_a2_cpu_bootable(unsigned int nr); |
16 | int __devinit smp_a2_kick_cpu(int nr); | 21 | extern int __devinit smp_a2_kick_cpu(int nr); |
22 | |||
23 | extern void opb_pic_init(void); | ||
17 | 24 | ||
18 | void opb_pic_init(void); | 25 | /* chroma specific managment */ |
26 | extern void wsp_h8_restart(char *cmd); | ||
27 | extern void wsp_h8_power_off(void); | ||
28 | extern void __init wsp_setup_h8(void); | ||
19 | 29 | ||
20 | #endif /* __WSP_H */ | 30 | #endif /* __WSP_H */ |