aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/40x/Kconfig7
-rw-r--r--arch/powerpc/platforms/44x/Kconfig2
-rw-r--r--arch/powerpc/platforms/512x/Kconfig10
-rw-r--r--arch/powerpc/platforms/512x/Makefile2
-rw-r--r--arch/powerpc/platforms/512x/clock.c9
-rw-r--r--arch/powerpc/platforms/512x/mpc512x.h1
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_generic.c (renamed from arch/powerpc/platforms/512x/mpc5121_generic.c)12
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c38
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig34
-rw-r--r--arch/powerpc/platforms/85xx/Makefile2
-rw-r--r--arch/powerpc/platforms/85xx/b4_qds.c102
-rw-r--r--arch/powerpc/platforms/85xx/corenet_ds.c5
-rw-r--r--arch/powerpc/platforms/85xx/smp.c2
-rw-r--r--arch/powerpc/platforms/85xx/t4240_qds.c98
-rw-r--r--arch/powerpc/platforms/Kconfig4
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype2
-rw-r--r--arch/powerpc/platforms/cell/Kconfig26
-rw-r--r--arch/powerpc/platforms/cell/Makefile3
-rw-r--r--arch/powerpc/platforms/cell/beat_htab.c26
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c209
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.h24
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c115
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c156
-rw-r--r--arch/powerpc/platforms/cell/pmu.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c1
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c20
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig5
-rw-r--r--arch/powerpc/platforms/pasemi/cpufreq.c5
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c14
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c5
-rw-r--r--arch/powerpc/platforms/powernv/Kconfig5
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S1
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c307
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c15
-rw-r--r--arch/powerpc/platforms/powernv/pci.c113
-rw-r--r--arch/powerpc/platforms/powernv/pci.h26
-rw-r--r--arch/powerpc/platforms/prep/Kconfig23
-rw-r--r--arch/powerpc/platforms/ps3/htab.c8
-rw-r--r--arch/powerpc/platforms/ps3/time.c4
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c54
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c12
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c26
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c16
-rw-r--r--arch/powerpc/platforms/pseries/mobility.c41
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h15
-rw-r--r--arch/powerpc/platforms/pseries/processor_idle.c34
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h5
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c2
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c32
-rw-r--r--arch/powerpc/platforms/pseries/setup.c40
-rw-r--r--arch/powerpc/platforms/wsp/Kconfig5
52 files changed, 829 insertions, 900 deletions
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index a392d12dd21f..bd40bbb15e14 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -20,7 +20,6 @@ config HOTFOOT
20 bool "Hotfoot" 20 bool "Hotfoot"
21 depends on 40x 21 depends on 40x
22 default n 22 default n
23 select 405EP
24 select PPC40x_SIMPLE 23 select PPC40x_SIMPLE
25 select PCI 24 select PCI
26 help 25 help
@@ -105,9 +104,6 @@ config 405GP
105 select IBM405_ERR51 104 select IBM405_ERR51
106 select IBM_EMAC_ZMII 105 select IBM_EMAC_ZMII
107 106
108config 405EP
109 bool
110
111config 405EX 107config 405EX
112 bool 108 bool
113 select IBM_EMAC_EMAC4 109 select IBM_EMAC_EMAC4
@@ -119,9 +115,6 @@ config 405EZ
119 select IBM_EMAC_MAL_CLR_ICINTSTAT 115 select IBM_EMAC_MAL_CLR_ICINTSTAT
120 select IBM_EMAC_MAL_COMMON_ERR 116 select IBM_EMAC_MAL_COMMON_ERR
121 117
122config 405GPR
123 bool
124
125config XILINX_VIRTEX 118config XILINX_VIRTEX
126 bool 119 bool
127 select DEFAULT_UIMAGE 120 select DEFAULT_UIMAGE
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 0effe9f5a1ea..7be93367d92f 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -274,6 +274,8 @@ config 440EPX
274 select IBM_EMAC_EMAC4 274 select IBM_EMAC_EMAC4
275 select IBM_EMAC_RGMII 275 select IBM_EMAC_RGMII
276 select IBM_EMAC_ZMII 276 select IBM_EMAC_ZMII
277 select USB_EHCI_BIG_ENDIAN_MMIO
278 select USB_EHCI_BIG_ENDIAN_DESC
277 279
278config 440GRX 280config 440GRX
279 bool 281 bool
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index c16999802ecf..fc9c1cbfcb1d 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -7,6 +7,8 @@ config PPC_MPC512x
7 select PPC_PCI_CHOICE 7 select PPC_PCI_CHOICE
8 select FSL_PCI if PCI 8 select FSL_PCI if PCI
9 select ARCH_WANT_OPTIONAL_GPIOLIB 9 select ARCH_WANT_OPTIONAL_GPIOLIB
10 select USB_EHCI_BIG_ENDIAN_MMIO
11 select USB_EHCI_BIG_ENDIAN_DESC
10 12
11config MPC5121_ADS 13config MPC5121_ADS
12 bool "Freescale MPC5121E ADS" 14 bool "Freescale MPC5121E ADS"
@@ -15,16 +17,16 @@ config MPC5121_ADS
15 help 17 help
16 This option enables support for the MPC5121E ADS board. 18 This option enables support for the MPC5121E ADS board.
17 19
18config MPC5121_GENERIC 20config MPC512x_GENERIC
19 bool "Generic support for simple MPC5121 based boards" 21 bool "Generic support for simple MPC512x based boards"
20 depends on PPC_MPC512x 22 depends on PPC_MPC512x
21 select DEFAULT_UIMAGE 23 select DEFAULT_UIMAGE
22 help 24 help
23 This option enables support for simple MPC5121 based boards 25 This option enables support for simple MPC512x based boards
24 which do not need custom platform specific setup. 26 which do not need custom platform specific setup.
25 27
26 Compatible boards include: Protonic LVT base boards (ZANMCU 28 Compatible boards include: Protonic LVT base boards (ZANMCU
27 and VICVT2). 29 and VICVT2), Freescale MPC5125 Tower system.
28 30
29config PDM360NG 31config PDM360NG
30 bool "ifm PDM360NG board" 32 bool "ifm PDM360NG board"
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 4efc1c4b6fb5..72fb9340e09f 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -3,5 +3,5 @@
3# 3#
4obj-y += clock.o mpc512x_shared.o 4obj-y += clock.o mpc512x_shared.o
5obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o 5obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o
6obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o 6obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o
7obj-$(CONFIG_PDM360NG) += pdm360ng.o 7obj-$(CONFIG_PDM360NG) += pdm360ng.o
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
index 52d57d281724..e504166e089a 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -29,6 +29,8 @@
29#include <asm/mpc5121.h> 29#include <asm/mpc5121.h>
30#include <asm/clk_interface.h> 30#include <asm/clk_interface.h>
31 31
32#include "mpc512x.h"
33
32#undef CLK_DEBUG 34#undef CLK_DEBUG
33 35
34static int clocks_initialized; 36static int clocks_initialized;
@@ -683,8 +685,13 @@ static void psc_clks_init(void)
683 struct device_node *np; 685 struct device_node *np;
684 struct platform_device *ofdev; 686 struct platform_device *ofdev;
685 u32 reg; 687 u32 reg;
688 const char *psc_compat;
689
690 psc_compat = mpc512x_select_psc_compat();
691 if (!psc_compat)
692 return;
686 693
687 for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { 694 for_each_compatible_node(np, NULL, psc_compat) {
688 if (!of_property_read_u32(np, "reg", &reg)) { 695 if (!of_property_read_u32(np, "reg", &reg)) {
689 int pscnum = (reg & 0xf00) >> 8; 696 int pscnum = (reg & 0xf00) >> 8;
690 struct clk *clk = psc_dev_clk(pscnum); 697 struct clk *clk = psc_dev_clk(pscnum);
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h
index c32b399eb952..0a8e60023944 100644
--- a/arch/powerpc/platforms/512x/mpc512x.h
+++ b/arch/powerpc/platforms/512x/mpc512x.h
@@ -15,6 +15,7 @@ extern void __init mpc512x_init_IRQ(void);
15extern void __init mpc512x_init(void); 15extern void __init mpc512x_init(void);
16extern int __init mpc5121_clk_init(void); 16extern int __init mpc5121_clk_init(void);
17void __init mpc512x_declare_of_platform_devices(void); 17void __init mpc512x_declare_of_platform_devices(void);
18extern const char *mpc512x_select_psc_compat(void);
18extern void mpc512x_restart(char *cmd); 19extern void mpc512x_restart(char *cmd);
19 20
20#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) 21#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc512x_generic.c
index ca1ca6669990..5fb919b30924 100644
--- a/arch/powerpc/platforms/512x/mpc5121_generic.c
+++ b/arch/powerpc/platforms/512x/mpc512x_generic.c
@@ -4,7 +4,7 @@
4 * Author: John Rigby, <jrigby@freescale.com> 4 * Author: John Rigby, <jrigby@freescale.com>
5 * 5 *
6 * Description: 6 * Description:
7 * MPC5121 SoC setup 7 * MPC512x SoC setup
8 * 8 *
9 * This is free software; you can redistribute it and/or modify it 9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by 10 * under the terms of the GNU General Public License as published by
@@ -28,20 +28,22 @@
28 */ 28 */
29static const char * const board[] __initconst = { 29static const char * const board[] __initconst = {
30 "prt,prtlvt", 30 "prt,prtlvt",
31 "fsl,mpc5125ads",
32 "ifm,ac14xx",
31 NULL 33 NULL
32}; 34};
33 35
34/* 36/*
35 * Called very early, MMU is off, device-tree isn't unflattened 37 * Called very early, MMU is off, device-tree isn't unflattened
36 */ 38 */
37static int __init mpc5121_generic_probe(void) 39static int __init mpc512x_generic_probe(void)
38{ 40{
39 return of_flat_dt_match(of_get_flat_dt_root(), board); 41 return of_flat_dt_match(of_get_flat_dt_root(), board);
40} 42}
41 43
42define_machine(mpc5121_generic) { 44define_machine(mpc512x_generic) {
43 .name = "MPC5121 generic", 45 .name = "MPC512x generic",
44 .probe = mpc5121_generic_probe, 46 .probe = mpc512x_generic_probe,
45 .init = mpc512x_init, 47 .init = mpc512x_init,
46 .init_early = mpc512x_init_diu, 48 .init_early = mpc512x_init_diu,
47 .setup_arch = mpc512x_setup_diu, 49 .setup_arch = mpc512x_setup_diu,
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index d30235b7e3f7..6eb94ab99d39 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -172,12 +172,9 @@ static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb;
172 172
173static inline void mpc512x_free_bootmem(struct page *page) 173static inline void mpc512x_free_bootmem(struct page *page)
174{ 174{
175 __ClearPageReserved(page);
176 BUG_ON(PageTail(page)); 175 BUG_ON(PageTail(page));
177 BUG_ON(atomic_read(&page->_count) > 1); 176 BUG_ON(atomic_read(&page->_count) > 1);
178 atomic_set(&page->_count, 1); 177 free_reserved_page(page);
179 __free_page(page);
180 totalram_pages++;
181} 178}
182 179
183void mpc512x_release_bootmem(void) 180void mpc512x_release_bootmem(void)
@@ -330,26 +327,34 @@ void __init mpc512x_init_IRQ(void)
330static struct of_device_id __initdata of_bus_ids[] = { 327static struct of_device_id __initdata of_bus_ids[] = {
331 { .compatible = "fsl,mpc5121-immr", }, 328 { .compatible = "fsl,mpc5121-immr", },
332 { .compatible = "fsl,mpc5121-localbus", }, 329 { .compatible = "fsl,mpc5121-localbus", },
330 { .compatible = "fsl,mpc5121-mbx", },
331 { .compatible = "fsl,mpc5121-nfc", },
332 { .compatible = "fsl,mpc5121-sram", },
333 { .compatible = "fsl,mpc5121-pci", },
334 { .compatible = "gpio-leds", },
333 {}, 335 {},
334}; 336};
335 337
336void __init mpc512x_declare_of_platform_devices(void) 338void __init mpc512x_declare_of_platform_devices(void)
337{ 339{
338 struct device_node *np;
339
340 if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) 340 if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
341 printk(KERN_ERR __FILE__ ": " 341 printk(KERN_ERR __FILE__ ": "
342 "Error while probing of_platform bus\n"); 342 "Error while probing of_platform bus\n");
343
344 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc");
345 if (np) {
346 of_platform_device_create(np, NULL, NULL);
347 of_node_put(np);
348 }
349} 343}
350 344
351#define DEFAULT_FIFO_SIZE 16 345#define DEFAULT_FIFO_SIZE 16
352 346
347const char *mpc512x_select_psc_compat(void)
348{
349 if (of_machine_is_compatible("fsl,mpc5121"))
350 return "fsl,mpc5121-psc";
351
352 if (of_machine_is_compatible("fsl,mpc5125"))
353 return "fsl,mpc5125-psc";
354
355 return NULL;
356}
357
353static unsigned int __init get_fifo_size(struct device_node *np, 358static unsigned int __init get_fifo_size(struct device_node *np,
354 char *prop_name) 359 char *prop_name)
355{ 360{
@@ -375,9 +380,16 @@ void __init mpc512x_psc_fifo_init(void)
375 void __iomem *psc; 380 void __iomem *psc;
376 unsigned int tx_fifo_size; 381 unsigned int tx_fifo_size;
377 unsigned int rx_fifo_size; 382 unsigned int rx_fifo_size;
383 const char *psc_compat;
378 int fifobase = 0; /* current fifo address in 32 bit words */ 384 int fifobase = 0; /* current fifo address in 32 bit words */
379 385
380 for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { 386 psc_compat = mpc512x_select_psc_compat();
387 if (!psc_compat) {
388 pr_err("%s: no compatible devices found\n", __func__);
389 return;
390 }
391
392 for_each_compatible_node(np, NULL, psc_compat) {
381 tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); 393 tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size");
382 rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); 394 rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size");
383 395
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index a0dcd577fb0d..8f02b05f4c96 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -305,6 +305,40 @@ config PPC_QEMU_E500
305 unset based on the emulated CPU (or actual host CPU in the case 305 unset based on the emulated CPU (or actual host CPU in the case
306 of KVM). 306 of KVM).
307 307
308if PPC64
309
310config T4240_QDS
311 bool "Freescale T4240 QDS"
312 select DEFAULT_UIMAGE
313 select E500
314 select PPC_E500MC
315 select PHYS_64BIT
316 select SWIOTLB
317 select ARCH_REQUIRE_GPIOLIB
318 select GPIO_MPC8XXX
319 select HAS_RAPIDIO
320 select PPC_EPAPR_HV_PIC
321 help
322 This option enables support for the T4240 QDS board
323
324config B4_QDS
325 bool "Freescale B4 QDS"
326 select DEFAULT_UIMAGE
327 select E500
328 select PPC_E500MC
329 select PHYS_64BIT
330 select SWIOTLB
331 select GENERIC_GPIO
332 select ARCH_REQUIRE_GPIOLIB
333 select HAS_RAPIDIO
334 select PPC_EPAPR_HV_PIC
335 help
336 This option enables support for the B4 QDS board
337 The B4 application development system B4 QDS is a complete
338 debugging environment intended for engineers developing
339 applications for the B4.
340
341endif
308endif # FSL_SOC_BOOKE 342endif # FSL_SOC_BOOKE
309 343
310config TQM85xx 344config TQM85xx
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 07d0dbb141c0..2eab37ea4a9d 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -22,6 +22,8 @@ obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o
22obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o 22obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o
23obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o 23obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o
24obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o 24obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o
25obj-$(CONFIG_T4240_QDS) += t4240_qds.o corenet_ds.o
26obj-$(CONFIG_B4_QDS) += b4_qds.o corenet_ds.o
25obj-$(CONFIG_STX_GP3) += stx_gp3.o 27obj-$(CONFIG_STX_GP3) += stx_gp3.o
26obj-$(CONFIG_TQM85xx) += tqm85xx.o 28obj-$(CONFIG_TQM85xx) += tqm85xx.o
27obj-$(CONFIG_SBC8548) += sbc8548.o 29obj-$(CONFIG_SBC8548) += sbc8548.o
diff --git a/arch/powerpc/platforms/85xx/b4_qds.c b/arch/powerpc/platforms/85xx/b4_qds.c
new file mode 100644
index 000000000000..0c6702f8b88e
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/b4_qds.c
@@ -0,0 +1,102 @@
1/*
2 * B4 QDS Setup
3 * Should apply for QDS platform of B4860 and it's personalities.
4 * viz B4860/B4420/B4220QDS
5 *
6 * Copyright 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/kernel.h>
15#include <linux/pci.h>
16#include <linux/kdev_t.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/phy.h>
20
21#include <asm/time.h>
22#include <asm/machdep.h>
23#include <asm/pci-bridge.h>
24#include <mm/mmu_decl.h>
25#include <asm/prom.h>
26#include <asm/udbg.h>
27#include <asm/mpic.h>
28
29#include <linux/of_platform.h>
30#include <sysdev/fsl_soc.h>
31#include <sysdev/fsl_pci.h>
32#include <asm/ehv_pic.h>
33
34#include "corenet_ds.h"
35
36/*
37 * Called very early, device-tree isn't unflattened
38 */
39static int __init b4_qds_probe(void)
40{
41 unsigned long root = of_get_flat_dt_root();
42#ifdef CONFIG_SMP
43 extern struct smp_ops_t smp_85xx_ops;
44#endif
45
46 if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS")) ||
47 (of_flat_dt_is_compatible(root, "fsl,B4420QDS")) ||
48 (of_flat_dt_is_compatible(root, "fsl,B4220QDS")))
49 return 1;
50
51 /* Check if we're running under the Freescale hypervisor */
52 if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS-hv")) ||
53 (of_flat_dt_is_compatible(root, "fsl,B4420QDS-hv")) ||
54 (of_flat_dt_is_compatible(root, "fsl,B4220QDS-hv"))) {
55 ppc_md.init_IRQ = ehv_pic_init;
56 ppc_md.get_irq = ehv_pic_get_irq;
57 ppc_md.restart = fsl_hv_restart;
58 ppc_md.power_off = fsl_hv_halt;
59 ppc_md.halt = fsl_hv_halt;
60#ifdef CONFIG_SMP
61 /*
62 * Disable the timebase sync operations because we can't write
63 * to the timebase registers under the hypervisor.
64 */
65 smp_85xx_ops.give_timebase = NULL;
66 smp_85xx_ops.take_timebase = NULL;
67#endif
68 return 1;
69 }
70
71 return 0;
72}
73
74define_machine(b4_qds) {
75 .name = "B4 QDS",
76 .probe = b4_qds_probe,
77 .setup_arch = corenet_ds_setup_arch,
78 .init_IRQ = corenet_ds_pic_init,
79#ifdef CONFIG_PCI
80 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
81#endif
82/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
83#ifdef CONFIG_PPC64
84 .get_irq = mpic_get_irq,
85#else
86 .get_irq = mpic_get_coreint_irq,
87#endif
88 .restart = fsl_rstcr_restart,
89 .calibrate_decr = generic_calibrate_decr,
90 .progress = udbg_progress,
91#ifdef CONFIG_PPC64
92 .power_save = book3e_idle,
93#else
94 .power_save = e500_idle,
95#endif
96};
97
98machine_arch_initcall(b4_qds, corenet_ds_publish_devices);
99
100#ifdef CONFIG_SWIOTLB
101machine_arch_initcall(b4_qds, swiotlb_setup_bus_notifier);
102#endif
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c
index 6f355d8c92f6..c59c617eee93 100644
--- a/arch/powerpc/platforms/85xx/corenet_ds.c
+++ b/arch/powerpc/platforms/85xx/corenet_ds.c
@@ -40,7 +40,7 @@ void __init corenet_ds_pic_init(void)
40 if (ppc_md.get_irq == mpic_get_coreint_irq) 40 if (ppc_md.get_irq == mpic_get_coreint_irq)
41 flags |= MPIC_ENABLE_COREINT; 41 flags |= MPIC_ENABLE_COREINT;
42 42
43 mpic = mpic_alloc(NULL, 0, flags, 0, 256, " OpenPIC "); 43 mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC ");
44 BUG_ON(mpic == NULL); 44 BUG_ON(mpic == NULL);
45 45
46 mpic_init(mpic); 46 mpic_init(mpic);
@@ -83,6 +83,9 @@ static const struct of_device_id of_device_ids[] = {
83 { 83 {
84 .compatible = "fsl,qoriq-pcie-v2.4", 84 .compatible = "fsl,qoriq-pcie-v2.4",
85 }, 85 },
86 {
87 .compatible = "fsl,qoriq-pcie-v3.0",
88 },
86 /* The following two are for the Freescale hypervisor */ 89 /* The following two are for the Freescale hypervisor */
87 { 90 {
88 .name = "hypervisor", 91 .name = "hypervisor",
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 148c2f2d9780..6a1759939c6b 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -201,7 +201,7 @@ static int __cpuinit smp_85xx_kick_cpu(int nr)
201 * We don't set the BPTR register here since it already points 201 * We don't set the BPTR register here since it already points
202 * to the boot page properly. 202 * to the boot page properly.
203 */ 203 */
204 mpic_reset_core(hw_cpu); 204 mpic_reset_core(nr);
205 205
206 /* 206 /*
207 * wait until core is ready... 207 * wait until core is ready...
diff --git a/arch/powerpc/platforms/85xx/t4240_qds.c b/arch/powerpc/platforms/85xx/t4240_qds.c
new file mode 100644
index 000000000000..5998e9f33304
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/t4240_qds.c
@@ -0,0 +1,98 @@
1/*
2 * T4240 QDS Setup
3 *
4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
5 *
6 * Copyright 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/kernel.h>
15#include <linux/pci.h>
16#include <linux/kdev_t.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/phy.h>
20
21#include <asm/time.h>
22#include <asm/machdep.h>
23#include <asm/pci-bridge.h>
24#include <mm/mmu_decl.h>
25#include <asm/prom.h>
26#include <asm/udbg.h>
27#include <asm/mpic.h>
28
29#include <linux/of_platform.h>
30#include <sysdev/fsl_soc.h>
31#include <sysdev/fsl_pci.h>
32#include <asm/ehv_pic.h>
33
34#include "corenet_ds.h"
35
36/*
37 * Called very early, device-tree isn't unflattened
38 */
39static int __init t4240_qds_probe(void)
40{
41 unsigned long root = of_get_flat_dt_root();
42#ifdef CONFIG_SMP
43 extern struct smp_ops_t smp_85xx_ops;
44#endif
45
46 if (of_flat_dt_is_compatible(root, "fsl,T4240QDS"))
47 return 1;
48
49 /* Check if we're running under the Freescale hypervisor */
50 if (of_flat_dt_is_compatible(root, "fsl,T4240QDS-hv")) {
51 ppc_md.init_IRQ = ehv_pic_init;
52 ppc_md.get_irq = ehv_pic_get_irq;
53 ppc_md.restart = fsl_hv_restart;
54 ppc_md.power_off = fsl_hv_halt;
55 ppc_md.halt = fsl_hv_halt;
56#ifdef CONFIG_SMP
57 /*
58 * Disable the timebase sync operations because we can't write
59 * to the timebase registers under the hypervisor.
60 */
61 smp_85xx_ops.give_timebase = NULL;
62 smp_85xx_ops.take_timebase = NULL;
63#endif
64 return 1;
65 }
66
67 return 0;
68}
69
70define_machine(t4240_qds) {
71 .name = "T4240 QDS",
72 .probe = t4240_qds_probe,
73 .setup_arch = corenet_ds_setup_arch,
74 .init_IRQ = corenet_ds_pic_init,
75#ifdef CONFIG_PCI
76 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
77#endif
78/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
79#ifdef CONFIG_PPC64
80 .get_irq = mpic_get_irq,
81#else
82 .get_irq = mpic_get_coreint_irq,
83#endif
84 .restart = fsl_rstcr_restart,
85 .calibrate_decr = generic_calibrate_decr,
86 .progress = udbg_progress,
87#ifdef CONFIG_PPC64
88 .power_save = book3e_idle,
89#else
90 .power_save = e500_idle,
91#endif
92};
93
94machine_arch_initcall(t4240_qds, corenet_ds_publish_devices);
95
96#ifdef CONFIG_SWIOTLB
97machine_arch_initcall(t4240_qds, swiotlb_setup_bus_notifier);
98#endif
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 52de8bccfb30..34d224be93ba 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -6,7 +6,6 @@ source "arch/powerpc/platforms/chrp/Kconfig"
6source "arch/powerpc/platforms/512x/Kconfig" 6source "arch/powerpc/platforms/512x/Kconfig"
7source "arch/powerpc/platforms/52xx/Kconfig" 7source "arch/powerpc/platforms/52xx/Kconfig"
8source "arch/powerpc/platforms/powermac/Kconfig" 8source "arch/powerpc/platforms/powermac/Kconfig"
9source "arch/powerpc/platforms/prep/Kconfig"
10source "arch/powerpc/platforms/maple/Kconfig" 9source "arch/powerpc/platforms/maple/Kconfig"
11source "arch/powerpc/platforms/pasemi/Kconfig" 10source "arch/powerpc/platforms/pasemi/Kconfig"
12source "arch/powerpc/platforms/ps3/Kconfig" 11source "arch/powerpc/platforms/ps3/Kconfig"
@@ -233,7 +232,7 @@ endmenu
233 232
234config PPC601_SYNC_FIX 233config PPC601_SYNC_FIX
235 bool "Workarounds for PPC601 bugs" 234 bool "Workarounds for PPC601 bugs"
236 depends on 6xx && (PPC_PREP || PPC_PMAC) 235 depends on 6xx && PPC_PMAC
237 help 236 help
238 Some versions of the PPC601 (the first PowerPC chip) have bugs which 237 Some versions of the PPC601 (the first PowerPC chip) have bugs which
239 mean that extra synchronization instructions are required near 238 mean that extra synchronization instructions are required near
@@ -344,7 +343,6 @@ config FSL_ULI1575
344 343
345config CPM 344config CPM
346 bool 345 bool
347 select PPC_CLOCK
348 346
349config OF_RTC 347config OF_RTC
350 bool 348 bool
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 18e3b76c78d7..54f3936001aa 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -230,7 +230,7 @@ config PHYS_64BIT
230 230
231config ALTIVEC 231config ALTIVEC
232 bool "AltiVec Support" 232 bool "AltiVec Support"
233 depends on 6xx || POWER4 233 depends on 6xx || POWER4 || (PPC_E500MC && PPC64)
234 ---help--- 234 ---help---
235 This option enables kernel support for the Altivec extensions to the 235 This option enables kernel support for the Altivec extensions to the
236 PowerPC processor. The kernel currently supports saving and restoring 236 PowerPC processor. The kernel currently supports saving and restoring
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 53aaefeb3386..9978f594cac0 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -113,34 +113,10 @@ config CBE_THERM
113 default m 113 default m
114 depends on CBE_RAS && SPU_BASE 114 depends on CBE_RAS && SPU_BASE
115 115
116config CBE_CPUFREQ
117 tristate "CBE frequency scaling"
118 depends on CBE_RAS && CPU_FREQ
119 default m
120 help
121 This adds the cpufreq driver for Cell BE processors.
122 For details, take a look at <file:Documentation/cpu-freq/>.
123 If you don't have such processor, say N
124
125config CBE_CPUFREQ_PMI_ENABLE
126 bool "CBE frequency scaling using PMI interface"
127 depends on CBE_CPUFREQ
128 default n
129 help
130 Select this, if you want to use the PMI interface
131 to switch frequencies. Using PMI, the
132 processor will not only be able to run at lower speed,
133 but also at lower core voltage.
134
135config CBE_CPUFREQ_PMI
136 tristate
137 depends on CBE_CPUFREQ_PMI_ENABLE
138 default CBE_CPUFREQ
139
140config PPC_PMI 116config PPC_PMI
141 tristate 117 tristate
142 default y 118 default y
143 depends on CBE_CPUFREQ_PMI || PPC_IBM_CELL_POWERBUTTON 119 depends on CPU_FREQ_CBE_PMI || PPC_IBM_CELL_POWERBUTTON
144 help 120 help
145 PMI (Platform Management Interrupt) is a way to 121 PMI (Platform Management Interrupt) is a way to
146 communicate with the BMC (Baseboard Management Controller). 122 communicate with the BMC (Baseboard Management Controller).
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index a4a89350bcfc..fe053e7c73ee 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -5,9 +5,6 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += iommu.o setup.o spider-pic.o \
5obj-$(CONFIG_CBE_RAS) += ras.o 5obj-$(CONFIG_CBE_RAS) += ras.o
6 6
7obj-$(CONFIG_CBE_THERM) += cbe_thermal.o 7obj-$(CONFIG_CBE_THERM) += cbe_thermal.o
8obj-$(CONFIG_CBE_CPUFREQ_PMI) += cbe_cpufreq_pmi.o
9obj-$(CONFIG_CBE_CPUFREQ) += cbe-cpufreq.o
10cbe-cpufreq-y += cbe_cpufreq_pervasive.o cbe_cpufreq.o
11obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o 8obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o
12 9
13obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o 10obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index 0f6f83988b3d..246e1d8b3af3 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -90,7 +90,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group)
90static long beat_lpar_hpte_insert(unsigned long hpte_group, 90static long beat_lpar_hpte_insert(unsigned long hpte_group,
91 unsigned long vpn, unsigned long pa, 91 unsigned long vpn, unsigned long pa,
92 unsigned long rflags, unsigned long vflags, 92 unsigned long rflags, unsigned long vflags,
93 int psize, int ssize) 93 int psize, int apsize, int ssize)
94{ 94{
95 unsigned long lpar_rc; 95 unsigned long lpar_rc;
96 u64 hpte_v, hpte_r, slot; 96 u64 hpte_v, hpte_r, slot;
@@ -103,9 +103,9 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group,
103 "rflags=%lx, vflags=%lx, psize=%d)\n", 103 "rflags=%lx, vflags=%lx, psize=%d)\n",
104 hpte_group, va, pa, rflags, vflags, psize); 104 hpte_group, va, pa, rflags, vflags, psize);
105 105
106 hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) | 106 hpte_v = hpte_encode_v(vpn, psize, apsize, MMU_SEGSIZE_256M) |
107 vflags | HPTE_V_VALID; 107 vflags | HPTE_V_VALID;
108 hpte_r = hpte_encode_r(pa, psize) | rflags; 108 hpte_r = hpte_encode_r(pa, psize, apsize) | rflags;
109 109
110 if (!(vflags & HPTE_V_BOLTED)) 110 if (!(vflags & HPTE_V_BOLTED))
111 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); 111 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
@@ -191,7 +191,7 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
191 u64 dummy0, dummy1; 191 u64 dummy0, dummy1;
192 unsigned long want_v; 192 unsigned long want_v;
193 193
194 want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); 194 want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M);
195 195
196 DBG_LOW(" update: " 196 DBG_LOW(" update: "
197 "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", 197 "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
@@ -228,7 +228,7 @@ static long beat_lpar_hpte_find(unsigned long vpn, int psize)
228 unsigned long want_v, hpte_v; 228 unsigned long want_v, hpte_v;
229 229
230 hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); 230 hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M);
231 want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); 231 want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M);
232 232
233 for (j = 0; j < 2; j++) { 233 for (j = 0; j < 2; j++) {
234 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; 234 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
@@ -283,7 +283,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
283 283
284 DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", 284 DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
285 slot, va, psize, local); 285 slot, va, psize, local);
286 want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); 286 want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M);
287 287
288 raw_spin_lock_irqsave(&beat_htab_lock, flags); 288 raw_spin_lock_irqsave(&beat_htab_lock, flags);
289 dummy1 = beat_lpar_hpte_getword0(slot); 289 dummy1 = beat_lpar_hpte_getword0(slot);
@@ -314,7 +314,7 @@ void __init hpte_init_beat(void)
314static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, 314static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
315 unsigned long vpn, unsigned long pa, 315 unsigned long vpn, unsigned long pa,
316 unsigned long rflags, unsigned long vflags, 316 unsigned long rflags, unsigned long vflags,
317 int psize, int ssize) 317 int psize, int apsize, int ssize)
318{ 318{
319 unsigned long lpar_rc; 319 unsigned long lpar_rc;
320 u64 hpte_v, hpte_r, slot; 320 u64 hpte_v, hpte_r, slot;
@@ -327,9 +327,9 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
327 "rflags=%lx, vflags=%lx, psize=%d)\n", 327 "rflags=%lx, vflags=%lx, psize=%d)\n",
328 hpte_group, vpn, pa, rflags, vflags, psize); 328 hpte_group, vpn, pa, rflags, vflags, psize);
329 329
330 hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) | 330 hpte_v = hpte_encode_v(vpn, psize, apsize, MMU_SEGSIZE_256M) |
331 vflags | HPTE_V_VALID; 331 vflags | HPTE_V_VALID;
332 hpte_r = hpte_encode_r(pa, psize) | rflags; 332 hpte_r = hpte_encode_r(pa, psize, apsize) | rflags;
333 333
334 if (!(vflags & HPTE_V_BOLTED)) 334 if (!(vflags & HPTE_V_BOLTED))
335 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); 335 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
@@ -372,8 +372,8 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
372 unsigned long want_v; 372 unsigned long want_v;
373 unsigned long pss; 373 unsigned long pss;
374 374
375 want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); 375 want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M);
376 pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; 376 pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc[psize];
377 377
378 DBG_LOW(" update: " 378 DBG_LOW(" update: "
379 "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", 379 "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
@@ -402,8 +402,8 @@ static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long vpn,
402 402
403 DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n", 403 DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n",
404 slot, vpn, psize, local); 404 slot, vpn, psize, local);
405 want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); 405 want_v = hpte_encode_avpn(vpn, psize, MMU_SEGSIZE_256M);
406 pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; 406 pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc[psize];
407 407
408 lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); 408 lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss);
409 409
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
deleted file mode 100644
index d4c39e32f147..000000000000
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ /dev/null
@@ -1,209 +0,0 @@
1/*
2 * cpufreq driver for the cell processor
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
5 *
6 * Author: Christian Krafft <krafft@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/cpufreq.h>
24#include <linux/module.h>
25#include <linux/of_platform.h>
26
27#include <asm/machdep.h>
28#include <asm/prom.h>
29#include <asm/cell-regs.h>
30#include "cbe_cpufreq.h"
31
32static DEFINE_MUTEX(cbe_switch_mutex);
33
34
35/* the CBE supports an 8 step frequency scaling */
36static struct cpufreq_frequency_table cbe_freqs[] = {
37 {1, 0},
38 {2, 0},
39 {3, 0},
40 {4, 0},
41 {5, 0},
42 {6, 0},
43 {8, 0},
44 {10, 0},
45 {0, CPUFREQ_TABLE_END},
46};
47
48/*
49 * hardware specific functions
50 */
51
52static int set_pmode(unsigned int cpu, unsigned int slow_mode)
53{
54 int rc;
55
56 if (cbe_cpufreq_has_pmi)
57 rc = cbe_cpufreq_set_pmode_pmi(cpu, slow_mode);
58 else
59 rc = cbe_cpufreq_set_pmode(cpu, slow_mode);
60
61 pr_debug("register contains slow mode %d\n", cbe_cpufreq_get_pmode(cpu));
62
63 return rc;
64}
65
66/*
67 * cpufreq functions
68 */
69
70static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
71{
72 const u32 *max_freqp;
73 u32 max_freq;
74 int i, cur_pmode;
75 struct device_node *cpu;
76
77 cpu = of_get_cpu_node(policy->cpu, NULL);
78
79 if (!cpu)
80 return -ENODEV;
81
82 pr_debug("init cpufreq on CPU %d\n", policy->cpu);
83
84 /*
85 * Let's check we can actually get to the CELL regs
86 */
87 if (!cbe_get_cpu_pmd_regs(policy->cpu) ||
88 !cbe_get_cpu_mic_tm_regs(policy->cpu)) {
89 pr_info("invalid CBE regs pointers for cpufreq\n");
90 return -EINVAL;
91 }
92
93 max_freqp = of_get_property(cpu, "clock-frequency", NULL);
94
95 of_node_put(cpu);
96
97 if (!max_freqp)
98 return -EINVAL;
99
100 /* we need the freq in kHz */
101 max_freq = *max_freqp / 1000;
102
103 pr_debug("max clock-frequency is at %u kHz\n", max_freq);
104 pr_debug("initializing frequency table\n");
105
106 /* initialize frequency table */
107 for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
108 cbe_freqs[i].frequency = max_freq / cbe_freqs[i].index;
109 pr_debug("%d: %d\n", i, cbe_freqs[i].frequency);
110 }
111
112 /* if DEBUG is enabled set_pmode() measures the latency
113 * of a transition */
114 policy->cpuinfo.transition_latency = 25000;
115
116 cur_pmode = cbe_cpufreq_get_pmode(policy->cpu);
117 pr_debug("current pmode is at %d\n",cur_pmode);
118
119 policy->cur = cbe_freqs[cur_pmode].frequency;
120
121#ifdef CONFIG_SMP
122 cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
123#endif
124
125 cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
126
127 /* this ensures that policy->cpuinfo_min
128 * and policy->cpuinfo_max are set correctly */
129 return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs);
130}
131
132static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
133{
134 cpufreq_frequency_table_put_attr(policy->cpu);
135 return 0;
136}
137
138static int cbe_cpufreq_verify(struct cpufreq_policy *policy)
139{
140 return cpufreq_frequency_table_verify(policy, cbe_freqs);
141}
142
143static int cbe_cpufreq_target(struct cpufreq_policy *policy,
144 unsigned int target_freq,
145 unsigned int relation)
146{
147 int rc;
148 struct cpufreq_freqs freqs;
149 unsigned int cbe_pmode_new;
150
151 cpufreq_frequency_table_target(policy,
152 cbe_freqs,
153 target_freq,
154 relation,
155 &cbe_pmode_new);
156
157 freqs.old = policy->cur;
158 freqs.new = cbe_freqs[cbe_pmode_new].frequency;
159 freqs.cpu = policy->cpu;
160
161 mutex_lock(&cbe_switch_mutex);
162 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
163
164 pr_debug("setting frequency for cpu %d to %d kHz, " \
165 "1/%d of max frequency\n",
166 policy->cpu,
167 cbe_freqs[cbe_pmode_new].frequency,
168 cbe_freqs[cbe_pmode_new].index);
169
170 rc = set_pmode(policy->cpu, cbe_pmode_new);
171
172 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
173 mutex_unlock(&cbe_switch_mutex);
174
175 return rc;
176}
177
178static struct cpufreq_driver cbe_cpufreq_driver = {
179 .verify = cbe_cpufreq_verify,
180 .target = cbe_cpufreq_target,
181 .init = cbe_cpufreq_cpu_init,
182 .exit = cbe_cpufreq_cpu_exit,
183 .name = "cbe-cpufreq",
184 .owner = THIS_MODULE,
185 .flags = CPUFREQ_CONST_LOOPS,
186};
187
188/*
189 * module init and destoy
190 */
191
192static int __init cbe_cpufreq_init(void)
193{
194 if (!machine_is(cell))
195 return -ENODEV;
196
197 return cpufreq_register_driver(&cbe_cpufreq_driver);
198}
199
200static void __exit cbe_cpufreq_exit(void)
201{
202 cpufreq_unregister_driver(&cbe_cpufreq_driver);
203}
204
205module_init(cbe_cpufreq_init);
206module_exit(cbe_cpufreq_exit);
207
208MODULE_LICENSE("GPL");
209MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.h b/arch/powerpc/platforms/cell/cbe_cpufreq.h
deleted file mode 100644
index c1d86bfa92ff..000000000000
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * cbe_cpufreq.h
3 *
4 * This file contains the definitions used by the cbe_cpufreq driver.
5 *
6 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
7 *
8 * Author: Christian Krafft <krafft@de.ibm.com>
9 *
10 */
11
12#include <linux/cpufreq.h>
13#include <linux/types.h>
14
15int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode);
16int cbe_cpufreq_get_pmode(int cpu);
17
18int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode);
19
20#if defined(CONFIG_CBE_CPUFREQ_PMI) || defined(CONFIG_CBE_CPUFREQ_PMI_MODULE)
21extern bool cbe_cpufreq_has_pmi;
22#else
23#define cbe_cpufreq_has_pmi (0)
24#endif
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c b/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c
deleted file mode 100644
index 20472e487b6f..000000000000
--- a/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c
+++ /dev/null
@@ -1,115 +0,0 @@
1/*
2 * pervasive backend for the cbe_cpufreq driver
3 *
4 * This driver makes use of the pervasive unit to
5 * engage the desired frequency.
6 *
7 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
8 *
9 * Author: Christian Krafft <krafft@de.ibm.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/io.h>
27#include <linux/kernel.h>
28#include <linux/time.h>
29#include <asm/machdep.h>
30#include <asm/hw_irq.h>
31#include <asm/cell-regs.h>
32
33#include "cbe_cpufreq.h"
34
35/* to write to MIC register */
36static u64 MIC_Slow_Fast_Timer_table[] = {
37 [0 ... 7] = 0x007fc00000000000ull,
38};
39
40/* more values for the MIC */
41static u64 MIC_Slow_Next_Timer_table[] = {
42 0x0000240000000000ull,
43 0x0000268000000000ull,
44 0x000029C000000000ull,
45 0x00002D0000000000ull,
46 0x0000300000000000ull,
47 0x0000334000000000ull,
48 0x000039C000000000ull,
49 0x00003FC000000000ull,
50};
51
52
53int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode)
54{
55 struct cbe_pmd_regs __iomem *pmd_regs;
56 struct cbe_mic_tm_regs __iomem *mic_tm_regs;
57 unsigned long flags;
58 u64 value;
59#ifdef DEBUG
60 long time;
61#endif
62
63 local_irq_save(flags);
64
65 mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu);
66 pmd_regs = cbe_get_cpu_pmd_regs(cpu);
67
68#ifdef DEBUG
69 time = jiffies;
70#endif
71
72 out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]);
73 out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]);
74
75 out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]);
76 out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]);
77
78 value = in_be64(&pmd_regs->pmcr);
79 /* set bits to zero */
80 value &= 0xFFFFFFFFFFFFFFF8ull;
81 /* set bits to next pmode */
82 value |= pmode;
83
84 out_be64(&pmd_regs->pmcr, value);
85
86#ifdef DEBUG
87 /* wait until new pmode appears in status register */
88 value = in_be64(&pmd_regs->pmsr) & 0x07;
89 while (value != pmode) {
90 cpu_relax();
91 value = in_be64(&pmd_regs->pmsr) & 0x07;
92 }
93
94 time = jiffies - time;
95 time = jiffies_to_msecs(time);
96 pr_debug("had to wait %lu ms for a transition using " \
97 "pervasive unit\n", time);
98#endif
99 local_irq_restore(flags);
100
101 return 0;
102}
103
104
105int cbe_cpufreq_get_pmode(int cpu)
106{
107 int ret;
108 struct cbe_pmd_regs __iomem *pmd_regs;
109
110 pmd_regs = cbe_get_cpu_pmd_regs(cpu);
111 ret = in_be64(&pmd_regs->pmsr) & 0x07;
112
113 return ret;
114}
115
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
deleted file mode 100644
index 60a07a4f9326..000000000000
--- a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/*
2 * pmi backend for the cbe_cpufreq driver
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
5 *
6 * Author: Christian Krafft <krafft@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <linux/timer.h>
26#include <linux/module.h>
27#include <linux/of_platform.h>
28
29#include <asm/processor.h>
30#include <asm/prom.h>
31#include <asm/pmi.h>
32#include <asm/cell-regs.h>
33
34#ifdef DEBUG
35#include <asm/time.h>
36#endif
37
38#include "cbe_cpufreq.h"
39
40static u8 pmi_slow_mode_limit[MAX_CBE];
41
42bool cbe_cpufreq_has_pmi = false;
43EXPORT_SYMBOL_GPL(cbe_cpufreq_has_pmi);
44
45/*
46 * hardware specific functions
47 */
48
49int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode)
50{
51 int ret;
52 pmi_message_t pmi_msg;
53#ifdef DEBUG
54 long time;
55#endif
56 pmi_msg.type = PMI_TYPE_FREQ_CHANGE;
57 pmi_msg.data1 = cbe_cpu_to_node(cpu);
58 pmi_msg.data2 = pmode;
59
60#ifdef DEBUG
61 time = jiffies;
62#endif
63 pmi_send_message(pmi_msg);
64
65#ifdef DEBUG
66 time = jiffies - time;
67 time = jiffies_to_msecs(time);
68 pr_debug("had to wait %lu ms for a transition using " \
69 "PMI\n", time);
70#endif
71 ret = pmi_msg.data2;
72 pr_debug("PMI returned slow mode %d\n", ret);
73
74 return ret;
75}
76EXPORT_SYMBOL_GPL(cbe_cpufreq_set_pmode_pmi);
77
78
79static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg)
80{
81 u8 node, slow_mode;
82
83 BUG_ON(pmi_msg.type != PMI_TYPE_FREQ_CHANGE);
84
85 node = pmi_msg.data1;
86 slow_mode = pmi_msg.data2;
87
88 pmi_slow_mode_limit[node] = slow_mode;
89
90 pr_debug("cbe_handle_pmi: node: %d max_freq: %d\n", node, slow_mode);
91}
92
93static int pmi_notifier(struct notifier_block *nb,
94 unsigned long event, void *data)
95{
96 struct cpufreq_policy *policy = data;
97 struct cpufreq_frequency_table *cbe_freqs;
98 u8 node;
99
100 /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE
101 * and CPUFREQ_NOTIFY policy events?)
102 */
103 if (event == CPUFREQ_START)
104 return 0;
105
106 cbe_freqs = cpufreq_frequency_get_table(policy->cpu);
107 node = cbe_cpu_to_node(policy->cpu);
108
109 pr_debug("got notified, event=%lu, node=%u\n", event, node);
110
111 if (pmi_slow_mode_limit[node] != 0) {
112 pr_debug("limiting node %d to slow mode %d\n",
113 node, pmi_slow_mode_limit[node]);
114
115 cpufreq_verify_within_limits(policy, 0,
116
117 cbe_freqs[pmi_slow_mode_limit[node]].frequency);
118 }
119
120 return 0;
121}
122
123static struct notifier_block pmi_notifier_block = {
124 .notifier_call = pmi_notifier,
125};
126
127static struct pmi_handler cbe_pmi_handler = {
128 .type = PMI_TYPE_FREQ_CHANGE,
129 .handle_pmi_message = cbe_cpufreq_handle_pmi,
130};
131
132
133
134static int __init cbe_cpufreq_pmi_init(void)
135{
136 cbe_cpufreq_has_pmi = pmi_register_handler(&cbe_pmi_handler) == 0;
137
138 if (!cbe_cpufreq_has_pmi)
139 return -ENODEV;
140
141 cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
142
143 return 0;
144}
145
146static void __exit cbe_cpufreq_pmi_exit(void)
147{
148 cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
149 pmi_unregister_handler(&cbe_pmi_handler);
150}
151
152module_init(cbe_cpufreq_pmi_init);
153module_exit(cbe_cpufreq_pmi_exit);
154
155MODULE_LICENSE("GPL");
156MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
index 59c1a1694104..348a27b12512 100644
--- a/arch/powerpc/platforms/cell/pmu.c
+++ b/arch/powerpc/platforms/cell/pmu.c
@@ -382,7 +382,7 @@ static int __init cbe_init_pm_irq(void)
382 unsigned int irq; 382 unsigned int irq;
383 int rc, node; 383 int rc, node;
384 384
385 for_each_node(node) { 385 for_each_online_node(node) {
386 irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | 386 irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
387 (node << IIC_IRQ_NODE_SHIFT)); 387 (node << IIC_IRQ_NODE_SHIFT));
388 if (irq == NO_IRQ) { 388 if (irq == NO_IRQ) {
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 68c57d38745a..90986923a53a 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -149,7 +149,6 @@ static int __fops ## _open(struct inode *inode, struct file *file) \
149 return spufs_attr_open(inode, file, __get, __set, __fmt); \ 149 return spufs_attr_open(inode, file, __get, __set, __fmt); \
150} \ 150} \
151static const struct file_operations __fops = { \ 151static const struct file_operations __fops = { \
152 .owner = THIS_MODULE, \
153 .open = __fops ## _open, \ 152 .open = __fops ## _open, \
154 .release = spufs_attr_release, \ 153 .release = spufs_attr_release, \
155 .read = spufs_attr_read, \ 154 .read = spufs_attr_read, \
@@ -352,7 +351,7 @@ static unsigned long spufs_get_unmapped_area(struct file *file,
352 351
353 /* Else, try to obtain a 64K pages slice */ 352 /* Else, try to obtain a 64K pages slice */
354 return slice_get_unmapped_area(addr, len, flags, 353 return slice_get_unmapped_area(addr, len, flags,
355 MMU_PAGE_64K, 1, 0); 354 MMU_PAGE_64K, 1);
356} 355}
357#endif /* CONFIG_SPU_FS_64K_LS */ 356#endif /* CONFIG_SPU_FS_64K_LS */
358 357
@@ -2591,7 +2590,6 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait)
2591} 2590}
2592 2591
2593static const struct file_operations spufs_switch_log_fops = { 2592static const struct file_operations spufs_switch_log_fops = {
2594 .owner = THIS_MODULE,
2595 .open = spufs_switch_log_open, 2593 .open = spufs_switch_log_open,
2596 .read = spufs_switch_log_read, 2594 .read = spufs_switch_log_read,
2597 .poll = spufs_switch_log_poll, 2595 .poll = spufs_switch_log_poll,
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 3f3bb4cdbbec..35f77a42bedf 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -99,6 +99,7 @@ spufs_new_inode(struct super_block *sb, umode_t mode)
99 if (!inode) 99 if (!inode)
100 goto out; 100 goto out;
101 101
102 inode->i_ino = get_next_ino();
102 inode->i_mode = mode; 103 inode->i_mode = mode;
103 inode->i_uid = current_fsuid(); 104 inode->i_uid = current_fsuid();
104 inode->i_gid = current_fsgid(); 105 inode->i_gid = current_fsgid();
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 039fc8e82199..2b4dc6abde6c 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -47,6 +47,25 @@ static struct platform_device mv643xx_eth_shared_device = {
47 .resource = mv643xx_eth_shared_resources, 47 .resource = mv643xx_eth_shared_resources,
48}; 48};
49 49
50/*
51 * The orion mdio driver only covers shared + 0x4 up to shared + 0x84 - 1
52 */
53static struct resource mv643xx_eth_mvmdio_resources[] = {
54 [0] = {
55 .name = "ethernet mdio base",
56 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x4,
57 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + 0x83,
58 .flags = IORESOURCE_MEM,
59 },
60};
61
62static struct platform_device mv643xx_eth_mvmdio_device = {
63 .name = "orion-mdio",
64 .id = -1,
65 .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources),
66 .resource = mv643xx_eth_shared_resources,
67};
68
50static struct resource mv643xx_eth_port1_resources[] = { 69static struct resource mv643xx_eth_port1_resources[] = {
51 [0] = { 70 [0] = {
52 .name = "eth port1 irq", 71 .name = "eth port1 irq",
@@ -82,6 +101,7 @@ static struct platform_device eth_port1_device = {
82 101
83static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { 102static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
84 &mv643xx_eth_shared_device, 103 &mv643xx_eth_shared_device,
104 &mv643xx_eth_mvmdio_device,
85 &eth_port1_device, 105 &eth_port1_device,
86}; 106};
87 107
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 5a8f50a9afa7..302ba43d73a1 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -9,7 +9,6 @@ config LINKSTATION
9 select FSL_SOC 9 select FSL_SOC
10 select PPC_UDBG_16550 if SERIAL_8250 10 select PPC_UDBG_16550 if SERIAL_8250
11 select DEFAULT_UIMAGE 11 select DEFAULT_UIMAGE
12 select MPC10X_OPENPIC
13 select MPC10X_BRIDGE 12 select MPC10X_BRIDGE
14 help 13 help
15 Select LINKSTATION if configuring for one of PPC- (MPC8241) 14 Select LINKSTATION if configuring for one of PPC- (MPC8241)
@@ -24,7 +23,6 @@ config STORCENTER
24 select MPIC 23 select MPIC
25 select FSL_SOC 24 select FSL_SOC
26 select PPC_UDBG_16550 if SERIAL_8250 25 select PPC_UDBG_16550 if SERIAL_8250
27 select MPC10X_OPENPIC
28 select MPC10X_BRIDGE 26 select MPC10X_BRIDGE
29 help 27 help
30 Select STORCENTER if configuring for the iomega StorCenter 28 Select STORCENTER if configuring for the iomega StorCenter
@@ -84,9 +82,6 @@ config MV64X60
84 select PPC_INDIRECT_PCI 82 select PPC_INDIRECT_PCI
85 select CHECK_CACHE_COHERENCY 83 select CHECK_CACHE_COHERENCY
86 84
87config MPC10X_OPENPIC
88 bool
89
90config GAMECUBE_COMMON 85config GAMECUBE_COMMON
91 bool 86 bool
92 87
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c
index 890f30e70f98..be1e7958909e 100644
--- a/arch/powerpc/platforms/pasemi/cpufreq.c
+++ b/arch/powerpc/platforms/pasemi/cpufreq.c
@@ -273,10 +273,9 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy,
273 273
274 freqs.old = policy->cur; 274 freqs.old = policy->cur;
275 freqs.new = pas_freqs[pas_astate_new].frequency; 275 freqs.new = pas_freqs[pas_astate_new].frequency;
276 freqs.cpu = policy->cpu;
277 276
278 mutex_lock(&pas_switch_mutex); 277 mutex_lock(&pas_switch_mutex);
279 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 278 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
280 279
281 pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", 280 pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n",
282 policy->cpu, 281 policy->cpu,
@@ -288,7 +287,7 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy,
288 for_each_online_cpu(i) 287 for_each_online_cpu(i)
289 set_astate(i, pas_astate_new); 288 set_astate(i, pas_astate_new);
290 289
291 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 290 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
292 mutex_unlock(&pas_switch_mutex); 291 mutex_unlock(&pas_switch_mutex);
293 292
294 ppc_proc_freq = freqs.new * 1000ul; 293 ppc_proc_freq = freqs.new * 1000ul;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 311b804353b1..3104fad82480 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -335,7 +335,8 @@ static int pmu_set_cpu_speed(int low_speed)
335 return 0; 335 return 0;
336} 336}
337 337
338static int do_set_cpu_speed(int speed_mode, int notify) 338static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode,
339 int notify)
339{ 340{
340 struct cpufreq_freqs freqs; 341 struct cpufreq_freqs freqs;
341 unsigned long l3cr; 342 unsigned long l3cr;
@@ -343,13 +344,12 @@ static int do_set_cpu_speed(int speed_mode, int notify)
343 344
344 freqs.old = cur_freq; 345 freqs.old = cur_freq;
345 freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; 346 freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
346 freqs.cpu = smp_processor_id();
347 347
348 if (freqs.old == freqs.new) 348 if (freqs.old == freqs.new)
349 return 0; 349 return 0;
350 350
351 if (notify) 351 if (notify)
352 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 352 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
353 if (speed_mode == CPUFREQ_LOW && 353 if (speed_mode == CPUFREQ_LOW &&
354 cpu_has_feature(CPU_FTR_L3CR)) { 354 cpu_has_feature(CPU_FTR_L3CR)) {
355 l3cr = _get_L3CR(); 355 l3cr = _get_L3CR();
@@ -366,7 +366,7 @@ static int do_set_cpu_speed(int speed_mode, int notify)
366 _set_L3CR(prev_l3cr); 366 _set_L3CR(prev_l3cr);
367 } 367 }
368 if (notify) 368 if (notify)
369 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 369 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
370 cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; 370 cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
371 371
372 return 0; 372 return 0;
@@ -393,7 +393,7 @@ static int pmac_cpufreq_target( struct cpufreq_policy *policy,
393 target_freq, relation, &newstate)) 393 target_freq, relation, &newstate))
394 return -EINVAL; 394 return -EINVAL;
395 395
396 rc = do_set_cpu_speed(newstate, 1); 396 rc = do_set_cpu_speed(policy, newstate, 1);
397 397
398 ppc_proc_freq = cur_freq * 1000ul; 398 ppc_proc_freq = cur_freq * 1000ul;
399 return rc; 399 return rc;
@@ -442,7 +442,7 @@ static int pmac_cpufreq_suspend(struct cpufreq_policy *policy)
442 no_schedule = 1; 442 no_schedule = 1;
443 sleep_freq = cur_freq; 443 sleep_freq = cur_freq;
444 if (cur_freq == low_freq && !is_pmu_based) 444 if (cur_freq == low_freq && !is_pmu_based)
445 do_set_cpu_speed(CPUFREQ_HIGH, 0); 445 do_set_cpu_speed(policy, CPUFREQ_HIGH, 0);
446 return 0; 446 return 0;
447} 447}
448 448
@@ -458,7 +458,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
458 * is that we force a switch to whatever it was, which is 458 * is that we force a switch to whatever it was, which is
459 * probably high speed due to our suspend() routine 459 * probably high speed due to our suspend() routine
460 */ 460 */
461 do_set_cpu_speed(sleep_freq == low_freq ? 461 do_set_cpu_speed(policy, sleep_freq == low_freq ?
462 CPUFREQ_LOW : CPUFREQ_HIGH, 0); 462 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
463 463
464 ppc_proc_freq = cur_freq * 1000ul; 464 ppc_proc_freq = cur_freq * 1000ul;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 9650c6029c82..7ba423431cfe 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -339,11 +339,10 @@ static int g5_cpufreq_target(struct cpufreq_policy *policy,
339 339
340 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; 340 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
341 freqs.new = g5_cpu_freqs[newstate].frequency; 341 freqs.new = g5_cpu_freqs[newstate].frequency;
342 freqs.cpu = 0;
343 342
344 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 343 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
345 rc = g5_switch_freq(newstate); 344 rc = g5_switch_freq(newstate);
346 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 345 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
347 346
348 mutex_unlock(&g5_switch_mutex); 347 mutex_unlock(&g5_switch_mutex);
349 348
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
index 74fea5c21839..d3e840d643af 100644
--- a/arch/powerpc/platforms/powernv/Kconfig
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -8,6 +8,11 @@ config PPC_POWERNV
8 select PPC_PCI_CHOICE if EMBEDDED 8 select PPC_PCI_CHOICE if EMBEDDED
9 default y 9 default y
10 10
11config POWERNV_MSI
12 bool "Support PCI MSI on PowerNV platform"
13 depends on PCI_MSI
14 default y
15
11config PPC_POWERNV_RTAS 16config PPC_POWERNV_RTAS
12 depends on PPC_POWERNV 17 depends on PPC_POWERNV
13 bool "Support for RTAS based PowerNV platforms such as BML" 18 bool "Support for RTAS based PowerNV platforms such as BML"
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 3bb07e5e43cd..6fabe92eafb6 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -107,3 +107,4 @@ OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR);
107OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); 107OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS);
108OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); 108OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS);
109OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); 109OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED);
110OPAL_CALL(opal_pci_msi_eoi, OPAL_PCI_MSI_EOI);
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 8e90e8906df3..8c6c9cf91c13 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -26,10 +26,12 @@
26#include <asm/prom.h> 26#include <asm/prom.h>
27#include <asm/pci-bridge.h> 27#include <asm/pci-bridge.h>
28#include <asm/machdep.h> 28#include <asm/machdep.h>
29#include <asm/msi_bitmap.h>
29#include <asm/ppc-pci.h> 30#include <asm/ppc-pci.h>
30#include <asm/opal.h> 31#include <asm/opal.h>
31#include <asm/iommu.h> 32#include <asm/iommu.h>
32#include <asm/tce.h> 33#include <asm/tce.h>
34#include <asm/xics.h>
33 35
34#include "powernv.h" 36#include "powernv.h"
35#include "pci.h" 37#include "pci.h"
@@ -87,6 +89,7 @@ static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
87 return IODA_INVALID_PE; 89 return IODA_INVALID_PE;
88 } while(test_and_set_bit(pe, phb->ioda.pe_alloc)); 90 } while(test_and_set_bit(pe, phb->ioda.pe_alloc));
89 91
92 phb->ioda.pe_array[pe].phb = phb;
90 phb->ioda.pe_array[pe].pe_number = pe; 93 phb->ioda.pe_array[pe].pe_number = pe;
91 return pe; 94 return pe;
92} 95}
@@ -431,22 +434,102 @@ static void pnv_pci_ioda_setup_PEs(void)
431 } 434 }
432} 435}
433 436
434static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *dev) 437static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev)
435{ 438{
436 /* We delay DMA setup after we have assigned all PE# */ 439 struct pci_dn *pdn = pnv_ioda_get_pdn(pdev);
440 struct pnv_ioda_pe *pe;
441
442 /*
443 * The function can be called while the PE#
444 * hasn't been assigned. Do nothing for the
445 * case.
446 */
447 if (!pdn || pdn->pe_number == IODA_INVALID_PE)
448 return;
449
450 pe = &phb->ioda.pe_array[pdn->pe_number];
451 set_iommu_table_base(&pdev->dev, &pe->tce32_table);
437} 452}
438 453
439static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) 454static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
455 u64 *startp, u64 *endp)
440{ 456{
441 struct pci_dev *dev; 457 u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
458 unsigned long start, end, inc;
459
460 start = __pa(startp);
461 end = __pa(endp);
462
463 /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */
464 if (tbl->it_busno) {
465 start <<= 12;
466 end <<= 12;
467 inc = 128 << 12;
468 start |= tbl->it_busno;
469 end |= tbl->it_busno;
470 } else if (tbl->it_type & TCE_PCI_SWINV_PAIR) {
471 /* p7ioc-style invalidation, 2 TCEs per write */
472 start |= (1ull << 63);
473 end |= (1ull << 63);
474 inc = 16;
475 } else {
476 /* Default (older HW) */
477 inc = 128;
478 }
442 479
443 list_for_each_entry(dev, &bus->devices, bus_list) { 480 end |= inc - 1; /* round up end to be different than start */
444 set_iommu_table_base(&dev->dev, &pe->tce32_table); 481
445 if (dev->subordinate) 482 mb(); /* Ensure above stores are visible */
446 pnv_ioda_setup_bus_dma(pe, dev->subordinate); 483 while (start <= end) {
484 __raw_writeq(start, invalidate);
485 start += inc;
486 }
487
488 /*
489 * The iommu layer will do another mb() for us on build()
490 * and we don't care on free()
491 */
492}
493
494static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
495 struct iommu_table *tbl,
496 u64 *startp, u64 *endp)
497{
498 unsigned long start, end, inc;
499 u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
500
501 /* We'll invalidate DMA address in PE scope */
502 start = 0x2ul << 60;
503 start |= (pe->pe_number & 0xFF);
504 end = start;
505
506 /* Figure out the start, end and step */
507 inc = tbl->it_offset + (((u64)startp - tbl->it_base) / sizeof(u64));
508 start |= (inc << 12);
509 inc = tbl->it_offset + (((u64)endp - tbl->it_base) / sizeof(u64));
510 end |= (inc << 12);
511 inc = (0x1ul << 12);
512 mb();
513
514 while (start <= end) {
515 __raw_writeq(start, invalidate);
516 start += inc;
447 } 517 }
448} 518}
449 519
520void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
521 u64 *startp, u64 *endp)
522{
523 struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
524 tce32_table);
525 struct pnv_phb *phb = pe->phb;
526
527 if (phb->type == PNV_PHB_IODA1)
528 pnv_pci_ioda1_tce_invalidate(tbl, startp, endp);
529 else
530 pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp);
531}
532
450static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, 533static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
451 struct pnv_ioda_pe *pe, unsigned int base, 534 struct pnv_ioda_pe *pe, unsigned int base,
452 unsigned int segs) 535 unsigned int segs)
@@ -518,16 +601,11 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
518 */ 601 */
519 tbl->it_busno = 0; 602 tbl->it_busno = 0;
520 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8); 603 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
521 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE 604 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE |
522 | TCE_PCI_SWINV_PAIR; 605 TCE_PCI_SWINV_PAIR;
523 } 606 }
524 iommu_init_table(tbl, phb->hose->node); 607 iommu_init_table(tbl, phb->hose->node);
525 608
526 if (pe->pdev)
527 set_iommu_table_base(&pe->pdev->dev, tbl);
528 else
529 pnv_ioda_setup_bus_dma(pe, pe->pbus);
530
531 return; 609 return;
532 fail: 610 fail:
533 /* XXX Failure: Try to fallback to 64-bit only ? */ 611 /* XXX Failure: Try to fallback to 64-bit only ? */
@@ -537,6 +615,76 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
537 __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs)); 615 __free_pages(tce_mem, get_order(TCE32_TABLE_SIZE * segs));
538} 616}
539 617
618static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
619 struct pnv_ioda_pe *pe)
620{
621 struct page *tce_mem = NULL;
622 void *addr;
623 const __be64 *swinvp;
624 struct iommu_table *tbl;
625 unsigned int tce_table_size, end;
626 int64_t rc;
627
628 /* We shouldn't already have a 32-bit DMA associated */
629 if (WARN_ON(pe->tce32_seg >= 0))
630 return;
631
632 /* The PE will reserve all possible 32-bits space */
633 pe->tce32_seg = 0;
634 end = (1 << ilog2(phb->ioda.m32_pci_base));
635 tce_table_size = (end / 0x1000) * 8;
636 pe_info(pe, "Setting up 32-bit TCE table at 0..%08x\n",
637 end);
638
639 /* Allocate TCE table */
640 tce_mem = alloc_pages_node(phb->hose->node, GFP_KERNEL,
641 get_order(tce_table_size));
642 if (!tce_mem) {
643 pe_err(pe, "Failed to allocate a 32-bit TCE memory\n");
644 goto fail;
645 }
646 addr = page_address(tce_mem);
647 memset(addr, 0, tce_table_size);
648
649 /*
650 * Map TCE table through TVT. The TVE index is the PE number
651 * shifted by 1 bit for 32-bits DMA space.
652 */
653 rc = opal_pci_map_pe_dma_window(phb->opal_id, pe->pe_number,
654 pe->pe_number << 1, 1, __pa(addr),
655 tce_table_size, 0x1000);
656 if (rc) {
657 pe_err(pe, "Failed to configure 32-bit TCE table,"
658 " err %ld\n", rc);
659 goto fail;
660 }
661
662 /* Setup linux iommu table */
663 tbl = &pe->tce32_table;
664 pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0);
665
666 /* OPAL variant of PHB3 invalidated TCEs */
667 swinvp = of_get_property(phb->hose->dn, "ibm,opal-tce-kill", NULL);
668 if (swinvp) {
669 /* We need a couple more fields -- an address and a data
670 * to or. Since the bus is only printed out on table free
671 * errors, and on the first pass the data will be a relative
672 * bus number, print that out instead.
673 */
674 tbl->it_busno = 0;
675 tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
676 tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE;
677 }
678 iommu_init_table(tbl, phb->hose->node);
679
680 return;
681fail:
682 if (pe->tce32_seg >= 0)
683 pe->tce32_seg = -1;
684 if (tce_mem)
685 __free_pages(tce_mem, get_order(tce_table_size));
686}
687
540static void pnv_ioda_setup_dma(struct pnv_phb *phb) 688static void pnv_ioda_setup_dma(struct pnv_phb *phb)
541{ 689{
542 struct pci_controller *hose = phb->hose; 690 struct pci_controller *hose = phb->hose;
@@ -579,20 +727,49 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb)
579 if (segs > remaining) 727 if (segs > remaining)
580 segs = remaining; 728 segs = remaining;
581 } 729 }
582 pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n", 730
583 pe->dma_weight, segs); 731 /*
584 pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs); 732 * For IODA2 compliant PHB3, we needn't care about the weight.
733 * The all available 32-bits DMA space will be assigned to
734 * the specific PE.
735 */
736 if (phb->type == PNV_PHB_IODA1) {
737 pe_info(pe, "DMA weight %d, assigned %d DMA32 segments\n",
738 pe->dma_weight, segs);
739 pnv_pci_ioda_setup_dma_pe(phb, pe, base, segs);
740 } else {
741 pe_info(pe, "Assign DMA32 space\n");
742 segs = 0;
743 pnv_pci_ioda2_setup_dma_pe(phb, pe);
744 }
745
585 remaining -= segs; 746 remaining -= segs;
586 base += segs; 747 base += segs;
587 } 748 }
588} 749}
589 750
590#ifdef CONFIG_PCI_MSI 751#ifdef CONFIG_PCI_MSI
752static void pnv_ioda2_msi_eoi(struct irq_data *d)
753{
754 unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
755 struct irq_chip *chip = irq_data_get_irq_chip(d);
756 struct pnv_phb *phb = container_of(chip, struct pnv_phb,
757 ioda.irq_chip);
758 int64_t rc;
759
760 rc = opal_pci_msi_eoi(phb->opal_id, hw_irq);
761 WARN_ON_ONCE(rc);
762
763 icp_native_eoi(d);
764}
765
591static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, 766static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
592 unsigned int hwirq, unsigned int is_64, 767 unsigned int hwirq, unsigned int virq,
593 struct msi_msg *msg) 768 unsigned int is_64, struct msi_msg *msg)
594{ 769{
595 struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); 770 struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev);
771 struct irq_data *idata;
772 struct irq_chip *ichip;
596 unsigned int xive_num = hwirq - phb->msi_base; 773 unsigned int xive_num = hwirq - phb->msi_base;
597 uint64_t addr64; 774 uint64_t addr64;
598 uint32_t addr32, data; 775 uint32_t addr32, data;
@@ -637,6 +814,23 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
637 } 814 }
638 msg->data = data; 815 msg->data = data;
639 816
817 /*
818 * Change the IRQ chip for the MSI interrupts on PHB3.
819 * The corresponding IRQ chip should be populated for
820 * the first time.
821 */
822 if (phb->type == PNV_PHB_IODA2) {
823 if (!phb->ioda.irq_chip_init) {
824 idata = irq_get_irq_data(virq);
825 ichip = irq_data_get_irq_chip(idata);
826 phb->ioda.irq_chip_init = 1;
827 phb->ioda.irq_chip = *ichip;
828 phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi;
829 }
830
831 irq_set_chip(virq, &phb->ioda.irq_chip);
832 }
833
640 pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," 834 pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d),"
641 " address=%x_%08x data=%x PE# %d\n", 835 " address=%x_%08x data=%x PE# %d\n",
642 pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, 836 pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num,
@@ -647,7 +841,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
647 841
648static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) 842static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
649{ 843{
650 unsigned int bmap_size; 844 unsigned int count;
651 const __be32 *prop = of_get_property(phb->hose->dn, 845 const __be32 *prop = of_get_property(phb->hose->dn,
652 "ibm,opal-msi-ranges", NULL); 846 "ibm,opal-msi-ranges", NULL);
653 if (!prop) { 847 if (!prop) {
@@ -658,18 +852,17 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb)
658 return; 852 return;
659 853
660 phb->msi_base = be32_to_cpup(prop); 854 phb->msi_base = be32_to_cpup(prop);
661 phb->msi_count = be32_to_cpup(prop + 1); 855 count = be32_to_cpup(prop + 1);
662 bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); 856 if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) {
663 phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL);
664 if (!phb->msi_map) {
665 pr_err("PCI %d: Failed to allocate MSI bitmap !\n", 857 pr_err("PCI %d: Failed to allocate MSI bitmap !\n",
666 phb->hose->global_number); 858 phb->hose->global_number);
667 return; 859 return;
668 } 860 }
861
669 phb->msi_setup = pnv_pci_ioda_msi_setup; 862 phb->msi_setup = pnv_pci_ioda_msi_setup;
670 phb->msi32_support = 1; 863 phb->msi32_support = 1;
671 pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", 864 pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
672 phb->msi_count, phb->msi_base); 865 count, phb->msi_base);
673} 866}
674#else 867#else
675static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } 868static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { }
@@ -852,18 +1045,19 @@ static u32 pnv_ioda_bdfn_to_pe(struct pnv_phb *phb, struct pci_bus *bus,
852 return phb->ioda.pe_rmap[(bus->number << 8) | devfn]; 1045 return phb->ioda.pe_rmap[(bus->number << 8) | devfn];
853} 1046}
854 1047
855void __init pnv_pci_init_ioda1_phb(struct device_node *np) 1048void __init pnv_pci_init_ioda_phb(struct device_node *np, int ioda_type)
856{ 1049{
857 struct pci_controller *hose; 1050 struct pci_controller *hose;
858 static int primary = 1; 1051 static int primary = 1;
859 struct pnv_phb *phb; 1052 struct pnv_phb *phb;
860 unsigned long size, m32map_off, iomap_off, pemap_off; 1053 unsigned long size, m32map_off, iomap_off, pemap_off;
861 const u64 *prop64; 1054 const u64 *prop64;
1055 const u32 *prop32;
862 u64 phb_id; 1056 u64 phb_id;
863 void *aux; 1057 void *aux;
864 long rc; 1058 long rc;
865 1059
866 pr_info(" Initializing IODA OPAL PHB %s\n", np->full_name); 1060 pr_info(" Initializing IODA%d OPAL PHB %s\n", ioda_type, np->full_name);
867 1061
868 prop64 = of_get_property(np, "ibm,opal-phbid", NULL); 1062 prop64 = of_get_property(np, "ibm,opal-phbid", NULL);
869 if (!prop64) { 1063 if (!prop64) {
@@ -890,37 +1084,34 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
890 hose->last_busno = 0xff; 1084 hose->last_busno = 0xff;
891 hose->private_data = phb; 1085 hose->private_data = phb;
892 phb->opal_id = phb_id; 1086 phb->opal_id = phb_id;
893 phb->type = PNV_PHB_IODA1; 1087 phb->type = ioda_type;
894 1088
895 /* Detect specific models for error handling */ 1089 /* Detect specific models for error handling */
896 if (of_device_is_compatible(np, "ibm,p7ioc-pciex")) 1090 if (of_device_is_compatible(np, "ibm,p7ioc-pciex"))
897 phb->model = PNV_PHB_MODEL_P7IOC; 1091 phb->model = PNV_PHB_MODEL_P7IOC;
1092 else if (of_device_is_compatible(np, "ibm,p8-pciex"))
1093 phb->model = PNV_PHB_MODEL_PHB3;
898 else 1094 else
899 phb->model = PNV_PHB_MODEL_UNKNOWN; 1095 phb->model = PNV_PHB_MODEL_UNKNOWN;
900 1096
901 /* We parse "ranges" now since we need to deduce the register base 1097 /* Parse 32-bit and IO ranges (if any) */
902 * from the IO base
903 */
904 pci_process_bridge_OF_ranges(phb->hose, np, primary); 1098 pci_process_bridge_OF_ranges(phb->hose, np, primary);
905 primary = 0; 1099 primary = 0;
906 1100
907 /* Magic formula from Milton */ 1101 /* Get registers */
908 phb->regs = of_iomap(np, 0); 1102 phb->regs = of_iomap(np, 0);
909 if (phb->regs == NULL) 1103 if (phb->regs == NULL)
910 pr_err(" Failed to map registers !\n"); 1104 pr_err(" Failed to map registers !\n");
911 1105
912
913 /* XXX This is hack-a-thon. This needs to be changed so that:
914 * - we obtain stuff like PE# etc... from device-tree
915 * - we properly re-allocate M32 ourselves
916 * (the OFW one isn't very good)
917 */
918
919 /* Initialize more IODA stuff */ 1106 /* Initialize more IODA stuff */
920 phb->ioda.total_pe = 128; 1107 prop32 = of_get_property(np, "ibm,opal-num-pes", NULL);
1108 if (!prop32)
1109 phb->ioda.total_pe = 1;
1110 else
1111 phb->ioda.total_pe = *prop32;
921 1112
922 phb->ioda.m32_size = resource_size(&hose->mem_resources[0]); 1113 phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
923 /* OFW Has already off top 64k of M32 space (MSI space) */ 1114 /* FW Has already off top 64k of M32 space (MSI space) */
924 phb->ioda.m32_size += 0x10000; 1115 phb->ioda.m32_size += 0x10000;
925 1116
926 phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe; 1117 phb->ioda.m32_segsize = phb->ioda.m32_size / phb->ioda.total_pe;
@@ -930,7 +1121,10 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
930 phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe; 1121 phb->ioda.io_segsize = phb->ioda.io_size / phb->ioda.total_pe;
931 phb->ioda.io_pci_base = 0; /* XXX calculate this ? */ 1122 phb->ioda.io_pci_base = 0; /* XXX calculate this ? */
932 1123
933 /* Allocate aux data & arrays */ 1124 /* Allocate aux data & arrays
1125 *
1126 * XXX TODO: Don't allocate io segmap on PHB3
1127 */
934 size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); 1128 size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long));
935 m32map_off = size; 1129 m32map_off = size;
936 size += phb->ioda.total_pe * sizeof(phb->ioda.m32_segmap[0]); 1130 size += phb->ioda.total_pe * sizeof(phb->ioda.m32_segmap[0]);
@@ -960,7 +1154,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
960 hose->mem_resources[2].start = 0; 1154 hose->mem_resources[2].start = 0;
961 hose->mem_resources[2].end = 0; 1155 hose->mem_resources[2].end = 0;
962 1156
963#if 0 1157#if 0 /* We should really do that ... */
964 rc = opal_pci_set_phb_mem_window(opal->phb_id, 1158 rc = opal_pci_set_phb_mem_window(opal->phb_id,
965 window_type, 1159 window_type,
966 window_num, 1160 window_num,
@@ -974,16 +1168,6 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
974 phb->ioda.m32_size, phb->ioda.m32_segsize, 1168 phb->ioda.m32_size, phb->ioda.m32_segsize,
975 phb->ioda.io_size, phb->ioda.io_segsize); 1169 phb->ioda.io_size, phb->ioda.io_segsize);
976 1170
977 if (phb->regs) {
978 pr_devel(" BUID = 0x%016llx\n", in_be64(phb->regs + 0x100));
979 pr_devel(" PHB2_CR = 0x%016llx\n", in_be64(phb->regs + 0x160));
980 pr_devel(" IO_BAR = 0x%016llx\n", in_be64(phb->regs + 0x170));
981 pr_devel(" IO_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x178));
982 pr_devel(" IO_SAR = 0x%016llx\n", in_be64(phb->regs + 0x180));
983 pr_devel(" M32_BAR = 0x%016llx\n", in_be64(phb->regs + 0x190));
984 pr_devel(" M32_BAMR = 0x%016llx\n", in_be64(phb->regs + 0x198));
985 pr_devel(" M32_SAR = 0x%016llx\n", in_be64(phb->regs + 0x1a0));
986 }
987 phb->hose->ops = &pnv_pci_ops; 1171 phb->hose->ops = &pnv_pci_ops;
988 1172
989 /* Setup RID -> PE mapping function */ 1173 /* Setup RID -> PE mapping function */
@@ -1011,7 +1195,18 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
1011 rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); 1195 rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET);
1012 if (rc) 1196 if (rc)
1013 pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); 1197 pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc);
1014 opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); 1198
1199 /*
1200 * On IODA1 map everything to PE#0, on IODA2 we assume the IODA reset
1201 * has cleared the RTT which has the same effect
1202 */
1203 if (ioda_type == PNV_PHB_IODA1)
1204 opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE);
1205}
1206
1207void pnv_pci_init_ioda2_phb(struct device_node *np)
1208{
1209 pnv_pci_init_ioda_phb(np, PNV_PHB_IODA2);
1015} 1210}
1016 1211
1017void __init pnv_pci_init_ioda_hub(struct device_node *np) 1212void __init pnv_pci_init_ioda_hub(struct device_node *np)
@@ -1034,6 +1229,6 @@ void __init pnv_pci_init_ioda_hub(struct device_node *np)
1034 for_each_child_of_node(np, phbn) { 1229 for_each_child_of_node(np, phbn) {
1035 /* Look for IODA1 PHBs */ 1230 /* Look for IODA1 PHBs */
1036 if (of_device_is_compatible(phbn, "ibm,ioda-phb")) 1231 if (of_device_is_compatible(phbn, "ibm,ioda-phb"))
1037 pnv_pci_init_ioda1_phb(phbn); 1232 pnv_pci_init_ioda_phb(phbn, PNV_PHB_IODA1);
1038 } 1233 }
1039} 1234}
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index 7db8771a40f5..92b37a0186c9 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -26,6 +26,7 @@
26#include <asm/prom.h> 26#include <asm/prom.h>
27#include <asm/pci-bridge.h> 27#include <asm/pci-bridge.h>
28#include <asm/machdep.h> 28#include <asm/machdep.h>
29#include <asm/msi_bitmap.h>
29#include <asm/ppc-pci.h> 30#include <asm/ppc-pci.h>
30#include <asm/opal.h> 31#include <asm/opal.h>
31#include <asm/iommu.h> 32#include <asm/iommu.h>
@@ -41,8 +42,8 @@
41 42
42#ifdef CONFIG_PCI_MSI 43#ifdef CONFIG_PCI_MSI
43static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, 44static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
44 unsigned int hwirq, unsigned int is_64, 45 unsigned int hwirq, unsigned int virq,
45 struct msi_msg *msg) 46 unsigned int is_64, struct msi_msg *msg)
46{ 47{
47 if (WARN_ON(!is_64)) 48 if (WARN_ON(!is_64))
48 return -ENXIO; 49 return -ENXIO;
@@ -55,7 +56,7 @@ static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
55 56
56static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) 57static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
57{ 58{
58 unsigned int bmap_size; 59 unsigned int count;
59 const __be32 *prop = of_get_property(phb->hose->dn, 60 const __be32 *prop = of_get_property(phb->hose->dn,
60 "ibm,opal-msi-ranges", NULL); 61 "ibm,opal-msi-ranges", NULL);
61 if (!prop) 62 if (!prop)
@@ -67,10 +68,8 @@ static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
67 if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) 68 if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix"))
68 return; 69 return;
69 phb->msi_base = be32_to_cpup(prop); 70 phb->msi_base = be32_to_cpup(prop);
70 phb->msi_count = be32_to_cpup(prop + 1); 71 count = be32_to_cpup(prop + 1);
71 bmap_size = BITS_TO_LONGS(phb->msi_count) * sizeof(unsigned long); 72 if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) {
72 phb->msi_map = zalloc_maybe_bootmem(bmap_size, GFP_KERNEL);
73 if (!phb->msi_map) {
74 pr_err("PCI %d: Failed to allocate MSI bitmap !\n", 73 pr_err("PCI %d: Failed to allocate MSI bitmap !\n",
75 phb->hose->global_number); 74 phb->hose->global_number);
76 return; 75 return;
@@ -78,7 +77,7 @@ static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb)
78 phb->msi_setup = pnv_pci_p5ioc2_msi_setup; 77 phb->msi_setup = pnv_pci_p5ioc2_msi_setup;
79 phb->msi32_support = 0; 78 phb->msi32_support = 0;
80 pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", 79 pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n",
81 phb->msi_count, phb->msi_base); 80 count, phb->msi_base);
82} 81}
83#else 82#else
84static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } 83static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { }
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index b8b8e0bd9897..55dfca844ddf 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -26,6 +26,7 @@
26#include <asm/prom.h> 26#include <asm/prom.h>
27#include <asm/pci-bridge.h> 27#include <asm/pci-bridge.h>
28#include <asm/machdep.h> 28#include <asm/machdep.h>
29#include <asm/msi_bitmap.h>
29#include <asm/ppc-pci.h> 30#include <asm/ppc-pci.h>
30#include <asm/opal.h> 31#include <asm/opal.h>
31#include <asm/iommu.h> 32#include <asm/iommu.h>
@@ -47,43 +48,7 @@ static int pnv_msi_check_device(struct pci_dev* pdev, int nvec, int type)
47 struct pci_controller *hose = pci_bus_to_host(pdev->bus); 48 struct pci_controller *hose = pci_bus_to_host(pdev->bus);
48 struct pnv_phb *phb = hose->private_data; 49 struct pnv_phb *phb = hose->private_data;
49 50
50 return (phb && phb->msi_map) ? 0 : -ENODEV; 51 return (phb && phb->msi_bmp.bitmap) ? 0 : -ENODEV;
51}
52
53static unsigned int pnv_get_one_msi(struct pnv_phb *phb)
54{
55 unsigned long flags;
56 unsigned int id, rc;
57
58 spin_lock_irqsave(&phb->lock, flags);
59
60 id = find_next_zero_bit(phb->msi_map, phb->msi_count, phb->msi_next);
61 if (id >= phb->msi_count && phb->msi_next)
62 id = find_next_zero_bit(phb->msi_map, phb->msi_count, 0);
63 if (id >= phb->msi_count) {
64 rc = 0;
65 goto out;
66 }
67 __set_bit(id, phb->msi_map);
68 rc = id + phb->msi_base;
69out:
70 spin_unlock_irqrestore(&phb->lock, flags);
71 return rc;
72}
73
74static void pnv_put_msi(struct pnv_phb *phb, unsigned int hwirq)
75{
76 unsigned long flags;
77 unsigned int id;
78
79 if (WARN_ON(hwirq < phb->msi_base ||
80 hwirq >= (phb->msi_base + phb->msi_count)))
81 return;
82 id = hwirq - phb->msi_base;
83
84 spin_lock_irqsave(&phb->lock, flags);
85 __clear_bit(id, phb->msi_map);
86 spin_unlock_irqrestore(&phb->lock, flags);
87} 52}
88 53
89static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 54static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
@@ -92,7 +57,8 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
92 struct pnv_phb *phb = hose->private_data; 57 struct pnv_phb *phb = hose->private_data;
93 struct msi_desc *entry; 58 struct msi_desc *entry;
94 struct msi_msg msg; 59 struct msi_msg msg;
95 unsigned int hwirq, virq; 60 int hwirq;
61 unsigned int virq;
96 int rc; 62 int rc;
97 63
98 if (WARN_ON(!phb)) 64 if (WARN_ON(!phb))
@@ -104,25 +70,25 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
104 pci_name(pdev)); 70 pci_name(pdev));
105 return -ENXIO; 71 return -ENXIO;
106 } 72 }
107 hwirq = pnv_get_one_msi(phb); 73 hwirq = msi_bitmap_alloc_hwirqs(&phb->msi_bmp, 1);
108 if (!hwirq) { 74 if (hwirq < 0) {
109 pr_warn("%s: Failed to find a free MSI\n", 75 pr_warn("%s: Failed to find a free MSI\n",
110 pci_name(pdev)); 76 pci_name(pdev));
111 return -ENOSPC; 77 return -ENOSPC;
112 } 78 }
113 virq = irq_create_mapping(NULL, hwirq); 79 virq = irq_create_mapping(NULL, phb->msi_base + hwirq);
114 if (virq == NO_IRQ) { 80 if (virq == NO_IRQ) {
115 pr_warn("%s: Failed to map MSI to linux irq\n", 81 pr_warn("%s: Failed to map MSI to linux irq\n",
116 pci_name(pdev)); 82 pci_name(pdev));
117 pnv_put_msi(phb, hwirq); 83 msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, 1);
118 return -ENOMEM; 84 return -ENOMEM;
119 } 85 }
120 rc = phb->msi_setup(phb, pdev, hwirq, entry->msi_attrib.is_64, 86 rc = phb->msi_setup(phb, pdev, phb->msi_base + hwirq,
121 &msg); 87 virq, entry->msi_attrib.is_64, &msg);
122 if (rc) { 88 if (rc) {
123 pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); 89 pr_warn("%s: Failed to setup MSI\n", pci_name(pdev));
124 irq_dispose_mapping(virq); 90 irq_dispose_mapping(virq);
125 pnv_put_msi(phb, hwirq); 91 msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, 1);
126 return rc; 92 return rc;
127 } 93 }
128 irq_set_msi_desc(virq, entry); 94 irq_set_msi_desc(virq, entry);
@@ -144,7 +110,8 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev)
144 if (entry->irq == NO_IRQ) 110 if (entry->irq == NO_IRQ)
145 continue; 111 continue;
146 irq_set_msi_desc(entry->irq, NULL); 112 irq_set_msi_desc(entry->irq, NULL);
147 pnv_put_msi(phb, virq_to_hw(entry->irq)); 113 msi_bitmap_free_hwirqs(&phb->msi_bmp,
114 virq_to_hw(entry->irq) - phb->msi_base, 1);
148 irq_dispose_mapping(entry->irq); 115 irq_dispose_mapping(entry->irq);
149 } 116 }
150} 117}
@@ -362,48 +329,6 @@ struct pci_ops pnv_pci_ops = {
362 .write = pnv_pci_write_config, 329 .write = pnv_pci_write_config,
363}; 330};
364 331
365
366static void pnv_tce_invalidate(struct iommu_table *tbl,
367 u64 *startp, u64 *endp)
368{
369 u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
370 unsigned long start, end, inc;
371
372 start = __pa(startp);
373 end = __pa(endp);
374
375
376 /* BML uses this case for p6/p7/galaxy2: Shift addr and put in node */
377 if (tbl->it_busno) {
378 start <<= 12;
379 end <<= 12;
380 inc = 128 << 12;
381 start |= tbl->it_busno;
382 end |= tbl->it_busno;
383 }
384 /* p7ioc-style invalidation, 2 TCEs per write */
385 else if (tbl->it_type & TCE_PCI_SWINV_PAIR) {
386 start |= (1ull << 63);
387 end |= (1ull << 63);
388 inc = 16;
389 }
390 /* Default (older HW) */
391 else
392 inc = 128;
393
394 end |= inc - 1; /* round up end to be different than start */
395
396 mb(); /* Ensure above stores are visible */
397 while (start <= end) {
398 __raw_writeq(start, invalidate);
399 start += inc;
400 }
401 /* The iommu layer will do another mb() for us on build() and
402 * we don't care on free()
403 */
404}
405
406
407static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, 332static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
408 unsigned long uaddr, enum dma_data_direction direction, 333 unsigned long uaddr, enum dma_data_direction direction,
409 struct dma_attrs *attrs) 334 struct dma_attrs *attrs)
@@ -428,7 +353,7 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
428 * of flags if that becomes the case 353 * of flags if that becomes the case
429 */ 354 */
430 if (tbl->it_type & TCE_PCI_SWINV_CREATE) 355 if (tbl->it_type & TCE_PCI_SWINV_CREATE)
431 pnv_tce_invalidate(tbl, tces, tcep - 1); 356 pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1);
432 357
433 return 0; 358 return 0;
434} 359}
@@ -442,8 +367,8 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
442 while (npages--) 367 while (npages--)
443 *(tcep++) = 0; 368 *(tcep++) = 0;
444 369
445 if (tbl->it_type & TCE_PCI_SWINV_FREE) 370 if (tbl->it_type & TCE_PCI_SWINV_CREATE)
446 pnv_tce_invalidate(tbl, tces, tcep - 1); 371 pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1);
447} 372}
448 373
449static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) 374static unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
@@ -525,7 +450,7 @@ static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
525 pnv_pci_dma_fallback_setup(hose, pdev); 450 pnv_pci_dma_fallback_setup(hose, pdev);
526} 451}
527 452
528/* Fixup wrong class code in p7ioc root complex */ 453/* Fixup wrong class code in p7ioc and p8 root complex */
529static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) 454static void pnv_p7ioc_rc_quirk(struct pci_dev *dev)
530{ 455{
531 dev->class = PCI_CLASS_BRIDGE_PCI << 8; 456 dev->class = PCI_CLASS_BRIDGE_PCI << 8;
@@ -591,6 +516,10 @@ void __init pnv_pci_init(void)
591 if (!found_ioda) 516 if (!found_ioda)
592 for_each_compatible_node(np, NULL, "ibm,p5ioc2") 517 for_each_compatible_node(np, NULL, "ibm,p5ioc2")
593 pnv_pci_init_p5ioc2_hub(np); 518 pnv_pci_init_p5ioc2_hub(np);
519
520 /* Look for ioda2 built-in PHB3's */
521 for_each_compatible_node(np, NULL, "ibm,ioda2-phb")
522 pnv_pci_init_ioda2_phb(np);
594 } 523 }
595 524
596 /* Setup the linkage between OF nodes and PHBs */ 525 /* Setup the linkage between OF nodes and PHBs */
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 7cfb7c883deb..48dc4bb856a1 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -4,9 +4,9 @@
4struct pci_dn; 4struct pci_dn;
5 5
6enum pnv_phb_type { 6enum pnv_phb_type {
7 PNV_PHB_P5IOC2, 7 PNV_PHB_P5IOC2 = 0,
8 PNV_PHB_IODA1, 8 PNV_PHB_IODA1 = 1,
9 PNV_PHB_IODA2, 9 PNV_PHB_IODA2 = 2,
10}; 10};
11 11
12/* Precise PHB model for error management */ 12/* Precise PHB model for error management */
@@ -14,6 +14,7 @@ enum pnv_phb_model {
14 PNV_PHB_MODEL_UNKNOWN, 14 PNV_PHB_MODEL_UNKNOWN,
15 PNV_PHB_MODEL_P5IOC2, 15 PNV_PHB_MODEL_P5IOC2,
16 PNV_PHB_MODEL_P7IOC, 16 PNV_PHB_MODEL_P7IOC,
17 PNV_PHB_MODEL_PHB3,
17}; 18};
18 19
19#define PNV_PCI_DIAG_BUF_SIZE 4096 20#define PNV_PCI_DIAG_BUF_SIZE 4096
@@ -22,8 +23,10 @@ enum pnv_phb_model {
22#define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ 23#define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */
23 24
24/* Data associated with a PE, including IOMMU tracking etc.. */ 25/* Data associated with a PE, including IOMMU tracking etc.. */
26struct pnv_phb;
25struct pnv_ioda_pe { 27struct pnv_ioda_pe {
26 unsigned long flags; 28 unsigned long flags;
29 struct pnv_phb *phb;
27 30
28 /* A PE can be associated with a single device or an 31 /* A PE can be associated with a single device or an
29 * entire bus (& children). In the former case, pdev 32 * entire bus (& children). In the former case, pdev
@@ -73,15 +76,13 @@ struct pnv_phb {
73 spinlock_t lock; 76 spinlock_t lock;
74 77
75#ifdef CONFIG_PCI_MSI 78#ifdef CONFIG_PCI_MSI
76 unsigned long *msi_map;
77 unsigned int msi_base; 79 unsigned int msi_base;
78 unsigned int msi_count;
79 unsigned int msi_next;
80 unsigned int msi32_support; 80 unsigned int msi32_support;
81 struct msi_bitmap msi_bmp;
81#endif 82#endif
82 int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, 83 int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev,
83 unsigned int hwirq, unsigned int is_64, 84 unsigned int hwirq, unsigned int virq,
84 struct msi_msg *msg); 85 unsigned int is_64, struct msi_msg *msg);
85 void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); 86 void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
86 void (*fixup_phb)(struct pci_controller *hose); 87 void (*fixup_phb)(struct pci_controller *hose);
87 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); 88 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
@@ -109,6 +110,10 @@ struct pnv_phb {
109 unsigned int *io_segmap; 110 unsigned int *io_segmap;
110 struct pnv_ioda_pe *pe_array; 111 struct pnv_ioda_pe *pe_array;
111 112
113 /* IRQ chip */
114 int irq_chip_init;
115 struct irq_chip irq_chip;
116
112 /* Sorted list of used PE's based 117 /* Sorted list of used PE's based
113 * on the sequence of creation 118 * on the sequence of creation
114 */ 119 */
@@ -150,6 +155,7 @@ extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
150 u64 dma_offset); 155 u64 dma_offset);
151extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); 156extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
152extern void pnv_pci_init_ioda_hub(struct device_node *np); 157extern void pnv_pci_init_ioda_hub(struct device_node *np);
153 158extern void pnv_pci_init_ioda2_phb(struct device_node *np);
154 159extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
160 u64 *startp, u64 *endp);
155#endif /* __POWERNV_PCI_H */ 161#endif /* __POWERNV_PCI_H */
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
deleted file mode 100644
index 1547f66235d9..000000000000
--- a/arch/powerpc/platforms/prep/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
1config PPC_PREP
2 bool "PowerPC Reference Platform (PReP) based machines"
3 depends on 6xx && BROKEN
4 select HAVE_PCSPKR_PLATFORM
5 select MPIC
6 select PPC_I8259
7 select PPC_INDIRECT_PCI
8 select PPC_UDBG_16550
9 select PPC_NATIVE
10 default n
11
12config PREP_RESIDUAL
13 bool "Support for PReP Residual Data"
14 depends on PPC_PREP
15 help
16 Some PReP systems have residual data passed to the kernel by the
17 firmware. This allows detection of memory size, devices present and
18 other useful pieces of information. Sometimes this information is
19 not present or incorrect, in which case it could lead to the machine
20 behaving incorrectly. If this happens, either disable PREP_RESIDUAL
21 or pass the 'noresidual' option to the kernel.
22
23 If you are running a PReP system, say Y here, otherwise say N.
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index 6cc58201db8c..177a2f70700c 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -46,7 +46,7 @@ static DEFINE_SPINLOCK(ps3_htab_lock);
46 46
47static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, 47static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn,
48 unsigned long pa, unsigned long rflags, unsigned long vflags, 48 unsigned long pa, unsigned long rflags, unsigned long vflags,
49 int psize, int ssize) 49 int psize, int apsize, int ssize)
50{ 50{
51 int result; 51 int result;
52 u64 hpte_v, hpte_r; 52 u64 hpte_v, hpte_r;
@@ -62,8 +62,8 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn,
62 */ 62 */
63 vflags &= ~HPTE_V_SECONDARY; 63 vflags &= ~HPTE_V_SECONDARY;
64 64
65 hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; 65 hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID;
66 hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags; 66 hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize, apsize) | rflags;
67 67
68 spin_lock_irqsave(&ps3_htab_lock, flags); 68 spin_lock_irqsave(&ps3_htab_lock, flags);
69 69
@@ -117,7 +117,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
117 unsigned long flags; 117 unsigned long flags;
118 long ret; 118 long ret;
119 119
120 want_v = hpte_encode_v(vpn, psize, ssize); 120 want_v = hpte_encode_avpn(vpn, psize, ssize);
121 121
122 spin_lock_irqsave(&ps3_htab_lock, flags); 122 spin_lock_irqsave(&ps3_htab_lock, flags);
123 123
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index 40b5cb433005..cba1e6be68e5 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -89,10 +89,8 @@ static int __init ps3_rtc_init(void)
89 return -ENODEV; 89 return -ENODEV;
90 90
91 pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0); 91 pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
92 if (IS_ERR(pdev))
93 return PTR_ERR(pdev);
94 92
95 return 0; 93 return PTR_RET(pdev);
96} 94}
97 95
98module_init(ps3_rtc_init); 96module_init(ps3_rtc_init);
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index aa3693f7fb27..8c80588abacc 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -28,18 +28,18 @@
28 28
29#include "pseries.h" 29#include "pseries.h"
30 30
31typedef struct { 31struct hypertas_fw_feature {
32 unsigned long val; 32 unsigned long val;
33 char * name; 33 char * name;
34} firmware_feature_t; 34};
35 35
36/* 36/*
37 * The names in this table match names in rtas/ibm,hypertas-functions. If the 37 * The names in this table match names in rtas/ibm,hypertas-functions. If the
38 * entry ends in a '*', only upto the '*' is matched. Otherwise the entire 38 * entry ends in a '*', only upto the '*' is matched. Otherwise the entire
39 * string must match. 39 * string must match.
40 */ 40 */
41static __initdata firmware_feature_t 41static __initdata struct hypertas_fw_feature
42firmware_features_table[FIRMWARE_MAX_FEATURES] = { 42hypertas_fw_features_table[] = {
43 {FW_FEATURE_PFT, "hcall-pft"}, 43 {FW_FEATURE_PFT, "hcall-pft"},
44 {FW_FEATURE_TCE, "hcall-tce"}, 44 {FW_FEATURE_TCE, "hcall-tce"},
45 {FW_FEATURE_SPRG0, "hcall-sprg0"}, 45 {FW_FEATURE_SPRG0, "hcall-sprg0"},
@@ -69,20 +69,18 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
69 * device-tree/ibm,hypertas-functions. Ultimately this functionality may 69 * device-tree/ibm,hypertas-functions. Ultimately this functionality may
70 * be moved into prom.c prom_init(). 70 * be moved into prom.c prom_init().
71 */ 71 */
72void __init fw_feature_init(const char *hypertas, unsigned long len) 72void __init fw_hypertas_feature_init(const char *hypertas, unsigned long len)
73{ 73{
74 const char *s; 74 const char *s;
75 int i; 75 int i;
76 76
77 pr_debug(" -> fw_feature_init()\n"); 77 pr_debug(" -> fw_hypertas_feature_init()\n");
78 78
79 for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { 79 for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
80 for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { 80 for (i = 0; i < ARRAY_SIZE(hypertas_fw_features_table); i++) {
81 const char *name = firmware_features_table[i].name; 81 const char *name = hypertas_fw_features_table[i].name;
82 size_t size; 82 size_t size;
83 /* check value against table of strings */ 83
84 if (!name)
85 continue;
86 /* 84 /*
87 * If there is a '*' at the end of name, only check 85 * If there is a '*' at the end of name, only check
88 * upto there 86 * upto there
@@ -96,10 +94,40 @@ void __init fw_feature_init(const char *hypertas, unsigned long len)
96 94
97 /* we have a match */ 95 /* we have a match */
98 powerpc_firmware_features |= 96 powerpc_firmware_features |=
99 firmware_features_table[i].val; 97 hypertas_fw_features_table[i].val;
100 break; 98 break;
101 } 99 }
102 } 100 }
103 101
104 pr_debug(" <- fw_feature_init()\n"); 102 pr_debug(" <- fw_hypertas_feature_init()\n");
103}
104
105struct vec5_fw_feature {
106 unsigned long val;
107 unsigned int feature;
108};
109
110static __initdata struct vec5_fw_feature
111vec5_fw_features_table[] = {
112 {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY},
113 {FW_FEATURE_PRRN, OV5_PRRN},
114};
115
116void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
117{
118 unsigned int index, feat;
119 int i;
120
121 pr_debug(" -> fw_vec5_feature_init()\n");
122
123 for (i = 0; i < ARRAY_SIZE(vec5_fw_features_table); i++) {
124 index = OV5_INDX(vec5_fw_features_table[i].feature);
125 feat = OV5_FEAT(vec5_fw_features_table[i].feature);
126
127 if (vec5[index] & feat)
128 powerpc_firmware_features |=
129 vec5_fw_features_table[i].val;
130 }
131
132 pr_debug(" <- fw_vec5_feature_init()\n");
105} 133}
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 2372c609fa2b..9a432de363b8 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -72,6 +72,7 @@ unsigned long memory_block_size_bytes(void)
72 return get_memblock_size(); 72 return get_memblock_size();
73} 73}
74 74
75#ifdef CONFIG_MEMORY_HOTREMOVE
75static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) 76static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
76{ 77{
77 unsigned long start, start_pfn; 78 unsigned long start, start_pfn;
@@ -153,6 +154,17 @@ static int pseries_remove_memory(struct device_node *np)
153 ret = pseries_remove_memblock(base, lmb_size); 154 ret = pseries_remove_memblock(base, lmb_size);
154 return ret; 155 return ret;
155} 156}
157#else
158static inline int pseries_remove_memblock(unsigned long base,
159 unsigned int memblock_size)
160{
161 return -EOPNOTSUPP;
162}
163static inline int pseries_remove_memory(struct device_node *np)
164{
165 return -EOPNOTSUPP;
166}
167#endif /* CONFIG_MEMORY_HOTREMOVE */
156 168
157static int pseries_add_memory(struct device_node *np) 169static int pseries_add_memory(struct device_node *np)
158{ 170{
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 1b2a174e7c59..86ae364900d6 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -924,6 +924,13 @@ static void restore_default_window(struct pci_dev *dev,
924 __restore_default_window(pci_dev_to_eeh_dev(dev), ddw_restore_token); 924 __restore_default_window(pci_dev_to_eeh_dev(dev), ddw_restore_token);
925} 925}
926 926
927struct failed_ddw_pdn {
928 struct device_node *pdn;
929 struct list_head list;
930};
931
932static LIST_HEAD(failed_ddw_pdn_list);
933
927/* 934/*
928 * If the PE supports dynamic dma windows, and there is space for a table 935 * If the PE supports dynamic dma windows, and there is space for a table
929 * that can map all pages in a linear offset, then setup such a table, 936 * that can map all pages in a linear offset, then setup such a table,
@@ -951,6 +958,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
951 struct dynamic_dma_window_prop *ddwprop; 958 struct dynamic_dma_window_prop *ddwprop;
952 const void *dma_window = NULL; 959 const void *dma_window = NULL;
953 unsigned long liobn, offset, size; 960 unsigned long liobn, offset, size;
961 struct failed_ddw_pdn *fpdn;
954 962
955 mutex_lock(&direct_window_init_mutex); 963 mutex_lock(&direct_window_init_mutex);
956 964
@@ -959,6 +967,18 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
959 goto out_unlock; 967 goto out_unlock;
960 968
961 /* 969 /*
970 * If we already went through this for a previous function of
971 * the same device and failed, we don't want to muck with the
972 * DMA window again, as it will race with in-flight operations
973 * and can lead to EEHs. The above mutex protects access to the
974 * list.
975 */
976 list_for_each_entry(fpdn, &failed_ddw_pdn_list, list) {
977 if (!strcmp(fpdn->pdn->full_name, pdn->full_name))
978 goto out_unlock;
979 }
980
981 /*
962 * the ibm,ddw-applicable property holds the tokens for: 982 * the ibm,ddw-applicable property holds the tokens for:
963 * ibm,query-pe-dma-window 983 * ibm,query-pe-dma-window
964 * ibm,create-pe-dma-window 984 * ibm,create-pe-dma-window
@@ -1114,6 +1134,12 @@ out_restore_window:
1114 if (ddw_restore_token) 1134 if (ddw_restore_token)
1115 restore_default_window(dev, ddw_restore_token); 1135 restore_default_window(dev, ddw_restore_token);
1116 1136
1137 fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL);
1138 if (!fpdn)
1139 goto out_unlock;
1140 fpdn->pdn = pdn;
1141 list_add(&fpdn->list, &failed_ddw_pdn_list);
1142
1117out_unlock: 1143out_unlock:
1118 mutex_unlock(&direct_window_init_mutex); 1144 mutex_unlock(&direct_window_init_mutex);
1119 return dma_addr; 1145 return dma_addr;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 0da39fed355a..6d62072a7d5a 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -109,7 +109,7 @@ void vpa_init(int cpu)
109static long pSeries_lpar_hpte_insert(unsigned long hpte_group, 109static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
110 unsigned long vpn, unsigned long pa, 110 unsigned long vpn, unsigned long pa,
111 unsigned long rflags, unsigned long vflags, 111 unsigned long rflags, unsigned long vflags,
112 int psize, int ssize) 112 int psize, int apsize, int ssize)
113{ 113{
114 unsigned long lpar_rc; 114 unsigned long lpar_rc;
115 unsigned long flags; 115 unsigned long flags;
@@ -121,8 +121,8 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
121 "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n", 121 "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n",
122 hpte_group, vpn, pa, rflags, vflags, psize); 122 hpte_group, vpn, pa, rflags, vflags, psize);
123 123
124 hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; 124 hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID;
125 hpte_r = hpte_encode_r(pa, psize) | rflags; 125 hpte_r = hpte_encode_r(pa, psize, apsize) | rflags;
126 126
127 if (!(vflags & HPTE_V_BOLTED)) 127 if (!(vflags & HPTE_V_BOLTED))
128 pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); 128 pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
@@ -155,7 +155,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
155 */ 155 */
156 if (unlikely(lpar_rc != H_SUCCESS)) { 156 if (unlikely(lpar_rc != H_SUCCESS)) {
157 if (!(vflags & HPTE_V_BOLTED)) 157 if (!(vflags & HPTE_V_BOLTED))
158 pr_devel(" lpar err %lu\n", lpar_rc); 158 pr_devel(" lpar err %ld\n", lpar_rc);
159 return -2; 159 return -2;
160 } 160 }
161 if (!(vflags & HPTE_V_BOLTED)) 161 if (!(vflags & HPTE_V_BOLTED))
@@ -186,7 +186,13 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
186 (0x1UL << 4), &dummy1, &dummy2); 186 (0x1UL << 4), &dummy1, &dummy2);
187 if (lpar_rc == H_SUCCESS) 187 if (lpar_rc == H_SUCCESS)
188 return i; 188 return i;
189 BUG_ON(lpar_rc != H_NOT_FOUND); 189
190 /*
191 * The test for adjunct partition is performed before the
192 * ANDCOND test. H_RESOURCE may be returned, so we need to
193 * check for that as well.
194 */
195 BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE);
190 196
191 slot_offset++; 197 slot_offset++;
192 slot_offset &= 0x7; 198 slot_offset &= 0x7;
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 6573808cc5f3..3d01eee9ffb1 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -37,14 +37,16 @@ struct update_props_workarea {
37#define UPDATE_DT_NODE 0x02000000 37#define UPDATE_DT_NODE 0x02000000
38#define ADD_DT_NODE 0x03000000 38#define ADD_DT_NODE 0x03000000
39 39
40static int mobility_rtas_call(int token, char *buf) 40#define MIGRATION_SCOPE (1)
41
42static int mobility_rtas_call(int token, char *buf, s32 scope)
41{ 43{
42 int rc; 44 int rc;
43 45
44 spin_lock(&rtas_data_buf_lock); 46 spin_lock(&rtas_data_buf_lock);
45 47
46 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); 48 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
47 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, 1); 49 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
48 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); 50 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
49 51
50 spin_unlock(&rtas_data_buf_lock); 52 spin_unlock(&rtas_data_buf_lock);
@@ -123,7 +125,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
123 return 0; 125 return 0;
124} 126}
125 127
126static int update_dt_node(u32 phandle) 128static int update_dt_node(u32 phandle, s32 scope)
127{ 129{
128 struct update_props_workarea *upwa; 130 struct update_props_workarea *upwa;
129 struct device_node *dn; 131 struct device_node *dn;
@@ -132,6 +134,7 @@ static int update_dt_node(u32 phandle)
132 char *prop_data; 134 char *prop_data;
133 char *rtas_buf; 135 char *rtas_buf;
134 int update_properties_token; 136 int update_properties_token;
137 u32 vd;
135 138
136 update_properties_token = rtas_token("ibm,update-properties"); 139 update_properties_token = rtas_token("ibm,update-properties");
137 if (update_properties_token == RTAS_UNKNOWN_SERVICE) 140 if (update_properties_token == RTAS_UNKNOWN_SERVICE)
@@ -151,19 +154,31 @@ static int update_dt_node(u32 phandle)
151 upwa->phandle = phandle; 154 upwa->phandle = phandle;
152 155
153 do { 156 do {
154 rc = mobility_rtas_call(update_properties_token, rtas_buf); 157 rc = mobility_rtas_call(update_properties_token, rtas_buf,
158 scope);
155 if (rc < 0) 159 if (rc < 0)
156 break; 160 break;
157 161
158 prop_data = rtas_buf + sizeof(*upwa); 162 prop_data = rtas_buf + sizeof(*upwa);
159 163
160 for (i = 0; i < upwa->nprops; i++) { 164 /* The first element of the buffer is the path of the node
165 * being updated in the form of a 8 byte string length
166 * followed by the string. Skip past this to get to the
167 * properties being updated.
168 */
169 vd = *prop_data++;
170 prop_data += vd;
171
172 /* The path we skipped over is counted as one of the elements
173 * returned so start counting at one.
174 */
175 for (i = 1; i < upwa->nprops; i++) {
161 char *prop_name; 176 char *prop_name;
162 u32 vd;
163 177
164 prop_name = prop_data + 1; 178 prop_name = prop_data;
165 prop_data += strlen(prop_name) + 1; 179 prop_data += strlen(prop_name) + 1;
166 vd = *prop_data++; 180 vd = *(u32 *)prop_data;
181 prop_data += sizeof(vd);
167 182
168 switch (vd) { 183 switch (vd) {
169 case 0x00000000: 184 case 0x00000000:
@@ -219,7 +234,7 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
219 return rc; 234 return rc;
220} 235}
221 236
222static int pseries_devicetree_update(void) 237int pseries_devicetree_update(s32 scope)
223{ 238{
224 char *rtas_buf; 239 char *rtas_buf;
225 u32 *data; 240 u32 *data;
@@ -235,7 +250,7 @@ static int pseries_devicetree_update(void)
235 return -ENOMEM; 250 return -ENOMEM;
236 251
237 do { 252 do {
238 rc = mobility_rtas_call(update_nodes_token, rtas_buf); 253 rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope);
239 if (rc && rc != 1) 254 if (rc && rc != 1)
240 break; 255 break;
241 256
@@ -256,7 +271,7 @@ static int pseries_devicetree_update(void)
256 delete_dt_node(phandle); 271 delete_dt_node(phandle);
257 break; 272 break;
258 case UPDATE_DT_NODE: 273 case UPDATE_DT_NODE:
259 update_dt_node(phandle); 274 update_dt_node(phandle, scope);
260 break; 275 break;
261 case ADD_DT_NODE: 276 case ADD_DT_NODE:
262 drc_index = *data++; 277 drc_index = *data++;
@@ -276,7 +291,7 @@ void post_mobility_fixup(void)
276 int rc; 291 int rc;
277 int activate_fw_token; 292 int activate_fw_token;
278 293
279 rc = pseries_devicetree_update(); 294 rc = pseries_devicetree_update(MIGRATION_SCOPE);
280 if (rc) { 295 if (rc) {
281 printk(KERN_ERR "Initial post-mobility device tree update " 296 printk(KERN_ERR "Initial post-mobility device tree update "
282 "failed: %d\n", rc); 297 "failed: %d\n", rc);
@@ -292,7 +307,7 @@ void post_mobility_fixup(void)
292 307
293 rc = rtas_call(activate_fw_token, 0, 1, NULL); 308 rc = rtas_call(activate_fw_token, 0, 1, NULL);
294 if (!rc) { 309 if (!rc) {
295 rc = pseries_devicetree_update(); 310 rc = pseries_devicetree_update(MIGRATION_SCOPE);
296 if (rc) 311 if (rc)
297 printk(KERN_ERR "Secondary post-mobility device tree " 312 printk(KERN_ERR "Secondary post-mobility device tree "
298 "update failed: %d\n", rc); 313 "update failed: %d\n", rc);
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index f368668d97b3..f35787b6a5e0 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -58,40 +58,39 @@ static inline long extended_cede_processor(unsigned long latency_hint)
58static inline long vpa_call(unsigned long flags, unsigned long cpu, 58static inline long vpa_call(unsigned long flags, unsigned long cpu,
59 unsigned long vpa) 59 unsigned long vpa)
60{ 60{
61 /* flags are in bits 16-18 (counting from most significant bit) */ 61 flags = flags << H_VPA_FUNC_SHIFT;
62 flags = flags << (63 - 18);
63 62
64 return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); 63 return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
65} 64}
66 65
67static inline long unregister_vpa(unsigned long cpu) 66static inline long unregister_vpa(unsigned long cpu)
68{ 67{
69 return vpa_call(0x5, cpu, 0); 68 return vpa_call(H_VPA_DEREG_VPA, cpu, 0);
70} 69}
71 70
72static inline long register_vpa(unsigned long cpu, unsigned long vpa) 71static inline long register_vpa(unsigned long cpu, unsigned long vpa)
73{ 72{
74 return vpa_call(0x1, cpu, vpa); 73 return vpa_call(H_VPA_REG_VPA, cpu, vpa);
75} 74}
76 75
77static inline long unregister_slb_shadow(unsigned long cpu) 76static inline long unregister_slb_shadow(unsigned long cpu)
78{ 77{
79 return vpa_call(0x7, cpu, 0); 78 return vpa_call(H_VPA_DEREG_SLB, cpu, 0);
80} 79}
81 80
82static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) 81static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
83{ 82{
84 return vpa_call(0x3, cpu, vpa); 83 return vpa_call(H_VPA_REG_SLB, cpu, vpa);
85} 84}
86 85
87static inline long unregister_dtl(unsigned long cpu) 86static inline long unregister_dtl(unsigned long cpu)
88{ 87{
89 return vpa_call(0x6, cpu, 0); 88 return vpa_call(H_VPA_DEREG_DTL, cpu, 0);
90} 89}
91 90
92static inline long register_dtl(unsigned long cpu, unsigned long vpa) 91static inline long register_dtl(unsigned long cpu, unsigned long vpa)
93{ 92{
94 return vpa_call(0x2, cpu, vpa); 93 return vpa_call(H_VPA_REG_DTL, cpu, vpa);
95} 94}
96 95
97static inline long plpar_page_set_loaned(unsigned long vpa) 96static inline long plpar_page_set_loaned(unsigned long vpa)
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index 4d806b419606..4644efa06941 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -23,8 +23,8 @@
23#include "pseries.h" 23#include "pseries.h"
24 24
25struct cpuidle_driver pseries_idle_driver = { 25struct cpuidle_driver pseries_idle_driver = {
26 .name = "pseries_idle", 26 .name = "pseries_idle",
27 .owner = THIS_MODULE, 27 .owner = THIS_MODULE,
28}; 28};
29 29
30#define MAX_IDLE_STATE_COUNT 2 30#define MAX_IDLE_STATE_COUNT 2
@@ -33,10 +33,8 @@ static int max_idle_state = MAX_IDLE_STATE_COUNT - 1;
33static struct cpuidle_device __percpu *pseries_cpuidle_devices; 33static struct cpuidle_device __percpu *pseries_cpuidle_devices;
34static struct cpuidle_state *cpuidle_state_table; 34static struct cpuidle_state *cpuidle_state_table;
35 35
36static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) 36static inline void idle_loop_prolog(unsigned long *in_purr)
37{ 37{
38
39 *kt_before = ktime_get();
40 *in_purr = mfspr(SPRN_PURR); 38 *in_purr = mfspr(SPRN_PURR);
41 /* 39 /*
42 * Indicate to the HV that we are idle. Now would be 40 * Indicate to the HV that we are idle. Now would be
@@ -45,12 +43,10 @@ static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before)
45 get_lppaca()->idle = 1; 43 get_lppaca()->idle = 1;
46} 44}
47 45
48static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) 46static inline void idle_loop_epilog(unsigned long in_purr)
49{ 47{
50 get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; 48 get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr;
51 get_lppaca()->idle = 0; 49 get_lppaca()->idle = 0;
52
53 return ktime_to_us(ktime_sub(ktime_get(), kt_before));
54} 50}
55 51
56static int snooze_loop(struct cpuidle_device *dev, 52static int snooze_loop(struct cpuidle_device *dev,
@@ -58,10 +54,9 @@ static int snooze_loop(struct cpuidle_device *dev,
58 int index) 54 int index)
59{ 55{
60 unsigned long in_purr; 56 unsigned long in_purr;
61 ktime_t kt_before;
62 int cpu = dev->cpu; 57 int cpu = dev->cpu;
63 58
64 idle_loop_prolog(&in_purr, &kt_before); 59 idle_loop_prolog(&in_purr);
65 local_irq_enable(); 60 local_irq_enable();
66 set_thread_flag(TIF_POLLING_NRFLAG); 61 set_thread_flag(TIF_POLLING_NRFLAG);
67 62
@@ -75,8 +70,8 @@ static int snooze_loop(struct cpuidle_device *dev,
75 clear_thread_flag(TIF_POLLING_NRFLAG); 70 clear_thread_flag(TIF_POLLING_NRFLAG);
76 smp_mb(); 71 smp_mb();
77 72
78 dev->last_residency = 73 idle_loop_epilog(in_purr);
79 (int)idle_loop_epilog(in_purr, kt_before); 74
80 return index; 75 return index;
81} 76}
82 77
@@ -102,9 +97,8 @@ static int dedicated_cede_loop(struct cpuidle_device *dev,
102 int index) 97 int index)
103{ 98{
104 unsigned long in_purr; 99 unsigned long in_purr;
105 ktime_t kt_before;
106 100
107 idle_loop_prolog(&in_purr, &kt_before); 101 idle_loop_prolog(&in_purr);
108 get_lppaca()->donate_dedicated_cpu = 1; 102 get_lppaca()->donate_dedicated_cpu = 1;
109 103
110 ppc64_runlatch_off(); 104 ppc64_runlatch_off();
@@ -112,8 +106,9 @@ static int dedicated_cede_loop(struct cpuidle_device *dev,
112 check_and_cede_processor(); 106 check_and_cede_processor();
113 107
114 get_lppaca()->donate_dedicated_cpu = 0; 108 get_lppaca()->donate_dedicated_cpu = 0;
115 dev->last_residency = 109
116 (int)idle_loop_epilog(in_purr, kt_before); 110 idle_loop_epilog(in_purr);
111
117 return index; 112 return index;
118} 113}
119 114
@@ -122,9 +117,8 @@ static int shared_cede_loop(struct cpuidle_device *dev,
122 int index) 117 int index)
123{ 118{
124 unsigned long in_purr; 119 unsigned long in_purr;
125 ktime_t kt_before;
126 120
127 idle_loop_prolog(&in_purr, &kt_before); 121 idle_loop_prolog(&in_purr);
128 122
129 /* 123 /*
130 * Yield the processor to the hypervisor. We return if 124 * Yield the processor to the hypervisor. We return if
@@ -135,8 +129,8 @@ static int shared_cede_loop(struct cpuidle_device *dev,
135 */ 129 */
136 check_and_cede_processor(); 130 check_and_cede_processor();
137 131
138 dev->last_residency = 132 idle_loop_epilog(in_purr);
139 (int)idle_loop_epilog(in_purr, kt_before); 133
140 return index; 134 return index;
141} 135}
142 136
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 9a3dda07566f..8af71e4cc17f 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -19,7 +19,10 @@ extern void request_event_sources_irqs(struct device_node *np,
19 19
20#include <linux/of.h> 20#include <linux/of.h>
21 21
22extern void __init fw_feature_init(const char *hypertas, unsigned long len); 22extern void __init fw_hypertas_feature_init(const char *hypertas,
23 unsigned long len);
24extern void __init fw_vec5_feature_init(const char *hypertas,
25 unsigned long len);
23 26
24struct pt_regs; 27struct pt_regs;
25 28
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index d6491bd481d0..f93cdf55628c 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -452,7 +452,7 @@ static int proc_ppc64_create_ofdt(void)
452 452
453 ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops); 453 ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
454 if (ent) 454 if (ent)
455 ent->size = 0; 455 proc_set_size(ent, 0);
456 456
457 return 0; 457 return 0;
458} 458}
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 47f3cda2a68b..b502ab61aafa 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -41,13 +41,12 @@
41 41
42 42
43static unsigned int ibm_scan_log_dump; /* RTAS token */ 43static unsigned int ibm_scan_log_dump; /* RTAS token */
44static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ 44static unsigned int *scanlog_buffer; /* The data buffer */
45 45
46static ssize_t scanlog_read(struct file *file, char __user *buf, 46static ssize_t scanlog_read(struct file *file, char __user *buf,
47 size_t count, loff_t *ppos) 47 size_t count, loff_t *ppos)
48{ 48{
49 struct proc_dir_entry *dp = PDE(file_inode(file)); 49 unsigned int *data = scanlog_buffer;
50 unsigned int *data = (unsigned int *)dp->data;
51 int status; 50 int status;
52 unsigned long len, off; 51 unsigned long len, off;
53 unsigned int wait_time; 52 unsigned int wait_time;
@@ -135,8 +134,7 @@ static ssize_t scanlog_write(struct file * file, const char __user * buf,
135 134
136static int scanlog_open(struct inode * inode, struct file * file) 135static int scanlog_open(struct inode * inode, struct file * file)
137{ 136{
138 struct proc_dir_entry *dp = PDE(inode); 137 unsigned int *data = scanlog_buffer;
139 unsigned int *data = (unsigned int *)dp->data;
140 138
141 if (data[0] != 0) { 139 if (data[0] != 0) {
142 /* This imperfect test stops a second copy of the 140 /* This imperfect test stops a second copy of the
@@ -152,11 +150,9 @@ static int scanlog_open(struct inode * inode, struct file * file)
152 150
153static int scanlog_release(struct inode * inode, struct file * file) 151static int scanlog_release(struct inode * inode, struct file * file)
154{ 152{
155 struct proc_dir_entry *dp = PDE(inode); 153 unsigned int *data = scanlog_buffer;
156 unsigned int *data = (unsigned int *)dp->data;
157 154
158 data[0] = 0; 155 data[0] = 0;
159
160 return 0; 156 return 0;
161} 157}
162 158
@@ -172,7 +168,6 @@ const struct file_operations scanlog_fops = {
172static int __init scanlog_init(void) 168static int __init scanlog_init(void)
173{ 169{
174 struct proc_dir_entry *ent; 170 struct proc_dir_entry *ent;
175 void *data;
176 int err = -ENOMEM; 171 int err = -ENOMEM;
177 172
178 ibm_scan_log_dump = rtas_token("ibm,scan-log-dump"); 173 ibm_scan_log_dump = rtas_token("ibm,scan-log-dump");
@@ -180,29 +175,24 @@ static int __init scanlog_init(void)
180 return -ENODEV; 175 return -ENODEV;
181 176
182 /* Ideally we could allocate a buffer < 4G */ 177 /* Ideally we could allocate a buffer < 4G */
183 data = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 178 scanlog_buffer = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
184 if (!data) 179 if (!scanlog_buffer)
185 goto err; 180 goto err;
186 181
187 ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL, 182 ent = proc_create("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
188 &scanlog_fops, data); 183 &scanlog_fops);
189 if (!ent) 184 if (!ent)
190 goto err; 185 goto err;
191
192 proc_ppc64_scan_log_dump = ent;
193
194 return 0; 186 return 0;
195err: 187err:
196 kfree(data); 188 kfree(scanlog_buffer);
197 return err; 189 return err;
198} 190}
199 191
200static void __exit scanlog_cleanup(void) 192static void __exit scanlog_cleanup(void)
201{ 193{
202 if (proc_ppc64_scan_log_dump) { 194 remove_proc_entry("powerpc/rtas/scan-log-dump", NULL);
203 kfree(proc_ppc64_scan_log_dump->data); 195 kfree(scanlog_buffer);
204 remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
205 }
206} 196}
207 197
208module_init(scanlog_init); 198module_init(scanlog_init);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8bcc9ca6682f..ac932a9eb440 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -628,25 +628,39 @@ static void __init pSeries_init_early(void)
628 * Called very early, MMU is off, device-tree isn't unflattened 628 * Called very early, MMU is off, device-tree isn't unflattened
629 */ 629 */
630 630
631static int __init pSeries_probe_hypertas(unsigned long node, 631static int __init pseries_probe_fw_features(unsigned long node,
632 const char *uname, int depth, 632 const char *uname, int depth,
633 void *data) 633 void *data)
634{ 634{
635 const char *hypertas; 635 const char *prop;
636 unsigned long len; 636 unsigned long len;
637 static int hypertas_found;
638 static int vec5_found;
637 639
638 if (depth != 1 || 640 if (depth != 1)
639 (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0))
640 return 0; 641 return 0;
641 642
642 hypertas = of_get_flat_dt_prop(node, "ibm,hypertas-functions", &len); 643 if (!strcmp(uname, "rtas") || !strcmp(uname, "rtas@0")) {
643 if (!hypertas) 644 prop = of_get_flat_dt_prop(node, "ibm,hypertas-functions",
644 return 1; 645 &len);
646 if (prop) {
647 powerpc_firmware_features |= FW_FEATURE_LPAR;
648 fw_hypertas_feature_init(prop, len);
649 }
645 650
646 powerpc_firmware_features |= FW_FEATURE_LPAR; 651 hypertas_found = 1;
647 fw_feature_init(hypertas, len); 652 }
648 653
649 return 1; 654 if (!strcmp(uname, "chosen")) {
655 prop = of_get_flat_dt_prop(node, "ibm,architecture-vec-5",
656 &len);
657 if (prop)
658 fw_vec5_feature_init(prop, len);
659
660 vec5_found = 1;
661 }
662
663 return hypertas_found && vec5_found;
650} 664}
651 665
652static int __init pSeries_probe(void) 666static int __init pSeries_probe(void)
@@ -669,7 +683,7 @@ static int __init pSeries_probe(void)
669 pr_debug("pSeries detected, looking for LPAR capability...\n"); 683 pr_debug("pSeries detected, looking for LPAR capability...\n");
670 684
671 /* Now try to figure out if we are running on LPAR */ 685 /* Now try to figure out if we are running on LPAR */
672 of_scan_flat_dt(pSeries_probe_hypertas, NULL); 686 of_scan_flat_dt(pseries_probe_fw_features, NULL);
673 687
674 if (firmware_has_feature(FW_FEATURE_LPAR)) 688 if (firmware_has_feature(FW_FEATURE_LPAR))
675 hpte_init_lpar(); 689 hpte_init_lpar();
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
index 79d2225b7608..422a175b10ee 100644
--- a/arch/powerpc/platforms/wsp/Kconfig
+++ b/arch/powerpc/platforms/wsp/Kconfig
@@ -9,7 +9,6 @@ config PPC_WSP
9 select PCI 9 select PCI
10 select PPC_IO_WORKAROUNDS if PCI 10 select PPC_IO_WORKAROUNDS if PCI
11 select PPC_INDIRECT_PIO if PCI 11 select PPC_INDIRECT_PIO if PCI
12 select PPC_WSP_COPRO
13 default n 12 default n
14 13
15menu "WSP platform selection" 14menu "WSP platform selection"
@@ -29,7 +28,3 @@ config PPC_CHROMA
29 default y 28 default y
30 29
31endmenu 30endmenu
32
33config PPC_A2_DD2
34 bool "Support for DD2 based A2/WSP systems"
35 depends on PPC_A2