diff options
Diffstat (limited to 'arch/powerpc/platforms')
32 files changed, 634 insertions, 681 deletions
diff --git a/arch/powerpc/platforms/44x/currituck.c b/arch/powerpc/platforms/44x/currituck.c index 583e67fee37e..9f6c33d63a42 100644 --- a/arch/powerpc/platforms/44x/currituck.c +++ b/arch/powerpc/platforms/44x/currituck.c | |||
@@ -160,7 +160,7 @@ static void __init ppc47x_setup_arch(void) | |||
160 | /* No need to check the DMA config as we /know/ our windows are all of | 160 | /* No need to check the DMA config as we /know/ our windows are all of |
161 | * RAM. Lets hope that doesn't change */ | 161 | * RAM. Lets hope that doesn't change */ |
162 | #ifdef CONFIG_SWIOTLB | 162 | #ifdef CONFIG_SWIOTLB |
163 | if (memblock_end_of_DRAM() > 0xffffffff) { | 163 | if ((memblock_end_of_DRAM() - 1) > 0xffffffff) { |
164 | ppc_swiotlb_enable = 1; | 164 | ppc_swiotlb_enable = 1; |
165 | set_pci_dma_ops(&swiotlb_dma_ops); | 165 | set_pci_dma_ops(&swiotlb_dma_ops); |
166 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 166 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/82xx/km82xx.c b/arch/powerpc/platforms/82xx/km82xx.c index 3661bcdc326a..cf964e19573a 100644 --- a/arch/powerpc/platforms/82xx/km82xx.c +++ b/arch/powerpc/platforms/82xx/km82xx.c | |||
@@ -128,6 +128,11 @@ static __initdata struct cpm_pin km82xx_pins[] = { | |||
128 | {3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXP */ | 128 | {3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXP */ |
129 | {3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXN */ | 129 | {3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, /* TXN */ |
130 | {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* RXD */ | 130 | {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* RXD */ |
131 | |||
132 | /* SPI */ | ||
133 | {3, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY},/* SPI_MISO PD16 */ | ||
134 | {3, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY},/* SPI_MOSI PD17 */ | ||
135 | {3, 18, CPM_PIN_INPUT | CPM_PIN_SECONDARY},/* SPI_CLK PD18 */ | ||
131 | }; | 136 | }; |
132 | 137 | ||
133 | static void __init init_ioports(void) | 138 | static void __init init_ioports(void) |
diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index a266ba876863..89923d723349 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Author: Heiko Schocher <hs@denx.de> | 3 | * Author: Heiko Schocher <hs@denx.de> |
4 | * | 4 | * |
5 | * Description: | 5 | * Description: |
6 | * Keymile KMETER1 board specific routines. | 6 | * Keymile 83xx platform specific routines. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
@@ -70,54 +70,88 @@ static void __init mpc83xx_km_setup_arch(void) | |||
70 | for_each_node_by_name(np, "spi") | 70 | for_each_node_by_name(np, "spi") |
71 | par_io_of_config(np); | 71 | par_io_of_config(np); |
72 | 72 | ||
73 | for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;) | 73 | for_each_node_by_name(np, "ucc") |
74 | par_io_of_config(np); | 74 | par_io_of_config(np); |
75 | } | 75 | } |
76 | 76 | ||
77 | np = of_find_compatible_node(NULL, "network", "ucc_geth"); | 77 | np = of_find_compatible_node(NULL, "network", "ucc_geth"); |
78 | if (np != NULL) { | 78 | if (np != NULL) { |
79 | uint svid; | 79 | /* |
80 | * handle mpc8360E Erratum QE_ENET10: | ||
81 | * RGMII AC values do not meet the specification | ||
82 | */ | ||
83 | uint svid = mfspr(SPRN_SVR); | ||
84 | struct device_node *np_par; | ||
85 | struct resource res; | ||
86 | void __iomem *base; | ||
87 | int ret; | ||
88 | |||
89 | np_par = of_find_node_by_name(NULL, "par_io"); | ||
90 | if (np_par == NULL) { | ||
91 | printk(KERN_WARNING "%s couldn;t find par_io node\n", | ||
92 | __func__); | ||
93 | return; | ||
94 | } | ||
95 | /* Map Parallel I/O ports registers */ | ||
96 | ret = of_address_to_resource(np_par, 0, &res); | ||
97 | if (ret) { | ||
98 | printk(KERN_WARNING "%s couldn;t map par_io registers\n", | ||
99 | __func__); | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | base = ioremap(res.start, res.end - res.start + 1); | ||
104 | |||
105 | /* | ||
106 | * set output delay adjustments to default values according | ||
107 | * table 5 in Errata Rev. 5, 9/2011: | ||
108 | * | ||
109 | * write 0b01 to UCC1 bits 18:19 | ||
110 | * write 0b01 to UCC2 option 1 bits 4:5 | ||
111 | * write 0b01 to UCC2 option 2 bits 16:17 | ||
112 | */ | ||
113 | clrsetbits_be32((base + 0xa8), 0x0c00f000, 0x04005000); | ||
114 | |||
115 | /* | ||
116 | * set output delay adjustments to default values according | ||
117 | * table 3-13 in Reference Manual Rev.3 05/2010: | ||
118 | * | ||
119 | * write 0b01 to UCC2 option 2 bits 16:17 | ||
120 | * write 0b0101 to UCC1 bits 20:23 | ||
121 | * write 0b0101 to UCC2 option 1 bits 24:27 | ||
122 | */ | ||
123 | clrsetbits_be32((base + 0xac), 0x0000cff0, 0x00004550); | ||
80 | 124 | ||
81 | /* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */ | ||
82 | svid = mfspr(SPRN_SVR); | ||
83 | if (SVR_REV(svid) == 0x0021) { | 125 | if (SVR_REV(svid) == 0x0021) { |
84 | struct device_node *np_par; | 126 | /* |
85 | struct resource res; | 127 | * UCC2 option 1: write 0b1010 to bits 24:27 |
86 | void __iomem *base; | 128 | * at address IMMRBAR+0x14AC |
87 | int ret; | 129 | */ |
88 | 130 | clrsetbits_be32((base + 0xac), 0x000000f0, 0x000000a0); | |
89 | np_par = of_find_node_by_name(NULL, "par_io"); | 131 | } else if (SVR_REV(svid) == 0x0020) { |
90 | if (np_par == NULL) { | 132 | /* |
91 | printk(KERN_WARNING "%s couldn;t find par_io node\n", | 133 | * UCC1: write 0b11 to bits 18:19 |
92 | __func__); | 134 | * at address IMMRBAR+0x14A8 |
93 | return; | 135 | */ |
94 | } | 136 | setbits32((base + 0xa8), 0x00003000); |
95 | /* Map Parallel I/O ports registers */ | ||
96 | ret = of_address_to_resource(np_par, 0, &res); | ||
97 | if (ret) { | ||
98 | printk(KERN_WARNING "%s couldn;t map par_io registers\n", | ||
99 | __func__); | ||
100 | return; | ||
101 | } | ||
102 | base = ioremap(res.start, resource_size(&res)); | ||
103 | 137 | ||
104 | /* | 138 | /* |
105 | * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2) | 139 | * UCC2 option 1: write 0b11 to bits 4:5 |
106 | * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1) | 140 | * at address IMMRBAR+0x14A8 |
107 | */ | 141 | */ |
108 | setbits32((base + 0xa8), 0x0c003000); | 142 | setbits32((base + 0xa8), 0x0c000000); |
109 | 143 | ||
110 | /* | 144 | /* |
111 | * IMMR + 0x14AC[20:27] = 10101010 | 145 | * UCC2 option 2: write 0b11 to bits 16:17 |
112 | * (data delay for both UCC's) | 146 | * at address IMMRBAR+0x14AC |
113 | */ | 147 | */ |
114 | clrsetbits_be32((base + 0xac), 0xff0, 0xaa0); | 148 | setbits32((base + 0xac), 0x0000c000); |
115 | iounmap(base); | ||
116 | of_node_put(np_par); | ||
117 | } | 149 | } |
150 | iounmap(base); | ||
151 | of_node_put(np_par); | ||
118 | of_node_put(np); | 152 | of_node_put(np); |
119 | } | 153 | } |
120 | #endif /* CONFIG_QUICC_ENGINE */ | 154 | #endif /* CONFIG_QUICC_ENGINE */ |
121 | } | 155 | } |
122 | 156 | ||
123 | machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); | 157 | machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); |
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index f000d81c4e31..159c01e91463 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -23,6 +23,15 @@ config FSL_85XX_CACHE_SRAM | |||
23 | cache-sram-size and cache-sram-offset kernel boot | 23 | cache-sram-size and cache-sram-offset kernel boot |
24 | parameters should be passed when this option is enabled. | 24 | parameters should be passed when this option is enabled. |
25 | 25 | ||
26 | config BSC9131_RDB | ||
27 | bool "Freescale BSC9131RDB" | ||
28 | select DEFAULT_UIMAGE | ||
29 | help | ||
30 | This option enables support for the Freescale BSC9131RDB board. | ||
31 | The BSC9131 is a heterogeneous SoC containing an e500v2 powerpc and a | ||
32 | StarCore SC3850 DSP | ||
33 | Manufacturer : Freescale Semiconductor, Inc | ||
34 | |||
26 | config MPC8540_ADS | 35 | config MPC8540_ADS |
27 | bool "Freescale MPC8540 ADS" | 36 | bool "Freescale MPC8540 ADS" |
28 | select DEFAULT_UIMAGE | 37 | select DEFAULT_UIMAGE |
@@ -175,12 +184,6 @@ config SBC8548 | |||
175 | help | 184 | help |
176 | This option enables support for the Wind River SBC8548 board | 185 | This option enables support for the Wind River SBC8548 board |
177 | 186 | ||
178 | config SBC8560 | ||
179 | bool "Wind River SBC8560" | ||
180 | select DEFAULT_UIMAGE | ||
181 | help | ||
182 | This option enables support for the Wind River SBC8560 board | ||
183 | |||
184 | config GE_IMP3A | 187 | config GE_IMP3A |
185 | bool "GE Intelligent Platforms IMP3A" | 188 | bool "GE Intelligent Platforms IMP3A" |
186 | select DEFAULT_UIMAGE | 189 | select DEFAULT_UIMAGE |
@@ -222,18 +225,6 @@ config P3041_DS | |||
222 | help | 225 | help |
223 | This option enables support for the P3041 DS board | 226 | This option enables support for the P3041 DS board |
224 | 227 | ||
225 | config P3060_QDS | ||
226 | bool "Freescale P3060 QDS" | ||
227 | select DEFAULT_UIMAGE | ||
228 | select PPC_E500MC | ||
229 | select PHYS_64BIT | ||
230 | select SWIOTLB | ||
231 | select GPIO_MPC8XXX | ||
232 | select HAS_RAPIDIO | ||
233 | select PPC_EPAPR_HV_PIC | ||
234 | help | ||
235 | This option enables support for the P3060 QDS board | ||
236 | |||
237 | config P4080_DS | 228 | config P4080_DS |
238 | bool "Freescale P4080 DS" | 229 | bool "Freescale P4080 DS" |
239 | select DEFAULT_UIMAGE | 230 | select DEFAULT_UIMAGE |
@@ -263,6 +254,22 @@ config P5020_DS | |||
263 | help | 254 | help |
264 | This option enables support for the P5020 DS board | 255 | This option enables support for the P5020 DS board |
265 | 256 | ||
257 | config PPC_QEMU_E500 | ||
258 | bool "QEMU generic e500 platform" | ||
259 | depends on EXPERIMENTAL | ||
260 | select DEFAULT_UIMAGE | ||
261 | help | ||
262 | This option enables support for running as a QEMU guest using | ||
263 | QEMU's generic e500 machine. This is not required if you're | ||
264 | using a QEMU machine that targets a specific board, such as | ||
265 | mpc8544ds. | ||
266 | |||
267 | Unlike most e500 boards that target a specific CPU, this | ||
268 | platform works with any e500-family CPU that QEMU supports. | ||
269 | Thus, you'll need to make sure CONFIG_PPC_E500MC is set or | ||
270 | unset based on the emulated CPU (or actual host CPU in the case | ||
271 | of KVM). | ||
272 | |||
266 | endif # FSL_SOC_BOOKE | 273 | endif # FSL_SOC_BOOKE |
267 | 274 | ||
268 | config TQM85xx | 275 | config TQM85xx |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 2125d4ca068a..3dfe81175036 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -5,6 +5,7 @@ obj-$(CONFIG_SMP) += smp.o | |||
5 | 5 | ||
6 | obj-y += common.o | 6 | obj-y += common.o |
7 | 7 | ||
8 | obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o | ||
8 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 9 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
9 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o | 10 | obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o |
10 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o | 11 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o |
@@ -17,14 +18,13 @@ obj-$(CONFIG_P1022_DS) += p1022_ds.o | |||
17 | obj-$(CONFIG_P1023_RDS) += p1023_rds.o | 18 | obj-$(CONFIG_P1023_RDS) += p1023_rds.o |
18 | obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o | 19 | obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o |
19 | obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o | 20 | obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o |
20 | obj-$(CONFIG_P3060_QDS) += p3060_qds.o corenet_ds.o | ||
21 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o | 21 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o |
22 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o | 22 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o |
23 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 23 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
24 | obj-$(CONFIG_TQM85xx) += tqm85xx.o | 24 | obj-$(CONFIG_TQM85xx) += tqm85xx.o |
25 | obj-$(CONFIG_SBC8560) += sbc8560.o | ||
26 | obj-$(CONFIG_SBC8548) += sbc8548.o | 25 | obj-$(CONFIG_SBC8548) += sbc8548.o |
27 | obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o | 26 | obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o |
28 | obj-$(CONFIG_KSI8560) += ksi8560.o | 27 | obj-$(CONFIG_KSI8560) += ksi8560.o |
29 | obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o | 28 | obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o |
30 | obj-$(CONFIG_GE_IMP3A) += ge_imp3a.o | 29 | obj-$(CONFIG_GE_IMP3A) += ge_imp3a.o |
30 | obj-$(CONFIG_PPC_QEMU_E500) += qemu_e500.o | ||
diff --git a/arch/powerpc/platforms/85xx/bsc913x_rdb.c b/arch/powerpc/platforms/85xx/bsc913x_rdb.c new file mode 100644 index 000000000000..9d57bedb940c --- /dev/null +++ b/arch/powerpc/platforms/85xx/bsc913x_rdb.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * BSC913xRDB Board Setup | ||
3 | * | ||
4 | * Author: Priyanka Jain <Priyanka.Jain@freescale.com> | ||
5 | * | ||
6 | * Copyright 2011-2012 Freescale Semiconductor Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <asm/mpic.h> | ||
17 | #include <sysdev/fsl_soc.h> | ||
18 | #include <asm/udbg.h> | ||
19 | |||
20 | #include "mpc85xx.h" | ||
21 | |||
22 | void __init bsc913x_rdb_pic_init(void) | ||
23 | { | ||
24 | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | | ||
25 | MPIC_SINGLE_DEST_CPU, | ||
26 | 0, 256, " OpenPIC "); | ||
27 | |||
28 | if (!mpic) | ||
29 | pr_err("bsc913x: Failed to allocate MPIC structure\n"); | ||
30 | else | ||
31 | mpic_init(mpic); | ||
32 | } | ||
33 | |||
34 | /* | ||
35 | * Setup the architecture | ||
36 | */ | ||
37 | static void __init bsc913x_rdb_setup_arch(void) | ||
38 | { | ||
39 | if (ppc_md.progress) | ||
40 | ppc_md.progress("bsc913x_rdb_setup_arch()", 0); | ||
41 | |||
42 | pr_info("bsc913x board from Freescale Semiconductor\n"); | ||
43 | } | ||
44 | |||
45 | machine_device_initcall(bsc9131_rdb, mpc85xx_common_publish_devices); | ||
46 | |||
47 | /* | ||
48 | * Called very early, device-tree isn't unflattened | ||
49 | */ | ||
50 | |||
51 | static int __init bsc9131_rdb_probe(void) | ||
52 | { | ||
53 | unsigned long root = of_get_flat_dt_root(); | ||
54 | |||
55 | return of_flat_dt_is_compatible(root, "fsl,bsc9131rdb"); | ||
56 | } | ||
57 | |||
58 | define_machine(bsc9131_rdb) { | ||
59 | .name = "BSC9131 RDB", | ||
60 | .probe = bsc9131_rdb_probe, | ||
61 | .setup_arch = bsc913x_rdb_setup_arch, | ||
62 | .init_IRQ = bsc913x_rdb_pic_init, | ||
63 | .get_irq = mpic_get_irq, | ||
64 | .restart = fsl_rstcr_restart, | ||
65 | .calibrate_decr = generic_calibrate_decr, | ||
66 | .progress = udbg_progress, | ||
67 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c index dd3617c531d7..925b02874233 100644 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/arch/powerpc/platforms/85xx/corenet_ds.c | |||
@@ -77,7 +77,7 @@ void __init corenet_ds_setup_arch(void) | |||
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | #ifdef CONFIG_SWIOTLB | 79 | #ifdef CONFIG_SWIOTLB |
80 | if (memblock_end_of_DRAM() > max) { | 80 | if ((memblock_end_of_DRAM() - 1) > max) { |
81 | ppc_swiotlb_enable = 1; | 81 | ppc_swiotlb_enable = 1; |
82 | set_pci_dma_ops(&swiotlb_dma_ops); | 82 | set_pci_dma_ops(&swiotlb_dma_ops); |
83 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 83 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/85xx/ge_imp3a.c b/arch/powerpc/platforms/85xx/ge_imp3a.c index 18014629416d..b6a728b0a8ca 100644 --- a/arch/powerpc/platforms/85xx/ge_imp3a.c +++ b/arch/powerpc/platforms/85xx/ge_imp3a.c | |||
@@ -125,7 +125,7 @@ static void __init ge_imp3a_setup_arch(void) | |||
125 | mpc85xx_smp_init(); | 125 | mpc85xx_smp_init(); |
126 | 126 | ||
127 | #ifdef CONFIG_SWIOTLB | 127 | #ifdef CONFIG_SWIOTLB |
128 | if (memblock_end_of_DRAM() > max) { | 128 | if ((memblock_end_of_DRAM() - 1) > max) { |
129 | ppc_swiotlb_enable = 1; | 129 | ppc_swiotlb_enable = 1; |
130 | set_pci_dma_ops(&swiotlb_dma_ops); | 130 | set_pci_dma_ops(&swiotlb_dma_ops); |
131 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 131 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 585bd22b1406..767c7cf18a9c 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c | |||
@@ -75,7 +75,7 @@ static void __init mpc8536_ds_setup_arch(void) | |||
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | #ifdef CONFIG_SWIOTLB | 77 | #ifdef CONFIG_SWIOTLB |
78 | if (memblock_end_of_DRAM() > max) { | 78 | if ((memblock_end_of_DRAM() - 1) > max) { |
79 | ppc_swiotlb_enable = 1; | 79 | ppc_swiotlb_enable = 1; |
80 | set_pci_dma_ops(&swiotlb_dma_ops); | 80 | set_pci_dma_ops(&swiotlb_dma_ops); |
81 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 81 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 1fd91e9e0ffb..6d3265fe7718 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c | |||
@@ -114,71 +114,53 @@ void __init mpc85xx_ds_pic_init(void) | |||
114 | } | 114 | } |
115 | 115 | ||
116 | #ifdef CONFIG_PCI | 116 | #ifdef CONFIG_PCI |
117 | static int primary_phb_addr; | ||
118 | extern int uli_exclude_device(struct pci_controller *hose, | 117 | extern int uli_exclude_device(struct pci_controller *hose, |
119 | u_char bus, u_char devfn); | 118 | u_char bus, u_char devfn); |
120 | 119 | ||
120 | static struct device_node *pci_with_uli; | ||
121 | |||
121 | static int mpc85xx_exclude_device(struct pci_controller *hose, | 122 | static int mpc85xx_exclude_device(struct pci_controller *hose, |
122 | u_char bus, u_char devfn) | 123 | u_char bus, u_char devfn) |
123 | { | 124 | { |
124 | struct device_node* node; | 125 | if (hose->dn == pci_with_uli) |
125 | struct resource rsrc; | ||
126 | |||
127 | node = hose->dn; | ||
128 | of_address_to_resource(node, 0, &rsrc); | ||
129 | |||
130 | if ((rsrc.start & 0xfffff) == primary_phb_addr) { | ||
131 | return uli_exclude_device(hose, bus, devfn); | 126 | return uli_exclude_device(hose, bus, devfn); |
132 | } | ||
133 | 127 | ||
134 | return PCIBIOS_SUCCESSFUL; | 128 | return PCIBIOS_SUCCESSFUL; |
135 | } | 129 | } |
136 | #endif /* CONFIG_PCI */ | 130 | #endif /* CONFIG_PCI */ |
137 | 131 | ||
138 | /* | 132 | static void __init mpc85xx_ds_pci_init(void) |
139 | * Setup the architecture | ||
140 | */ | ||
141 | static void __init mpc85xx_ds_setup_arch(void) | ||
142 | { | 133 | { |
143 | #ifdef CONFIG_PCI | 134 | #ifdef CONFIG_PCI |
144 | struct device_node *np; | 135 | struct device_node *node; |
145 | struct pci_controller *hose; | ||
146 | #endif | ||
147 | dma_addr_t max = 0xffffffff; | ||
148 | 136 | ||
149 | if (ppc_md.progress) | 137 | fsl_pci_init(); |
150 | ppc_md.progress("mpc85xx_ds_setup_arch()", 0); | ||
151 | 138 | ||
152 | #ifdef CONFIG_PCI | 139 | /* See if we have a ULI under the primary */ |
153 | for_each_node_by_type(np, "pci") { | 140 | |
154 | if (of_device_is_compatible(np, "fsl,mpc8540-pci") || | 141 | node = of_find_node_by_name(NULL, "uli1575"); |
155 | of_device_is_compatible(np, "fsl,mpc8548-pcie") || | 142 | while ((pci_with_uli = of_get_parent(node))) { |
156 | of_device_is_compatible(np, "fsl,p2020-pcie")) { | 143 | of_node_put(node); |
157 | struct resource rsrc; | 144 | node = pci_with_uli; |
158 | of_address_to_resource(np, 0, &rsrc); | 145 | |
159 | if ((rsrc.start & 0xfffff) == primary_phb_addr) | 146 | if (pci_with_uli == fsl_pci_primary) { |
160 | fsl_add_bridge(np, 1); | 147 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; |
161 | else | 148 | break; |
162 | fsl_add_bridge(np, 0); | ||
163 | |||
164 | hose = pci_find_hose_for_OF_device(np); | ||
165 | max = min(max, hose->dma_window_base_cur + | ||
166 | hose->dma_window_size); | ||
167 | } | 149 | } |
168 | } | 150 | } |
169 | |||
170 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | ||
171 | #endif | 151 | #endif |
152 | } | ||
172 | 153 | ||
173 | mpc85xx_smp_init(); | 154 | /* |
155 | * Setup the architecture | ||
156 | */ | ||
157 | static void __init mpc85xx_ds_setup_arch(void) | ||
158 | { | ||
159 | if (ppc_md.progress) | ||
160 | ppc_md.progress("mpc85xx_ds_setup_arch()", 0); | ||
174 | 161 | ||
175 | #ifdef CONFIG_SWIOTLB | 162 | mpc85xx_ds_pci_init(); |
176 | if (memblock_end_of_DRAM() > max) { | 163 | mpc85xx_smp_init(); |
177 | ppc_swiotlb_enable = 1; | ||
178 | set_pci_dma_ops(&swiotlb_dma_ops); | ||
179 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | ||
180 | } | ||
181 | #endif | ||
182 | 164 | ||
183 | printk("MPC85xx DS board from Freescale Semiconductor\n"); | 165 | printk("MPC85xx DS board from Freescale Semiconductor\n"); |
184 | } | 166 | } |
@@ -190,14 +172,7 @@ static int __init mpc8544_ds_probe(void) | |||
190 | { | 172 | { |
191 | unsigned long root = of_get_flat_dt_root(); | 173 | unsigned long root = of_get_flat_dt_root(); |
192 | 174 | ||
193 | if (of_flat_dt_is_compatible(root, "MPC8544DS")) { | 175 | return !!of_flat_dt_is_compatible(root, "MPC8544DS"); |
194 | #ifdef CONFIG_PCI | ||
195 | primary_phb_addr = 0xb000; | ||
196 | #endif | ||
197 | return 1; | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | 176 | } |
202 | 177 | ||
203 | machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices); | 178 | machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices); |
@@ -215,14 +190,7 @@ static int __init mpc8572_ds_probe(void) | |||
215 | { | 190 | { |
216 | unsigned long root = of_get_flat_dt_root(); | 191 | unsigned long root = of_get_flat_dt_root(); |
217 | 192 | ||
218 | if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS")) { | 193 | return !!of_flat_dt_is_compatible(root, "fsl,MPC8572DS"); |
219 | #ifdef CONFIG_PCI | ||
220 | primary_phb_addr = 0x8000; | ||
221 | #endif | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | return 0; | ||
226 | } | 194 | } |
227 | 195 | ||
228 | /* | 196 | /* |
@@ -232,14 +200,7 @@ static int __init p2020_ds_probe(void) | |||
232 | { | 200 | { |
233 | unsigned long root = of_get_flat_dt_root(); | 201 | unsigned long root = of_get_flat_dt_root(); |
234 | 202 | ||
235 | if (of_flat_dt_is_compatible(root, "fsl,P2020DS")) { | 203 | return !!of_flat_dt_is_compatible(root, "fsl,P2020DS"); |
236 | #ifdef CONFIG_PCI | ||
237 | primary_phb_addr = 0x9000; | ||
238 | #endif | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | return 0; | ||
243 | } | 204 | } |
244 | 205 | ||
245 | define_machine(mpc8544_ds) { | 206 | define_machine(mpc8544_ds) { |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index d208ebccb91c..8e4b094c553b 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -359,7 +359,7 @@ static void __init mpc85xx_mds_setup_arch(void) | |||
359 | mpc85xx_mds_qe_init(); | 359 | mpc85xx_mds_qe_init(); |
360 | 360 | ||
361 | #ifdef CONFIG_SWIOTLB | 361 | #ifdef CONFIG_SWIOTLB |
362 | if (memblock_end_of_DRAM() > max) { | 362 | if ((memblock_end_of_DRAM() - 1) > max) { |
363 | ppc_swiotlb_enable = 1; | 363 | ppc_swiotlb_enable = 1; |
364 | set_pci_dma_ops(&swiotlb_dma_ops); | 364 | set_pci_dma_ops(&swiotlb_dma_ops); |
365 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 365 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index 313fce4f5574..1910fdcb75b2 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c | |||
@@ -169,6 +169,7 @@ machine_device_initcall(p1020_rdb_pc, mpc85xx_common_publish_devices); | |||
169 | machine_device_initcall(p1020_utm_pc, mpc85xx_common_publish_devices); | 169 | machine_device_initcall(p1020_utm_pc, mpc85xx_common_publish_devices); |
170 | machine_device_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices); | 170 | machine_device_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices); |
171 | machine_device_initcall(p1025_rdb, mpc85xx_common_publish_devices); | 171 | machine_device_initcall(p1025_rdb, mpc85xx_common_publish_devices); |
172 | machine_device_initcall(p1024_rdb, mpc85xx_common_publish_devices); | ||
172 | 173 | ||
173 | /* | 174 | /* |
174 | * Called very early, device-tree isn't unflattened | 175 | * Called very early, device-tree isn't unflattened |
@@ -237,6 +238,13 @@ static int __init p1020_utm_pc_probe(void) | |||
237 | return of_flat_dt_is_compatible(root, "fsl,P1020UTM-PC"); | 238 | return of_flat_dt_is_compatible(root, "fsl,P1020UTM-PC"); |
238 | } | 239 | } |
239 | 240 | ||
241 | static int __init p1024_rdb_probe(void) | ||
242 | { | ||
243 | unsigned long root = of_get_flat_dt_root(); | ||
244 | |||
245 | return of_flat_dt_is_compatible(root, "fsl,P1024RDB"); | ||
246 | } | ||
247 | |||
240 | define_machine(p2020_rdb) { | 248 | define_machine(p2020_rdb) { |
241 | .name = "P2020 RDB", | 249 | .name = "P2020 RDB", |
242 | .probe = p2020_rdb_probe, | 250 | .probe = p2020_rdb_probe, |
@@ -348,3 +356,17 @@ define_machine(p1020_rdb_pc) { | |||
348 | .calibrate_decr = generic_calibrate_decr, | 356 | .calibrate_decr = generic_calibrate_decr, |
349 | .progress = udbg_progress, | 357 | .progress = udbg_progress, |
350 | }; | 358 | }; |
359 | |||
360 | define_machine(p1024_rdb) { | ||
361 | .name = "P1024 RDB", | ||
362 | .probe = p1024_rdb_probe, | ||
363 | .setup_arch = mpc85xx_rdb_setup_arch, | ||
364 | .init_IRQ = mpc85xx_rdb_pic_init, | ||
365 | #ifdef CONFIG_PCI | ||
366 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
367 | #endif | ||
368 | .get_irq = mpic_get_irq, | ||
369 | .restart = fsl_rstcr_restart, | ||
370 | .calibrate_decr = generic_calibrate_decr, | ||
371 | .progress = udbg_progress, | ||
372 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index f700c81a1321..89ee02c54561 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <sysdev/fsl_pci.h> | 27 | #include <sysdev/fsl_pci.h> |
28 | #include <asm/udbg.h> | 28 | #include <asm/udbg.h> |
29 | #include <asm/fsl_guts.h> | 29 | #include <asm/fsl_guts.h> |
30 | #include <asm/fsl_lbc.h> | ||
30 | #include "smp.h" | 31 | #include "smp.h" |
31 | 32 | ||
32 | #include "mpc85xx.h" | 33 | #include "mpc85xx.h" |
@@ -142,17 +143,73 @@ static void p1022ds_set_gamma_table(enum fsl_diu_monitor_port port, | |||
142 | { | 143 | { |
143 | } | 144 | } |
144 | 145 | ||
146 | struct fsl_law { | ||
147 | u32 lawbar; | ||
148 | u32 reserved1; | ||
149 | u32 lawar; | ||
150 | u32 reserved[5]; | ||
151 | }; | ||
152 | |||
153 | #define LAWBAR_MASK 0x00F00000 | ||
154 | #define LAWBAR_SHIFT 12 | ||
155 | |||
156 | #define LAWAR_EN 0x80000000 | ||
157 | #define LAWAR_TGT_MASK 0x01F00000 | ||
158 | #define LAW_TRGT_IF_LBC (0x04 << 20) | ||
159 | |||
160 | #define LAWAR_MASK (LAWAR_EN | LAWAR_TGT_MASK) | ||
161 | #define LAWAR_MATCH (LAWAR_EN | LAW_TRGT_IF_LBC) | ||
162 | |||
163 | #define BR_BA 0xFFFF8000 | ||
164 | |||
165 | /* | ||
166 | * Map a BRx value to a physical address | ||
167 | * | ||
168 | * The localbus BRx registers only store the lower 32 bits of the address. To | ||
169 | * obtain the upper four bits, we need to scan the LAW table. The entry which | ||
170 | * maps to the localbus will contain the upper four bits. | ||
171 | */ | ||
172 | static phys_addr_t lbc_br_to_phys(const void *ecm, unsigned int count, u32 br) | ||
173 | { | ||
174 | #ifndef CONFIG_PHYS_64BIT | ||
175 | /* | ||
176 | * If we only have 32-bit addressing, then the BRx address *is* the | ||
177 | * physical address. | ||
178 | */ | ||
179 | return br & BR_BA; | ||
180 | #else | ||
181 | const struct fsl_law *law = ecm + 0xc08; | ||
182 | unsigned int i; | ||
183 | |||
184 | for (i = 0; i < count; i++) { | ||
185 | u64 lawbar = in_be32(&law[i].lawbar); | ||
186 | u32 lawar = in_be32(&law[i].lawar); | ||
187 | |||
188 | if ((lawar & LAWAR_MASK) == LAWAR_MATCH) | ||
189 | /* Extract the upper four bits */ | ||
190 | return (br & BR_BA) | ((lawbar & LAWBAR_MASK) << 12); | ||
191 | } | ||
192 | |||
193 | return 0; | ||
194 | #endif | ||
195 | } | ||
196 | |||
145 | /** | 197 | /** |
146 | * p1022ds_set_monitor_port: switch the output to a different monitor port | 198 | * p1022ds_set_monitor_port: switch the output to a different monitor port |
147 | * | ||
148 | */ | 199 | */ |
149 | static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | 200 | static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) |
150 | { | 201 | { |
151 | struct device_node *guts_node; | 202 | struct device_node *guts_node; |
152 | struct device_node *indirect_node = NULL; | 203 | struct device_node *lbc_node = NULL; |
204 | struct device_node *law_node = NULL; | ||
153 | struct ccsr_guts __iomem *guts; | 205 | struct ccsr_guts __iomem *guts; |
206 | struct fsl_lbc_regs *lbc = NULL; | ||
207 | void *ecm = NULL; | ||
154 | u8 __iomem *lbc_lcs0_ba = NULL; | 208 | u8 __iomem *lbc_lcs0_ba = NULL; |
155 | u8 __iomem *lbc_lcs1_ba = NULL; | 209 | u8 __iomem *lbc_lcs1_ba = NULL; |
210 | phys_addr_t cs0_addr, cs1_addr; | ||
211 | const __be32 *iprop; | ||
212 | unsigned int num_laws; | ||
156 | u8 b; | 213 | u8 b; |
157 | 214 | ||
158 | /* Map the global utilities registers. */ | 215 | /* Map the global utilities registers. */ |
@@ -168,24 +225,42 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) | |||
168 | goto exit; | 225 | goto exit; |
169 | } | 226 | } |
170 | 227 | ||
171 | indirect_node = of_find_compatible_node(NULL, NULL, | 228 | lbc_node = of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc"); |
172 | "fsl,p1022ds-indirect-pixis"); | 229 | if (!lbc_node) { |
173 | if (!indirect_node) { | 230 | pr_err("p1022ds: missing localbus node\n"); |
174 | pr_err("p1022ds: missing pixis indirect mode node\n"); | 231 | goto exit; |
232 | } | ||
233 | |||
234 | lbc = of_iomap(lbc_node, 0); | ||
235 | if (!lbc) { | ||
236 | pr_err("p1022ds: could not map localbus node\n"); | ||
237 | goto exit; | ||
238 | } | ||
239 | |||
240 | law_node = of_find_compatible_node(NULL, NULL, "fsl,ecm-law"); | ||
241 | if (!law_node) { | ||
242 | pr_err("p1022ds: missing local access window node\n"); | ||
175 | goto exit; | 243 | goto exit; |
176 | } | 244 | } |
177 | 245 | ||
178 | lbc_lcs0_ba = of_iomap(indirect_node, 0); | 246 | ecm = of_iomap(law_node, 0); |
179 | if (!lbc_lcs0_ba) { | 247 | if (!ecm) { |
180 | pr_err("p1022ds: could not map localbus chip select 0\n"); | 248 | pr_err("p1022ds: could not map local access window node\n"); |
181 | goto exit; | 249 | goto exit; |
182 | } | 250 | } |
183 | 251 | ||
184 | lbc_lcs1_ba = of_iomap(indirect_node, 1); | 252 | iprop = of_get_property(law_node, "fsl,num-laws", 0); |
185 | if (!lbc_lcs1_ba) { | 253 | if (!iprop) { |
186 | pr_err("p1022ds: could not map localbus chip select 1\n"); | 254 | pr_err("p1022ds: LAW node is missing fsl,num-laws property\n"); |
187 | goto exit; | 255 | goto exit; |
188 | } | 256 | } |
257 | num_laws = be32_to_cpup(iprop); | ||
258 | |||
259 | cs0_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[0].br)); | ||
260 | cs1_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[1].br)); | ||
261 | |||
262 | lbc_lcs0_ba = ioremap(cs0_addr, 1); | ||
263 | lbc_lcs1_ba = ioremap(cs1_addr, 1); | ||
189 | 264 | ||
190 | /* Make sure we're in indirect mode first. */ | 265 | /* Make sure we're in indirect mode first. */ |
191 | if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != | 266 | if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) != |
@@ -254,10 +329,15 @@ exit: | |||
254 | iounmap(lbc_lcs1_ba); | 329 | iounmap(lbc_lcs1_ba); |
255 | if (lbc_lcs0_ba) | 330 | if (lbc_lcs0_ba) |
256 | iounmap(lbc_lcs0_ba); | 331 | iounmap(lbc_lcs0_ba); |
332 | if (lbc) | ||
333 | iounmap(lbc); | ||
334 | if (ecm) | ||
335 | iounmap(ecm); | ||
257 | if (guts) | 336 | if (guts) |
258 | iounmap(guts); | 337 | iounmap(guts); |
259 | 338 | ||
260 | of_node_put(indirect_node); | 339 | of_node_put(law_node); |
340 | of_node_put(lbc_node); | ||
261 | of_node_put(guts_node); | 341 | of_node_put(guts_node); |
262 | } | 342 | } |
263 | 343 | ||
@@ -348,13 +428,7 @@ void __init p1022_ds_pic_init(void) | |||
348 | */ | 428 | */ |
349 | static void __init disable_one_node(struct device_node *np, struct property *new) | 429 | static void __init disable_one_node(struct device_node *np, struct property *new) |
350 | { | 430 | { |
351 | struct property *old; | 431 | prom_update_property(np, new); |
352 | |||
353 | old = of_find_property(np, new->name, NULL); | ||
354 | if (old) | ||
355 | prom_update_property(np, new, old); | ||
356 | else | ||
357 | prom_add_property(np, new); | ||
358 | } | 432 | } |
359 | 433 | ||
360 | /* TRUE if there is a "video=fslfb" command-line parameter. */ | 434 | /* TRUE if there is a "video=fslfb" command-line parameter. */ |
@@ -450,7 +524,7 @@ static void __init p1022_ds_setup_arch(void) | |||
450 | mpc85xx_smp_init(); | 524 | mpc85xx_smp_init(); |
451 | 525 | ||
452 | #ifdef CONFIG_SWIOTLB | 526 | #ifdef CONFIG_SWIOTLB |
453 | if (memblock_end_of_DRAM() > max) { | 527 | if ((memblock_end_of_DRAM() - 1) > max) { |
454 | ppc_swiotlb_enable = 1; | 528 | ppc_swiotlb_enable = 1; |
455 | set_pci_dma_ops(&swiotlb_dma_ops); | 529 | set_pci_dma_ops(&swiotlb_dma_ops); |
456 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 530 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/85xx/p3060_qds.c b/arch/powerpc/platforms/85xx/p3060_qds.c deleted file mode 100644 index 081cf4ac1881..000000000000 --- a/arch/powerpc/platforms/85xx/p3060_qds.c +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * P3060 QDS Setup | ||
3 | * | ||
4 | * Copyright 2011 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/phy.h> | ||
15 | #include <asm/machdep.h> | ||
16 | #include <asm/udbg.h> | ||
17 | #include <asm/mpic.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <sysdev/fsl_soc.h> | ||
20 | #include <sysdev/fsl_pci.h> | ||
21 | #include <asm/ehv_pic.h> | ||
22 | #include "corenet_ds.h" | ||
23 | |||
24 | /* | ||
25 | * Called very early, device-tree isn't unflattened | ||
26 | */ | ||
27 | static int __init p3060_qds_probe(void) | ||
28 | { | ||
29 | unsigned long root = of_get_flat_dt_root(); | ||
30 | #ifdef CONFIG_SMP | ||
31 | extern struct smp_ops_t smp_85xx_ops; | ||
32 | #endif | ||
33 | |||
34 | if (of_flat_dt_is_compatible(root, "fsl,P3060QDS")) | ||
35 | return 1; | ||
36 | |||
37 | /* Check if we're running under the Freescale hypervisor */ | ||
38 | if (of_flat_dt_is_compatible(root, "fsl,P3060QDS-hv")) { | ||
39 | ppc_md.init_IRQ = ehv_pic_init; | ||
40 | ppc_md.get_irq = ehv_pic_get_irq; | ||
41 | ppc_md.restart = fsl_hv_restart; | ||
42 | ppc_md.power_off = fsl_hv_halt; | ||
43 | ppc_md.halt = fsl_hv_halt; | ||
44 | #ifdef CONFIG_SMP | ||
45 | /* | ||
46 | * Disable the timebase sync operations because we can't write | ||
47 | * to the timebase registers under the hypervisor. | ||
48 | */ | ||
49 | smp_85xx_ops.give_timebase = NULL; | ||
50 | smp_85xx_ops.take_timebase = NULL; | ||
51 | #endif | ||
52 | return 1; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | define_machine(p3060_qds) { | ||
59 | .name = "P3060 QDS", | ||
60 | .probe = p3060_qds_probe, | ||
61 | .setup_arch = corenet_ds_setup_arch, | ||
62 | .init_IRQ = corenet_ds_pic_init, | ||
63 | #ifdef CONFIG_PCI | ||
64 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
65 | #endif | ||
66 | .get_irq = mpic_get_coreint_irq, | ||
67 | .restart = fsl_rstcr_restart, | ||
68 | .calibrate_decr = generic_calibrate_decr, | ||
69 | .progress = udbg_progress, | ||
70 | .power_save = e500_idle, | ||
71 | }; | ||
72 | |||
73 | machine_device_initcall(p3060_qds, corenet_ds_publish_devices); | ||
74 | |||
75 | #ifdef CONFIG_SWIOTLB | ||
76 | machine_arch_initcall(p3060_qds, swiotlb_setup_bus_notifier); | ||
77 | #endif | ||
diff --git a/arch/powerpc/platforms/85xx/qemu_e500.c b/arch/powerpc/platforms/85xx/qemu_e500.c new file mode 100644 index 000000000000..95a2e53af71b --- /dev/null +++ b/arch/powerpc/platforms/85xx/qemu_e500.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * Paravirt target for a generic QEMU e500 machine | ||
3 | * | ||
4 | * This is intended to be a flexible device-tree-driven platform, not fixed | ||
5 | * to a particular piece of hardware or a particular spec of virtual hardware, | ||
6 | * beyond the assumption of an e500-family CPU. Some things are still hardcoded | ||
7 | * here, such as MPIC, but this is a limitation of the current code rather than | ||
8 | * an interface contract with QEMU. | ||
9 | * | ||
10 | * Copyright 2012 Freescale Semiconductor Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/of_fdt.h> | ||
20 | #include <asm/machdep.h> | ||
21 | #include <asm/time.h> | ||
22 | #include <asm/udbg.h> | ||
23 | #include <asm/mpic.h> | ||
24 | #include <sysdev/fsl_soc.h> | ||
25 | #include <sysdev/fsl_pci.h> | ||
26 | #include "smp.h" | ||
27 | #include "mpc85xx.h" | ||
28 | |||
29 | void __init qemu_e500_pic_init(void) | ||
30 | { | ||
31 | struct mpic *mpic; | ||
32 | |||
33 | mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU, | ||
34 | 0, 256, " OpenPIC "); | ||
35 | |||
36 | BUG_ON(mpic == NULL); | ||
37 | mpic_init(mpic); | ||
38 | } | ||
39 | |||
40 | static void __init qemu_e500_setup_arch(void) | ||
41 | { | ||
42 | ppc_md.progress("qemu_e500_setup_arch()", 0); | ||
43 | |||
44 | fsl_pci_init(); | ||
45 | mpc85xx_smp_init(); | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * Called very early, device-tree isn't unflattened | ||
50 | */ | ||
51 | static int __init qemu_e500_probe(void) | ||
52 | { | ||
53 | unsigned long root = of_get_flat_dt_root(); | ||
54 | |||
55 | return !!of_flat_dt_is_compatible(root, "fsl,qemu-e500"); | ||
56 | } | ||
57 | |||
58 | machine_device_initcall(qemu_e500, mpc85xx_common_publish_devices); | ||
59 | |||
60 | define_machine(qemu_e500) { | ||
61 | .name = "QEMU e500", | ||
62 | .probe = qemu_e500_probe, | ||
63 | .setup_arch = qemu_e500_setup_arch, | ||
64 | .init_IRQ = qemu_e500_pic_init, | ||
65 | #ifdef CONFIG_PCI | ||
66 | .pcibios_fixup_bus = fsl_pcibios_fixup_bus, | ||
67 | #endif | ||
68 | .get_irq = mpic_get_irq, | ||
69 | .restart = fsl_rstcr_restart, | ||
70 | .calibrate_decr = generic_calibrate_decr, | ||
71 | .progress = udbg_progress, | ||
72 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c deleted file mode 100644 index b1be632ede43..000000000000 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ /dev/null | |||
@@ -1,254 +0,0 @@ | |||
1 | /* | ||
2 | * Wind River SBC8560 setup and early boot code. | ||
3 | * | ||
4 | * Copyright 2007 Wind River Systems Inc. | ||
5 | * | ||
6 | * By Paul Gortmaker (see MAINTAINERS for contact information) | ||
7 | * | ||
8 | * Based largely on the MPC8560ADS support - Copyright 2005 Freescale Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/stddef.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/kdev_t.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/of_platform.h> | ||
23 | |||
24 | #include <asm/time.h> | ||
25 | #include <asm/machdep.h> | ||
26 | #include <asm/pci-bridge.h> | ||
27 | #include <asm/mpic.h> | ||
28 | #include <mm/mmu_decl.h> | ||
29 | #include <asm/udbg.h> | ||
30 | |||
31 | #include <sysdev/fsl_soc.h> | ||
32 | #include <sysdev/fsl_pci.h> | ||
33 | |||
34 | #include "mpc85xx.h" | ||
35 | |||
36 | #ifdef CONFIG_CPM2 | ||
37 | #include <asm/cpm2.h> | ||
38 | #include <sysdev/cpm2_pic.h> | ||
39 | #endif | ||
40 | |||
41 | static void __init sbc8560_pic_init(void) | ||
42 | { | ||
43 | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN, | ||
44 | 0, 256, " OpenPIC "); | ||
45 | BUG_ON(mpic == NULL); | ||
46 | mpic_init(mpic); | ||
47 | |||
48 | mpc85xx_cpm2_pic_init(); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Setup the architecture | ||
53 | */ | ||
54 | #ifdef CONFIG_CPM2 | ||
55 | struct cpm_pin { | ||
56 | int port, pin, flags; | ||
57 | }; | ||
58 | |||
59 | static const struct cpm_pin sbc8560_pins[] = { | ||
60 | /* SCC1 */ | ||
61 | {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
62 | {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | ||
63 | {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
64 | |||
65 | /* SCC2 */ | ||
66 | {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
67 | {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
68 | {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
69 | |||
70 | /* FCC2 */ | ||
71 | {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
72 | {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
73 | {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
74 | {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
75 | {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
76 | {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
77 | {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
78 | {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
79 | {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
80 | {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
81 | {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
82 | {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, | ||
83 | {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
84 | {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
85 | {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK14 */ | ||
86 | {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK13 */ | ||
87 | |||
88 | /* FCC3 */ | ||
89 | {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
90 | {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
91 | {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
92 | {1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
93 | {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
94 | {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
95 | {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
96 | {1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
97 | {1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
98 | {1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
99 | {1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
100 | {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, | ||
101 | {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
102 | {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, | ||
103 | {2, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK16 */ | ||
104 | {2, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK15 */ | ||
105 | }; | ||
106 | |||
107 | static void __init init_ioports(void) | ||
108 | { | ||
109 | int i; | ||
110 | |||
111 | for (i = 0; i < ARRAY_SIZE(sbc8560_pins); i++) { | ||
112 | const struct cpm_pin *pin = &sbc8560_pins[i]; | ||
113 | cpm2_set_pin(pin->port, pin->pin, pin->flags); | ||
114 | } | ||
115 | |||
116 | cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX); | ||
117 | cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX); | ||
118 | cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX); | ||
119 | cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX); | ||
120 | cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX); | ||
121 | cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX); | ||
122 | cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX); | ||
123 | cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX); | ||
124 | } | ||
125 | #endif | ||
126 | |||
127 | static void __init sbc8560_setup_arch(void) | ||
128 | { | ||
129 | #ifdef CONFIG_PCI | ||
130 | struct device_node *np; | ||
131 | #endif | ||
132 | |||
133 | if (ppc_md.progress) | ||
134 | ppc_md.progress("sbc8560_setup_arch()", 0); | ||
135 | |||
136 | #ifdef CONFIG_CPM2 | ||
137 | cpm2_reset(); | ||
138 | init_ioports(); | ||
139 | #endif | ||
140 | |||
141 | #ifdef CONFIG_PCI | ||
142 | for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") | ||
143 | fsl_add_bridge(np, 1); | ||
144 | #endif | ||
145 | } | ||
146 | |||
147 | static void sbc8560_show_cpuinfo(struct seq_file *m) | ||
148 | { | ||
149 | uint pvid, svid, phid1; | ||
150 | |||
151 | pvid = mfspr(SPRN_PVR); | ||
152 | svid = mfspr(SPRN_SVR); | ||
153 | |||
154 | seq_printf(m, "Vendor\t\t: Wind River\n"); | ||
155 | seq_printf(m, "PVR\t\t: 0x%x\n", pvid); | ||
156 | seq_printf(m, "SVR\t\t: 0x%x\n", svid); | ||
157 | |||
158 | /* Display cpu Pll setting */ | ||
159 | phid1 = mfspr(SPRN_HID1); | ||
160 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | ||
161 | } | ||
162 | |||
163 | machine_device_initcall(sbc8560, mpc85xx_common_publish_devices); | ||
164 | |||
165 | /* | ||
166 | * Called very early, device-tree isn't unflattened | ||
167 | */ | ||
168 | static int __init sbc8560_probe(void) | ||
169 | { | ||
170 | unsigned long root = of_get_flat_dt_root(); | ||
171 | |||
172 | return of_flat_dt_is_compatible(root, "SBC8560"); | ||
173 | } | ||
174 | |||
175 | #ifdef CONFIG_RTC_DRV_M48T59 | ||
176 | static int __init sbc8560_rtc_init(void) | ||
177 | { | ||
178 | struct device_node *np; | ||
179 | struct resource res; | ||
180 | struct platform_device *rtc_dev; | ||
181 | |||
182 | np = of_find_compatible_node(NULL, NULL, "m48t59"); | ||
183 | if (np == NULL) { | ||
184 | printk("No RTC in DTB. Has it been eaten by wild dogs?\n"); | ||
185 | return -ENODEV; | ||
186 | } | ||
187 | |||
188 | of_address_to_resource(np, 0, &res); | ||
189 | of_node_put(np); | ||
190 | |||
191 | printk("Found RTC (m48t59) at i/o 0x%x\n", res.start); | ||
192 | |||
193 | rtc_dev = platform_device_register_simple("rtc-m48t59", 0, &res, 1); | ||
194 | |||
195 | if (IS_ERR(rtc_dev)) { | ||
196 | printk("Registering sbc8560 RTC device failed\n"); | ||
197 | return PTR_ERR(rtc_dev); | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | arch_initcall(sbc8560_rtc_init); | ||
204 | |||
205 | #endif /* M48T59 */ | ||
206 | |||
207 | static __u8 __iomem *brstcr; | ||
208 | |||
209 | static int __init sbc8560_bdrstcr_init(void) | ||
210 | { | ||
211 | struct device_node *np; | ||
212 | struct resource res; | ||
213 | |||
214 | np = of_find_compatible_node(NULL, NULL, "wrs,sbc8560-brstcr"); | ||
215 | if (np == NULL) { | ||
216 | printk(KERN_WARNING "sbc8560: No board specific RSTCR in DTB.\n"); | ||
217 | return -ENODEV; | ||
218 | } | ||
219 | |||
220 | of_address_to_resource(np, 0, &res); | ||
221 | |||
222 | printk(KERN_INFO "sbc8560: Found BRSTCR at %pR\n", &res); | ||
223 | |||
224 | brstcr = ioremap(res.start, resource_size(&res)); | ||
225 | if(!brstcr) | ||
226 | printk(KERN_WARNING "sbc8560: ioremap of brstcr failed.\n"); | ||
227 | |||
228 | of_node_put(np); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | arch_initcall(sbc8560_bdrstcr_init); | ||
234 | |||
235 | void sbc8560_rstcr_restart(char * cmd) | ||
236 | { | ||
237 | local_irq_disable(); | ||
238 | if(brstcr) | ||
239 | clrbits8(brstcr, 0x80); | ||
240 | |||
241 | while(1); | ||
242 | } | ||
243 | |||
244 | define_machine(sbc8560) { | ||
245 | .name = "SBC8560", | ||
246 | .probe = sbc8560_probe, | ||
247 | .setup_arch = sbc8560_setup_arch, | ||
248 | .init_IRQ = sbc8560_pic_init, | ||
249 | .show_cpuinfo = sbc8560_show_cpuinfo, | ||
250 | .get_irq = mpic_get_irq, | ||
251 | .restart = sbc8560_rstcr_restart, | ||
252 | .calibrate_decr = generic_calibrate_decr, | ||
253 | .progress = udbg_progress, | ||
254 | }; | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 3755e61d7ecf..817245bc0219 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -102,7 +102,7 @@ mpc86xx_hpcn_setup_arch(void) | |||
102 | #endif | 102 | #endif |
103 | 103 | ||
104 | #ifdef CONFIG_SWIOTLB | 104 | #ifdef CONFIG_SWIOTLB |
105 | if (memblock_end_of_DRAM() > max) { | 105 | if ((memblock_end_of_DRAM() - 1) > max) { |
106 | ppc_swiotlb_enable = 1; | 106 | ppc_swiotlb_enable = 1; |
107 | set_pci_dma_ops(&swiotlb_dma_ops); | 107 | set_pci_dma_ops(&swiotlb_dma_ops); |
108 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; | 108 | ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; |
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 61c9550819a2..30fd01de6bed 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype | |||
@@ -159,6 +159,10 @@ config PPC_E500MC | |||
159 | bool "e500mc Support" | 159 | bool "e500mc Support" |
160 | select PPC_FPU | 160 | select PPC_FPU |
161 | depends on E500 | 161 | depends on E500 |
162 | help | ||
163 | This must be enabled for running on e500mc (and derivatives | ||
164 | such as e5500/e6500), and must be disabled for running on | ||
165 | e500v1 or e500v2. | ||
162 | 166 | ||
163 | config PPC_FPU | 167 | config PPC_FPU |
164 | bool | 168 | bool |
diff --git a/arch/powerpc/platforms/cell/beat_hvCall.S b/arch/powerpc/platforms/cell/beat_hvCall.S index 74c817448948..96c801907126 100644 --- a/arch/powerpc/platforms/cell/beat_hvCall.S +++ b/arch/powerpc/platforms/cell/beat_hvCall.S | |||
@@ -22,8 +22,6 @@ | |||
22 | 22 | ||
23 | #include <asm/ppc_asm.h> | 23 | #include <asm/ppc_asm.h> |
24 | 24 | ||
25 | #define STK_PARM(i) (48 + ((i)-3)*8) | ||
26 | |||
27 | /* Not implemented on Beat, now */ | 25 | /* Not implemented on Beat, now */ |
28 | #define HCALL_INST_PRECALL | 26 | #define HCALL_INST_PRECALL |
29 | #define HCALL_INST_POSTCALL | 27 | #define HCALL_INST_POSTCALL |
@@ -74,7 +72,7 @@ _GLOBAL(beat_hcall_norets8) | |||
74 | mr r6,r7 | 72 | mr r6,r7 |
75 | mr r7,r8 | 73 | mr r7,r8 |
76 | mr r8,r9 | 74 | mr r8,r9 |
77 | ld r10,STK_PARM(r10)(r1) | 75 | ld r10,STK_PARAM(R10)(r1) |
78 | 76 | ||
79 | HVSC /* invoke the hypervisor */ | 77 | HVSC /* invoke the hypervisor */ |
80 | 78 | ||
@@ -94,7 +92,7 @@ _GLOBAL(beat_hcall1) | |||
94 | 92 | ||
95 | HCALL_INST_PRECALL | 93 | HCALL_INST_PRECALL |
96 | 94 | ||
97 | std r4,STK_PARM(r4)(r1) /* save ret buffer */ | 95 | std r4,STK_PARAM(R4)(r1) /* save ret buffer */ |
98 | 96 | ||
99 | mr r11,r3 | 97 | mr r11,r3 |
100 | mr r3,r5 | 98 | mr r3,r5 |
@@ -108,7 +106,7 @@ _GLOBAL(beat_hcall1) | |||
108 | 106 | ||
109 | HCALL_INST_POSTCALL | 107 | HCALL_INST_POSTCALL |
110 | 108 | ||
111 | ld r12,STK_PARM(r4)(r1) | 109 | ld r12,STK_PARAM(R4)(r1) |
112 | std r4, 0(r12) | 110 | std r4, 0(r12) |
113 | 111 | ||
114 | lwz r0,8(r1) | 112 | lwz r0,8(r1) |
@@ -125,7 +123,7 @@ _GLOBAL(beat_hcall2) | |||
125 | 123 | ||
126 | HCALL_INST_PRECALL | 124 | HCALL_INST_PRECALL |
127 | 125 | ||
128 | std r4,STK_PARM(r4)(r1) /* save ret buffer */ | 126 | std r4,STK_PARAM(R4)(r1) /* save ret buffer */ |
129 | 127 | ||
130 | mr r11,r3 | 128 | mr r11,r3 |
131 | mr r3,r5 | 129 | mr r3,r5 |
@@ -139,7 +137,7 @@ _GLOBAL(beat_hcall2) | |||
139 | 137 | ||
140 | HCALL_INST_POSTCALL | 138 | HCALL_INST_POSTCALL |
141 | 139 | ||
142 | ld r12,STK_PARM(r4)(r1) | 140 | ld r12,STK_PARAM(R4)(r1) |
143 | std r4, 0(r12) | 141 | std r4, 0(r12) |
144 | std r5, 8(r12) | 142 | std r5, 8(r12) |
145 | 143 | ||
@@ -157,7 +155,7 @@ _GLOBAL(beat_hcall3) | |||
157 | 155 | ||
158 | HCALL_INST_PRECALL | 156 | HCALL_INST_PRECALL |
159 | 157 | ||
160 | std r4,STK_PARM(r4)(r1) /* save ret buffer */ | 158 | std r4,STK_PARAM(R4)(r1) /* save ret buffer */ |
161 | 159 | ||
162 | mr r11,r3 | 160 | mr r11,r3 |
163 | mr r3,r5 | 161 | mr r3,r5 |
@@ -171,7 +169,7 @@ _GLOBAL(beat_hcall3) | |||
171 | 169 | ||
172 | HCALL_INST_POSTCALL | 170 | HCALL_INST_POSTCALL |
173 | 171 | ||
174 | ld r12,STK_PARM(r4)(r1) | 172 | ld r12,STK_PARAM(R4)(r1) |
175 | std r4, 0(r12) | 173 | std r4, 0(r12) |
176 | std r5, 8(r12) | 174 | std r5, 8(r12) |
177 | std r6, 16(r12) | 175 | std r6, 16(r12) |
@@ -190,7 +188,7 @@ _GLOBAL(beat_hcall4) | |||
190 | 188 | ||
191 | HCALL_INST_PRECALL | 189 | HCALL_INST_PRECALL |
192 | 190 | ||
193 | std r4,STK_PARM(r4)(r1) /* save ret buffer */ | 191 | std r4,STK_PARAM(R4)(r1) /* save ret buffer */ |
194 | 192 | ||
195 | mr r11,r3 | 193 | mr r11,r3 |
196 | mr r3,r5 | 194 | mr r3,r5 |
@@ -204,7 +202,7 @@ _GLOBAL(beat_hcall4) | |||
204 | 202 | ||
205 | HCALL_INST_POSTCALL | 203 | HCALL_INST_POSTCALL |
206 | 204 | ||
207 | ld r12,STK_PARM(r4)(r1) | 205 | ld r12,STK_PARAM(R4)(r1) |
208 | std r4, 0(r12) | 206 | std r4, 0(r12) |
209 | std r5, 8(r12) | 207 | std r5, 8(r12) |
210 | std r6, 16(r12) | 208 | std r6, 16(r12) |
@@ -224,7 +222,7 @@ _GLOBAL(beat_hcall5) | |||
224 | 222 | ||
225 | HCALL_INST_PRECALL | 223 | HCALL_INST_PRECALL |
226 | 224 | ||
227 | std r4,STK_PARM(r4)(r1) /* save ret buffer */ | 225 | std r4,STK_PARAM(R4)(r1) /* save ret buffer */ |
228 | 226 | ||
229 | mr r11,r3 | 227 | mr r11,r3 |
230 | mr r3,r5 | 228 | mr r3,r5 |
@@ -238,7 +236,7 @@ _GLOBAL(beat_hcall5) | |||
238 | 236 | ||
239 | HCALL_INST_POSTCALL | 237 | HCALL_INST_POSTCALL |
240 | 238 | ||
241 | ld r12,STK_PARM(r4)(r1) | 239 | ld r12,STK_PARAM(R4)(r1) |
242 | std r4, 0(r12) | 240 | std r4, 0(r12) |
243 | std r5, 8(r12) | 241 | std r5, 8(r12) |
244 | std r6, 16(r12) | 242 | std r6, 16(r12) |
@@ -259,7 +257,7 @@ _GLOBAL(beat_hcall6) | |||
259 | 257 | ||
260 | HCALL_INST_PRECALL | 258 | HCALL_INST_PRECALL |
261 | 259 | ||
262 | std r4,STK_PARM(r4)(r1) /* save ret buffer */ | 260 | std r4,STK_PARAM(R4)(r1) /* save ret buffer */ |
263 | 261 | ||
264 | mr r11,r3 | 262 | mr r11,r3 |
265 | mr r3,r5 | 263 | mr r3,r5 |
@@ -273,7 +271,7 @@ _GLOBAL(beat_hcall6) | |||
273 | 271 | ||
274 | HCALL_INST_POSTCALL | 272 | HCALL_INST_POSTCALL |
275 | 273 | ||
276 | ld r12,STK_PARM(r4)(r1) | 274 | ld r12,STK_PARAM(R4)(r1) |
277 | std r4, 0(r12) | 275 | std r4, 0(r12) |
278 | std r5, 8(r12) | 276 | std r5, 8(r12) |
279 | std r6, 16(r12) | 277 | std r6, 16(r12) |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index b9f509a34c01..c264969c9319 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -518,7 +518,6 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, | |||
518 | __set_bit(0, window->table.it_map); | 518 | __set_bit(0, window->table.it_map); |
519 | tce_build_cell(&window->table, window->table.it_offset, 1, | 519 | tce_build_cell(&window->table, window->table.it_offset, 1, |
520 | (unsigned long)iommu->pad_page, DMA_TO_DEVICE, NULL); | 520 | (unsigned long)iommu->pad_page, DMA_TO_DEVICE, NULL); |
521 | window->table.it_hint = window->table.it_blocksize; | ||
522 | 521 | ||
523 | return window; | 522 | return window; |
524 | } | 523 | } |
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index efdacc829576..d17e98bc0c10 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c | |||
@@ -42,11 +42,9 @@ static void cbe_power_save(void) | |||
42 | { | 42 | { |
43 | unsigned long ctrl, thread_switch_control; | 43 | unsigned long ctrl, thread_switch_control; |
44 | 44 | ||
45 | /* | 45 | /* Ensure our interrupt state is properly tracked */ |
46 | * We need to hard disable interrupts, the local_irq_enable() done by | 46 | if (!prep_irq_for_idle()) |
47 | * our caller upon return will hard re-enable. | 47 | return; |
48 | */ | ||
49 | hard_irq_disable(); | ||
50 | 48 | ||
51 | ctrl = mfspr(SPRN_CTRLF); | 49 | ctrl = mfspr(SPRN_CTRLF); |
52 | 50 | ||
@@ -81,6 +79,9 @@ static void cbe_power_save(void) | |||
81 | */ | 79 | */ |
82 | ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); | 80 | ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); |
83 | mtspr(SPRN_CTRLT, ctrl); | 81 | mtspr(SPRN_CTRLT, ctrl); |
82 | |||
83 | /* Re-enable interrupts in MSR */ | ||
84 | __hard_irq_enable(); | ||
84 | } | 85 | } |
85 | 86 | ||
86 | static int cbe_system_reset_exception(struct pt_regs *regs) | 87 | static int cbe_system_reset_exception(struct pt_regs *regs) |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 66519d263da7..d544d7816df3 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -317,28 +317,23 @@ out: | |||
317 | return ret; | 317 | return ret; |
318 | } | 318 | } |
319 | 319 | ||
320 | static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) | 320 | static int spufs_context_open(struct path *path) |
321 | { | 321 | { |
322 | int ret; | 322 | int ret; |
323 | struct file *filp; | 323 | struct file *filp; |
324 | 324 | ||
325 | ret = get_unused_fd(); | 325 | ret = get_unused_fd(); |
326 | if (ret < 0) { | 326 | if (ret < 0) |
327 | dput(dentry); | 327 | return ret; |
328 | mntput(mnt); | ||
329 | goto out; | ||
330 | } | ||
331 | 328 | ||
332 | filp = dentry_open(dentry, mnt, O_RDONLY, current_cred()); | 329 | filp = dentry_open(path, O_RDONLY, current_cred()); |
333 | if (IS_ERR(filp)) { | 330 | if (IS_ERR(filp)) { |
334 | put_unused_fd(ret); | 331 | put_unused_fd(ret); |
335 | ret = PTR_ERR(filp); | 332 | return PTR_ERR(filp); |
336 | goto out; | ||
337 | } | 333 | } |
338 | 334 | ||
339 | filp->f_op = &spufs_context_fops; | 335 | filp->f_op = &spufs_context_fops; |
340 | fd_install(ret, filp); | 336 | fd_install(ret, filp); |
341 | out: | ||
342 | return ret; | 337 | return ret; |
343 | } | 338 | } |
344 | 339 | ||
@@ -453,6 +448,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, | |||
453 | int affinity; | 448 | int affinity; |
454 | struct spu_gang *gang; | 449 | struct spu_gang *gang; |
455 | struct spu_context *neighbor; | 450 | struct spu_context *neighbor; |
451 | struct path path = {.mnt = mnt, .dentry = dentry}; | ||
456 | 452 | ||
457 | ret = -EPERM; | 453 | ret = -EPERM; |
458 | if ((flags & SPU_CREATE_NOSCHED) && | 454 | if ((flags & SPU_CREATE_NOSCHED) && |
@@ -495,11 +491,7 @@ spufs_create_context(struct inode *inode, struct dentry *dentry, | |||
495 | put_spu_context(neighbor); | 491 | put_spu_context(neighbor); |
496 | } | 492 | } |
497 | 493 | ||
498 | /* | 494 | ret = spufs_context_open(&path); |
499 | * get references for dget and mntget, will be released | ||
500 | * in error path of *_open(). | ||
501 | */ | ||
502 | ret = spufs_context_open(dget(dentry), mntget(mnt)); | ||
503 | if (ret < 0) { | 495 | if (ret < 0) { |
504 | WARN_ON(spufs_rmdir(inode, dentry)); | 496 | WARN_ON(spufs_rmdir(inode, dentry)); |
505 | if (affinity) | 497 | if (affinity) |
@@ -556,28 +548,27 @@ out: | |||
556 | return ret; | 548 | return ret; |
557 | } | 549 | } |
558 | 550 | ||
559 | static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) | 551 | static int spufs_gang_open(struct path *path) |
560 | { | 552 | { |
561 | int ret; | 553 | int ret; |
562 | struct file *filp; | 554 | struct file *filp; |
563 | 555 | ||
564 | ret = get_unused_fd(); | 556 | ret = get_unused_fd(); |
565 | if (ret < 0) { | 557 | if (ret < 0) |
566 | dput(dentry); | 558 | return ret; |
567 | mntput(mnt); | ||
568 | goto out; | ||
569 | } | ||
570 | 559 | ||
571 | filp = dentry_open(dentry, mnt, O_RDONLY, current_cred()); | 560 | /* |
561 | * get references for dget and mntget, will be released | ||
562 | * in error path of *_open(). | ||
563 | */ | ||
564 | filp = dentry_open(path, O_RDONLY, current_cred()); | ||
572 | if (IS_ERR(filp)) { | 565 | if (IS_ERR(filp)) { |
573 | put_unused_fd(ret); | 566 | put_unused_fd(ret); |
574 | ret = PTR_ERR(filp); | 567 | return PTR_ERR(filp); |
575 | goto out; | ||
576 | } | 568 | } |
577 | 569 | ||
578 | filp->f_op = &simple_dir_operations; | 570 | filp->f_op = &simple_dir_operations; |
579 | fd_install(ret, filp); | 571 | fd_install(ret, filp); |
580 | out: | ||
581 | return ret; | 572 | return ret; |
582 | } | 573 | } |
583 | 574 | ||
@@ -585,17 +576,14 @@ static int spufs_create_gang(struct inode *inode, | |||
585 | struct dentry *dentry, | 576 | struct dentry *dentry, |
586 | struct vfsmount *mnt, umode_t mode) | 577 | struct vfsmount *mnt, umode_t mode) |
587 | { | 578 | { |
579 | struct path path = {.mnt = mnt, .dentry = dentry}; | ||
588 | int ret; | 580 | int ret; |
589 | 581 | ||
590 | ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); | 582 | ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); |
591 | if (ret) | 583 | if (ret) |
592 | goto out; | 584 | goto out; |
593 | 585 | ||
594 | /* | 586 | ret = spufs_gang_open(&path); |
595 | * get references for dget and mntget, will be released | ||
596 | * in error path of *_open(). | ||
597 | */ | ||
598 | ret = spufs_gang_open(dget(dentry), mntget(mnt)); | ||
599 | if (ret < 0) { | 587 | if (ret < 0) { |
600 | int err = simple_rmdir(inode, dentry); | 588 | int err = simple_rmdir(inode, dentry); |
601 | WARN_ON(err); | 589 | WARN_ON(err); |
diff --git a/arch/powerpc/platforms/powernv/opal-takeover.S b/arch/powerpc/platforms/powernv/opal-takeover.S index 77b48b2b9309..3cd262897c27 100644 --- a/arch/powerpc/platforms/powernv/opal-takeover.S +++ b/arch/powerpc/platforms/powernv/opal-takeover.S | |||
@@ -14,8 +14,6 @@ | |||
14 | #include <asm/asm-offsets.h> | 14 | #include <asm/asm-offsets.h> |
15 | #include <asm/opal.h> | 15 | #include <asm/opal.h> |
16 | 16 | ||
17 | #define STK_PARAM(i) (48 + ((i)-3)*8) | ||
18 | |||
19 | #define H_HAL_TAKEOVER 0x5124 | 17 | #define H_HAL_TAKEOVER 0x5124 |
20 | #define H_HAL_TAKEOVER_QUERY_MAGIC -1 | 18 | #define H_HAL_TAKEOVER_QUERY_MAGIC -1 |
21 | 19 | ||
@@ -23,14 +21,14 @@ | |||
23 | _GLOBAL(opal_query_takeover) | 21 | _GLOBAL(opal_query_takeover) |
24 | mfcr r0 | 22 | mfcr r0 |
25 | stw r0,8(r1) | 23 | stw r0,8(r1) |
26 | std r3,STK_PARAM(r3)(r1) | 24 | std r3,STK_PARAM(R3)(r1) |
27 | std r4,STK_PARAM(r4)(r1) | 25 | std r4,STK_PARAM(R4)(r1) |
28 | li r3,H_HAL_TAKEOVER | 26 | li r3,H_HAL_TAKEOVER |
29 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC | 27 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC |
30 | HVSC | 28 | HVSC |
31 | ld r10,STK_PARAM(r3)(r1) | 29 | ld r10,STK_PARAM(R3)(r1) |
32 | std r4,0(r10) | 30 | std r4,0(r10) |
33 | ld r10,STK_PARAM(r4)(r1) | 31 | ld r10,STK_PARAM(R4)(r1) |
34 | std r5,0(r10) | 32 | std r5,0(r10) |
35 | lwz r0,8(r1) | 33 | lwz r0,8(r1) |
36 | mtcrf 0xff,r0 | 34 | mtcrf 0xff,r0 |
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index 4cb375c0f8d1..fb506317ebb0 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c | |||
@@ -85,8 +85,10 @@ static int eeh_event_handler(void * dummy) | |||
85 | set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */ | 85 | set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */ |
86 | edev = handle_eeh_events(event); | 86 | edev = handle_eeh_events(event); |
87 | 87 | ||
88 | eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING); | 88 | if (edev) { |
89 | pci_dev_put(edev->pdev); | 89 | eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING); |
90 | pci_dev_put(edev->pdev); | ||
91 | } | ||
90 | 92 | ||
91 | kfree(event); | 93 | kfree(event); |
92 | mutex_unlock(&eeh_event_mutex); | 94 | mutex_unlock(&eeh_event_mutex); |
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 8752f79a6af8..c33360ec4f4f 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c | |||
@@ -81,7 +81,7 @@ static int pseries_eeh_init(void) | |||
81 | ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); | 81 | ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); |
82 | ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); | 82 | ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); |
83 | ibm_configure_pe = rtas_token("ibm,configure-pe"); | 83 | ibm_configure_pe = rtas_token("ibm,configure-pe"); |
84 | ibm_configure_bridge = rtas_token ("ibm,configure-bridge"); | 84 | ibm_configure_bridge = rtas_token("ibm,configure-bridge"); |
85 | 85 | ||
86 | /* necessary sanity check */ | 86 | /* necessary sanity check */ |
87 | if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { | 87 | if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) { |
@@ -89,7 +89,7 @@ static int pseries_eeh_init(void) | |||
89 | __func__); | 89 | __func__); |
90 | return -EINVAL; | 90 | return -EINVAL; |
91 | } else if (ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE) { | 91 | } else if (ibm_set_slot_reset == RTAS_UNKNOWN_SERVICE) { |
92 | pr_warning("%s: RTAS service <ibm, set-slot-reset> invalid\n", | 92 | pr_warning("%s: RTAS service <ibm,set-slot-reset> invalid\n", |
93 | __func__); | 93 | __func__); |
94 | return -EINVAL; | 94 | return -EINVAL; |
95 | } else if (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE && | 95 | } else if (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE && |
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 3ce73d0052b1..444fe7759e55 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S | |||
@@ -13,8 +13,6 @@ | |||
13 | #include <asm/asm-offsets.h> | 13 | #include <asm/asm-offsets.h> |
14 | #include <asm/ptrace.h> | 14 | #include <asm/ptrace.h> |
15 | 15 | ||
16 | #define STK_PARM(i) (48 + ((i)-3)*8) | ||
17 | |||
18 | #ifdef CONFIG_TRACEPOINTS | 16 | #ifdef CONFIG_TRACEPOINTS |
19 | 17 | ||
20 | .section ".toc","aw" | 18 | .section ".toc","aw" |
@@ -26,7 +24,7 @@ hcall_tracepoint_refcount: | |||
26 | .section ".text" | 24 | .section ".text" |
27 | 25 | ||
28 | /* | 26 | /* |
29 | * precall must preserve all registers. use unused STK_PARM() | 27 | * precall must preserve all registers. use unused STK_PARAM() |
30 | * areas to save snapshots and opcode. We branch around this | 28 | * areas to save snapshots and opcode. We branch around this |
31 | * in early init (eg when populating the MMU hashtable) by using an | 29 | * in early init (eg when populating the MMU hashtable) by using an |
32 | * unconditional cpu feature. | 30 | * unconditional cpu feature. |
@@ -40,28 +38,28 @@ END_FTR_SECTION(0, 1); \ | |||
40 | cmpdi r12,0; \ | 38 | cmpdi r12,0; \ |
41 | beq+ 1f; \ | 39 | beq+ 1f; \ |
42 | mflr r0; \ | 40 | mflr r0; \ |
43 | std r3,STK_PARM(r3)(r1); \ | 41 | std r3,STK_PARAM(R3)(r1); \ |
44 | std r4,STK_PARM(r4)(r1); \ | 42 | std r4,STK_PARAM(R4)(r1); \ |
45 | std r5,STK_PARM(r5)(r1); \ | 43 | std r5,STK_PARAM(R5)(r1); \ |
46 | std r6,STK_PARM(r6)(r1); \ | 44 | std r6,STK_PARAM(R6)(r1); \ |
47 | std r7,STK_PARM(r7)(r1); \ | 45 | std r7,STK_PARAM(R7)(r1); \ |
48 | std r8,STK_PARM(r8)(r1); \ | 46 | std r8,STK_PARAM(R8)(r1); \ |
49 | std r9,STK_PARM(r9)(r1); \ | 47 | std r9,STK_PARAM(R9)(r1); \ |
50 | std r10,STK_PARM(r10)(r1); \ | 48 | std r10,STK_PARAM(R10)(r1); \ |
51 | std r0,16(r1); \ | 49 | std r0,16(r1); \ |
52 | addi r4,r1,STK_PARM(FIRST_REG); \ | 50 | addi r4,r1,STK_PARAM(FIRST_REG); \ |
53 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ | 51 | stdu r1,-STACK_FRAME_OVERHEAD(r1); \ |
54 | bl .__trace_hcall_entry; \ | 52 | bl .__trace_hcall_entry; \ |
55 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | 53 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
56 | ld r0,16(r1); \ | 54 | ld r0,16(r1); \ |
57 | ld r3,STK_PARM(r3)(r1); \ | 55 | ld r3,STK_PARAM(R3)(r1); \ |
58 | ld r4,STK_PARM(r4)(r1); \ | 56 | ld r4,STK_PARAM(R4)(r1); \ |
59 | ld r5,STK_PARM(r5)(r1); \ | 57 | ld r5,STK_PARAM(R5)(r1); \ |
60 | ld r6,STK_PARM(r6)(r1); \ | 58 | ld r6,STK_PARAM(R6)(r1); \ |
61 | ld r7,STK_PARM(r7)(r1); \ | 59 | ld r7,STK_PARAM(R7)(r1); \ |
62 | ld r8,STK_PARM(r8)(r1); \ | 60 | ld r8,STK_PARAM(R8)(r1); \ |
63 | ld r9,STK_PARM(r9)(r1); \ | 61 | ld r9,STK_PARAM(R9)(r1); \ |
64 | ld r10,STK_PARM(r10)(r1); \ | 62 | ld r10,STK_PARAM(R10)(r1); \ |
65 | mtlr r0; \ | 63 | mtlr r0; \ |
66 | 1: | 64 | 1: |
67 | 65 | ||
@@ -79,8 +77,8 @@ END_FTR_SECTION(0, 1); \ | |||
79 | cmpdi r12,0; \ | 77 | cmpdi r12,0; \ |
80 | beq+ 1f; \ | 78 | beq+ 1f; \ |
81 | mflr r0; \ | 79 | mflr r0; \ |
82 | ld r6,STK_PARM(r3)(r1); \ | 80 | ld r6,STK_PARAM(R3)(r1); \ |
83 | std r3,STK_PARM(r3)(r1); \ | 81 | std r3,STK_PARAM(R3)(r1); \ |
84 | mr r4,r3; \ | 82 | mr r4,r3; \ |
85 | mr r3,r6; \ | 83 | mr r3,r6; \ |
86 | std r0,16(r1); \ | 84 | std r0,16(r1); \ |
@@ -88,7 +86,7 @@ END_FTR_SECTION(0, 1); \ | |||
88 | bl .__trace_hcall_exit; \ | 86 | bl .__trace_hcall_exit; \ |
89 | addi r1,r1,STACK_FRAME_OVERHEAD; \ | 87 | addi r1,r1,STACK_FRAME_OVERHEAD; \ |
90 | ld r0,16(r1); \ | 88 | ld r0,16(r1); \ |
91 | ld r3,STK_PARM(r3)(r1); \ | 89 | ld r3,STK_PARAM(R3)(r1); \ |
92 | mtlr r0; \ | 90 | mtlr r0; \ |
93 | 1: | 91 | 1: |
94 | 92 | ||
@@ -114,7 +112,7 @@ _GLOBAL(plpar_hcall_norets) | |||
114 | mfcr r0 | 112 | mfcr r0 |
115 | stw r0,8(r1) | 113 | stw r0,8(r1) |
116 | 114 | ||
117 | HCALL_INST_PRECALL(r4) | 115 | HCALL_INST_PRECALL(R4) |
118 | 116 | ||
119 | HVSC /* invoke the hypervisor */ | 117 | HVSC /* invoke the hypervisor */ |
120 | 118 | ||
@@ -130,9 +128,9 @@ _GLOBAL(plpar_hcall) | |||
130 | mfcr r0 | 128 | mfcr r0 |
131 | stw r0,8(r1) | 129 | stw r0,8(r1) |
132 | 130 | ||
133 | HCALL_INST_PRECALL(r5) | 131 | HCALL_INST_PRECALL(R5) |
134 | 132 | ||
135 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | 133 | std r4,STK_PARAM(R4)(r1) /* Save ret buffer */ |
136 | 134 | ||
137 | mr r4,r5 | 135 | mr r4,r5 |
138 | mr r5,r6 | 136 | mr r5,r6 |
@@ -143,7 +141,7 @@ _GLOBAL(plpar_hcall) | |||
143 | 141 | ||
144 | HVSC /* invoke the hypervisor */ | 142 | HVSC /* invoke the hypervisor */ |
145 | 143 | ||
146 | ld r12,STK_PARM(r4)(r1) | 144 | ld r12,STK_PARAM(R4)(r1) |
147 | std r4, 0(r12) | 145 | std r4, 0(r12) |
148 | std r5, 8(r12) | 146 | std r5, 8(r12) |
149 | std r6, 16(r12) | 147 | std r6, 16(r12) |
@@ -168,7 +166,7 @@ _GLOBAL(plpar_hcall_raw) | |||
168 | mfcr r0 | 166 | mfcr r0 |
169 | stw r0,8(r1) | 167 | stw r0,8(r1) |
170 | 168 | ||
171 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | 169 | std r4,STK_PARAM(R4)(r1) /* Save ret buffer */ |
172 | 170 | ||
173 | mr r4,r5 | 171 | mr r4,r5 |
174 | mr r5,r6 | 172 | mr r5,r6 |
@@ -179,7 +177,7 @@ _GLOBAL(plpar_hcall_raw) | |||
179 | 177 | ||
180 | HVSC /* invoke the hypervisor */ | 178 | HVSC /* invoke the hypervisor */ |
181 | 179 | ||
182 | ld r12,STK_PARM(r4)(r1) | 180 | ld r12,STK_PARAM(R4)(r1) |
183 | std r4, 0(r12) | 181 | std r4, 0(r12) |
184 | std r5, 8(r12) | 182 | std r5, 8(r12) |
185 | std r6, 16(r12) | 183 | std r6, 16(r12) |
@@ -196,9 +194,9 @@ _GLOBAL(plpar_hcall9) | |||
196 | mfcr r0 | 194 | mfcr r0 |
197 | stw r0,8(r1) | 195 | stw r0,8(r1) |
198 | 196 | ||
199 | HCALL_INST_PRECALL(r5) | 197 | HCALL_INST_PRECALL(R5) |
200 | 198 | ||
201 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | 199 | std r4,STK_PARAM(R4)(r1) /* Save ret buffer */ |
202 | 200 | ||
203 | mr r4,r5 | 201 | mr r4,r5 |
204 | mr r5,r6 | 202 | mr r5,r6 |
@@ -206,14 +204,14 @@ _GLOBAL(plpar_hcall9) | |||
206 | mr r7,r8 | 204 | mr r7,r8 |
207 | mr r8,r9 | 205 | mr r8,r9 |
208 | mr r9,r10 | 206 | mr r9,r10 |
209 | ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ | 207 | ld r10,STK_PARAM(R11)(r1) /* put arg7 in R10 */ |
210 | ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ | 208 | ld r11,STK_PARAM(R12)(r1) /* put arg8 in R11 */ |
211 | ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ | 209 | ld r12,STK_PARAM(R13)(r1) /* put arg9 in R12 */ |
212 | 210 | ||
213 | HVSC /* invoke the hypervisor */ | 211 | HVSC /* invoke the hypervisor */ |
214 | 212 | ||
215 | mr r0,r12 | 213 | mr r0,r12 |
216 | ld r12,STK_PARM(r4)(r1) | 214 | ld r12,STK_PARAM(R4)(r1) |
217 | std r4, 0(r12) | 215 | std r4, 0(r12) |
218 | std r5, 8(r12) | 216 | std r5, 8(r12) |
219 | std r6, 16(r12) | 217 | std r6, 16(r12) |
@@ -238,7 +236,7 @@ _GLOBAL(plpar_hcall9_raw) | |||
238 | mfcr r0 | 236 | mfcr r0 |
239 | stw r0,8(r1) | 237 | stw r0,8(r1) |
240 | 238 | ||
241 | std r4,STK_PARM(r4)(r1) /* Save ret buffer */ | 239 | std r4,STK_PARAM(R4)(r1) /* Save ret buffer */ |
242 | 240 | ||
243 | mr r4,r5 | 241 | mr r4,r5 |
244 | mr r5,r6 | 242 | mr r5,r6 |
@@ -246,14 +244,14 @@ _GLOBAL(plpar_hcall9_raw) | |||
246 | mr r7,r8 | 244 | mr r7,r8 |
247 | mr r8,r9 | 245 | mr r8,r9 |
248 | mr r9,r10 | 246 | mr r9,r10 |
249 | ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ | 247 | ld r10,STK_PARAM(R11)(r1) /* put arg7 in R10 */ |
250 | ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ | 248 | ld r11,STK_PARAM(R12)(r1) /* put arg8 in R11 */ |
251 | ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ | 249 | ld r12,STK_PARAM(R13)(r1) /* put arg9 in R12 */ |
252 | 250 | ||
253 | HVSC /* invoke the hypervisor */ | 251 | HVSC /* invoke the hypervisor */ |
254 | 252 | ||
255 | mr r0,r12 | 253 | mr r0,r12 |
256 | ld r12,STK_PARM(r4)(r1) | 254 | ld r12,STK_PARAM(R4)(r1) |
257 | std r4, 0(r12) | 255 | std r4, 0(r12) |
258 | std r5, 8(r12) | 256 | std r5, 8(r12) |
259 | std r6, 16(r12) | 257 | std r6, 16(r12) |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 0915b1ad66ce..07c09cbbfb19 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -106,7 +106,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, | |||
106 | tcep++; | 106 | tcep++; |
107 | } | 107 | } |
108 | 108 | ||
109 | if (tbl->it_type == TCE_PCI_SWINV_CREATE) | 109 | if (tbl->it_type & TCE_PCI_SWINV_CREATE) |
110 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); | 110 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); |
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
@@ -121,7 +121,7 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | |||
121 | while (npages--) | 121 | while (npages--) |
122 | *(tcep++) = 0; | 122 | *(tcep++) = 0; |
123 | 123 | ||
124 | if (tbl->it_type == TCE_PCI_SWINV_FREE) | 124 | if (tbl->it_type & TCE_PCI_SWINV_FREE) |
125 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); | 125 | tce_invalidate_pSeries_sw(tbl, tces, tcep - 1); |
126 | } | 126 | } |
127 | 127 | ||
@@ -192,12 +192,15 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
192 | long l, limit; | 192 | long l, limit; |
193 | long tcenum_start = tcenum, npages_start = npages; | 193 | long tcenum_start = tcenum, npages_start = npages; |
194 | int ret = 0; | 194 | int ret = 0; |
195 | unsigned long flags; | ||
195 | 196 | ||
196 | if (npages == 1) { | 197 | if (npages == 1) { |
197 | return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, | 198 | return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, |
198 | direction, attrs); | 199 | direction, attrs); |
199 | } | 200 | } |
200 | 201 | ||
202 | local_irq_save(flags); /* to protect tcep and the page behind it */ | ||
203 | |||
201 | tcep = __get_cpu_var(tce_page); | 204 | tcep = __get_cpu_var(tce_page); |
202 | 205 | ||
203 | /* This is safe to do since interrupts are off when we're called | 206 | /* This is safe to do since interrupts are off when we're called |
@@ -207,6 +210,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
207 | tcep = (u64 *)__get_free_page(GFP_ATOMIC); | 210 | tcep = (u64 *)__get_free_page(GFP_ATOMIC); |
208 | /* If allocation fails, fall back to the loop implementation */ | 211 | /* If allocation fails, fall back to the loop implementation */ |
209 | if (!tcep) { | 212 | if (!tcep) { |
213 | local_irq_restore(flags); | ||
210 | return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, | 214 | return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, |
211 | direction, attrs); | 215 | direction, attrs); |
212 | } | 216 | } |
@@ -240,6 +244,8 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
240 | tcenum += limit; | 244 | tcenum += limit; |
241 | } while (npages > 0 && !rc); | 245 | } while (npages > 0 && !rc); |
242 | 246 | ||
247 | local_irq_restore(flags); | ||
248 | |||
243 | if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) { | 249 | if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) { |
244 | ret = (int)rc; | 250 | ret = (int)rc; |
245 | tce_freemulti_pSeriesLP(tbl, tcenum_start, | 251 | tce_freemulti_pSeriesLP(tbl, tcenum_start, |
@@ -707,6 +713,21 @@ static int __init disable_ddw_setup(char *str) | |||
707 | 713 | ||
708 | early_param("disable_ddw", disable_ddw_setup); | 714 | early_param("disable_ddw", disable_ddw_setup); |
709 | 715 | ||
716 | static inline void __remove_ddw(struct device_node *np, const u32 *ddw_avail, u64 liobn) | ||
717 | { | ||
718 | int ret; | ||
719 | |||
720 | ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn); | ||
721 | if (ret) | ||
722 | pr_warning("%s: failed to remove DMA window: rtas returned " | ||
723 | "%d to ibm,remove-pe-dma-window(%x) %llx\n", | ||
724 | np->full_name, ret, ddw_avail[2], liobn); | ||
725 | else | ||
726 | pr_debug("%s: successfully removed DMA window: rtas returned " | ||
727 | "%d to ibm,remove-pe-dma-window(%x) %llx\n", | ||
728 | np->full_name, ret, ddw_avail[2], liobn); | ||
729 | } | ||
730 | |||
710 | static void remove_ddw(struct device_node *np) | 731 | static void remove_ddw(struct device_node *np) |
711 | { | 732 | { |
712 | struct dynamic_dma_window_prop *dwp; | 733 | struct dynamic_dma_window_prop *dwp; |
@@ -736,15 +757,7 @@ static void remove_ddw(struct device_node *np) | |||
736 | pr_debug("%s successfully cleared tces in window.\n", | 757 | pr_debug("%s successfully cleared tces in window.\n", |
737 | np->full_name); | 758 | np->full_name); |
738 | 759 | ||
739 | ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn); | 760 | __remove_ddw(np, ddw_avail, liobn); |
740 | if (ret) | ||
741 | pr_warning("%s: failed to remove direct window: rtas returned " | ||
742 | "%d to ibm,remove-pe-dma-window(%x) %llx\n", | ||
743 | np->full_name, ret, ddw_avail[2], liobn); | ||
744 | else | ||
745 | pr_debug("%s: successfully removed direct window: rtas returned " | ||
746 | "%d to ibm,remove-pe-dma-window(%x) %llx\n", | ||
747 | np->full_name, ret, ddw_avail[2], liobn); | ||
748 | 761 | ||
749 | delprop: | 762 | delprop: |
750 | ret = prom_remove_property(np, win64); | 763 | ret = prom_remove_property(np, win64); |
@@ -869,6 +882,35 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail, | |||
869 | return ret; | 882 | return ret; |
870 | } | 883 | } |
871 | 884 | ||
885 | static void restore_default_window(struct pci_dev *dev, | ||
886 | u32 ddw_restore_token, unsigned long liobn) | ||
887 | { | ||
888 | struct eeh_dev *edev; | ||
889 | u32 cfg_addr; | ||
890 | u64 buid; | ||
891 | int ret; | ||
892 | |||
893 | /* | ||
894 | * Get the config address and phb buid of the PE window. | ||
895 | * Rely on eeh to retrieve this for us. | ||
896 | * Retrieve them from the pci device, not the node with the | ||
897 | * dma-window property | ||
898 | */ | ||
899 | edev = pci_dev_to_eeh_dev(dev); | ||
900 | cfg_addr = edev->config_addr; | ||
901 | if (edev->pe_config_addr) | ||
902 | cfg_addr = edev->pe_config_addr; | ||
903 | buid = edev->phb->buid; | ||
904 | |||
905 | do { | ||
906 | ret = rtas_call(ddw_restore_token, 3, 1, NULL, cfg_addr, | ||
907 | BUID_HI(buid), BUID_LO(buid)); | ||
908 | } while (rtas_busy_delay(ret)); | ||
909 | dev_info(&dev->dev, | ||
910 | "ibm,reset-pe-dma-windows(%x) %x %x %x returned %d\n", | ||
911 | ddw_restore_token, cfg_addr, BUID_HI(buid), BUID_LO(buid), ret); | ||
912 | } | ||
913 | |||
872 | /* | 914 | /* |
873 | * If the PE supports dynamic dma windows, and there is space for a table | 915 | * If the PE supports dynamic dma windows, and there is space for a table |
874 | * that can map all pages in a linear offset, then setup such a table, | 916 | * that can map all pages in a linear offset, then setup such a table, |
@@ -889,9 +931,13 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
889 | u64 dma_addr, max_addr; | 931 | u64 dma_addr, max_addr; |
890 | struct device_node *dn; | 932 | struct device_node *dn; |
891 | const u32 *uninitialized_var(ddw_avail); | 933 | const u32 *uninitialized_var(ddw_avail); |
934 | const u32 *uninitialized_var(ddw_extensions); | ||
935 | u32 ddw_restore_token = 0; | ||
892 | struct direct_window *window; | 936 | struct direct_window *window; |
893 | struct property *win64; | 937 | struct property *win64; |
894 | struct dynamic_dma_window_prop *ddwprop; | 938 | struct dynamic_dma_window_prop *ddwprop; |
939 | const void *dma_window = NULL; | ||
940 | unsigned long liobn, offset, size; | ||
895 | 941 | ||
896 | mutex_lock(&direct_window_init_mutex); | 942 | mutex_lock(&direct_window_init_mutex); |
897 | 943 | ||
@@ -911,7 +957,40 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
911 | if (!ddw_avail || len < 3 * sizeof(u32)) | 957 | if (!ddw_avail || len < 3 * sizeof(u32)) |
912 | goto out_unlock; | 958 | goto out_unlock; |
913 | 959 | ||
914 | /* | 960 | /* |
961 | * the extensions property is only required to exist in certain | ||
962 | * levels of firmware and later | ||
963 | * the ibm,ddw-extensions property is a list with the first | ||
964 | * element containing the number of extensions and each | ||
965 | * subsequent entry is a value corresponding to that extension | ||
966 | */ | ||
967 | ddw_extensions = of_get_property(pdn, "ibm,ddw-extensions", &len); | ||
968 | if (ddw_extensions) { | ||
969 | /* | ||
970 | * each new defined extension length should be added to | ||
971 | * the top of the switch so the "earlier" entries also | ||
972 | * get picked up | ||
973 | */ | ||
974 | switch (ddw_extensions[0]) { | ||
975 | /* ibm,reset-pe-dma-windows */ | ||
976 | case 1: | ||
977 | ddw_restore_token = ddw_extensions[1]; | ||
978 | break; | ||
979 | } | ||
980 | } | ||
981 | |||
982 | /* | ||
983 | * Only remove the existing DMA window if we can restore back to | ||
984 | * the default state. Removing the existing window maximizes the | ||
985 | * resources available to firmware for dynamic window creation. | ||
986 | */ | ||
987 | if (ddw_restore_token) { | ||
988 | dma_window = of_get_property(pdn, "ibm,dma-window", NULL); | ||
989 | of_parse_dma_window(pdn, dma_window, &liobn, &offset, &size); | ||
990 | __remove_ddw(pdn, ddw_avail, liobn); | ||
991 | } | ||
992 | |||
993 | /* | ||
915 | * Query if there is a second window of size to map the | 994 | * Query if there is a second window of size to map the |
916 | * whole partition. Query returns number of windows, largest | 995 | * whole partition. Query returns number of windows, largest |
917 | * block assigned to PE (partition endpoint), and two bitmasks | 996 | * block assigned to PE (partition endpoint), and two bitmasks |
@@ -920,7 +999,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
920 | dn = pci_device_to_OF_node(dev); | 999 | dn = pci_device_to_OF_node(dev); |
921 | ret = query_ddw(dev, ddw_avail, &query); | 1000 | ret = query_ddw(dev, ddw_avail, &query); |
922 | if (ret != 0) | 1001 | if (ret != 0) |
923 | goto out_unlock; | 1002 | goto out_restore_window; |
924 | 1003 | ||
925 | if (query.windows_available == 0) { | 1004 | if (query.windows_available == 0) { |
926 | /* | 1005 | /* |
@@ -929,7 +1008,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
929 | * trading in for a larger page size. | 1008 | * trading in for a larger page size. |
930 | */ | 1009 | */ |
931 | dev_dbg(&dev->dev, "no free dynamic windows"); | 1010 | dev_dbg(&dev->dev, "no free dynamic windows"); |
932 | goto out_unlock; | 1011 | goto out_restore_window; |
933 | } | 1012 | } |
934 | if (query.page_size & 4) { | 1013 | if (query.page_size & 4) { |
935 | page_shift = 24; /* 16MB */ | 1014 | page_shift = 24; /* 16MB */ |
@@ -940,7 +1019,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
940 | } else { | 1019 | } else { |
941 | dev_dbg(&dev->dev, "no supported direct page size in mask %x", | 1020 | dev_dbg(&dev->dev, "no supported direct page size in mask %x", |
942 | query.page_size); | 1021 | query.page_size); |
943 | goto out_unlock; | 1022 | goto out_restore_window; |
944 | } | 1023 | } |
945 | /* verify the window * number of ptes will map the partition */ | 1024 | /* verify the window * number of ptes will map the partition */ |
946 | /* check largest block * page size > max memory hotplug addr */ | 1025 | /* check largest block * page size > max memory hotplug addr */ |
@@ -949,14 +1028,14 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) | |||
949 | dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u " | 1028 | dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u " |
950 | "%llu-sized pages\n", max_addr, query.largest_available_block, | 1029 | "%llu-sized pages\n", max_addr, query.largest_available_block, |
951 | 1ULL << page_shift); | 1030 | 1ULL << page_shift); |
952 | goto out_unlock; | 1031 | goto out_restore_window; |
953 | } | 1032 | } |
954 | len = order_base_2(max_addr); | 1033 | len = order_base_2(max_addr); |
955 | win64 = kzalloc(sizeof(struct property), GFP_KERNEL); | 1034 | win64 = kzalloc(sizeof(struct property), GFP_KERNEL); |
956 | if (!win64) { | 1035 | if (!win64) { |
957 | dev_info(&dev->dev, | 1036 | dev_info(&dev->dev, |
958 | "couldn't allocate property for 64bit dma window\n"); | 1037 | "couldn't allocate property for 64bit dma window\n"); |
959 | goto out_unlock; | 1038 | goto out_restore_window; |
960 | } | 1039 | } |
961 | win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL); | 1040 | win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL); |
962 | win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL); | 1041 | win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL); |
@@ -1018,6 +1097,10 @@ out_free_prop: | |||
1018 | kfree(win64->value); | 1097 | kfree(win64->value); |
1019 | kfree(win64); | 1098 | kfree(win64); |
1020 | 1099 | ||
1100 | out_restore_window: | ||
1101 | if (ddw_restore_token) | ||
1102 | restore_default_window(dev, ddw_restore_token, liobn); | ||
1103 | |||
1021 | out_unlock: | 1104 | out_unlock: |
1022 | mutex_unlock(&direct_window_init_mutex); | 1105 | mutex_unlock(&direct_window_init_mutex); |
1023 | return dma_addr; | 1106 | return dma_addr; |
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 029a562af373..dd30b12edfe4 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c | |||
@@ -67,7 +67,6 @@ static int update_dt_property(struct device_node *dn, struct property **prop, | |||
67 | const char *name, u32 vd, char *value) | 67 | const char *name, u32 vd, char *value) |
68 | { | 68 | { |
69 | struct property *new_prop = *prop; | 69 | struct property *new_prop = *prop; |
70 | struct property *old_prop; | ||
71 | int more = 0; | 70 | int more = 0; |
72 | 71 | ||
73 | /* A negative 'vd' value indicates that only part of the new property | 72 | /* A negative 'vd' value indicates that only part of the new property |
@@ -117,12 +116,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop, | |||
117 | } | 116 | } |
118 | 117 | ||
119 | if (!more) { | 118 | if (!more) { |
120 | old_prop = of_find_property(dn, new_prop->name, NULL); | 119 | prom_update_property(dn, new_prop); |
121 | if (old_prop) | ||
122 | prom_update_property(dn, new_prop, old_prop); | ||
123 | else | ||
124 | prom_add_property(dn, new_prop); | ||
125 | |||
126 | new_prop = NULL; | 120 | new_prop = NULL; |
127 | } | 121 | } |
128 | 122 | ||
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 36f957f31842..8733a86ad52e 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
@@ -68,9 +68,7 @@ static const char *pseries_nvram_os_partitions[] = { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | static void oops_to_nvram(struct kmsg_dumper *dumper, | 70 | static void oops_to_nvram(struct kmsg_dumper *dumper, |
71 | enum kmsg_dump_reason reason, | 71 | enum kmsg_dump_reason reason); |
72 | const char *old_msgs, unsigned long old_len, | ||
73 | const char *new_msgs, unsigned long new_len); | ||
74 | 72 | ||
75 | static struct kmsg_dumper nvram_kmsg_dumper = { | 73 | static struct kmsg_dumper nvram_kmsg_dumper = { |
76 | .dump = oops_to_nvram | 74 | .dump = oops_to_nvram |
@@ -504,28 +502,6 @@ int __init pSeries_nvram_init(void) | |||
504 | } | 502 | } |
505 | 503 | ||
506 | /* | 504 | /* |
507 | * Try to capture the last capture_len bytes of the printk buffer. Return | ||
508 | * the amount actually captured. | ||
509 | */ | ||
510 | static size_t capture_last_msgs(const char *old_msgs, size_t old_len, | ||
511 | const char *new_msgs, size_t new_len, | ||
512 | char *captured, size_t capture_len) | ||
513 | { | ||
514 | if (new_len >= capture_len) { | ||
515 | memcpy(captured, new_msgs + (new_len - capture_len), | ||
516 | capture_len); | ||
517 | return capture_len; | ||
518 | } else { | ||
519 | /* Grab the end of old_msgs. */ | ||
520 | size_t old_tail_len = min(old_len, capture_len - new_len); | ||
521 | memcpy(captured, old_msgs + (old_len - old_tail_len), | ||
522 | old_tail_len); | ||
523 | memcpy(captured + old_tail_len, new_msgs, new_len); | ||
524 | return old_tail_len + new_len; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * Are we using the ibm,rtas-log for oops/panic reports? And if so, | 505 | * Are we using the ibm,rtas-log for oops/panic reports? And if so, |
530 | * would logging this oops/panic overwrite an RTAS event that rtas_errd | 506 | * would logging this oops/panic overwrite an RTAS event that rtas_errd |
531 | * hasn't had a chance to read and process? Return 1 if so, else 0. | 507 | * hasn't had a chance to read and process? Return 1 if so, else 0. |
@@ -541,27 +517,6 @@ static int clobbering_unread_rtas_event(void) | |||
541 | NVRAM_RTAS_READ_TIMEOUT); | 517 | NVRAM_RTAS_READ_TIMEOUT); |
542 | } | 518 | } |
543 | 519 | ||
544 | /* Squeeze out each line's <n> severity prefix. */ | ||
545 | static size_t elide_severities(char *buf, size_t len) | ||
546 | { | ||
547 | char *in, *out, *buf_end = buf + len; | ||
548 | /* Assume a <n> at the very beginning marks the start of a line. */ | ||
549 | int newline = 1; | ||
550 | |||
551 | in = out = buf; | ||
552 | while (in < buf_end) { | ||
553 | if (newline && in+3 <= buf_end && | ||
554 | *in == '<' && isdigit(in[1]) && in[2] == '>') { | ||
555 | in += 3; | ||
556 | newline = 0; | ||
557 | } else { | ||
558 | newline = (*in == '\n'); | ||
559 | *out++ = *in++; | ||
560 | } | ||
561 | } | ||
562 | return out - buf; | ||
563 | } | ||
564 | |||
565 | /* Derived from logfs_compress() */ | 520 | /* Derived from logfs_compress() */ |
566 | static int nvram_compress(const void *in, void *out, size_t inlen, | 521 | static int nvram_compress(const void *in, void *out, size_t inlen, |
567 | size_t outlen) | 522 | size_t outlen) |
@@ -619,9 +574,7 @@ static int zip_oops(size_t text_len) | |||
619 | * partition. If that's too much, go back and capture uncompressed text. | 574 | * partition. If that's too much, go back and capture uncompressed text. |
620 | */ | 575 | */ |
621 | static void oops_to_nvram(struct kmsg_dumper *dumper, | 576 | static void oops_to_nvram(struct kmsg_dumper *dumper, |
622 | enum kmsg_dump_reason reason, | 577 | enum kmsg_dump_reason reason) |
623 | const char *old_msgs, unsigned long old_len, | ||
624 | const char *new_msgs, unsigned long new_len) | ||
625 | { | 578 | { |
626 | static unsigned int oops_count = 0; | 579 | static unsigned int oops_count = 0; |
627 | static bool panicking = false; | 580 | static bool panicking = false; |
@@ -660,14 +613,14 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, | |||
660 | return; | 613 | return; |
661 | 614 | ||
662 | if (big_oops_buf) { | 615 | if (big_oops_buf) { |
663 | text_len = capture_last_msgs(old_msgs, old_len, | 616 | kmsg_dump_get_buffer(dumper, false, |
664 | new_msgs, new_len, big_oops_buf, big_oops_buf_sz); | 617 | big_oops_buf, big_oops_buf_sz, &text_len); |
665 | text_len = elide_severities(big_oops_buf, text_len); | ||
666 | rc = zip_oops(text_len); | 618 | rc = zip_oops(text_len); |
667 | } | 619 | } |
668 | if (rc != 0) { | 620 | if (rc != 0) { |
669 | text_len = capture_last_msgs(old_msgs, old_len, | 621 | kmsg_dump_rewind(dumper); |
670 | new_msgs, new_len, oops_data, oops_data_sz); | 622 | kmsg_dump_get_buffer(dumper, true, |
623 | oops_data, oops_data_sz, &text_len); | ||
671 | err_type = ERR_TYPE_KERNEL_PANIC; | 624 | err_type = ERR_TYPE_KERNEL_PANIC; |
672 | *oops_len = (u16) text_len; | 625 | *oops_len = (u16) text_len; |
673 | } | 626 | } |
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 41a34bc4a9a2..455760b1fe6e 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/moduleparam.h> | 11 | #include <linux/moduleparam.h> |
12 | #include <linux/cpuidle.h> | 12 | #include <linux/cpuidle.h> |
13 | #include <linux/cpu.h> | 13 | #include <linux/cpu.h> |
14 | #include <linux/notifier.h> | ||
14 | 15 | ||
15 | #include <asm/paca.h> | 16 | #include <asm/paca.h> |
16 | #include <asm/reg.h> | 17 | #include <asm/reg.h> |
@@ -99,15 +100,18 @@ out: | |||
99 | static void check_and_cede_processor(void) | 100 | static void check_and_cede_processor(void) |
100 | { | 101 | { |
101 | /* | 102 | /* |
102 | * Interrupts are soft-disabled at this point, | 103 | * Ensure our interrupt state is properly tracked, |
103 | * but not hard disabled. So an interrupt might have | 104 | * also checks if no interrupt has occurred while we |
104 | * occurred before entering NAP, and would be potentially | 105 | * were soft-disabled |
105 | * lost (edge events, decrementer events, etc...) unless | ||
106 | * we first hard disable then check. | ||
107 | */ | 106 | */ |
108 | hard_irq_disable(); | 107 | if (prep_irq_for_idle()) { |
109 | if (get_paca()->irq_happened == 0) | ||
110 | cede_processor(); | 108 | cede_processor(); |
109 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
110 | /* Ensure that H_CEDE returns with IRQs on */ | ||
111 | if (WARN_ON(!(mfmsr() & MSR_EE))) | ||
112 | __hard_irq_enable(); | ||
113 | #endif | ||
114 | } | ||
111 | } | 115 | } |
112 | 116 | ||
113 | static int dedicated_cede_loop(struct cpuidle_device *dev, | 117 | static int dedicated_cede_loop(struct cpuidle_device *dev, |
@@ -186,17 +190,40 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { | |||
186 | .enter = &shared_cede_loop }, | 190 | .enter = &shared_cede_loop }, |
187 | }; | 191 | }; |
188 | 192 | ||
189 | int pseries_notify_cpuidle_add_cpu(int cpu) | 193 | static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, |
194 | unsigned long action, void *hcpu) | ||
190 | { | 195 | { |
196 | int hotcpu = (unsigned long)hcpu; | ||
191 | struct cpuidle_device *dev = | 197 | struct cpuidle_device *dev = |
192 | per_cpu_ptr(pseries_cpuidle_devices, cpu); | 198 | per_cpu_ptr(pseries_cpuidle_devices, hotcpu); |
199 | |||
193 | if (dev && cpuidle_get_driver()) { | 200 | if (dev && cpuidle_get_driver()) { |
194 | cpuidle_disable_device(dev); | 201 | switch (action) { |
195 | cpuidle_enable_device(dev); | 202 | case CPU_ONLINE: |
203 | case CPU_ONLINE_FROZEN: | ||
204 | cpuidle_pause_and_lock(); | ||
205 | cpuidle_enable_device(dev); | ||
206 | cpuidle_resume_and_unlock(); | ||
207 | break; | ||
208 | |||
209 | case CPU_DEAD: | ||
210 | case CPU_DEAD_FROZEN: | ||
211 | cpuidle_pause_and_lock(); | ||
212 | cpuidle_disable_device(dev); | ||
213 | cpuidle_resume_and_unlock(); | ||
214 | break; | ||
215 | |||
216 | default: | ||
217 | return NOTIFY_DONE; | ||
218 | } | ||
196 | } | 219 | } |
197 | return 0; | 220 | return NOTIFY_OK; |
198 | } | 221 | } |
199 | 222 | ||
223 | static struct notifier_block setup_hotplug_notifier = { | ||
224 | .notifier_call = pseries_cpuidle_add_cpu_notifier, | ||
225 | }; | ||
226 | |||
200 | /* | 227 | /* |
201 | * pseries_cpuidle_driver_init() | 228 | * pseries_cpuidle_driver_init() |
202 | */ | 229 | */ |
@@ -321,6 +348,7 @@ static int __init pseries_processor_idle_init(void) | |||
321 | return retval; | 348 | return retval; |
322 | } | 349 | } |
323 | 350 | ||
351 | register_cpu_notifier(&setup_hotplug_notifier); | ||
324 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); | 352 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); |
325 | 353 | ||
326 | return 0; | 354 | return 0; |
@@ -329,6 +357,7 @@ static int __init pseries_processor_idle_init(void) | |||
329 | static void __exit pseries_processor_idle_exit(void) | 357 | static void __exit pseries_processor_idle_exit(void) |
330 | { | 358 | { |
331 | 359 | ||
360 | unregister_cpu_notifier(&setup_hotplug_notifier); | ||
332 | pseries_idle_devices_uninit(); | 361 | pseries_idle_devices_uninit(); |
333 | cpuidle_unregister_driver(&pseries_idle_driver); | 362 | cpuidle_unregister_driver(&pseries_idle_driver); |
334 | 363 | ||
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 7b3bf76ef834..39f71fba9b38 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c | |||
@@ -432,7 +432,7 @@ static int do_update_property(char *buf, size_t bufsize) | |||
432 | unsigned char *value; | 432 | unsigned char *value; |
433 | char *name, *end, *next_prop; | 433 | char *name, *end, *next_prop; |
434 | int rc, length; | 434 | int rc, length; |
435 | struct property *newprop, *oldprop; | 435 | struct property *newprop; |
436 | buf = parse_node(buf, bufsize, &np); | 436 | buf = parse_node(buf, bufsize, &np); |
437 | end = buf + bufsize; | 437 | end = buf + bufsize; |
438 | 438 | ||
@@ -443,6 +443,9 @@ static int do_update_property(char *buf, size_t bufsize) | |||
443 | if (!next_prop) | 443 | if (!next_prop) |
444 | return -EINVAL; | 444 | return -EINVAL; |
445 | 445 | ||
446 | if (!strlen(name)) | ||
447 | return -ENODEV; | ||
448 | |||
446 | newprop = new_property(name, length, value, NULL); | 449 | newprop = new_property(name, length, value, NULL); |
447 | if (!newprop) | 450 | if (!newprop) |
448 | return -ENOMEM; | 451 | return -ENOMEM; |
@@ -450,18 +453,11 @@ static int do_update_property(char *buf, size_t bufsize) | |||
450 | if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) | 453 | if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size")) |
451 | slb_set_size(*(int *)value); | 454 | slb_set_size(*(int *)value); |
452 | 455 | ||
453 | oldprop = of_find_property(np, name,NULL); | ||
454 | if (!oldprop) { | ||
455 | if (strlen(name)) | ||
456 | return prom_add_property(np, newprop); | ||
457 | return -ENODEV; | ||
458 | } | ||
459 | |||
460 | upd_value.node = np; | 456 | upd_value.node = np; |
461 | upd_value.property = newprop; | 457 | upd_value.property = newprop; |
462 | pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value); | 458 | pSeries_reconfig_notify(PSERIES_UPDATE_PROPERTY, &upd_value); |
463 | 459 | ||
464 | rc = prom_update_property(np, newprop, oldprop); | 460 | rc = prom_update_property(np, newprop); |
465 | if (rc) | 461 | if (rc) |
466 | return rc; | 462 | return rc; |
467 | 463 | ||
@@ -486,7 +482,7 @@ static int do_update_property(char *buf, size_t bufsize) | |||
486 | 482 | ||
487 | rc = pSeries_reconfig_notify(action, value); | 483 | rc = pSeries_reconfig_notify(action, value); |
488 | if (rc) { | 484 | if (rc) { |
489 | prom_update_property(np, oldprop, newprop); | 485 | prom_update_property(np, newprop); |
490 | return rc; | 486 | return rc; |
491 | } | 487 | } |
492 | } | 488 | } |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index e16bb8d48550..71706bc34a0d 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -147,7 +147,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
147 | set_cpu_current_state(cpu, CPU_STATE_ONLINE); | 147 | set_cpu_current_state(cpu, CPU_STATE_ONLINE); |
148 | set_default_offline_state(cpu); | 148 | set_default_offline_state(cpu); |
149 | #endif | 149 | #endif |
150 | pseries_notify_cpuidle_add_cpu(cpu); | ||
151 | } | 150 | } |
152 | 151 | ||
153 | static int __devinit smp_pSeries_kick_cpu(int nr) | 152 | static int __devinit smp_pSeries_kick_cpu(int nr) |