diff options
Diffstat (limited to 'arch/powerpc/platforms')
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 | ||
108 | config 405EP | ||
109 | bool | ||
110 | |||
111 | config 405EX | 107 | config 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 | ||
122 | config 405GPR | ||
123 | bool | ||
124 | |||
125 | config XILINX_VIRTEX | 118 | config 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 | ||
278 | config 440GRX | 280 | config 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 | ||
11 | config MPC5121_ADS | 13 | config 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 | ||
18 | config MPC5121_GENERIC | 20 | config 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 | ||
29 | config PDM360NG | 31 | config 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 | # |
4 | obj-y += clock.o mpc512x_shared.o | 4 | obj-y += clock.o mpc512x_shared.o |
5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o | 5 | obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o |
6 | obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o | 6 | obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o |
7 | obj-$(CONFIG_PDM360NG) += pdm360ng.o | 7 | obj-$(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 | ||
34 | static int clocks_initialized; | 36 | static 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", ®)) { | 695 | if (!of_property_read_u32(np, "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); | |||
15 | extern void __init mpc512x_init(void); | 15 | extern void __init mpc512x_init(void); |
16 | extern int __init mpc5121_clk_init(void); | 16 | extern int __init mpc5121_clk_init(void); |
17 | void __init mpc512x_declare_of_platform_devices(void); | 17 | void __init mpc512x_declare_of_platform_devices(void); |
18 | extern const char *mpc512x_select_psc_compat(void); | ||
18 | extern void mpc512x_restart(char *cmd); | 19 | extern 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 | */ |
29 | static const char * const board[] __initconst = { | 29 | static 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 | */ |
37 | static int __init mpc5121_generic_probe(void) | 39 | static 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 | ||
42 | define_machine(mpc5121_generic) { | 44 | define_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 | ||
173 | static inline void mpc512x_free_bootmem(struct page *page) | 173 | static 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 | ||
183 | void mpc512x_release_bootmem(void) | 180 | void mpc512x_release_bootmem(void) |
@@ -330,26 +327,34 @@ void __init mpc512x_init_IRQ(void) | |||
330 | static struct of_device_id __initdata of_bus_ids[] = { | 327 | static 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 | ||
336 | void __init mpc512x_declare_of_platform_devices(void) | 338 | void __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 | ||
347 | const 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 | |||
353 | static unsigned int __init get_fifo_size(struct device_node *np, | 358 | static 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 | ||
308 | if PPC64 | ||
309 | |||
310 | config 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 | |||
324 | config 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 | |||
341 | endif | ||
308 | endif # FSL_SOC_BOOKE | 342 | endif # FSL_SOC_BOOKE |
309 | 343 | ||
310 | config TQM85xx | 344 | config 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 | |||
22 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o | 22 | obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o |
23 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o | 23 | obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o |
24 | obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o | 24 | obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o |
25 | obj-$(CONFIG_T4240_QDS) += t4240_qds.o corenet_ds.o | ||
26 | obj-$(CONFIG_B4_QDS) += b4_qds.o corenet_ds.o | ||
25 | obj-$(CONFIG_STX_GP3) += stx_gp3.o | 27 | obj-$(CONFIG_STX_GP3) += stx_gp3.o |
26 | obj-$(CONFIG_TQM85xx) += tqm85xx.o | 28 | obj-$(CONFIG_TQM85xx) += tqm85xx.o |
27 | obj-$(CONFIG_SBC8548) += sbc8548.o | 29 | obj-$(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 | */ | ||
39 | static 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 | |||
74 | define_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 | |||
98 | machine_arch_initcall(b4_qds, corenet_ds_publish_devices); | ||
99 | |||
100 | #ifdef CONFIG_SWIOTLB | ||
101 | machine_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 | */ | ||
39 | static 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 | |||
70 | define_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 | |||
94 | machine_arch_initcall(t4240_qds, corenet_ds_publish_devices); | ||
95 | |||
96 | #ifdef CONFIG_SWIOTLB | ||
97 | machine_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" | |||
6 | source "arch/powerpc/platforms/512x/Kconfig" | 6 | source "arch/powerpc/platforms/512x/Kconfig" |
7 | source "arch/powerpc/platforms/52xx/Kconfig" | 7 | source "arch/powerpc/platforms/52xx/Kconfig" |
8 | source "arch/powerpc/platforms/powermac/Kconfig" | 8 | source "arch/powerpc/platforms/powermac/Kconfig" |
9 | source "arch/powerpc/platforms/prep/Kconfig" | ||
10 | source "arch/powerpc/platforms/maple/Kconfig" | 9 | source "arch/powerpc/platforms/maple/Kconfig" |
11 | source "arch/powerpc/platforms/pasemi/Kconfig" | 10 | source "arch/powerpc/platforms/pasemi/Kconfig" |
12 | source "arch/powerpc/platforms/ps3/Kconfig" | 11 | source "arch/powerpc/platforms/ps3/Kconfig" |
@@ -233,7 +232,7 @@ endmenu | |||
233 | 232 | ||
234 | config PPC601_SYNC_FIX | 233 | config 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 | ||
345 | config CPM | 344 | config CPM |
346 | bool | 345 | bool |
347 | select PPC_CLOCK | ||
348 | 346 | ||
349 | config OF_RTC | 347 | config 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 | ||
231 | config ALTIVEC | 231 | config 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 | ||
116 | config 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 | |||
125 | config 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 | |||
135 | config CBE_CPUFREQ_PMI | ||
136 | tristate | ||
137 | depends on CBE_CPUFREQ_PMI_ENABLE | ||
138 | default CBE_CPUFREQ | ||
139 | |||
140 | config PPC_PMI | 116 | config 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 \ | |||
5 | obj-$(CONFIG_CBE_RAS) += ras.o | 5 | obj-$(CONFIG_CBE_RAS) += ras.o |
6 | 6 | ||
7 | obj-$(CONFIG_CBE_THERM) += cbe_thermal.o | 7 | obj-$(CONFIG_CBE_THERM) += cbe_thermal.o |
8 | obj-$(CONFIG_CBE_CPUFREQ_PMI) += cbe_cpufreq_pmi.o | ||
9 | obj-$(CONFIG_CBE_CPUFREQ) += cbe-cpufreq.o | ||
10 | cbe-cpufreq-y += cbe_cpufreq_pervasive.o cbe_cpufreq.o | ||
11 | obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o | 8 | obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o |
12 | 9 | ||
13 | obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o | 10 | obj-$(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) | |||
90 | static long beat_lpar_hpte_insert(unsigned long hpte_group, | 90 | static 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) | |||
314 | static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, | 314 | static 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 | |||
32 | static DEFINE_MUTEX(cbe_switch_mutex); | ||
33 | |||
34 | |||
35 | /* the CBE supports an 8 step frequency scaling */ | ||
36 | static 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 | |||
52 | static 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 | |||
70 | static 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 | |||
132 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) | ||
133 | { | ||
134 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int cbe_cpufreq_verify(struct cpufreq_policy *policy) | ||
139 | { | ||
140 | return cpufreq_frequency_table_verify(policy, cbe_freqs); | ||
141 | } | ||
142 | |||
143 | static 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 | |||
178 | static 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 | |||
192 | static 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 | |||
200 | static void __exit cbe_cpufreq_exit(void) | ||
201 | { | ||
202 | cpufreq_unregister_driver(&cbe_cpufreq_driver); | ||
203 | } | ||
204 | |||
205 | module_init(cbe_cpufreq_init); | ||
206 | module_exit(cbe_cpufreq_exit); | ||
207 | |||
208 | MODULE_LICENSE("GPL"); | ||
209 | MODULE_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 | |||
15 | int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode); | ||
16 | int cbe_cpufreq_get_pmode(int cpu); | ||
17 | |||
18 | int cbe_cpufreq_set_pmode_pmi(int cpu, unsigned int pmode); | ||
19 | |||
20 | #if defined(CONFIG_CBE_CPUFREQ_PMI) || defined(CONFIG_CBE_CPUFREQ_PMI_MODULE) | ||
21 | extern 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 */ | ||
36 | static u64 MIC_Slow_Fast_Timer_table[] = { | ||
37 | [0 ... 7] = 0x007fc00000000000ull, | ||
38 | }; | ||
39 | |||
40 | /* more values for the MIC */ | ||
41 | static 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 | |||
53 | int 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 | |||
105 | int 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 | |||
40 | static u8 pmi_slow_mode_limit[MAX_CBE]; | ||
41 | |||
42 | bool cbe_cpufreq_has_pmi = false; | ||
43 | EXPORT_SYMBOL_GPL(cbe_cpufreq_has_pmi); | ||
44 | |||
45 | /* | ||
46 | * hardware specific functions | ||
47 | */ | ||
48 | |||
49 | int 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 | } | ||
76 | EXPORT_SYMBOL_GPL(cbe_cpufreq_set_pmode_pmi); | ||
77 | |||
78 | |||
79 | static 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 | |||
93 | static 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 | |||
123 | static struct notifier_block pmi_notifier_block = { | ||
124 | .notifier_call = pmi_notifier, | ||
125 | }; | ||
126 | |||
127 | static struct pmi_handler cbe_pmi_handler = { | ||
128 | .type = PMI_TYPE_FREQ_CHANGE, | ||
129 | .handle_pmi_message = cbe_cpufreq_handle_pmi, | ||
130 | }; | ||
131 | |||
132 | |||
133 | |||
134 | static 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 | |||
146 | static 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 | |||
152 | module_init(cbe_cpufreq_pmi_init); | ||
153 | module_exit(cbe_cpufreq_pmi_exit); | ||
154 | |||
155 | MODULE_LICENSE("GPL"); | ||
156 | MODULE_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 | } \ |
151 | static const struct file_operations __fops = { \ | 151 | static 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 | ||
2593 | static const struct file_operations spufs_switch_log_fops = { | 2592 | static 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 | */ | ||
53 | static 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 | |||
62 | static 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 | |||
50 | static struct resource mv643xx_eth_port1_resources[] = { | 69 | static 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 | ||
83 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { | 102 | static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { |
84 | &mv643xx_eth_shared_device, | 103 | &mv643xx_eth_shared_device, |
104 | &mv643xx_eth_mvmdio_device, | ||
85 | ð_port1_device, | 105 | ð_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 | ||
87 | config MPC10X_OPENPIC | ||
88 | bool | ||
89 | |||
90 | config GAMECUBE_COMMON | 85 | config 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 | ||
338 | static int do_set_cpu_speed(int speed_mode, int notify) | 338 | static 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 | ||
11 | config POWERNV_MSI | ||
12 | bool "Support PCI MSI on PowerNV platform" | ||
13 | depends on PCI_MSI | ||
14 | default y | ||
15 | |||
11 | config PPC_POWERNV_RTAS | 16 | config 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); | |||
107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | 107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); |
108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | 108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); |
109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | 109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); |
110 | OPAL_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 | ||
434 | static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *dev) | 437 | static 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 | ||
439 | static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) | 454 | static 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 | |||
494 | static 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 | ||
520 | void 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 | |||
450 | static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | 533 | static 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 | ||
618 | static 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; | ||
681 | fail: | ||
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 | |||
540 | static void pnv_ioda_setup_dma(struct pnv_phb *phb) | 688 | static 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 |
752 | static 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 | |||
591 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | 766 | static 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 | ||
648 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) | 842 | static 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 |
675 | static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } | 868 | static 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 | ||
855 | void __init pnv_pci_init_ioda1_phb(struct device_node *np) | 1048 | void __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 | |||
1207 | void pnv_pci_init_ioda2_phb(struct device_node *np) | ||
1208 | { | ||
1209 | pnv_pci_init_ioda_phb(np, PNV_PHB_IODA2); | ||
1015 | } | 1210 | } |
1016 | 1211 | ||
1017 | void __init pnv_pci_init_ioda_hub(struct device_node *np) | 1212 | void __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 |
43 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | 44 | static 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 | ||
56 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) | 57 | static 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 |
84 | static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } | 83 | static 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 | |||
53 | static 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; | ||
69 | out: | ||
70 | spin_unlock_irqrestore(&phb->lock, flags); | ||
71 | return rc; | ||
72 | } | ||
73 | |||
74 | static 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 | ||
89 | static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 54 | static 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 | |||
366 | static 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 | |||
407 | static int pnv_tce_build(struct iommu_table *tbl, long index, long npages, | 332 | static 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 | ||
449 | static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) | 374 | static 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 */ |
529 | static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) | 454 | static 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 @@ | |||
4 | struct pci_dn; | 4 | struct pci_dn; |
5 | 5 | ||
6 | enum pnv_phb_type { | 6 | enum 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.. */ |
26 | struct pnv_phb; | ||
25 | struct pnv_ioda_pe { | 27 | struct 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); |
151 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); | 156 | extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); |
152 | extern void pnv_pci_init_ioda_hub(struct device_node *np); | 157 | extern void pnv_pci_init_ioda_hub(struct device_node *np); |
153 | 158 | extern void pnv_pci_init_ioda2_phb(struct device_node *np); | |
154 | 159 | extern 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 @@ | |||
1 | config 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 | |||
12 | config 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 | ||
47 | static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, | 47 | static 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 | ||
98 | module_init(ps3_rtc_init); | 96 | module_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 | ||
31 | typedef struct { | 31 | struct 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 | */ |
41 | static __initdata firmware_feature_t | 41 | static __initdata struct hypertas_fw_feature |
42 | firmware_features_table[FIRMWARE_MAX_FEATURES] = { | 42 | hypertas_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 | */ |
72 | void __init fw_feature_init(const char *hypertas, unsigned long len) | 72 | void __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 | |||
105 | struct vec5_fw_feature { | ||
106 | unsigned long val; | ||
107 | unsigned int feature; | ||
108 | }; | ||
109 | |||
110 | static __initdata struct vec5_fw_feature | ||
111 | vec5_fw_features_table[] = { | ||
112 | {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY}, | ||
113 | {FW_FEATURE_PRRN, OV5_PRRN}, | ||
114 | }; | ||
115 | |||
116 | void __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 | ||
75 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) | 76 | static 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 | ||
158 | static inline int pseries_remove_memblock(unsigned long base, | ||
159 | unsigned int memblock_size) | ||
160 | { | ||
161 | return -EOPNOTSUPP; | ||
162 | } | ||
163 | static inline int pseries_remove_memory(struct device_node *np) | ||
164 | { | ||
165 | return -EOPNOTSUPP; | ||
166 | } | ||
167 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | ||
156 | 168 | ||
157 | static int pseries_add_memory(struct device_node *np) | 169 | static 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 | ||
927 | struct failed_ddw_pdn { | ||
928 | struct device_node *pdn; | ||
929 | struct list_head list; | ||
930 | }; | ||
931 | |||
932 | static 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 | |||
1117 | out_unlock: | 1143 | out_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) | |||
109 | static long pSeries_lpar_hpte_insert(unsigned long hpte_group, | 109 | static 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 | ||
40 | static int mobility_rtas_call(int token, char *buf) | 40 | #define MIGRATION_SCOPE (1) |
41 | |||
42 | static 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 | ||
126 | static int update_dt_node(u32 phandle) | 128 | static 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 | ||
222 | static int pseries_devicetree_update(void) | 237 | int 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) | |||
58 | static inline long vpa_call(unsigned long flags, unsigned long cpu, | 58 | static 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 | ||
67 | static inline long unregister_vpa(unsigned long cpu) | 66 | static 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 | ||
72 | static inline long register_vpa(unsigned long cpu, unsigned long vpa) | 71 | static 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 | ||
77 | static inline long unregister_slb_shadow(unsigned long cpu) | 76 | static 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 | ||
82 | static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) | 81 | static 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 | ||
87 | static inline long unregister_dtl(unsigned long cpu) | 86 | static 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 | ||
92 | static inline long register_dtl(unsigned long cpu, unsigned long vpa) | 91 | static 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 | ||
97 | static inline long plpar_page_set_loaned(unsigned long vpa) | 96 | static 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 | ||
25 | struct cpuidle_driver pseries_idle_driver = { | 25 | struct 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; | |||
33 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | 33 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; |
34 | static struct cpuidle_state *cpuidle_state_table; | 34 | static struct cpuidle_state *cpuidle_state_table; |
35 | 35 | ||
36 | static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) | 36 | static 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 | ||
48 | static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) | 46 | static 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 | ||
56 | static int snooze_loop(struct cpuidle_device *dev, | 52 | static 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 | ||
22 | extern void __init fw_feature_init(const char *hypertas, unsigned long len); | 22 | extern void __init fw_hypertas_feature_init(const char *hypertas, |
23 | unsigned long len); | ||
24 | extern void __init fw_vec5_feature_init(const char *hypertas, | ||
25 | unsigned long len); | ||
23 | 26 | ||
24 | struct pt_regs; | 27 | struct 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 | ||
43 | static unsigned int ibm_scan_log_dump; /* RTAS token */ | 43 | static unsigned int ibm_scan_log_dump; /* RTAS token */ |
44 | static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ | 44 | static unsigned int *scanlog_buffer; /* The data buffer */ |
45 | 45 | ||
46 | static ssize_t scanlog_read(struct file *file, char __user *buf, | 46 | static 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 | ||
136 | static int scanlog_open(struct inode * inode, struct file * file) | 135 | static 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 | ||
153 | static int scanlog_release(struct inode * inode, struct file * file) | 151 | static 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 = { | |||
172 | static int __init scanlog_init(void) | 168 | static 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; |
195 | err: | 187 | err: |
196 | kfree(data); | 188 | kfree(scanlog_buffer); |
197 | return err; | 189 | return err; |
198 | } | 190 | } |
199 | 191 | ||
200 | static void __exit scanlog_cleanup(void) | 192 | static 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 | ||
208 | module_init(scanlog_init); | 198 | module_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 | ||
631 | static int __init pSeries_probe_hypertas(unsigned long node, | 631 | static 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 | ||
652 | static int __init pSeries_probe(void) | 666 | static 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 | ||
15 | menu "WSP platform selection" | 14 | menu "WSP platform selection" |
@@ -29,7 +28,3 @@ config PPC_CHROMA | |||
29 | default y | 28 | default y |
30 | 29 | ||
31 | endmenu | 30 | endmenu |
32 | |||
33 | config PPC_A2_DD2 | ||
34 | bool "Support for DD2 based A2/WSP systems" | ||
35 | depends on PPC_A2 | ||