aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/44x/currituck.c2
-rw-r--r--arch/powerpc/platforms/82xx/km82xx.c5
-rw-r--r--arch/powerpc/platforms/83xx/km83xx.c100
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig43
-rw-r--r--arch/powerpc/platforms/85xx/Makefile4
-rw-r--r--arch/powerpc/platforms/85xx/bsc913x_rdb.c67
-rw-r--r--arch/powerpc/platforms/85xx/corenet_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/ge_imp3a.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc8536_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c97
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_rdb.c22
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c116
-rw-r--r--arch/powerpc/platforms/85xx/p3060_qds.c77
-rw-r--r--arch/powerpc/platforms/85xx/qemu_e500.c72
-rw-r--r--arch/powerpc/platforms/85xx/sbc8560.c254
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c2
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype4
-rw-r--r--arch/powerpc/platforms/cell/beat_hvCall.S28
-rw-r--r--arch/powerpc/platforms/cell/iommu.c1
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c11
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c48
-rw-r--r--arch/powerpc/platforms/powernv/opal-takeover.S10
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c6
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c4
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S78
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c117
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c8
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c61
-rw-r--r--arch/powerpc/platforms/pseries/processor_idle.c53
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c16
-rw-r--r--arch/powerpc/platforms/pseries/smp.c1
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
133static void __init init_ioports(void) 138static 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
123machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); 157machine_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
26config 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
26config MPC8540_ADS 35config 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
178config SBC8560
179 bool "Wind River SBC8560"
180 select DEFAULT_UIMAGE
181 help
182 This option enables support for the Wind River SBC8560 board
183
184config GE_IMP3A 187config 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
225config 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
237config P4080_DS 228config 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
257config 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
266endif # FSL_SOC_BOOKE 273endif # FSL_SOC_BOOKE
267 274
268config TQM85xx 275config 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
6obj-y += common.o 6obj-y += common.o
7 7
8obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o
8obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o 9obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
9obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o 10obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
10obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o 11obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
@@ -17,14 +18,13 @@ obj-$(CONFIG_P1022_DS) += p1022_ds.o
17obj-$(CONFIG_P1023_RDS) += p1023_rds.o 18obj-$(CONFIG_P1023_RDS) += p1023_rds.o
18obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o 19obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o
19obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o 20obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o
20obj-$(CONFIG_P3060_QDS) += p3060_qds.o corenet_ds.o
21obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o 21obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o
22obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o 22obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o
23obj-$(CONFIG_STX_GP3) += stx_gp3.o 23obj-$(CONFIG_STX_GP3) += stx_gp3.o
24obj-$(CONFIG_TQM85xx) += tqm85xx.o 24obj-$(CONFIG_TQM85xx) += tqm85xx.o
25obj-$(CONFIG_SBC8560) += sbc8560.o
26obj-$(CONFIG_SBC8548) += sbc8548.o 25obj-$(CONFIG_SBC8548) += sbc8548.o
27obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o 26obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o
28obj-$(CONFIG_KSI8560) += ksi8560.o 27obj-$(CONFIG_KSI8560) += ksi8560.o
29obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o 28obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o
30obj-$(CONFIG_GE_IMP3A) += ge_imp3a.o 29obj-$(CONFIG_GE_IMP3A) += ge_imp3a.o
30obj-$(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
22void __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 */
37static 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
45machine_device_initcall(bsc9131_rdb, mpc85xx_common_publish_devices);
46
47/*
48 * Called very early, device-tree isn't unflattened
49 */
50
51static 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
58define_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
117static int primary_phb_addr;
118extern int uli_exclude_device(struct pci_controller *hose, 117extern int uli_exclude_device(struct pci_controller *hose,
119 u_char bus, u_char devfn); 118 u_char bus, u_char devfn);
120 119
120static struct device_node *pci_with_uli;
121
121static int mpc85xx_exclude_device(struct pci_controller *hose, 122static 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/* 132static void __init mpc85xx_ds_pci_init(void)
139 * Setup the architecture
140 */
141static 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 */
157static 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
203machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices); 178machine_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
245define_machine(mpc8544_ds) { 206define_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);
169machine_device_initcall(p1020_utm_pc, mpc85xx_common_publish_devices); 169machine_device_initcall(p1020_utm_pc, mpc85xx_common_publish_devices);
170machine_device_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices); 170machine_device_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices);
171machine_device_initcall(p1025_rdb, mpc85xx_common_publish_devices); 171machine_device_initcall(p1025_rdb, mpc85xx_common_publish_devices);
172machine_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
241static 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
240define_machine(p2020_rdb) { 248define_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
360define_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
146struct 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 */
172static 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 */
149static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) 200static 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 */
349static void __init disable_one_node(struct device_node *np, struct property *new) 429static 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 */
27static 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
58define_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
73machine_device_initcall(p3060_qds, corenet_ds_publish_devices);
74
75#ifdef CONFIG_SWIOTLB
76machine_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
29void __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
40static 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 */
51static 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
58machine_device_initcall(qemu_e500, mpc85xx_common_publish_devices);
59
60define_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
41static 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
55struct cpm_pin {
56 int port, pin, flags;
57};
58
59static 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
107static 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
127static 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
147static 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
163machine_device_initcall(sbc8560, mpc85xx_common_publish_devices);
164
165/*
166 * Called very early, device-tree isn't unflattened
167 */
168static 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
176static 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
203arch_initcall(sbc8560_rtc_init);
204
205#endif /* M48T59 */
206
207static __u8 __iomem *brstcr;
208
209static 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
233arch_initcall(sbc8560_bdrstcr_init);
234
235void sbc8560_rstcr_restart(char * cmd)
236{
237 local_irq_disable();
238 if(brstcr)
239 clrbits8(brstcr, 0x80);
240
241 while(1);
242}
243
244define_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
163config PPC_FPU 167config 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
86static int cbe_system_reset_exception(struct pt_regs *regs) 87static 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
320static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) 320static 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);
341out:
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
559static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) 551static 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);
580out:
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; \
661: 641:
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; \
931: 911:
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
708early_param("disable_ddw", disable_ddw_setup); 714early_param("disable_ddw", disable_ddw_setup);
709 715
716static 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
710static void remove_ddw(struct device_node *np) 731static 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
749delprop: 762delprop:
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
885static 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
1100out_restore_window:
1101 if (ddw_restore_token)
1102 restore_default_window(dev, ddw_restore_token, liobn);
1103
1021out_unlock: 1104out_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
70static void oops_to_nvram(struct kmsg_dumper *dumper, 70static 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
75static struct kmsg_dumper nvram_kmsg_dumper = { 73static 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 */
510static 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. */
545static 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() */
566static int nvram_compress(const void *in, void *out, size_t inlen, 521static 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 */
621static void oops_to_nvram(struct kmsg_dumper *dumper, 576static 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:
99static void check_and_cede_processor(void) 100static 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
113static int dedicated_cede_loop(struct cpuidle_device *dev, 117static 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
189int pseries_notify_cpuidle_add_cpu(int cpu) 193static 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
223static 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)
329static void __exit pseries_processor_idle_exit(void) 357static 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
153static int __devinit smp_pSeries_kick_cpu(int nr) 152static int __devinit smp_pSeries_kick_cpu(int nr)