aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-18 13:53:16 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 13:53:16 -0400
commit9b610fda0df5d0f0b0c64242e37441ad1b384aac (patch)
tree0ea14b15f2e6546f37fe18d8ac3dc83077ec0e55 /arch/powerpc/platforms
parentb8f8c3cf0a4ac0632ec3f0e15e9dc0c29de917af (diff)
parent5b664cb235e97afbf34db9c4d77f08ebd725335e (diff)
Merge branch 'linus' into timers/nohz
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/44x/Kconfig35
-rw-r--r--arch/powerpc/platforms/44x/Makefile2
-rw-r--r--arch/powerpc/platforms/44x/sam440ep.c79
-rw-r--r--arch/powerpc/platforms/44x/virtex.c60
-rw-r--r--arch/powerpc/platforms/44x/warp-nand.c57
-rw-r--r--arch/powerpc/platforms/44x/warp.c293
-rw-r--r--arch/powerpc/platforms/512x/Kconfig17
-rw-r--r--arch/powerpc/platforms/512x/Makefile4
-rw-r--r--arch/powerpc/platforms/512x/clock.c729
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c69
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.h16
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c204
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_generic.c58
-rw-r--r--arch/powerpc/platforms/512x/mpc512x.h17
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c83
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c14
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpio.c14
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c3
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig11
-rw-r--r--arch/powerpc/platforms/82xx/ep8248e.c4
-rw-r--r--arch/powerpc/platforms/82xx/mpc8272_ads.c4
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c2
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig30
-rw-r--r--arch/powerpc/platforms/83xx/Makefile2
-rw-r--r--arch/powerpc/platforms/83xx/asp834x.c90
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_rdk.c102
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig15
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/mpc8536_ds.c125
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c8
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c14
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c12
-rw-r--r--arch/powerpc/platforms/85xx/tqm85xx.c23
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig16
-rw-r--r--arch/powerpc/platforms/86xx/Makefile1
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c25
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx.h3
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c64
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_smp.c6
-rw-r--r--arch/powerpc/platforms/86xx/pic.c78
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c25
-rw-r--r--arch/powerpc/platforms/8xx/mpc86xads_setup.c4
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads_setup.c3
-rw-r--r--arch/powerpc/platforms/Kconfig33
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype25
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c76
-rw-r--r--arch/powerpc/platforms/cell/beat_htab.c4
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_pciex.c5
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c1
-rw-r--r--arch/powerpc/platforms/cell/iommu.c8
-rw-r--r--arch/powerpc/platforms/cell/ras.c22
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c2
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c44
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c12
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c203
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c47
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c21
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c28
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h19
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c8
-rw-r--r--arch/powerpc/platforms/chrp/setup.c7
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig10
-rw-r--r--arch/powerpc/platforms/embedded6xx/Makefile1
-rw-r--r--arch/powerpc/platforms/embedded6xx/c2k.c158
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/maple/time.c2
-rw-r--r--arch/powerpc/platforms/powermac/Makefile5
-rw-r--r--arch/powerpc/platforms/powermac/pic.c8
-rw-r--r--arch/powerpc/platforms/powermac/smp.c6
-rw-r--r--arch/powerpc/platforms/ps3/smp.c7
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c38
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c14
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c11
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c1
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c117
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c15
-rw-r--r--arch/powerpc/platforms/pseries/kexec.c2
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c4
-rw-r--r--arch/powerpc/platforms/pseries/ras.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c38
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c4
-rw-r--r--arch/powerpc/platforms/pseries/xics.c6
84 files changed, 2888 insertions, 560 deletions
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 6abe91357eee..249ba01c6674 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -17,6 +17,15 @@ config EBONY
17 help 17 help
18 This option enables support for the IBM PPC440GP evaluation board. 18 This option enables support for the IBM PPC440GP evaluation board.
19 19
20config SAM440EP
21 bool "Sam440ep"
22 depends on 44x
23 default n
24 select 440EP
25 select PCI
26 help
27 This option enables support for the ACube Sam440ep board.
28
20config SEQUOIA 29config SEQUOIA
21 bool "Sequoia" 30 bool "Sequoia"
22 depends on 44x 31 depends on 44x
@@ -102,6 +111,22 @@ config YOSEMITE
102# help 111# help
103# This option enables support for the IBM PPC440GX evaluation board. 112# This option enables support for the IBM PPC440GX evaluation board.
104 113
114config XILINX_VIRTEX440_GENERIC_BOARD
115 bool "Generic Xilinx Virtex 440 board"
116 depends on 44x
117 default n
118 select XILINX_VIRTEX_5_FXT
119 help
120 This option enables generic support for Xilinx Virtex based boards
121 that use a 440 based processor in the Virtex 5 FXT FPGA architecture.
122
123 The generic virtex board support matches any device tree which
124 specifies 'xlnx,virtex440' in its compatible field. This includes
125 the Xilinx ML5xx reference designs using the powerpc core.
126
127 Most Virtex 5 designs should use this unless it needs to do some
128 special configuration at board probe time.
129
105# 44x specific CPU modules, selected based on the board above. 130# 44x specific CPU modules, selected based on the board above.
106config 440EP 131config 440EP
107 bool 132 bool
@@ -152,3 +177,13 @@ config 460EX
152# 44x errata/workaround config symbols, selected by the CPU models above 177# 44x errata/workaround config symbols, selected by the CPU models above
153config IBM440EP_ERR42 178config IBM440EP_ERR42
154 bool 179 bool
180
181# Xilinx specific config options.
182config XILINX_VIRTEX
183 bool
184
185# Xilinx Virtex 5 FXT FPGA architecture, selected by a Xilinx board above
186config XILINX_VIRTEX_5_FXT
187 bool
188 select XILINX_VIRTEX
189
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index 774165f9acdd..8d0b1a192d62 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -3,9 +3,11 @@ obj-$(CONFIG_EBONY) += ebony.o
3obj-$(CONFIG_TAISHAN) += taishan.o 3obj-$(CONFIG_TAISHAN) += taishan.o
4obj-$(CONFIG_BAMBOO) += bamboo.o 4obj-$(CONFIG_BAMBOO) += bamboo.o
5obj-$(CONFIG_YOSEMITE) += bamboo.o 5obj-$(CONFIG_YOSEMITE) += bamboo.o
6obj-$(CONFIG_SAM440EP) += sam440ep.o
6obj-$(CONFIG_SEQUOIA) += sequoia.o 7obj-$(CONFIG_SEQUOIA) += sequoia.o
7obj-$(CONFIG_KATMAI) += katmai.o 8obj-$(CONFIG_KATMAI) += katmai.o
8obj-$(CONFIG_RAINIER) += rainier.o 9obj-$(CONFIG_RAINIER) += rainier.o
9obj-$(CONFIG_WARP) += warp.o 10obj-$(CONFIG_WARP) += warp.o
10obj-$(CONFIG_WARP) += warp-nand.o 11obj-$(CONFIG_WARP) += warp-nand.o
11obj-$(CONFIG_CANYONLANDS) += canyonlands.o 12obj-$(CONFIG_CANYONLANDS) += canyonlands.o
13obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
diff --git a/arch/powerpc/platforms/44x/sam440ep.c b/arch/powerpc/platforms/44x/sam440ep.c
new file mode 100644
index 000000000000..47f10e647735
--- /dev/null
+++ b/arch/powerpc/platforms/44x/sam440ep.c
@@ -0,0 +1,79 @@
1/*
2 * Sam440ep board specific routines based off bamboo.c code
3 * original copyrights below
4 *
5 * Wade Farnsworth <wfarnsworth@mvista.com>
6 * Copyright 2004 MontaVista Software Inc.
7 *
8 * Rewritten and ported to the merged powerpc tree:
9 * Josh Boyer <jwboyer@linux.vnet.ibm.com>
10 * Copyright 2007 IBM Corporation
11 *
12 * Modified from bamboo.c for sam440ep:
13 * Copyright 2008 Giuseppe Coviello <gicoviello@gmail.com>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20#include <linux/init.h>
21#include <linux/of_platform.h>
22
23#include <asm/machdep.h>
24#include <asm/prom.h>
25#include <asm/udbg.h>
26#include <asm/time.h>
27#include <asm/uic.h>
28#include <asm/pci-bridge.h>
29#include <asm/ppc4xx.h>
30#include <linux/i2c.h>
31
32static __initdata struct of_device_id sam440ep_of_bus[] = {
33 { .compatible = "ibm,plb4", },
34 { .compatible = "ibm,opb", },
35 { .compatible = "ibm,ebc", },
36 {},
37};
38
39static int __init sam440ep_device_probe(void)
40{
41 of_platform_bus_probe(NULL, sam440ep_of_bus, NULL);
42
43 return 0;
44}
45machine_device_initcall(sam440ep, sam440ep_device_probe);
46
47static int __init sam440ep_probe(void)
48{
49 unsigned long root = of_get_flat_dt_root();
50
51 if (!of_flat_dt_is_compatible(root, "acube,sam440ep"))
52 return 0;
53
54 ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
55
56 return 1;
57}
58
59define_machine(sam440ep) {
60 .name = "Sam440ep",
61 .probe = sam440ep_probe,
62 .progress = udbg_progress,
63 .init_IRQ = uic_init_tree,
64 .get_irq = uic_get_irq,
65 .restart = ppc4xx_reset_system,
66 .calibrate_decr = generic_calibrate_decr,
67};
68
69static struct i2c_board_info sam440ep_rtc_info = {
70 .type = "m41st85",
71 .addr = 0x68,
72 .irq = -1,
73};
74
75static int sam440ep_setup_rtc(void)
76{
77 return i2c_register_board_info(0, &sam440ep_rtc_info, 1);
78}
79machine_device_initcall(sam440ep, sam440ep_setup_rtc);
diff --git a/arch/powerpc/platforms/44x/virtex.c b/arch/powerpc/platforms/44x/virtex.c
new file mode 100644
index 000000000000..68637faf70ae
--- /dev/null
+++ b/arch/powerpc/platforms/44x/virtex.c
@@ -0,0 +1,60 @@
1/*
2 * Xilinx Virtex 5FXT based board support, derived from
3 * the Xilinx Virtex (IIpro & 4FX) based board support
4 *
5 * Copyright 2007 Secret Lab Technologies Ltd.
6 * Copyright 2008 Xilinx, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/init.h>
14#include <linux/of_platform.h>
15#include <asm/machdep.h>
16#include <asm/prom.h>
17#include <asm/time.h>
18#include <asm/xilinx_intc.h>
19#include <asm/reg.h>
20#include <asm/ppc4xx.h>
21#include "44x.h"
22
23static struct of_device_id xilinx_of_bus_ids[] __initdata = {
24 { .compatible = "simple-bus", },
25 { .compatible = "xlnx,plb-v46-1.00.a", },
26 { .compatible = "xlnx,plb-v46-1.02.a", },
27 { .compatible = "xlnx,plb-v34-1.01.a", },
28 { .compatible = "xlnx,plb-v34-1.02.a", },
29 { .compatible = "xlnx,opb-v20-1.10.c", },
30 { .compatible = "xlnx,dcr-v29-1.00.a", },
31 { .compatible = "xlnx,compound", },
32 {}
33};
34
35static int __init virtex_device_probe(void)
36{
37 of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
38
39 return 0;
40}
41machine_device_initcall(virtex, virtex_device_probe);
42
43static int __init virtex_probe(void)
44{
45 unsigned long root = of_get_flat_dt_root();
46
47 if (!of_flat_dt_is_compatible(root, "xlnx,virtex440"))
48 return 0;
49
50 return 1;
51}
52
53define_machine(virtex) {
54 .name = "Xilinx Virtex440",
55 .probe = virtex_probe,
56 .init_IRQ = xilinx_intc_init_tree,
57 .get_irq = xilinx_intc_get_irq,
58 .calibrate_decr = generic_calibrate_decr,
59 .restart = ppc4xx_reset_system,
60};
diff --git a/arch/powerpc/platforms/44x/warp-nand.c b/arch/powerpc/platforms/44x/warp-nand.c
index 9150318cfc56..e55746b824b4 100644
--- a/arch/powerpc/platforms/44x/warp-nand.c
+++ b/arch/powerpc/platforms/44x/warp-nand.c
@@ -11,8 +11,10 @@
11#include <linux/mtd/partitions.h> 11#include <linux/mtd/partitions.h>
12#include <linux/mtd/nand.h> 12#include <linux/mtd/nand.h>
13#include <linux/mtd/ndfc.h> 13#include <linux/mtd/ndfc.h>
14#include <linux/of.h>
14#include <asm/machdep.h> 15#include <asm/machdep.h>
15 16
17
16#ifdef CONFIG_MTD_NAND_NDFC 18#ifdef CONFIG_MTD_NAND_NDFC
17 19
18#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */ 20#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */
@@ -35,13 +37,23 @@ static struct mtd_partition nand_parts[] = {
35 { 37 {
36 .name = "root", 38 .name = "root",
37 .offset = 0x0200000, 39 .offset = 0x0200000,
38 .size = 0x3400000 40 .size = 0x3E00000
41 },
42 {
43 .name = "persistent",
44 .offset = 0x4000000,
45 .size = 0x4000000
39 }, 46 },
40 { 47 {
41 .name = "user", 48 .name = "persistent1",
42 .offset = 0x3600000, 49 .offset = 0x8000000,
43 .size = 0x0A00000 50 .size = 0x4000000
44 }, 51 },
52 {
53 .name = "persistent2",
54 .offset = 0xC000000,
55 .size = 0x4000000
56 }
45}; 57};
46 58
47struct ndfc_controller_settings warp_ndfc_settings = { 59struct ndfc_controller_settings warp_ndfc_settings = {
@@ -67,27 +79,22 @@ static struct platform_device warp_ndfc_device = {
67 .resource = &warp_ndfc, 79 .resource = &warp_ndfc,
68}; 80};
69 81
70static struct nand_ecclayout nand_oob_16 = { 82/* Do NOT set the ecclayout: let it default so it is correct for both
71 .eccbytes = 3, 83 * 64M and 256M flash chips.
72 .eccpos = { 0, 1, 2, 3, 6, 7 }, 84 */
73 .oobfree = { {.offset = 8, .length = 16} }
74};
75
76static struct platform_nand_chip warp_nand_chip0 = { 85static struct platform_nand_chip warp_nand_chip0 = {
77 .nr_chips = 1, 86 .nr_chips = 1,
78 .chip_offset = CS_NAND_0, 87 .chip_offset = CS_NAND_0,
79 .nr_partitions = ARRAY_SIZE(nand_parts), 88 .nr_partitions = ARRAY_SIZE(nand_parts),
80 .partitions = nand_parts, 89 .partitions = nand_parts,
81 .chip_delay = 50, 90 .chip_delay = 20,
82 .ecclayout = &nand_oob_16,
83 .priv = &warp_chip0_settings, 91 .priv = &warp_chip0_settings,
84}; 92};
85 93
86static struct platform_device warp_nand_device = { 94static struct platform_device warp_nand_device = {
87 .name = "ndfc-chip", 95 .name = "ndfc-chip",
88 .id = 0, 96 .id = 0,
89 .num_resources = 1, 97 .num_resources = 0,
90 .resource = &warp_ndfc,
91 .dev = { 98 .dev = {
92 .platform_data = &warp_nand_chip0, 99 .platform_data = &warp_nand_chip0,
93 .parent = &warp_ndfc_device.dev, 100 .parent = &warp_ndfc_device.dev,
@@ -96,6 +103,28 @@ static struct platform_device warp_nand_device = {
96 103
97static int warp_setup_nand_flash(void) 104static int warp_setup_nand_flash(void)
98{ 105{
106 struct device_node *np;
107
108 /* Try to detect a rev A based on NOR size. */
109 np = of_find_compatible_node(NULL, NULL, "cfi-flash");
110 if (np) {
111 struct property *pp;
112
113 pp = of_find_property(np, "reg", NULL);
114 if (pp && (pp->length == 12)) {
115 u32 *v = pp->value;
116 if (v[2] == 0x4000000) {
117 /* Rev A = 64M NAND */
118 warp_nand_chip0.nr_partitions = 3;
119
120 nand_parts[1].size = 0x3000000;
121 nand_parts[2].offset = 0x3200000;
122 nand_parts[2].size = 0x0e00000;
123 }
124 }
125 of_node_put(np);
126 }
127
99 platform_device_register(&warp_ndfc_device); 128 platform_device_register(&warp_ndfc_device);
100 platform_device_register(&warp_nand_device); 129 platform_device_register(&warp_nand_device);
101 130
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 39cf6150a72b..9565995cba7f 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -12,6 +12,9 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/of_platform.h> 13#include <linux/of_platform.h>
14#include <linux/kthread.h> 14#include <linux/kthread.h>
15#include <linux/i2c.h>
16#include <linux/interrupt.h>
17#include <linux/delay.h>
15 18
16#include <asm/machdep.h> 19#include <asm/machdep.h>
17#include <asm/prom.h> 20#include <asm/prom.h>
@@ -27,6 +30,18 @@ static __initdata struct of_device_id warp_of_bus[] = {
27 {}, 30 {},
28}; 31};
29 32
33static __initdata struct i2c_board_info warp_i2c_info[] = {
34 { I2C_BOARD_INFO("ad7414", 0x4a) }
35};
36
37static int __init warp_arch_init(void)
38{
39 /* This should go away once support is moved to the dts. */
40 i2c_register_board_info(0, warp_i2c_info, ARRAY_SIZE(warp_i2c_info));
41 return 0;
42}
43machine_arch_initcall(warp, warp_arch_init);
44
30static int __init warp_device_probe(void) 45static int __init warp_device_probe(void)
31{ 46{
32 of_platform_bus_probe(NULL, warp_of_bus, NULL); 47 of_platform_bus_probe(NULL, warp_of_bus, NULL);
@@ -52,61 +67,232 @@ define_machine(warp) {
52}; 67};
53 68
54 69
55#define LED_GREEN (0x80000000 >> 0) 70/* I am not sure this is the best place for this... */
56#define LED_RED (0x80000000 >> 1) 71static int __init warp_post_info(void)
72{
73 struct device_node *np;
74 void __iomem *fpga;
75 u32 post1, post2;
76
77 /* Sighhhh... POST information is in the sd area. */
78 np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
79 if (np == NULL)
80 return -ENOENT;
81
82 fpga = of_iomap(np, 0);
83 of_node_put(np);
84 if (fpga == NULL)
85 return -ENOENT;
86
87 post1 = in_be32(fpga + 0x40);
88 post2 = in_be32(fpga + 0x44);
89
90 iounmap(fpga);
91
92 if (post1 || post2)
93 printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
94 else
95 printk(KERN_INFO "Warp POST OK\n");
96
97 return 0;
98}
99machine_late_initcall(warp, warp_post_info);
100
101
102#ifdef CONFIG_SENSORS_AD7414
103
104static LIST_HEAD(dtm_shutdown_list);
105static void __iomem *dtm_fpga;
106static void __iomem *gpio_base;
107
108
109struct dtm_shutdown {
110 struct list_head list;
111 void (*func)(void *arg);
112 void *arg;
113};
57 114
58 115
59/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */ 116int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
60void warp_set_power_leds(int green, int red)
61{ 117{
62 static void __iomem *gpio_base = NULL; 118 struct dtm_shutdown *shutdown;
63 unsigned leds; 119
64 120 shutdown = kmalloc(sizeof(struct dtm_shutdown), GFP_KERNEL);
65 if (gpio_base == NULL) { 121 if (shutdown == NULL)
66 struct device_node *np; 122 return -ENOMEM;
67 123
68 /* Power LEDS are on the second GPIO controller */ 124 shutdown->func = func;
69 np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP"); 125 shutdown->arg = arg;
70 if (np) 126
71 np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP"); 127 list_add(&shutdown->list, &dtm_shutdown_list);
72 if (np == NULL) { 128
73 printk(KERN_ERR __FILE__ ": Unable to find gpio\n"); 129 return 0;
74 return; 130}
131
132int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
133{
134 struct dtm_shutdown *shutdown;
135
136 list_for_each_entry(shutdown, &dtm_shutdown_list, list)
137 if (shutdown->func == func && shutdown->arg == arg) {
138 list_del(&shutdown->list);
139 kfree(shutdown);
140 return 0;
141 }
142
143 return -EINVAL;
144}
145
146static irqreturn_t temp_isr(int irq, void *context)
147{
148 struct dtm_shutdown *shutdown;
149
150 local_irq_disable();
151
152 /* Run through the shutdown list. */
153 list_for_each_entry(shutdown, &dtm_shutdown_list, list)
154 shutdown->func(shutdown->arg);
155
156 printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
157
158 while (1) {
159 if (dtm_fpga) {
160 unsigned reset = in_be32(dtm_fpga + 0x14);
161 out_be32(dtm_fpga + 0x14, reset);
75 } 162 }
76 163
77 gpio_base = of_iomap(np, 0); 164 if (gpio_base) {
78 of_node_put(np); 165 unsigned leds = in_be32(gpio_base);
79 if (gpio_base == NULL) { 166
80 printk(KERN_ERR __FILE__ ": Unable to map gpio"); 167 /* green off, red toggle */
81 return; 168 leds &= ~0x80000000;
169 leds ^= 0x40000000;
170
171 out_be32(gpio_base, leds);
82 } 172 }
173
174 mdelay(500);
175 }
176}
177
178static int pika_setup_leds(void)
179{
180 struct device_node *np;
181 const u32 *gpios;
182 int len;
183
184 np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
185 if (!np) {
186 printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
187 return -ENOENT;
83 } 188 }
84 189
85 leds = in_be32(gpio_base); 190 gpios = of_get_property(np, "gpios", &len);
191 of_node_put(np);
192 if (!gpios || len < 4) {
193 printk(KERN_ERR __FILE__
194 ": Unable to get gpios property (%d)\n", len);
195 return -ENOENT;
196 }
86 197
87 switch (green) { 198 np = of_find_node_by_phandle(gpios[0]);
88 case 0: leds &= ~LED_GREEN; break; 199 if (!np) {
89 case 1: leds |= LED_GREEN; break; 200 printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
201 return -ENOENT;
90 } 202 }
91 switch (red) { 203
92 case 0: leds &= ~LED_RED; break; 204 gpio_base = of_iomap(np, 0);
93 case 1: leds |= LED_RED; break; 205 of_node_put(np);
206 if (!gpio_base) {
207 printk(KERN_ERR __FILE__ ": Unable to map gpio");
208 return -ENOMEM;
94 } 209 }
95 210
96 out_be32(gpio_base, leds); 211 return 0;
97} 212}
98EXPORT_SYMBOL(warp_set_power_leds);
99 213
214static void pika_setup_critical_temp(struct i2c_client *client)
215{
216 struct device_node *np;
217 int irq, rc;
218
219 /* Do this before enabling critical temp interrupt since we
220 * may immediately interrupt.
221 */
222 pika_setup_leds();
223
224 /* These registers are in 1 degree increments. */
225 i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
226 i2c_smbus_write_byte_data(client, 3, 55); /* Tlow */
227
228 np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
229 if (np == NULL) {
230 printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
231 return;
232 }
233
234 irq = irq_of_parse_and_map(np, 0);
235 of_node_put(np);
236 if (irq == NO_IRQ) {
237 printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
238 return;
239 }
240
241 rc = request_irq(irq, temp_isr, 0, "ad7414", NULL);
242 if (rc) {
243 printk(KERN_ERR __FILE__
244 ": Unable to request ad7414 irq %d = %d\n", irq, rc);
245 return;
246 }
247}
248
249static inline void pika_dtm_check_fan(void __iomem *fpga)
250{
251 static int fan_state;
252 u32 fan = in_be32(fpga + 0x34) & (1 << 14);
253
254 if (fan_state != fan) {
255 fan_state = fan;
256 if (fan)
257 printk(KERN_WARNING "Fan rotation error detected."
258 " Please check hardware.\n");
259 }
260}
100 261
101#ifdef CONFIG_SENSORS_AD7414
102static int pika_dtm_thread(void __iomem *fpga) 262static int pika_dtm_thread(void __iomem *fpga)
103{ 263{
104 extern int ad7414_get_temp(int index); 264 struct i2c_adapter *adap;
265 struct i2c_client *client;
266
267 /* We loop in case either driver was compiled as a module and
268 * has not been insmoded yet.
269 */
270 while (!(adap = i2c_get_adapter(0))) {
271 set_current_state(TASK_INTERRUPTIBLE);
272 schedule_timeout(HZ);
273 }
274
275 while (1) {
276 list_for_each_entry(client, &adap->clients, list)
277 if (client->addr == 0x4a)
278 goto found_it;
279
280 set_current_state(TASK_INTERRUPTIBLE);
281 schedule_timeout(HZ);
282 }
283
284found_it:
285 i2c_put_adapter(adap);
286
287 pika_setup_critical_temp(client);
288
289 printk(KERN_INFO "PIKA DTM thread running.\n");
105 290
106 while (!kthread_should_stop()) { 291 while (!kthread_should_stop()) {
107 int temp = ad7414_get_temp(0); 292 u16 temp = swab16(i2c_smbus_read_word_data(client, 0));
293 out_be32(fpga + 0x20, temp);
108 294
109 out_be32(fpga, temp); 295 pika_dtm_check_fan(fpga);
110 296
111 set_current_state(TASK_INTERRUPTIBLE); 297 set_current_state(TASK_INTERRUPTIBLE);
112 schedule_timeout(HZ); 298 schedule_timeout(HZ);
@@ -115,37 +301,44 @@ static int pika_dtm_thread(void __iomem *fpga)
115 return 0; 301 return 0;
116} 302}
117 303
304
118static int __init pika_dtm_start(void) 305static int __init pika_dtm_start(void)
119{ 306{
120 struct task_struct *dtm_thread; 307 struct task_struct *dtm_thread;
121 struct device_node *np; 308 struct device_node *np;
122 struct resource res;
123 void __iomem *fpga;
124 309
125 np = of_find_compatible_node(NULL, NULL, "pika,fpga"); 310 np = of_find_compatible_node(NULL, NULL, "pika,fpga");
126 if (np == NULL) 311 if (np == NULL)
127 return -ENOENT; 312 return -ENOENT;
128 313
129 /* We do not call of_iomap here since it would map in the entire 314 dtm_fpga = of_iomap(np, 0);
130 * fpga space, which is over 8k.
131 */
132 if (of_address_to_resource(np, 0, &res)) {
133 of_node_put(np);
134 return -ENOENT;
135 }
136 of_node_put(np); 315 of_node_put(np);
137 316 if (dtm_fpga == NULL)
138 fpga = ioremap(res.start, 0x24);
139 if (fpga == NULL)
140 return -ENOENT; 317 return -ENOENT;
141 318
142 dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm"); 319 dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
143 if (IS_ERR(dtm_thread)) { 320 if (IS_ERR(dtm_thread)) {
144 iounmap(fpga); 321 iounmap(dtm_fpga);
145 return PTR_ERR(dtm_thread); 322 return PTR_ERR(dtm_thread);
146 } 323 }
147 324
148 return 0; 325 return 0;
149} 326}
150device_initcall(pika_dtm_start); 327machine_late_initcall(warp, pika_dtm_start);
328
329#else /* !CONFIG_SENSORS_AD7414 */
330
331int pika_dtm_register_shutdown(void (*func)(void *arg), void *arg)
332{
333 return 0;
334}
335
336int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
337{
338 return 0;
339}
340
151#endif 341#endif
342
343EXPORT_SYMBOL(pika_dtm_register_shutdown);
344EXPORT_SYMBOL(pika_dtm_unregister_shutdown);
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 4c0da0c079e9..c62f893ede19 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -2,18 +2,29 @@ config PPC_MPC512x
2 bool 2 bool
3 select FSL_SOC 3 select FSL_SOC
4 select IPIC 4 select IPIC
5 default n 5 select PPC_CLOCK
6 6
7config PPC_MPC5121 7config PPC_MPC5121
8 bool 8 bool
9 select PPC_MPC512x 9 select PPC_MPC512x
10 default n
11 10
12config MPC5121_ADS 11config MPC5121_ADS
13 bool "Freescale MPC5121E ADS" 12 bool "Freescale MPC5121E ADS"
14 depends on PPC_MULTIPLATFORM && PPC32 13 depends on PPC_MULTIPLATFORM && PPC32
15 select DEFAULT_UIMAGE 14 select DEFAULT_UIMAGE
16 select PPC_MPC5121 15 select PPC_MPC5121
16 select MPC5121_ADS_CPLD
17 help 17 help
18 This option enables support for the MPC5121E ADS board. 18 This option enables support for the MPC5121E ADS board.
19 default n 19
20config MPC5121_GENERIC
21 bool "Generic support for simple MPC5121 based boards"
22 depends on PPC_MULTIPLATFORM && PPC32
23 select DEFAULT_UIMAGE
24 select PPC_MPC5121
25 help
26 This option enables support for simple MPC5121 based boards
27 which do not need custom platform specific setup.
28
29 Compatible boards include: Protonic LVT base boards (ZANMCU
30 and VICVT2).
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
index 232c89f2039a..90be2f5717e6 100644
--- a/arch/powerpc/platforms/512x/Makefile
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -1,4 +1,6 @@
1# 1#
2# Makefile for the Freescale PowerPC 512x linux kernel. 2# Makefile for the Freescale PowerPC 512x linux kernel.
3# 3#
4obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o 4obj-y += clock.o mpc512x_shared.o
5obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o
6obj-$(CONFIG_MPC5121_GENERIC) += mpc5121_generic.o
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
new file mode 100644
index 000000000000..f416014ee727
--- /dev/null
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -0,0 +1,729 @@
1/*
2 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby <jrigby@freescale.com>
5 *
6 * Implements the clk api defined in include/linux/clk.h
7 *
8 * Original based on linux/arch/arm/mach-integrator/clock.c
9 *
10 * Copyright (C) 2004 ARM Limited.
11 * Written by Deep Blue Solutions Limited.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/err.h>
21#include <linux/string.h>
22#include <linux/clk.h>
23#include <linux/mutex.h>
24#include <linux/io.h>
25
26#include <linux/of_platform.h>
27#include <asm/mpc512x.h>
28#include <asm/clk_interface.h>
29
30#undef CLK_DEBUG
31
32static int clocks_initialized;
33
34#define CLK_HAS_RATE 0x1 /* has rate in MHz */
35#define CLK_HAS_CTRL 0x2 /* has control reg and bit */
36
37struct clk {
38 struct list_head node;
39 char name[32];
40 int flags;
41 struct device *dev;
42 unsigned long rate;
43 struct module *owner;
44 void (*calc) (struct clk *);
45 struct clk *parent;
46 int reg, bit; /* CLK_HAS_CTRL */
47 int div_shift; /* only used by generic_div_clk_calc */
48};
49
50static LIST_HEAD(clocks);
51static DEFINE_MUTEX(clocks_mutex);
52
53static struct clk *mpc5121_clk_get(struct device *dev, const char *id)
54{
55 struct clk *p, *clk = ERR_PTR(-ENOENT);
56 int dev_match = 0;
57 int id_match = 0;
58
59 if (dev == NULL && id == NULL)
60 return NULL;
61
62 mutex_lock(&clocks_mutex);
63 list_for_each_entry(p, &clocks, node) {
64 if (dev && dev == p->dev)
65 dev_match++;
66 if (strcmp(id, p->name) == 0)
67 id_match++;
68 if ((dev_match || id_match) && try_module_get(p->owner)) {
69 clk = p;
70 break;
71 }
72 }
73 mutex_unlock(&clocks_mutex);
74
75 return clk;
76}
77
78#ifdef CLK_DEBUG
79static void dump_clocks(void)
80{
81 struct clk *p;
82
83 mutex_lock(&clocks_mutex);
84 printk(KERN_INFO "CLOCKS:\n");
85 list_for_each_entry(p, &clocks, node) {
86 printk(KERN_INFO " %s %ld", p->name, p->rate);
87 if (p->parent)
88 printk(KERN_INFO " %s %ld", p->parent->name,
89 p->parent->rate);
90 if (p->flags & CLK_HAS_CTRL)
91 printk(KERN_INFO " reg/bit %d/%d", p->reg, p->bit);
92 printk("\n");
93 }
94 mutex_unlock(&clocks_mutex);
95}
96#define DEBUG_CLK_DUMP() dump_clocks()
97#else
98#define DEBUG_CLK_DUMP()
99#endif
100
101
102static void mpc5121_clk_put(struct clk *clk)
103{
104 module_put(clk->owner);
105}
106
107#define NRPSC 12
108
109struct mpc512x_clockctl {
110 u32 spmr; /* System PLL Mode Reg */
111 u32 sccr[2]; /* System Clk Ctrl Reg 1 & 2 */
112 u32 scfr1; /* System Clk Freq Reg 1 */
113 u32 scfr2; /* System Clk Freq Reg 2 */
114 u32 reserved;
115 u32 bcr; /* Bread Crumb Reg */
116 u32 pccr[NRPSC]; /* PSC Clk Ctrl Reg 0-11 */
117 u32 spccr; /* SPDIF Clk Ctrl Reg */
118 u32 cccr; /* CFM Clk Ctrl Reg */
119 u32 dccr; /* DIU Clk Cnfg Reg */
120};
121
122struct mpc512x_clockctl __iomem *clockctl;
123
124static int mpc5121_clk_enable(struct clk *clk)
125{
126 unsigned int mask;
127
128 if (clk->flags & CLK_HAS_CTRL) {
129 mask = in_be32(&clockctl->sccr[clk->reg]);
130 mask |= 1 << clk->bit;
131 out_be32(&clockctl->sccr[clk->reg], mask);
132 }
133 return 0;
134}
135
136static void mpc5121_clk_disable(struct clk *clk)
137{
138 unsigned int mask;
139
140 if (clk->flags & CLK_HAS_CTRL) {
141 mask = in_be32(&clockctl->sccr[clk->reg]);
142 mask &= ~(1 << clk->bit);
143 out_be32(&clockctl->sccr[clk->reg], mask);
144 }
145}
146
147static unsigned long mpc5121_clk_get_rate(struct clk *clk)
148{
149 if (clk->flags & CLK_HAS_RATE)
150 return clk->rate;
151 else
152 return 0;
153}
154
155static long mpc5121_clk_round_rate(struct clk *clk, unsigned long rate)
156{
157 return rate;
158}
159
160static int mpc5121_clk_set_rate(struct clk *clk, unsigned long rate)
161{
162 return 0;
163}
164
165static int clk_register(struct clk *clk)
166{
167 mutex_lock(&clocks_mutex);
168 list_add(&clk->node, &clocks);
169 mutex_unlock(&clocks_mutex);
170 return 0;
171}
172
173static unsigned long spmf_mult(void)
174{
175 /*
176 * Convert spmf to multiplier
177 */
178 static int spmf_to_mult[] = {
179 68, 1, 12, 16,
180 20, 24, 28, 32,
181 36, 40, 44, 48,
182 52, 56, 60, 64
183 };
184 int spmf = (clockctl->spmr >> 24) & 0xf;
185 return spmf_to_mult[spmf];
186}
187
188static unsigned long sysdiv_div_x_2(void)
189{
190 /*
191 * Convert sysdiv to divisor x 2
192 * Some divisors have fractional parts so
193 * multiply by 2 then divide by this value
194 */
195 static int sysdiv_to_div_x_2[] = {
196 4, 5, 6, 7,
197 8, 9, 10, 14,
198 12, 16, 18, 22,
199 20, 24, 26, 30,
200 28, 32, 34, 38,
201 36, 40, 42, 46,
202 44, 48, 50, 54,
203 52, 56, 58, 62,
204 60, 64, 66,
205 };
206 int sysdiv = (clockctl->scfr2 >> 26) & 0x3f;
207 return sysdiv_to_div_x_2[sysdiv];
208}
209
210static unsigned long ref_to_sys(unsigned long rate)
211{
212 rate *= spmf_mult();
213 rate *= 2;
214 rate /= sysdiv_div_x_2();
215
216 return rate;
217}
218
219static unsigned long sys_to_ref(unsigned long rate)
220{
221 rate *= sysdiv_div_x_2();
222 rate /= 2;
223 rate /= spmf_mult();
224
225 return rate;
226}
227
228static long ips_to_ref(unsigned long rate)
229{
230 int ips_div = (clockctl->scfr1 >> 23) & 0x7;
231
232 rate *= ips_div; /* csb_clk = ips_clk * ips_div */
233 rate *= 2; /* sys_clk = csb_clk * 2 */
234 return sys_to_ref(rate);
235}
236
237static unsigned long devtree_getfreq(char *clockname)
238{
239 struct device_node *np;
240 const unsigned int *prop;
241 unsigned int val = 0;
242
243 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr");
244 if (np) {
245 prop = of_get_property(np, clockname, NULL);
246 if (prop)
247 val = *prop;
248 of_node_put(np);
249 }
250 return val;
251}
252
253static void ref_clk_calc(struct clk *clk)
254{
255 unsigned long rate;
256
257 rate = devtree_getfreq("bus-frequency");
258 if (rate == 0) {
259 printk(KERN_ERR "No bus-frequency in dev tree\n");
260 clk->rate = 0;
261 return;
262 }
263 clk->rate = ips_to_ref(rate);
264}
265
266static struct clk ref_clk = {
267 .name = "ref_clk",
268 .calc = ref_clk_calc,
269};
270
271
272static void sys_clk_calc(struct clk *clk)
273{
274 clk->rate = ref_to_sys(ref_clk.rate);
275}
276
277static struct clk sys_clk = {
278 .name = "sys_clk",
279 .calc = sys_clk_calc,
280};
281
282static void diu_clk_calc(struct clk *clk)
283{
284 int diudiv_x_2 = clockctl->scfr1 & 0xff;
285 unsigned long rate;
286
287 rate = sys_clk.rate;
288
289 rate *= 2;
290 rate /= diudiv_x_2;
291
292 clk->rate = rate;
293}
294
295static void half_clk_calc(struct clk *clk)
296{
297 clk->rate = clk->parent->rate / 2;
298}
299
300static void generic_div_clk_calc(struct clk *clk)
301{
302 int div = (clockctl->scfr1 >> clk->div_shift) & 0x7;
303
304 clk->rate = clk->parent->rate / div;
305}
306
307static void unity_clk_calc(struct clk *clk)
308{
309 clk->rate = clk->parent->rate;
310}
311
312static struct clk csb_clk = {
313 .name = "csb_clk",
314 .calc = half_clk_calc,
315 .parent = &sys_clk,
316};
317
318static void e300_clk_calc(struct clk *clk)
319{
320 int spmf = (clockctl->spmr >> 16) & 0xf;
321 int ratex2 = clk->parent->rate * spmf;
322
323 clk->rate = ratex2 / 2;
324}
325
326static struct clk e300_clk = {
327 .name = "e300_clk",
328 .calc = e300_clk_calc,
329 .parent = &csb_clk,
330};
331
332static struct clk ips_clk = {
333 .name = "ips_clk",
334 .calc = generic_div_clk_calc,
335 .parent = &csb_clk,
336 .div_shift = 23,
337};
338
339/*
340 * Clocks controlled by SCCR1 (.reg = 0)
341 */
342static struct clk lpc_clk = {
343 .name = "lpc_clk",
344 .flags = CLK_HAS_CTRL,
345 .reg = 0,
346 .bit = 30,
347 .calc = generic_div_clk_calc,
348 .parent = &ips_clk,
349 .div_shift = 11,
350};
351
352static struct clk nfc_clk = {
353 .name = "nfc_clk",
354 .flags = CLK_HAS_CTRL,
355 .reg = 0,
356 .bit = 29,
357 .calc = generic_div_clk_calc,
358 .parent = &ips_clk,
359 .div_shift = 8,
360};
361
362static struct clk pata_clk = {
363 .name = "pata_clk",
364 .flags = CLK_HAS_CTRL,
365 .reg = 0,
366 .bit = 28,
367 .calc = unity_clk_calc,
368 .parent = &ips_clk,
369};
370
371/*
372 * PSC clocks (bits 27 - 16)
373 * are setup elsewhere
374 */
375
376static struct clk sata_clk = {
377 .name = "sata_clk",
378 .flags = CLK_HAS_CTRL,
379 .reg = 0,
380 .bit = 14,
381 .calc = unity_clk_calc,
382 .parent = &ips_clk,
383};
384
385static struct clk fec_clk = {
386 .name = "fec_clk",
387 .flags = CLK_HAS_CTRL,
388 .reg = 0,
389 .bit = 13,
390 .calc = unity_clk_calc,
391 .parent = &ips_clk,
392};
393
394static struct clk pci_clk = {
395 .name = "pci_clk",
396 .flags = CLK_HAS_CTRL,
397 .reg = 0,
398 .bit = 11,
399 .calc = generic_div_clk_calc,
400 .parent = &csb_clk,
401 .div_shift = 20,
402};
403
404/*
405 * Clocks controlled by SCCR2 (.reg = 1)
406 */
407static struct clk diu_clk = {
408 .name = "diu_clk",
409 .flags = CLK_HAS_CTRL,
410 .reg = 1,
411 .bit = 31,
412 .calc = diu_clk_calc,
413};
414
415static struct clk axe_clk = {
416 .name = "axe_clk",
417 .flags = CLK_HAS_CTRL,
418 .reg = 1,
419 .bit = 30,
420 .calc = unity_clk_calc,
421 .parent = &csb_clk,
422};
423
424static struct clk usb1_clk = {
425 .name = "usb1_clk",
426 .flags = CLK_HAS_CTRL,
427 .reg = 1,
428 .bit = 28,
429 .calc = unity_clk_calc,
430 .parent = &csb_clk,
431};
432
433static struct clk usb2_clk = {
434 .name = "usb2_clk",
435 .flags = CLK_HAS_CTRL,
436 .reg = 1,
437 .bit = 27,
438 .calc = unity_clk_calc,
439 .parent = &csb_clk,
440};
441
442static struct clk i2c_clk = {
443 .name = "i2c_clk",
444 .flags = CLK_HAS_CTRL,
445 .reg = 1,
446 .bit = 26,
447 .calc = unity_clk_calc,
448 .parent = &ips_clk,
449};
450
451static struct clk mscan_clk = {
452 .name = "mscan_clk",
453 .flags = CLK_HAS_CTRL,
454 .reg = 1,
455 .bit = 25,
456 .calc = unity_clk_calc,
457 .parent = &ips_clk,
458};
459
460static struct clk sdhc_clk = {
461 .name = "sdhc_clk",
462 .flags = CLK_HAS_CTRL,
463 .reg = 1,
464 .bit = 24,
465 .calc = unity_clk_calc,
466 .parent = &ips_clk,
467};
468
469static struct clk mbx_bus_clk = {
470 .name = "mbx_bus_clk",
471 .flags = CLK_HAS_CTRL,
472 .reg = 1,
473 .bit = 22,
474 .calc = half_clk_calc,
475 .parent = &csb_clk,
476};
477
478static struct clk mbx_clk = {
479 .name = "mbx_clk",
480 .flags = CLK_HAS_CTRL,
481 .reg = 1,
482 .bit = 21,
483 .calc = unity_clk_calc,
484 .parent = &csb_clk,
485};
486
487static struct clk mbx_3d_clk = {
488 .name = "mbx_3d_clk",
489 .flags = CLK_HAS_CTRL,
490 .reg = 1,
491 .bit = 20,
492 .calc = generic_div_clk_calc,
493 .parent = &mbx_bus_clk,
494 .div_shift = 14,
495};
496
497static void psc_mclk_in_calc(struct clk *clk)
498{
499 clk->rate = devtree_getfreq("psc_mclk_in");
500 if (!clk->rate)
501 clk->rate = 25000000;
502}
503
504static struct clk psc_mclk_in = {
505 .name = "psc_mclk_in",
506 .calc = psc_mclk_in_calc,
507};
508
509static struct clk spdif_txclk = {
510 .name = "spdif_txclk",
511 .flags = CLK_HAS_CTRL,
512 .reg = 1,
513 .bit = 23,
514};
515
516static struct clk spdif_rxclk = {
517 .name = "spdif_rxclk",
518 .flags = CLK_HAS_CTRL,
519 .reg = 1,
520 .bit = 23,
521};
522
523static void ac97_clk_calc(struct clk *clk)
524{
525 /* ac97 bit clock is always 24.567 MHz */
526 clk->rate = 24567000;
527}
528
529static struct clk ac97_clk = {
530 .name = "ac97_clk_in",
531 .calc = ac97_clk_calc,
532};
533
534struct clk *rate_clks[] = {
535 &ref_clk,
536 &sys_clk,
537 &diu_clk,
538 &csb_clk,
539 &e300_clk,
540 &ips_clk,
541 &fec_clk,
542 &sata_clk,
543 &pata_clk,
544 &nfc_clk,
545 &lpc_clk,
546 &mbx_bus_clk,
547 &mbx_clk,
548 &mbx_3d_clk,
549 &axe_clk,
550 &usb1_clk,
551 &usb2_clk,
552 &i2c_clk,
553 &mscan_clk,
554 &sdhc_clk,
555 &pci_clk,
556 &psc_mclk_in,
557 &spdif_txclk,
558 &spdif_rxclk,
559 &ac97_clk,
560 NULL
561};
562
563static void rate_clk_init(struct clk *clk)
564{
565 if (clk->calc) {
566 clk->calc(clk);
567 clk->flags |= CLK_HAS_RATE;
568 clk_register(clk);
569 } else {
570 printk(KERN_WARNING
571 "Could not initialize clk %s without a calc routine\n",
572 clk->name);
573 }
574}
575
576static void rate_clks_init(void)
577{
578 struct clk **cpp, *clk;
579
580 cpp = rate_clks;
581 while ((clk = *cpp++))
582 rate_clk_init(clk);
583}
584
585/*
586 * There are two clk enable registers with 32 enable bits each
587 * psc clocks and device clocks are all stored in dev_clks
588 */
589struct clk dev_clks[2][32];
590
591/*
592 * Given a psc number return the dev_clk
593 * associated with it
594 */
595static struct clk *psc_dev_clk(int pscnum)
596{
597 int reg, bit;
598 struct clk *clk;
599
600 reg = 0;
601 bit = 27 - pscnum;
602
603 clk = &dev_clks[reg][bit];
604 clk->reg = 0;
605 clk->bit = bit;
606 return clk;
607}
608
609/*
610 * PSC clock rate calculation
611 */
612static void psc_calc_rate(struct clk *clk, int pscnum, struct device_node *np)
613{
614 unsigned long mclk_src = sys_clk.rate;
615 unsigned long mclk_div;
616
617 /*
618 * Can only change value of mclk divider
619 * when the divider is disabled.
620 *
621 * Zero is not a valid divider so minimum
622 * divider is 1
623 *
624 * disable/set divider/enable
625 */
626 out_be32(&clockctl->pccr[pscnum], 0);
627 out_be32(&clockctl->pccr[pscnum], 0x00020000);
628 out_be32(&clockctl->pccr[pscnum], 0x00030000);
629
630 if (clockctl->pccr[pscnum] & 0x80) {
631 clk->rate = spdif_rxclk.rate;
632 return;
633 }
634
635 switch ((clockctl->pccr[pscnum] >> 14) & 0x3) {
636 case 0:
637 mclk_src = sys_clk.rate;
638 break;
639 case 1:
640 mclk_src = ref_clk.rate;
641 break;
642 case 2:
643 mclk_src = psc_mclk_in.rate;
644 break;
645 case 3:
646 mclk_src = spdif_txclk.rate;
647 break;
648 }
649
650 mclk_div = ((clockctl->pccr[pscnum] >> 17) & 0x7fff) + 1;
651 clk->rate = mclk_src / mclk_div;
652}
653
654/*
655 * Find all psc nodes in device tree and assign a clock
656 * with name "psc%d_mclk" and dev pointing at the device
657 * returned from of_find_device_by_node
658 */
659static void psc_clks_init(void)
660{
661 struct device_node *np;
662 const u32 *cell_index;
663 struct of_device *ofdev;
664
665 for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
666 cell_index = of_get_property(np, "cell-index", NULL);
667 if (cell_index) {
668 int pscnum = *cell_index;
669 struct clk *clk = psc_dev_clk(pscnum);
670
671 clk->flags = CLK_HAS_RATE | CLK_HAS_CTRL;
672 ofdev = of_find_device_by_node(np);
673 clk->dev = &ofdev->dev;
674 /*
675 * AC97 is special rate clock does
676 * not go through normal path
677 */
678 if (strcmp("ac97", np->name) == 0)
679 clk->rate = ac97_clk.rate;
680 else
681 psc_calc_rate(clk, pscnum, np);
682 sprintf(clk->name, "psc%d_mclk", pscnum);
683 clk_register(clk);
684 clk_enable(clk);
685 }
686 }
687}
688
689static struct clk_interface mpc5121_clk_functions = {
690 .clk_get = mpc5121_clk_get,
691 .clk_enable = mpc5121_clk_enable,
692 .clk_disable = mpc5121_clk_disable,
693 .clk_get_rate = mpc5121_clk_get_rate,
694 .clk_put = mpc5121_clk_put,
695 .clk_round_rate = mpc5121_clk_round_rate,
696 .clk_set_rate = mpc5121_clk_set_rate,
697 .clk_set_parent = NULL,
698 .clk_get_parent = NULL,
699};
700
701static int
702mpc5121_clk_init(void)
703{
704 struct device_node *np;
705
706 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock");
707 if (np) {
708 clockctl = of_iomap(np, 0);
709 of_node_put(np);
710 }
711
712 if (!clockctl) {
713 printk(KERN_ERR "Could not map clock control registers\n");
714 return 0;
715 }
716
717 rate_clks_init();
718 psc_clks_init();
719
720 /* leave clockctl mapped forever */
721 /*iounmap(clockctl); */
722 DEBUG_CLK_DUMP();
723 clocks_initialized++;
724 clk_functions = mpc5121_clk_functions;
725 return 0;
726}
727
728
729arch_initcall(mpc5121_clk_init);
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
index 50bd3a319022..5ebf6939a697 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Thur Mar 29 2007 4 * Author: John Rigby, <jrigby@freescale.com>, Thur Mar 29 2007
5 * 5 *
@@ -15,7 +15,6 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/of_platform.h> 18#include <linux/of_platform.h>
20 19
21#include <asm/machdep.h> 20#include <asm/machdep.h>
@@ -23,65 +22,22 @@
23#include <asm/prom.h> 22#include <asm/prom.h>
24#include <asm/time.h> 23#include <asm/time.h>
25 24
26/** 25#include "mpc512x.h"
27 * mpc512x_find_ips_freq - Find the IPS bus frequency for a device 26#include "mpc5121_ads.h"
28 * @node: device node
29 *
30 * Returns IPS bus frequency, or 0 if the bus frequency cannot be found.
31 */
32unsigned long
33mpc512x_find_ips_freq(struct device_node *node)
34{
35 struct device_node *np;
36 const unsigned int *p_ips_freq = NULL;
37
38 of_node_get(node);
39 while (node) {
40 p_ips_freq = of_get_property(node, "bus-frequency", NULL);
41 if (p_ips_freq)
42 break;
43
44 np = of_get_parent(node);
45 of_node_put(node);
46 node = np;
47 }
48 if (node)
49 of_node_put(node);
50
51 return p_ips_freq ? *p_ips_freq : 0;
52}
53EXPORT_SYMBOL(mpc512x_find_ips_freq);
54
55static struct of_device_id __initdata of_bus_ids[] = {
56 { .name = "soc", },
57 { .name = "localbus", },
58 {},
59};
60 27
61static void __init mpc5121_ads_declare_of_platform_devices(void) 28static void __init mpc5121_ads_setup_arch(void)
62{ 29{
63 /* Find every child of the SOC node and add it to of_platform */ 30 printk(KERN_INFO "MPC5121 ADS board from Freescale Semiconductor\n");
64 if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) 31 /*
65 printk(KERN_ERR __FILE__ ": " 32 * cpld regs are needed early
66 "Error while probing of_platform bus\n"); 33 */
34 mpc5121_ads_cpld_map();
67} 35}
68 36
69static void __init mpc5121_ads_init_IRQ(void) 37static void __init mpc5121_ads_init_IRQ(void)
70{ 38{
71 struct device_node *np; 39 mpc512x_init_IRQ();
72 40 mpc5121_ads_cpld_pic_init();
73 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
74 if (!np)
75 return;
76
77 ipic_init(np, 0);
78 of_node_put(np);
79
80 /*
81 * Initialize the default interrupt mapping priorities,
82 * in case the boot rom changed something on us.
83 */
84 ipic_set_default_priority();
85} 41}
86 42
87/* 43/*
@@ -97,7 +53,8 @@ static int __init mpc5121_ads_probe(void)
97define_machine(mpc5121_ads) { 53define_machine(mpc5121_ads) {
98 .name = "MPC5121 ADS", 54 .name = "MPC5121 ADS",
99 .probe = mpc5121_ads_probe, 55 .probe = mpc5121_ads_probe,
100 .init = mpc5121_ads_declare_of_platform_devices, 56 .setup_arch = mpc5121_ads_setup_arch,
57 .init = mpc512x_declare_of_platform_devices,
101 .init_IRQ = mpc5121_ads_init_IRQ, 58 .init_IRQ = mpc5121_ads_init_IRQ,
102 .get_irq = ipic_get_irq, 59 .get_irq = ipic_get_irq,
103 .calibrate_decr = generic_calibrate_decr, 60 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.h b/arch/powerpc/platforms/512x/mpc5121_ads.h
new file mode 100644
index 000000000000..662076cfee2f
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.h
@@ -0,0 +1,16 @@
1/*
2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * Prototypes for ADS5121 specific code
10 */
11
12#ifndef __MPC512ADS_H__
13#define __MPC512ADS_H__
14extern void __init mpc5121_ads_cpld_map(void);
15extern void __init mpc5121_ads_cpld_pic_init(void);
16#endif /* __MPC512ADS_H__ */
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
new file mode 100644
index 000000000000..a6ce80566625
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -0,0 +1,204 @@
1/*
2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>
5 *
6 * Description:
7 * MPC5121ADS CPLD irq handling
8 *
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
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#undef DEBUG
16
17#include <linux/kernel.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/io.h>
21#include <asm/prom.h>
22
23static struct device_node *cpld_pic_node;
24static struct irq_host *cpld_pic_host;
25
26/*
27 * Bits to ignore in the misc_status register
28 * 0x10 touch screen pendown is hard routed to irq1
29 * 0x02 pci status is read from pci status register
30 */
31#define MISC_IGNORE 0x12
32
33/*
34 * Nothing to ignore in pci status register
35 */
36#define PCI_IGNORE 0x00
37
38struct cpld_pic {
39 u8 pci_mask;
40 u8 pci_status;
41 u8 route;
42 u8 misc_mask;
43 u8 misc_status;
44 u8 misc_control;
45};
46
47static struct cpld_pic __iomem *cpld_regs;
48
49static void __iomem *
50irq_to_pic_mask(unsigned int irq)
51{
52 return irq <= 7 ? &cpld_regs->pci_mask : &cpld_regs->misc_mask;
53}
54
55static unsigned int
56irq_to_pic_bit(unsigned int irq)
57{
58 return 1 << (irq & 0x7);
59}
60
61static void
62cpld_mask_irq(unsigned int irq)
63{
64 unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
65 void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
66
67 out_8(pic_mask,
68 in_8(pic_mask) | irq_to_pic_bit(cpld_irq));
69}
70
71static void
72cpld_unmask_irq(unsigned int irq)
73{
74 unsigned int cpld_irq = (unsigned int)irq_map[irq].hwirq;
75 void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
76
77 out_8(pic_mask,
78 in_8(pic_mask) & ~irq_to_pic_bit(cpld_irq));
79}
80
81static struct irq_chip cpld_pic = {
82 .typename = " CPLD PIC ",
83 .mask = cpld_mask_irq,
84 .ack = cpld_mask_irq,
85 .unmask = cpld_unmask_irq,
86};
87
88static int
89cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp,
90 u8 __iomem *maskp)
91{
92 int cpld_irq;
93 u8 status = in_8(statusp);
94 u8 mask = in_8(maskp);
95
96 /* ignore don't cares and masked irqs */
97 status |= (ignore | mask);
98
99 if (status == 0xff)
100 return NO_IRQ_IGNORE;
101
102 cpld_irq = ffz(status) + offset;
103
104 return irq_linear_revmap(cpld_pic_host, cpld_irq);
105}
106
107static void
108cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
109{
110 irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status,
111 &cpld_regs->pci_mask);
112 if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
113 generic_handle_irq(irq);
114 return;
115 }
116
117 irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status,
118 &cpld_regs->misc_mask);
119 if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
120 generic_handle_irq(irq);
121 return;
122 }
123}
124
125static int
126cpld_pic_host_match(struct irq_host *h, struct device_node *node)
127{
128 return cpld_pic_node == node;
129}
130
131static int
132cpld_pic_host_map(struct irq_host *h, unsigned int virq,
133 irq_hw_number_t hw)
134{
135 get_irq_desc(virq)->status |= IRQ_LEVEL;
136 set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq);
137 return 0;
138}
139
140static struct
141irq_host_ops cpld_pic_host_ops = {
142 .match = cpld_pic_host_match,
143 .map = cpld_pic_host_map,
144};
145
146void __init
147mpc5121_ads_cpld_map(void)
148{
149 struct device_node *np = NULL;
150
151 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld-pic");
152 if (!np) {
153 printk(KERN_ERR "CPLD PIC init: can not find cpld-pic node\n");
154 return;
155 }
156
157 cpld_regs = of_iomap(np, 0);
158 of_node_put(np);
159}
160
161void __init
162mpc5121_ads_cpld_pic_init(void)
163{
164 unsigned int cascade_irq;
165 struct device_node *np = NULL;
166
167 pr_debug("cpld_ic_init\n");
168
169 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld-pic");
170 if (!np) {
171 printk(KERN_ERR "CPLD PIC init: can not find cpld-pic node\n");
172 return;
173 }
174
175 if (!cpld_regs)
176 goto end;
177
178 cascade_irq = irq_of_parse_and_map(np, 0);
179 if (cascade_irq == NO_IRQ)
180 goto end;
181
182 /*
183 * statically route touch screen pendown through 1
184 * and ignore it here
185 * route all others through our cascade irq
186 */
187 out_8(&cpld_regs->route, 0xfd);
188 out_8(&cpld_regs->pci_mask, 0xff);
189 /* unmask pci ints in misc mask */
190 out_8(&cpld_regs->misc_mask, ~(MISC_IGNORE));
191
192 cpld_pic_node = of_node_get(np);
193
194 cpld_pic_host =
195 irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
196 if (!cpld_pic_host) {
197 printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
198 goto end;
199 }
200
201 set_irq_chained_handler(cascade_irq, cpld_pic_cascade);
202end:
203 of_node_put(np);
204}
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c
new file mode 100644
index 000000000000..2479de9e2d12
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_generic.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>
5 *
6 * Description:
7 * MPC5121 SoC setup
8 *
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
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/of_platform.h>
18
19#include <asm/machdep.h>
20#include <asm/ipic.h>
21#include <asm/prom.h>
22#include <asm/time.h>
23
24#include "mpc512x.h"
25
26/*
27 * list of supported boards
28 */
29static char *board[] __initdata = {
30 "prt,prtlvt",
31 NULL
32};
33
34/*
35 * Called very early, MMU is off, device-tree isn't unflattened
36 */
37static int __init mpc5121_generic_probe(void)
38{
39 unsigned long node = of_get_flat_dt_root();
40 int i = 0;
41
42 while (board[i]) {
43 if (of_flat_dt_is_compatible(node, board[i]))
44 break;
45 i++;
46 }
47
48 return board[i] != NULL;
49}
50
51define_machine(mpc5121_generic) {
52 .name = "MPC5121 generic",
53 .probe = mpc5121_generic_probe,
54 .init = mpc512x_declare_of_platform_devices,
55 .init_IRQ = mpc512x_init_IRQ,
56 .get_irq = ipic_get_irq,
57 .calibrate_decr = generic_calibrate_decr,
58};
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h
new file mode 100644
index 000000000000..9c03693cb009
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc512x.h
@@ -0,0 +1,17 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * Prototypes for MPC512x shared code
10 */
11
12#ifndef __MPC512X_H__
13#define __MPC512X_H__
14extern unsigned long mpc512x_find_ips_freq(struct device_node *node);
15extern void __init mpc512x_init_IRQ(void);
16void __init mpc512x_declare_of_platform_devices(void);
17#endif /* __MPC512X_H__ */
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
new file mode 100644
index 000000000000..d8cd579f3191
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -0,0 +1,83 @@
1/*
2 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby <jrigby@freescale.com>
5 *
6 * Description:
7 * MPC512x Shared code
8 *
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
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#include <linux/kernel.h>
16#include <linux/io.h>
17#include <linux/irq.h>
18#include <linux/of_platform.h>
19
20#include <asm/machdep.h>
21#include <asm/ipic.h>
22#include <asm/prom.h>
23#include <asm/time.h>
24
25#include "mpc512x.h"
26
27unsigned long
28mpc512x_find_ips_freq(struct device_node *node)
29{
30 struct device_node *np;
31 const unsigned int *p_ips_freq = NULL;
32
33 of_node_get(node);
34 while (node) {
35 p_ips_freq = of_get_property(node, "bus-frequency", NULL);
36 if (p_ips_freq)
37 break;
38
39 np = of_get_parent(node);
40 of_node_put(node);
41 node = np;
42 }
43 if (node)
44 of_node_put(node);
45
46 return p_ips_freq ? *p_ips_freq : 0;
47}
48EXPORT_SYMBOL(mpc512x_find_ips_freq);
49
50void __init mpc512x_init_IRQ(void)
51{
52 struct device_node *np;
53
54 np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-ipic");
55 if (!np)
56 return;
57
58 ipic_init(np, 0);
59 of_node_put(np);
60
61 /*
62 * Initialize the default interrupt mapping priorities,
63 * in case the boot rom changed something on us.
64 */
65 ipic_set_default_priority();
66}
67
68/*
69 * Nodes to do bus probe on, soc and localbus
70 */
71static struct of_device_id __initdata of_bus_ids[] = {
72 { .compatible = "fsl,mpc5121-immr", },
73 { .compatible = "fsl,mpc5121-localbus", },
74 {},
75};
76
77void __init mpc512x_declare_of_platform_devices(void)
78{
79 if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
80 printk(KERN_ERR __FILE__ ": "
81 "Error while probing of_platform bus\n");
82}
83
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index 41c7fd91e99e..fe92e65103ed 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -14,6 +14,7 @@ static struct mpc52xx_sdma __iomem *bes;
14static struct mpc52xx_xlb __iomem *xlb; 14static struct mpc52xx_xlb __iomem *xlb;
15static struct mpc52xx_gpio __iomem *gps; 15static struct mpc52xx_gpio __iomem *gps;
16static struct mpc52xx_gpio_wkup __iomem *gpw; 16static struct mpc52xx_gpio_wkup __iomem *gpw;
17static void __iomem *pci;
17static void __iomem *sram; 18static void __iomem *sram;
18static const int sram_size = 0x4000; /* 16 kBytes */ 19static const int sram_size = 0x4000; /* 16 kBytes */
19static void __iomem *mbar; 20static void __iomem *mbar;
@@ -50,6 +51,8 @@ static int lite5200_pm_prepare(void)
50 { .type = "builtin", .compatible = "mpc5200", }, /* efika */ 51 { .type = "builtin", .compatible = "mpc5200", }, /* efika */
51 {} 52 {}
52 }; 53 };
54 u64 regaddr64 = 0;
55 const u32 *regaddr_p;
53 56
54 /* deep sleep? let mpc52xx code handle that */ 57 /* deep sleep? let mpc52xx code handle that */
55 if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) 58 if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
@@ -60,8 +63,12 @@ static int lite5200_pm_prepare(void)
60 63
61 /* map registers */ 64 /* map registers */
62 np = of_find_matching_node(NULL, immr_ids); 65 np = of_find_matching_node(NULL, immr_ids);
63 mbar = of_iomap(np, 0); 66 regaddr_p = of_get_address(np, 0, NULL, NULL);
67 if (regaddr_p)
68 regaddr64 = of_translate_address(np, regaddr_p);
64 of_node_put(np); 69 of_node_put(np);
70
71 mbar = ioremap((u32) regaddr64, 0xC000);
65 if (!mbar) { 72 if (!mbar) {
66 printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); 73 printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
67 return -ENOSYS; 74 return -ENOSYS;
@@ -71,6 +78,7 @@ static int lite5200_pm_prepare(void)
71 pic = mbar + 0x500; 78 pic = mbar + 0x500;
72 gps = mbar + 0xb00; 79 gps = mbar + 0xb00;
73 gpw = mbar + 0xc00; 80 gpw = mbar + 0xc00;
81 pci = mbar + 0xd00;
74 bes = mbar + 0x1200; 82 bes = mbar + 0x1200;
75 xlb = mbar + 0x1f00; 83 xlb = mbar + 0x1f00;
76 sram = mbar + 0x8000; 84 sram = mbar + 0x8000;
@@ -85,6 +93,7 @@ static struct mpc52xx_sdma sbes;
85static struct mpc52xx_xlb sxlb; 93static struct mpc52xx_xlb sxlb;
86static struct mpc52xx_gpio sgps; 94static struct mpc52xx_gpio sgps;
87static struct mpc52xx_gpio_wkup sgpw; 95static struct mpc52xx_gpio_wkup sgpw;
96static char spci[0x200];
88 97
89static void lite5200_save_regs(void) 98static void lite5200_save_regs(void)
90{ 99{
@@ -94,6 +103,7 @@ static void lite5200_save_regs(void)
94 _memcpy_fromio(&sxlb, xlb, sizeof(*xlb)); 103 _memcpy_fromio(&sxlb, xlb, sizeof(*xlb));
95 _memcpy_fromio(&sgps, gps, sizeof(*gps)); 104 _memcpy_fromio(&sgps, gps, sizeof(*gps));
96 _memcpy_fromio(&sgpw, gpw, sizeof(*gpw)); 105 _memcpy_fromio(&sgpw, gpw, sizeof(*gpw));
106 _memcpy_fromio(spci, pci, 0x200);
97 107
98 _memcpy_fromio(saved_sram, sram, sram_size); 108 _memcpy_fromio(saved_sram, sram, sram_size);
99} 109}
@@ -103,6 +113,8 @@ static void lite5200_restore_regs(void)
103 int i; 113 int i;
104 _memcpy_toio(sram, saved_sram, sram_size); 114 _memcpy_toio(sram, saved_sram, sram_size);
105 115
116 /* PCI Configuration */
117 _memcpy_toio(pci, spci, 0x200);
106 118
107 /* 119 /*
108 * GPIOs. Interrupt Master Enable has higher address then other 120 * GPIOs. Interrupt Master Enable has higher address then other
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
index 48da5dfe4856..8a455ebce98d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
@@ -100,7 +100,7 @@ static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
100 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 100 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
101 struct mpc52xx_gpiochip *chip = container_of(mm_gc, 101 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
102 struct mpc52xx_gpiochip, mmchip); 102 struct mpc52xx_gpiochip, mmchip);
103 struct mpc52xx_gpio_wkup *regs = mm_gc->regs; 103 struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
104 unsigned long flags; 104 unsigned long flags;
105 105
106 spin_lock_irqsave(&gpio_lock, flags); 106 spin_lock_irqsave(&gpio_lock, flags);
@@ -122,7 +122,7 @@ static int
122mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 122mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
123{ 123{
124 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 124 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
125 struct mpc52xx_gpio_wkup *regs = mm_gc->regs; 125 struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
126 struct mpc52xx_gpiochip *chip = container_of(mm_gc, 126 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
127 struct mpc52xx_gpiochip, mmchip); 127 struct mpc52xx_gpiochip, mmchip);
128 unsigned long flags; 128 unsigned long flags;
@@ -150,7 +150,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
150 const struct of_device_id *match) 150 const struct of_device_id *match)
151{ 151{
152 struct mpc52xx_gpiochip *chip; 152 struct mpc52xx_gpiochip *chip;
153 struct mpc52xx_gpio_wkup *regs; 153 struct mpc52xx_gpio_wkup __iomem *regs;
154 struct of_gpio_chip *ofchip; 154 struct of_gpio_chip *ofchip;
155 int ret; 155 int ret;
156 156
@@ -260,7 +260,7 @@ static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
260 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 260 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
261 struct mpc52xx_gpiochip *chip = container_of(mm_gc, 261 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
262 struct mpc52xx_gpiochip, mmchip); 262 struct mpc52xx_gpiochip, mmchip);
263 struct mpc52xx_gpio *regs = mm_gc->regs; 263 struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
264 unsigned long flags; 264 unsigned long flags;
265 265
266 spin_lock_irqsave(&gpio_lock, flags); 266 spin_lock_irqsave(&gpio_lock, flags);
@@ -284,7 +284,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
284 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 284 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
285 struct mpc52xx_gpiochip *chip = container_of(mm_gc, 285 struct mpc52xx_gpiochip *chip = container_of(mm_gc,
286 struct mpc52xx_gpiochip, mmchip); 286 struct mpc52xx_gpiochip, mmchip);
287 struct mpc52xx_gpio *regs = mm_gc->regs; 287 struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
288 unsigned long flags; 288 unsigned long flags;
289 289
290 spin_lock_irqsave(&gpio_lock, flags); 290 spin_lock_irqsave(&gpio_lock, flags);
@@ -312,7 +312,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
312{ 312{
313 struct mpc52xx_gpiochip *chip; 313 struct mpc52xx_gpiochip *chip;
314 struct of_gpio_chip *ofchip; 314 struct of_gpio_chip *ofchip;
315 struct mpc52xx_gpio *regs; 315 struct mpc52xx_gpio __iomem *regs;
316 int ret; 316 int ret;
317 317
318 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 318 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -387,7 +387,7 @@ mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
387static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 387static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
388{ 388{
389 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 389 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
390 struct mpc52xx_gpt *regs = mm_gc->regs; 390 struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
391 391
392 out_be32(&regs->mode, 0x04); 392 out_be32(&regs->mode, 0x04);
393 393
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index e3428ddd9040..5a382bb15f62 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -63,6 +63,7 @@
63 63
64#define MPC52xx_PCI_TCR_P 0x01000000 64#define MPC52xx_PCI_TCR_P 0x01000000
65#define MPC52xx_PCI_TCR_LD 0x00010000 65#define MPC52xx_PCI_TCR_LD 0x00010000
66#define MPC52xx_PCI_TCR_WCT8 0x00000008
66 67
67#define MPC52xx_PCI_TBATR_DISABLE 0x0 68#define MPC52xx_PCI_TBATR_DISABLE 0x0
68#define MPC52xx_PCI_TBATR_ENABLE 0x1 69#define MPC52xx_PCI_TBATR_ENABLE 0x1
@@ -313,7 +314,7 @@ mpc52xx_pci_setup(struct pci_controller *hose,
313 out_be32(&pci_regs->tbatr1, 314 out_be32(&pci_regs->tbatr1,
314 MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM ); 315 MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
315 316
316 out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD); 317 out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8);
317 318
318 tmp = in_be32(&pci_regs->gscr); 319 tmp = in_be32(&pci_regs->gscr);
319#if 0 320#if 0
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
index 917ac8891555..1c8034bfa796 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -1,7 +1,8 @@
1choice 1menuconfig PPC_82xx
2 prompt "82xx Board Type" 2 bool "82xx-based boards (PQ II)"
3 depends on PPC_82xx 3 depends on 6xx && PPC_MULTIPLATFORM
4 default MPC8272_ADS 4
5if PPC_82xx
5 6
6config MPC8272_ADS 7config MPC8272_ADS
7 bool "Freescale MPC8272 ADS" 8 bool "Freescale MPC8272 ADS"
@@ -36,7 +37,7 @@ config EP8248E
36 This board is also resold by Freescale as the QUICCStart 37 This board is also resold by Freescale as the QUICCStart
37 MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE. 38 MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE.
38 39
39endchoice 40endif
40 41
41config PQ2ADS 42config PQ2ADS
42 bool 43 bool
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index d5770fdf7f09..373e993a5ed5 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -59,6 +59,7 @@ static void __init ep8248e_pic_init(void)
59 of_node_put(np); 59 of_node_put(np);
60} 60}
61 61
62#ifdef CONFIG_FS_ENET_MDIO_FCC
62static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level) 63static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level)
63{ 64{
64 if (level) 65 if (level)
@@ -164,6 +165,7 @@ static struct of_platform_driver ep8248e_mdio_driver = {
164 .probe = ep8248e_mdio_probe, 165 .probe = ep8248e_mdio_probe,
165 .remove = ep8248e_mdio_remove, 166 .remove = ep8248e_mdio_remove,
166}; 167};
168#endif
167 169
168struct cpm_pin { 170struct cpm_pin {
169 int port, pin, flags; 171 int port, pin, flags;
@@ -296,7 +298,9 @@ static __initdata struct of_device_id of_bus_ids[] = {
296static int __init declare_of_platform_devices(void) 298static int __init declare_of_platform_devices(void)
297{ 299{
298 of_platform_bus_probe(NULL, of_bus_ids, NULL); 300 of_platform_bus_probe(NULL, of_bus_ids, NULL);
301#ifdef CONFIG_FS_ENET_MDIO_FCC
299 of_register_platform_driver(&ep8248e_mdio_driver); 302 of_register_platform_driver(&ep8248e_mdio_driver);
303#endif
300 304
301 return 0; 305 return 0;
302} 306}
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 7d3018751988..8054c685d323 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -96,6 +96,10 @@ static struct cpm_pin mpc8272_ads_pins[] = {
96 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 96 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
97 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 97 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
98 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 98 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
99
100 /* I2C */
101 {3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
102 {3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
99}; 103};
100 104
101static void __init init_ioports(void) 105static void __init init_ioports(void)
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index a8013816125c..9876d7e072f4 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -109,7 +109,7 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
109{ 109{
110 get_irq_desc(virq)->status |= IRQ_LEVEL; 110 get_irq_desc(virq)->status |= IRQ_LEVEL;
111 set_irq_chip_data(virq, h->host_data); 111 set_irq_chip_data(virq, h->host_data);
112 set_irq_chip(virq, &pq2ads_pci_ic); 112 set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq);
113 return 0; 113 return 0;
114} 114}
115 115
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 13587e2e8680..27d9bf86de01 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -1,10 +1,12 @@
1menuconfig MPC83xx 1menuconfig PPC_83xx
2 bool "83xx Board Type" 2 bool "83xx-based boards"
3 depends on PPC_83xx 3 depends on 6xx && PPC_MULTIPLATFORM
4 select PPC_UDBG_16550 4 select PPC_UDBG_16550
5 select PPC_INDIRECT_PCI 5 select PPC_INDIRECT_PCI
6 select FSL_SOC
7 select IPIC
6 8
7if MPC83xx 9if PPC_83xx
8 10
9config MPC831x_RDB 11config MPC831x_RDB
10 bool "Freescale MPC831x RDB" 12 bool "Freescale MPC831x RDB"
@@ -58,6 +60,17 @@ config MPC836x_MDS
58 help 60 help
59 This option enables support for the MPC836x MDS Processor Board. 61 This option enables support for the MPC836x MDS Processor Board.
60 62
63config MPC836x_RDK
64 bool "Freescale/Logic MPC836x RDK"
65 select DEFAULT_UIMAGE
66 select QUICC_ENGINE
67 select QE_GPIO
68 select FSL_GTM
69 select FSL_LBC
70 help
71 This option enables support for the MPC836x RDK Processor Board,
72 also known as ZOOM PowerQUICC Kit.
73
61config MPC837x_MDS 74config MPC837x_MDS
62 bool "Freescale MPC837x MDS" 75 bool "Freescale MPC837x MDS"
63 select DEFAULT_UIMAGE 76 select DEFAULT_UIMAGE
@@ -79,6 +92,15 @@ config SBC834x
79 help 92 help
80 This option enables support for the Wind River SBC834x board. 93 This option enables support for the Wind River SBC834x board.
81 94
95config ASP834x
96 bool "Analogue & Micro ASP 834x"
97 select PPC_MPC834x
98 select REDBOOT
99 help
100 This enables support for the Analogue & Micro ASP 83xx
101 board.
102
103
82endif 104endif
83 105
84# used for usb 106# used for usb
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 7e6dd3e259d8..f331fd7dd836 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -8,7 +8,9 @@ obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o
8obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o 8obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o
9obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o 9obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
10obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o 10obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o
11obj-$(CONFIG_MPC836x_RDK) += mpc836x_rdk.o
11obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o 12obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o
12obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o 13obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
13obj-$(CONFIG_SBC834x) += sbc834x.o 14obj-$(CONFIG_SBC834x) += sbc834x.o
14obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o 15obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o
16obj-$(CONFIG_ASP834x) += asp834x.o
diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c
new file mode 100644
index 000000000000..bb30d67ad0a2
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/asp834x.c
@@ -0,0 +1,90 @@
1/*
2 * arch/powerpc/platforms/83xx/asp834x.c
3 *
4 * Analogue & Micro ASP8347 board specific routines
5 * clone of mpc834x_itx
6 *
7 * Copyright 2008 Codehermit
8 *
9 * Maintainer: Bryan O'Donoghue <bodonoghue@codhermit.ie>
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/pci.h>
18#include <linux/of_platform.h>
19
20#include <asm/time.h>
21#include <asm/ipic.h>
22#include <asm/udbg.h>
23
24#include "mpc83xx.h"
25
26/* ************************************************************************
27 *
28 * Setup the architecture
29 *
30 */
31static void __init asp834x_setup_arch(void)
32{
33 if (ppc_md.progress)
34 ppc_md.progress("asp834x_setup_arch()", 0);
35
36 mpc834x_usb_cfg();
37}
38
39static void __init asp834x_init_IRQ(void)
40{
41 struct device_node *np;
42
43 np = of_find_node_by_type(NULL, "ipic");
44 if (!np)
45 return;
46
47 ipic_init(np, 0);
48
49 of_node_put(np);
50
51 /* Initialize the default interrupt mapping priorities,
52 * in case the boot rom changed something on us.
53 */
54 ipic_set_default_priority();
55}
56
57static struct __initdata of_device_id asp8347_ids[] = {
58 { .type = "soc", },
59 { .compatible = "soc", },
60 { .compatible = "simple-bus", },
61 {},
62};
63
64static int __init asp8347_declare_of_platform_devices(void)
65{
66 of_platform_bus_probe(NULL, asp8347_ids, NULL);
67 return 0;
68}
69machine_device_initcall(asp834x, asp8347_declare_of_platform_devices);
70
71/*
72 * Called very early, MMU is off, device-tree isn't unflattened
73 */
74static int __init asp834x_probe(void)
75{
76 unsigned long root = of_get_flat_dt_root();
77 return of_flat_dt_is_compatible(root, "analogue-and-micro,asp8347e");
78}
79
80define_machine(asp834x) {
81 .name = "ASP8347E",
82 .probe = asp834x_probe,
83 .setup_arch = asp834x_setup_arch,
84 .init_IRQ = asp834x_init_IRQ,
85 .get_irq = ipic_get_irq,
86 .restart = mpc83xx_restart,
87 .time_init = mpc83xx_time_init,
88 .calibrate_decr = generic_calibrate_decr,
89 .progress = udbg_progress,
90};
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
new file mode 100644
index 000000000000..c10dec4bf178
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
@@ -0,0 +1,102 @@
1/*
2 * MPC8360E-RDK board file.
3 *
4 * Copyright (c) 2006 Freescale Semicondutor, Inc.
5 * Copyright (c) 2007-2008 MontaVista Software, Inc.
6 *
7 * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/kernel.h>
16#include <linux/pci.h>
17#include <linux/of_platform.h>
18#include <linux/io.h>
19#include <asm/prom.h>
20#include <asm/time.h>
21#include <asm/ipic.h>
22#include <asm/udbg.h>
23#include <asm/qe.h>
24#include <asm/qe_ic.h>
25#include <sysdev/fsl_soc.h>
26
27#include "mpc83xx.h"
28
29static struct of_device_id __initdata mpc836x_rdk_ids[] = {
30 { .compatible = "simple-bus", },
31 {},
32};
33
34static int __init mpc836x_rdk_declare_of_platform_devices(void)
35{
36 return of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL);
37}
38machine_device_initcall(mpc836x_rdk, mpc836x_rdk_declare_of_platform_devices);
39
40static void __init mpc836x_rdk_setup_arch(void)
41{
42#ifdef CONFIG_PCI
43 struct device_node *np;
44#endif
45
46 if (ppc_md.progress)
47 ppc_md.progress("mpc836x_rdk_setup_arch()", 0);
48
49#ifdef CONFIG_PCI
50 for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
51 mpc83xx_add_bridge(np);
52#endif
53
54 qe_reset();
55}
56
57static void __init mpc836x_rdk_init_IRQ(void)
58{
59 struct device_node *np;
60
61 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
62 if (!np)
63 return;
64
65 ipic_init(np, 0);
66
67 /*
68 * Initialize the default interrupt mapping priorities,
69 * in case the boot rom changed something on us.
70 */
71 ipic_set_default_priority();
72 of_node_put(np);
73
74 np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
75 if (!np)
76 return;
77
78 qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic);
79 of_node_put(np);
80}
81
82/*
83 * Called very early, MMU is off, device-tree isn't unflattened.
84 */
85static int __init mpc836x_rdk_probe(void)
86{
87 unsigned long root = of_get_flat_dt_root();
88
89 return of_flat_dt_is_compatible(root, "fsl,mpc8360rdk");
90}
91
92define_machine(mpc836x_rdk) {
93 .name = "MPC836x RDK",
94 .probe = mpc836x_rdk_probe,
95 .setup_arch = mpc836x_rdk_setup_arch,
96 .init_IRQ = mpc836x_rdk_init_IRQ,
97 .get_irq = ipic_get_irq,
98 .restart = mpc83xx_restart,
99 .time_init = mpc83xx_time_init,
100 .calibrate_decr = generic_calibrate_decr,
101 .progress = udbg_progress,
102};
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 7ff29d53dc2d..cebea5cadbc1 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -34,9 +34,16 @@ config MPC85xx_MDS
34 bool "Freescale MPC85xx MDS" 34 bool "Freescale MPC85xx MDS"
35 select DEFAULT_UIMAGE 35 select DEFAULT_UIMAGE
36 select QUICC_ENGINE 36 select QUICC_ENGINE
37 select PHYLIB
37 help 38 help
38 This option enables support for the MPC85xx MDS board 39 This option enables support for the MPC85xx MDS board
39 40
41config MPC8536_DS
42 bool "Freescale MPC8536 DS"
43 select DEFAULT_UIMAGE
44 help
45 This option enables support for the MPC8536 DS board
46
40config MPC85xx_DS 47config MPC85xx_DS
41 bool "Freescale MPC85xx DS" 48 bool "Freescale MPC85xx DS"
42 select PPC_I8259 49 select PPC_I8259
@@ -74,6 +81,14 @@ config TQM8541
74 select TQM85xx 81 select TQM85xx
75 select CPM2 82 select CPM2
76 83
84config TQM8548
85 bool "TQ Components TQM8548"
86 help
87 This option enables support for the TQ Components TQM8548 board.
88 select DEFAULT_UIMAGE
89 select PPC_CPM_NEW_BINDING
90 select TQM85xx
91
77config TQM8555 92config TQM8555
78 bool "TQ Components TQM8555" 93 bool "TQ Components TQM8555"
79 help 94 help
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 6cea185f62b2..cb3054e1001d 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -4,6 +4,7 @@
4obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o 4obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
5obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o 5obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
6obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o 6obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
7obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o
7obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o 8obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
8obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o 9obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
9obj-$(CONFIG_STX_GP3) += stx_gp3.o 10obj-$(CONFIG_STX_GP3) += stx_gp3.o
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
new file mode 100644
index 000000000000..6b846aa1ced9
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -0,0 +1,125 @@
1/*
2 * MPC8536 DS Board Setup
3 *
4 * Copyright 2008 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <linux/stddef.h>
13#include <linux/kernel.h>
14#include <linux/pci.h>
15#include <linux/kdev_t.h>
16#include <linux/delay.h>
17#include <linux/seq_file.h>
18#include <linux/interrupt.h>
19#include <linux/of_platform.h>
20
21#include <asm/system.h>
22#include <asm/time.h>
23#include <asm/machdep.h>
24#include <asm/pci-bridge.h>
25#include <mm/mmu_decl.h>
26#include <asm/prom.h>
27#include <asm/udbg.h>
28#include <asm/mpic.h>
29
30#include <sysdev/fsl_soc.h>
31#include <sysdev/fsl_pci.h>
32
33void __init mpc8536_ds_pic_init(void)
34{
35 struct mpic *mpic;
36 struct resource r;
37 struct device_node *np;
38
39 np = of_find_node_by_type(NULL, "open-pic");
40 if (np == NULL) {
41 printk(KERN_ERR "Could not find open-pic node\n");
42 return;
43 }
44
45 if (of_address_to_resource(np, 0, &r)) {
46 printk(KERN_ERR "Failed to map mpic register space\n");
47 of_node_put(np);
48 return;
49 }
50
51 mpic = mpic_alloc(np, r.start,
52 MPIC_PRIMARY | MPIC_WANTS_RESET |
53 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
54 0, 256, " OpenPIC ");
55 BUG_ON(mpic == NULL);
56 of_node_put(np);
57
58 mpic_init(mpic);
59}
60
61/*
62 * Setup the architecture
63 */
64static void __init mpc8536_ds_setup_arch(void)
65{
66#ifdef CONFIG_PCI
67 struct device_node *np;
68#endif
69
70 if (ppc_md.progress)
71 ppc_md.progress("mpc8536_ds_setup_arch()", 0);
72
73#ifdef CONFIG_PCI
74 for_each_node_by_type(np, "pci") {
75 if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
76 of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
77 struct resource rsrc;
78 of_address_to_resource(np, 0, &rsrc);
79 if ((rsrc.start & 0xfffff) == 0x8000)
80 fsl_add_bridge(np, 1);
81 else
82 fsl_add_bridge(np, 0);
83 }
84 }
85
86#endif
87
88 printk("MPC8536 DS board from Freescale Semiconductor\n");
89}
90
91static struct of_device_id __initdata mpc8536_ds_ids[] = {
92 { .type = "soc", },
93 { .compatible = "soc", },
94 {},
95};
96
97static int __init mpc8536_ds_publish_devices(void)
98{
99 return of_platform_bus_probe(NULL, mpc8536_ds_ids, NULL);
100}
101machine_device_initcall(mpc8536_ds, mpc8536_ds_publish_devices);
102
103/*
104 * Called very early, device-tree isn't unflattened
105 */
106static int __init mpc8536_ds_probe(void)
107{
108 unsigned long root = of_get_flat_dt_root();
109
110 return of_flat_dt_is_compatible(root, "fsl,mpc8536ds");
111}
112
113define_machine(mpc8536_ds) {
114 .name = "MPC8536 DS",
115 .probe = mpc8536_ds_probe,
116 .setup_arch = mpc8536_ds_setup_arch,
117 .init_IRQ = mpc8536_ds_pic_init,
118#ifdef CONFIG_PCI
119 .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
120#endif
121 .get_irq = mpic_get_irq,
122 .restart = fsl_rstcr_restart,
123 .calibrate_decr = generic_calibrate_decr,
124 .progress = udbg_progress,
125};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 3582c841844b..ba498d6f2d02 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -119,6 +119,8 @@ static const struct cpm_pin mpc8560_ads_pins[] = {
119 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 119 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
120 120
121 /* SCC2 */ 121 /* SCC2 */
122 {2, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
123 {2, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
122 {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 124 {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
123 {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 125 {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
124 {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 126 {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
@@ -145,7 +147,6 @@ static const struct cpm_pin mpc8560_ads_pins[] = {
145 {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 147 {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
146 {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 148 {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
147 {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 149 {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
148 {1, 7, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
149 {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 150 {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
150 {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 151 {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
151 {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 152 {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
@@ -156,8 +157,9 @@ static const struct cpm_pin mpc8560_ads_pins[] = {
156 {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 157 {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
157 {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 158 {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
158 {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 159 {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
159 {2, 16, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK16 */ 160 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK16 */
160 {2, 17, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* CLK15 */ 161 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK15 */
162 {2, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
161}; 163};
162 164
163static void __init init_ioports(void) 165static void __init init_ioports(void)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 8b1de7884be6..50d7ea8f922b 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -26,6 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/fsl_devices.h> 28#include <linux/fsl_devices.h>
29#include <linux/of_platform.h>
29 30
30#include <asm/system.h> 31#include <asm/system.h>
31#include <asm/pgtable.h> 32#include <asm/pgtable.h>
@@ -335,6 +336,19 @@ static int __init mpc85xx_cds_probe(void)
335 return of_flat_dt_is_compatible(root, "MPC85xxCDS"); 336 return of_flat_dt_is_compatible(root, "MPC85xxCDS");
336} 337}
337 338
339static struct of_device_id __initdata of_bus_ids[] = {
340 { .type = "soc", },
341 { .compatible = "soc", },
342 { .compatible = "simple-bus", },
343 {},
344};
345
346static int __init declare_of_platform_devices(void)
347{
348 return of_platform_bus_probe(NULL, of_bus_ids, NULL);
349}
350machine_device_initcall(mpc85xx_cds, declare_of_platform_devices);
351
338define_machine(mpc85xx_cds) { 352define_machine(mpc85xx_cds) {
339 .name = "MPC85xx CDS", 353 .name = "MPC85xx CDS",
340 .probe = mpc85xx_cds_probe, 354 .probe = mpc85xx_cds_probe,
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index dfd8b4ad9b28..25f41cd2d33a 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -58,14 +58,13 @@ void __init mpc85xx_ds_pic_init(void)
58{ 58{
59 struct mpic *mpic; 59 struct mpic *mpic;
60 struct resource r; 60 struct resource r;
61 struct device_node *np = NULL; 61 struct device_node *np;
62#ifdef CONFIG_PPC_I8259 62#ifdef CONFIG_PPC_I8259
63 struct device_node *cascade_node = NULL; 63 struct device_node *cascade_node = NULL;
64 int cascade_irq; 64 int cascade_irq;
65#endif 65#endif
66 66
67 np = of_find_node_by_type(np, "open-pic"); 67 np = of_find_node_by_type(NULL, "open-pic");
68
69 if (np == NULL) { 68 if (np == NULL) {
70 printk(KERN_ERR "Could not find open-pic node\n"); 69 printk(KERN_ERR "Could not find open-pic node\n");
71 return; 70 return;
@@ -78,9 +77,11 @@ void __init mpc85xx_ds_pic_init(void)
78 } 77 }
79 78
80 mpic = mpic_alloc(np, r.start, 79 mpic = mpic_alloc(np, r.start,
81 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 80 MPIC_PRIMARY | MPIC_WANTS_RESET |
81 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
82 0, 256, " OpenPIC "); 82 0, 256, " OpenPIC ");
83 BUG_ON(mpic == NULL); 83 BUG_ON(mpic == NULL);
84 of_node_put(np);
84 85
85 mpic_init(mpic); 86 mpic_init(mpic);
86 87
@@ -184,7 +185,7 @@ static int __init mpc8544_ds_probe(void)
184 } 185 }
185} 186}
186 187
187static struct of_device_id mpc85xxds_ids[] = { 188static struct of_device_id __initdata mpc85xxds_ids[] = {
188 { .type = "soc", }, 189 { .type = "soc", },
189 { .compatible = "soc", }, 190 { .compatible = "soc", },
190 {}, 191 {},
@@ -195,6 +196,7 @@ static int __init mpc85xxds_publish_devices(void)
195 return of_platform_bus_probe(NULL, mpc85xxds_ids, NULL); 196 return of_platform_bus_probe(NULL, mpc85xxds_ids, NULL);
196} 197}
197machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices); 198machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices);
199machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices);
198 200
199/* 201/*
200 * Called very early, device-tree isn't unflattened 202 * Called very early, device-tree isn't unflattened
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 77681acf1bae..d850880d6964 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -120,8 +120,18 @@ static void __init tqm85xx_setup_arch(void)
120#endif 120#endif
121 121
122#ifdef CONFIG_PCI 122#ifdef CONFIG_PCI
123 for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") 123 for_each_node_by_type(np, "pci") {
124 fsl_add_bridge(np, 1); 124 if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
125 of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
126 struct resource rsrc;
127 if (!of_address_to_resource(np, 0, &rsrc)) {
128 if ((rsrc.start & 0xfffff) == 0x8000)
129 fsl_add_bridge(np, 1);
130 else
131 fsl_add_bridge(np, 0);
132 }
133 }
134 }
125#endif 135#endif
126} 136}
127 137
@@ -165,10 +175,11 @@ static int __init tqm85xx_probe(void)
165{ 175{
166 unsigned long root = of_get_flat_dt_root(); 176 unsigned long root = of_get_flat_dt_root();
167 177
168 if ((of_flat_dt_is_compatible(root, "tqm,8540")) || 178 if ((of_flat_dt_is_compatible(root, "tqc,tqm8540")) ||
169 (of_flat_dt_is_compatible(root, "tqm,8541")) || 179 (of_flat_dt_is_compatible(root, "tqc,tqm8541")) ||
170 (of_flat_dt_is_compatible(root, "tqm,8555")) || 180 (of_flat_dt_is_compatible(root, "tqc,tqm8548")) ||
171 (of_flat_dt_is_compatible(root, "tqm,8560"))) 181 (of_flat_dt_is_compatible(root, "tqc,tqm8555")) ||
182 (of_flat_dt_is_compatible(root, "tqc,tqm8560")))
172 return 1; 183 return 1;
173 184
174 return 0; 185 return 0;
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 053f49a1dcae..80a81e02bb55 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -1,7 +1,13 @@
1choice 1config PPC_86xx
2 prompt "86xx Board Type" 2menuconfig PPC_86xx
3 depends on PPC_86xx 3 bool "86xx-based boards"
4 default MPC8641_HPCN 4 depends on 6xx && PPC_MULTIPLATFORM
5 select FSL_SOC
6 select ALTIVEC
7 help
8 The Freescale E600 SoCs have 74xx cores.
9
10if PPC_86xx
5 11
6config MPC8641_HPCN 12config MPC8641_HPCN
7 bool "Freescale MPC8641 HPCN" 13 bool "Freescale MPC8641 HPCN"
@@ -24,7 +30,7 @@ config MPC8610_HPCD
24 help 30 help
25 This option enables support for the MPC8610 HPCD board. 31 This option enables support for the MPC8610 HPCD board.
26 32
27endchoice 33endif
28 34
29config MPC8641 35config MPC8641
30 bool 36 bool
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index 1b9b4a9b2525..8fee37dec795 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -2,6 +2,7 @@
2# Makefile for the PowerPC 86xx linux kernel. 2# Makefile for the PowerPC 86xx linux kernel.
3# 3#
4 4
5obj-y := pic.o
5obj-$(CONFIG_SMP) += mpc86xx_smp.o 6obj-$(CONFIG_SMP) += mpc86xx_smp.o
6obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o 7obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o
7obj-$(CONFIG_SBC8641D) += sbc8641d.o 8obj-$(CONFIG_SBC8641D) += sbc8641d.o
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index dea13208bf64..30725302884a 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -39,6 +39,8 @@
39#include <sysdev/fsl_pci.h> 39#include <sysdev/fsl_pci.h>
40#include <sysdev/fsl_soc.h> 40#include <sysdev/fsl_soc.h>
41 41
42#include "mpc86xx.h"
43
42static unsigned char *pixis_bdcfg0, *pixis_arch; 44static unsigned char *pixis_bdcfg0, *pixis_arch;
43 45
44static struct of_device_id __initdata mpc8610_ids[] = { 46static struct of_device_id __initdata mpc8610_ids[] = {
@@ -56,27 +58,6 @@ static int __init mpc8610_declare_of_platform_devices(void)
56} 58}
57machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); 59machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
58 60
59static void __init mpc86xx_hpcd_init_irq(void)
60{
61 struct mpic *mpic1;
62 struct device_node *np;
63 struct resource res;
64
65 /* Determine PIC address. */
66 np = of_find_node_by_type(NULL, "open-pic");
67 if (np == NULL)
68 return;
69 of_address_to_resource(np, 0, &res);
70
71 /* Alloc mpic structure and per isu has 16 INT entries. */
72 mpic1 = mpic_alloc(np, res.start,
73 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
74 0, 256, " MPIC ");
75 BUG_ON(mpic1 == NULL);
76
77 mpic_init(mpic1);
78}
79
80#ifdef CONFIG_PCI 61#ifdef CONFIG_PCI
81static void __devinit quirk_uli1575(struct pci_dev *dev) 62static void __devinit quirk_uli1575(struct pci_dev *dev)
82{ 63{
@@ -404,7 +385,7 @@ define_machine(mpc86xx_hpcd) {
404 .name = "MPC86xx HPCD", 385 .name = "MPC86xx HPCD",
405 .probe = mpc86xx_hpcd_probe, 386 .probe = mpc86xx_hpcd_probe,
406 .setup_arch = mpc86xx_hpcd_setup_arch, 387 .setup_arch = mpc86xx_hpcd_setup_arch,
407 .init_IRQ = mpc86xx_hpcd_init_irq, 388 .init_IRQ = mpc86xx_init_irq,
408 .get_irq = mpic_get_irq, 389 .get_irq = mpic_get_irq,
409 .restart = fsl_rstcr_restart, 390 .restart = fsl_rstcr_restart,
410 .time_init = mpc86xx_time_init, 391 .time_init = mpc86xx_time_init,
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
index 525ffa1904f9..08efb57559d1 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx.h
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -15,6 +15,7 @@
15 * mpc86xx_* files. Mostly for use by mpc86xx_setup(). 15 * mpc86xx_* files. Mostly for use by mpc86xx_setup().
16 */ 16 */
17 17
18extern void __init mpc86xx_smp_init(void); 18extern void mpc86xx_smp_init(void);
19extern void mpc86xx_init_irq(void);
19 20
20#endif /* __MPC86XX_H__ */ 21#endif /* __MPC86XX_H__ */
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index f13704aabbea..7916599c9126 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -28,7 +28,6 @@
28#include <asm/prom.h> 28#include <asm/prom.h>
29#include <mm/mmu_decl.h> 29#include <mm/mmu_decl.h>
30#include <asm/udbg.h> 30#include <asm/udbg.h>
31#include <asm/i8259.h>
32 31
33#include <asm/mpic.h> 32#include <asm/mpic.h>
34 33
@@ -46,67 +45,6 @@
46#endif 45#endif
47 46
48#ifdef CONFIG_PCI 47#ifdef CONFIG_PCI
49static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
50{
51 unsigned int cascade_irq = i8259_irq();
52 if (cascade_irq != NO_IRQ)
53 generic_handle_irq(cascade_irq);
54 desc->chip->eoi(irq);
55}
56#endif /* CONFIG_PCI */
57
58static void __init
59mpc86xx_hpcn_init_irq(void)
60{
61 struct mpic *mpic1;
62 struct device_node *np;
63 struct resource res;
64#ifdef CONFIG_PCI
65 struct device_node *cascade_node = NULL;
66 int cascade_irq;
67#endif
68
69 /* Determine PIC address. */
70 np = of_find_node_by_type(NULL, "open-pic");
71 if (np == NULL)
72 return;
73 of_address_to_resource(np, 0, &res);
74
75 /* Alloc mpic structure and per isu has 16 INT entries. */
76 mpic1 = mpic_alloc(np, res.start,
77 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
78 0, 256, " MPIC ");
79 BUG_ON(mpic1 == NULL);
80
81 mpic_init(mpic1);
82
83#ifdef CONFIG_PCI
84 /* Initialize i8259 controller */
85 for_each_node_by_type(np, "interrupt-controller")
86 if (of_device_is_compatible(np, "chrp,iic")) {
87 cascade_node = np;
88 break;
89 }
90 if (cascade_node == NULL) {
91 printk(KERN_DEBUG "mpc86xxhpcn: no ISA interrupt controller\n");
92 return;
93 }
94
95 cascade_irq = irq_of_parse_and_map(cascade_node, 0);
96 if (cascade_irq == NO_IRQ) {
97 printk(KERN_ERR "mpc86xxhpcn: failed to map cascade interrupt");
98 return;
99 }
100 DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq);
101
102 i8259_init(cascade_node, 0);
103 of_node_put(cascade_node);
104
105 set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
106#endif
107}
108
109#ifdef CONFIG_PCI
110extern int uses_fsl_uli_m1575; 48extern int uses_fsl_uli_m1575;
111extern int uli_exclude_device(struct pci_controller *hose, 49extern int uli_exclude_device(struct pci_controller *hose,
112 u_char bus, u_char devfn); 50 u_char bus, u_char devfn);
@@ -237,7 +175,7 @@ define_machine(mpc86xx_hpcn) {
237 .name = "MPC86xx HPCN", 175 .name = "MPC86xx HPCN",
238 .probe = mpc86xx_hpcn_probe, 176 .probe = mpc86xx_hpcn_probe,
239 .setup_arch = mpc86xx_hpcn_setup_arch, 177 .setup_arch = mpc86xx_hpcn_setup_arch,
240 .init_IRQ = mpc86xx_hpcn_init_irq, 178 .init_IRQ = mpc86xx_init_irq,
241 .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, 179 .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
242 .get_irq = mpic_get_irq, 180 .get_irq = mpic_get_irq,
243 .restart = fsl_rstcr_restart, 181 .restart = fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
index ba55b0ff0f74..835f2dc24dc9 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17 17
18#include <asm/code-patching.h>
18#include <asm/page.h> 19#include <asm/page.h>
19#include <asm/pgtable.h> 20#include <asm/pgtable.h>
20#include <asm/pci-bridge.h> 21#include <asm/pci-bridge.h>
@@ -56,8 +57,7 @@ smp_86xx_kick_cpu(int nr)
56 unsigned int save_vector; 57 unsigned int save_vector;
57 unsigned long target, flags; 58 unsigned long target, flags;
58 int n = 0; 59 int n = 0;
59 volatile unsigned int *vector 60 unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100);
60 = (volatile unsigned int *)(KERNELBASE + 0x100);
61 61
62 if (nr < 0 || nr >= NR_CPUS) 62 if (nr < 0 || nr >= NR_CPUS)
63 return; 63 return;
@@ -71,7 +71,7 @@ smp_86xx_kick_cpu(int nr)
71 71
72 /* Setup fake reset vector to call __secondary_start_mpc86xx. */ 72 /* Setup fake reset vector to call __secondary_start_mpc86xx. */
73 target = (unsigned long) __secondary_start_mpc86xx; 73 target = (unsigned long) __secondary_start_mpc86xx;
74 create_branch((unsigned long)vector, target, BRANCH_SET_LINK); 74 patch_branch(vector, target, BRANCH_SET_LINK);
75 75
76 /* Kick that CPU */ 76 /* Kick that CPU */
77 smp_86xx_release_core(nr); 77 smp_86xx_release_core(nr);
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
new file mode 100644
index 000000000000..8881c5de500d
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/pic.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright 2008 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/stddef.h>
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/of_platform.h>
14
15#include <asm/system.h>
16#include <asm/mpic.h>
17#include <asm/i8259.h>
18
19#ifdef CONFIG_PPC_I8259
20static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
21{
22 unsigned int cascade_irq = i8259_irq();
23 if (cascade_irq != NO_IRQ)
24 generic_handle_irq(cascade_irq);
25 desc->chip->eoi(irq);
26}
27#endif /* CONFIG_PPC_I8259 */
28
29void __init mpc86xx_init_irq(void)
30{
31 struct mpic *mpic;
32 struct device_node *np;
33 struct resource res;
34#ifdef CONFIG_PPC_I8259
35 struct device_node *cascade_node = NULL;
36 int cascade_irq;
37#endif
38
39 /* Determine PIC address. */
40 np = of_find_node_by_type(NULL, "open-pic");
41 if (np == NULL)
42 return;
43 of_address_to_resource(np, 0, &res);
44
45 mpic = mpic_alloc(np, res.start,
46 MPIC_PRIMARY | MPIC_WANTS_RESET |
47 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
48 0, 256, " MPIC ");
49 of_node_put(np);
50 BUG_ON(mpic == NULL);
51
52 mpic_init(mpic);
53
54#ifdef CONFIG_PPC_I8259
55 /* Initialize i8259 controller */
56 for_each_node_by_type(np, "interrupt-controller")
57 if (of_device_is_compatible(np, "chrp,iic")) {
58 cascade_node = np;
59 break;
60 }
61
62 if (cascade_node == NULL) {
63 printk(KERN_DEBUG "Could not find i8259 PIC\n");
64 return;
65 }
66
67 cascade_irq = irq_of_parse_and_map(cascade_node, 0);
68 if (cascade_irq == NO_IRQ) {
69 printk(KERN_ERR "Failed to map cascade interrupt\n");
70 return;
71 }
72
73 i8259_init(cascade_node, 0);
74 of_node_put(cascade_node);
75
76 set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
77#endif
78}
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 510a06ef0b55..00e6fad3b3ca 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -38,29 +38,6 @@
38#include "mpc86xx.h" 38#include "mpc86xx.h"
39 39
40static void __init 40static void __init
41sbc8641_init_irq(void)
42{
43 struct mpic *mpic1;
44 struct device_node *np;
45 struct resource res;
46
47 /* Determine PIC address. */
48 np = of_find_node_by_type(NULL, "open-pic");
49 if (np == NULL)
50 return;
51 of_address_to_resource(np, 0, &res);
52
53 /* Alloc mpic structure and per isu has 16 INT entries. */
54 mpic1 = mpic_alloc(np, res.start,
55 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
56 0, 256, " MPIC ");
57 of_node_put(np);
58 BUG_ON(mpic1 == NULL);
59
60 mpic_init(mpic1);
61}
62
63static void __init
64sbc8641_setup_arch(void) 41sbc8641_setup_arch(void)
65{ 42{
66#ifdef CONFIG_PCI 43#ifdef CONFIG_PCI
@@ -151,7 +128,7 @@ define_machine(sbc8641) {
151 .name = "SBC8641D", 128 .name = "SBC8641D",
152 .probe = sbc8641_probe, 129 .probe = sbc8641_probe,
153 .setup_arch = sbc8641_setup_arch, 130 .setup_arch = sbc8641_setup_arch,
154 .init_IRQ = sbc8641_init_irq, 131 .init_IRQ = mpc86xx_init_irq,
155 .show_cpuinfo = sbc8641_show_cpuinfo, 132 .show_cpuinfo = sbc8641_show_cpuinfo,
156 .get_irq = mpic_get_irq, 133 .get_irq = mpic_get_irq,
157 .restart = fsl_rstcr_restart, 134 .restart = fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index c028a5b71bbb..caaec29796b7 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -65,6 +65,10 @@ static struct cpm_pin mpc866ads_pins[] = {
65 {CPM_PORTD, 13, CPM_PIN_OUTPUT}, 65 {CPM_PORTD, 13, CPM_PIN_OUTPUT},
66 {CPM_PORTD, 14, CPM_PIN_OUTPUT}, 66 {CPM_PORTD, 14, CPM_PIN_OUTPUT},
67 {CPM_PORTD, 15, CPM_PIN_OUTPUT}, 67 {CPM_PORTD, 15, CPM_PIN_OUTPUT},
68
69 /* I2C */
70 {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
71 {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
68}; 72};
69 73
70static void __init init_ioports(void) 74static void __init init_ioports(void)
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 6e7ded0233f6..45ed6cdc1310 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -158,6 +158,9 @@ static struct cpm_pin mpc885ads_pins[] = {
158 {CPM_PORTE, 28, CPM_PIN_OUTPUT}, 158 {CPM_PORTE, 28, CPM_PIN_OUTPUT},
159 {CPM_PORTE, 29, CPM_PIN_OUTPUT}, 159 {CPM_PORTE, 29, CPM_PIN_OUTPUT},
160#endif 160#endif
161 /* I2C */
162 {CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
163 {CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
161}; 164};
162 165
163static void __init init_ioports(void) 166static void __init init_ioports(void)
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 87454c526973..690c1f46e698 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -1,36 +1,9 @@
1menu "Platform support" 1menu "Platform support"
2 2
3choice
4 prompt "Machine type"
5 depends on PPC64 || 6xx
6 default PPC_MULTIPLATFORM
7
8config PPC_MULTIPLATFORM 3config PPC_MULTIPLATFORM
9 bool "Generic desktop/server/laptop" 4 bool
10 help 5 depends on PPC64 || 6xx
11 Select this option if configuring for an IBM pSeries or 6 default y
12 RS/6000 machine, an Apple machine, or a PReP, CHRP,
13 Maple or Cell-based machine.
14
15config PPC_82xx
16 bool "Freescale 82xx"
17 depends on 6xx
18
19config PPC_83xx
20 bool "Freescale 83xx"
21 depends on 6xx
22 select FSL_SOC
23 select MPC83xx
24 select IPIC
25
26config PPC_86xx
27 bool "Freescale 86xx"
28 depends on 6xx
29 select FSL_SOC
30 select ALTIVEC
31 help
32 The Freescale E600 SoCs have 74xx cores.
33endchoice
34 7
35config CLASSIC32 8config CLASSIC32
36 def_bool y 9 def_bool y
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index f7efaa925a13..5bc4b611ff88 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -95,6 +95,11 @@ config E500
95 select FSL_EMB_PERFMON 95 select FSL_EMB_PERFMON
96 bool 96 bool
97 97
98config PPC_E500MC
99 bool "e500mc Support"
100 select PPC_FPU
101 depends on E500
102
98config PPC_FPU 103config PPC_FPU
99 bool 104 bool
100 default y if PPC64 105 default y if PPC64
@@ -155,9 +160,25 @@ config ALTIVEC
155 160
156 If in doubt, say Y here. 161 If in doubt, say Y here.
157 162
163config VSX
164 bool "VSX Support"
165 depends on POWER4 && ALTIVEC && PPC_FPU
166 ---help---
167
168 This option enables kernel support for the Vector Scaler extensions
169 to the PowerPC processor. The kernel currently supports saving and
170 restoring VSX registers, and turning on the 'VSX enable' bit so user
171 processes can execute VSX instructions.
172
173 This option is only useful if you have a processor that supports
174 VSX (P7 and above), but does not have any affect on a non-VSX
175 CPUs (it does, however add code to the kernel).
176
177 If in doubt, say Y here.
178
158config SPE 179config SPE
159 bool "SPE Support" 180 bool "SPE Support"
160 depends on E200 || E500 181 depends on E200 || (E500 && !PPC_E500MC)
161 default y 182 default y
162 ---help--- 183 ---help---
163 This option enables kernel support for the Signal Processing 184 This option enables kernel support for the Signal Processing
@@ -182,7 +203,7 @@ config PPC_STD_MMU_32
182 203
183config PPC_MM_SLICES 204config PPC_MM_SLICES
184 bool 205 bool
185 default y if HUGETLB_PAGE 206 default y if HUGETLB_PAGE || PPC_64K_PAGES
186 default n 207 default n
187 208
188config VIRT_CPU_ACCOUNTING 209config VIRT_CPU_ACCOUNTING
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index c39f5c225f2e..896548ba1ca1 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -14,6 +14,7 @@
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/msi.h> 15#include <linux/msi.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/debugfs.h>
17 18
18#include <asm/dcr.h> 19#include <asm/dcr.h>
19#include <asm/machdep.h> 20#include <asm/machdep.h>
@@ -69,8 +70,19 @@ struct axon_msic {
69 dma_addr_t fifo_phys; 70 dma_addr_t fifo_phys;
70 dcr_host_t dcr_host; 71 dcr_host_t dcr_host;
71 u32 read_offset; 72 u32 read_offset;
73#ifdef DEBUG
74 u32 __iomem *trigger;
75#endif
72}; 76};
73 77
78#ifdef DEBUG
79void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic);
80#else
81static inline void axon_msi_debug_setup(struct device_node *dn,
82 struct axon_msic *msic) { }
83#endif
84
85
74static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val) 86static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
75{ 87{
76 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n); 88 pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
@@ -346,7 +358,14 @@ static int axon_msi_probe(struct of_device *device,
346 goto out_free_msic; 358 goto out_free_msic;
347 } 359 }
348 360
349 msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, 361 virq = irq_of_parse_and_map(dn, 0);
362 if (virq == NO_IRQ) {
363 printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n",
364 dn->full_name);
365 goto out_free_fifo;
366 }
367
368 msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
350 NR_IRQS, &msic_host_ops, 0); 369 NR_IRQS, &msic_host_ops, 0);
351 if (!msic->irq_host) { 370 if (!msic->irq_host) {
352 printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", 371 printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
@@ -356,13 +375,6 @@ static int axon_msi_probe(struct of_device *device,
356 375
357 msic->irq_host->host_data = msic; 376 msic->irq_host->host_data = msic;
358 377
359 virq = irq_of_parse_and_map(dn, 0);
360 if (virq == NO_IRQ) {
361 printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n",
362 dn->full_name);
363 goto out_free_host;
364 }
365
366 set_irq_data(virq, msic); 378 set_irq_data(virq, msic);
367 set_irq_chained_handler(virq, axon_msi_cascade); 379 set_irq_chained_handler(virq, axon_msi_cascade);
368 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq); 380 pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
@@ -381,12 +393,12 @@ static int axon_msi_probe(struct of_device *device,
381 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs; 393 ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
382 ppc_md.msi_check_device = axon_msi_check_device; 394 ppc_md.msi_check_device = axon_msi_check_device;
383 395
396 axon_msi_debug_setup(dn, msic);
397
384 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); 398 printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name);
385 399
386 return 0; 400 return 0;
387 401
388out_free_host:
389 kfree(msic->irq_host);
390out_free_fifo: 402out_free_fifo:
391 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt, 403 dma_free_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, msic->fifo_virt,
392 msic->fifo_phys); 404 msic->fifo_phys);
@@ -418,3 +430,47 @@ static int __init axon_msi_init(void)
418 return of_register_platform_driver(&axon_msi_driver); 430 return of_register_platform_driver(&axon_msi_driver);
419} 431}
420subsys_initcall(axon_msi_init); 432subsys_initcall(axon_msi_init);
433
434
435#ifdef DEBUG
436static int msic_set(void *data, u64 val)
437{
438 struct axon_msic *msic = data;
439 out_le32(msic->trigger, val);
440 return 0;
441}
442
443static int msic_get(void *data, u64 *val)
444{
445 *val = 0;
446 return 0;
447}
448
449DEFINE_SIMPLE_ATTRIBUTE(fops_msic, msic_get, msic_set, "%llu\n");
450
451void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic)
452{
453 char name[8];
454 u64 addr;
455
456 addr = of_translate_address(dn, of_get_property(dn, "reg", NULL));
457 if (addr == OF_BAD_ADDR) {
458 pr_debug("axon_msi: couldn't translate reg property\n");
459 return;
460 }
461
462 msic->trigger = ioremap(addr, 0x4);
463 if (!msic->trigger) {
464 pr_debug("axon_msi: ioremap failed\n");
465 return;
466 }
467
468 snprintf(name, sizeof(name), "msic_%d", of_node_to_nid(dn));
469
470 if (!debugfs_create_file(name, 0600, powerpc_debugfs_root,
471 msic, &fops_msic)) {
472 pr_debug("axon_msi: debugfs_create_file failed!\n");
473 return;
474 }
475}
476#endif /* DEBUG */
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index 81467ff055c8..2e67bd840e01 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -112,7 +112,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group,
112 if (!(vflags & HPTE_V_BOLTED)) 112 if (!(vflags & HPTE_V_BOLTED))
113 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); 113 DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
114 114
115 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) 115 if (rflags & _PAGE_NO_CACHE)
116 hpte_r &= ~_PAGE_COHERENT; 116 hpte_r &= ~_PAGE_COHERENT;
117 117
118 spin_lock(&beat_htab_lock); 118 spin_lock(&beat_htab_lock);
@@ -334,7 +334,7 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
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);
336 336
337 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) 337 if (rflags & _PAGE_NO_CACHE)
338 hpte_r &= ~_PAGE_COHERENT; 338 hpte_r &= ~_PAGE_COHERENT;
339 339
340 /* insert into not-volted entry */ 340 /* insert into not-volted entry */
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 31da84c458d2..0e04f8fb152a 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -217,7 +217,7 @@ static u##size scc_pciex_in##name(unsigned long port) \
217static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \ 217static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \
218{ \ 218{ \
219 struct iowa_bus *bus = iowa_pio_find_bus(p); \ 219 struct iowa_bus *bus = iowa_pio_find_bus(p); \
220 u##size *dst = b; \ 220 __le##size *dst = b; \
221 for (; c != 0; c--, dst++) \ 221 for (; c != 0; c--, dst++) \
222 *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \ 222 *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \
223 scc_pciex_io_flush(bus); \ 223 scc_pciex_io_flush(bus); \
@@ -231,10 +231,11 @@ static void scc_pciex_outs##name(unsigned long p, const void *b, \
231 unsigned long c) \ 231 unsigned long c) \
232{ \ 232{ \
233 struct iowa_bus *bus = iowa_pio_find_bus(p); \ 233 struct iowa_bus *bus = iowa_pio_find_bus(p); \
234 const u##size *src = b; \ 234 const __le##size *src = b; \
235 for (; c != 0; c--, src++) \ 235 for (; c != 0; c--, src++) \
236 __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \ 236 __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \
237} 237}
238#define __le8 u8
238#define cpu_to_le8(x) (x) 239#define cpu_to_le8(x) (x)
239#define le8_to_cpu(x) (x) 240#define le8_to_cpu(x) (x)
240PCIEX_PIO_FUNC(8, b) 241PCIEX_PIO_FUNC(8, b)
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 5bf7df146022..2d5bb22d6c09 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -218,6 +218,7 @@ void iic_request_IPIs(void)
218{ 218{
219 iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call"); 219 iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
220 iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched"); 220 iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
221 iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE, "IPI-call-single");
221#ifdef CONFIG_DEBUGGER 222#ifdef CONFIG_DEBUGGER
222 iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); 223 iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
223#endif /* CONFIG_DEBUGGER */ 224#endif /* CONFIG_DEBUGGER */
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 45646b2b4af4..eeacb3a52ca1 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -540,7 +540,7 @@ static unsigned long cell_dma_direct_offset;
540static unsigned long dma_iommu_fixed_base; 540static unsigned long dma_iommu_fixed_base;
541struct dma_mapping_ops dma_iommu_fixed_ops; 541struct dma_mapping_ops dma_iommu_fixed_ops;
542 542
543static void cell_dma_dev_setup_iommu(struct device *dev) 543static struct iommu_table *cell_get_iommu_table(struct device *dev)
544{ 544{
545 struct iommu_window *window; 545 struct iommu_window *window;
546 struct cbe_iommu *iommu; 546 struct cbe_iommu *iommu;
@@ -555,11 +555,11 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
555 printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", 555 printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
556 archdata->of_node ? archdata->of_node->full_name : "?", 556 archdata->of_node ? archdata->of_node->full_name : "?",
557 archdata->numa_node); 557 archdata->numa_node);
558 return; 558 return NULL;
559 } 559 }
560 window = list_entry(iommu->windows.next, struct iommu_window, list); 560 window = list_entry(iommu->windows.next, struct iommu_window, list);
561 561
562 archdata->dma_data = &window->table; 562 return &window->table;
563} 563}
564 564
565static void cell_dma_dev_setup_fixed(struct device *dev); 565static void cell_dma_dev_setup_fixed(struct device *dev);
@@ -572,7 +572,7 @@ static void cell_dma_dev_setup(struct device *dev)
572 if (get_dma_ops(dev) == &dma_iommu_fixed_ops) 572 if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
573 cell_dma_dev_setup_fixed(dev); 573 cell_dma_dev_setup_fixed(dev);
574 else if (get_pci_dma_ops() == &dma_iommu_ops) 574 else if (get_pci_dma_ops() == &dma_iommu_ops)
575 cell_dma_dev_setup_iommu(dev); 575 archdata->dma_data = cell_get_iommu_table(dev);
576 else if (get_pci_dma_ops() == &dma_direct_ops) 576 else if (get_pci_dma_ops() == &dma_direct_ops)
577 archdata->dma_data = (void *)cell_dma_direct_offset; 577 archdata->dma_data = (void *)cell_dma_direct_offset;
578 else 578 else
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c
index 655704ad03cf..505f9b9bdf0c 100644
--- a/arch/powerpc/platforms/cell/ras.c
+++ b/arch/powerpc/platforms/cell/ras.c
@@ -17,6 +17,7 @@
17#include <asm/reg.h> 17#include <asm/reg.h>
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/prom.h> 19#include <asm/prom.h>
20#include <asm/kexec.h>
20#include <asm/machdep.h> 21#include <asm/machdep.h>
21#include <asm/rtas.h> 22#include <asm/rtas.h>
22#include <asm/cell-regs.h> 23#include <asm/cell-regs.h>
@@ -226,6 +227,11 @@ static int cbe_ptcal_notify_reboot(struct notifier_block *nb,
226 return cbe_ptcal_disable(); 227 return cbe_ptcal_disable();
227} 228}
228 229
230static void cbe_ptcal_crash_shutdown(void)
231{
232 cbe_ptcal_disable();
233}
234
229static struct notifier_block cbe_ptcal_reboot_notifier = { 235static struct notifier_block cbe_ptcal_reboot_notifier = {
230 .notifier_call = cbe_ptcal_notify_reboot 236 .notifier_call = cbe_ptcal_notify_reboot
231}; 237};
@@ -241,12 +247,20 @@ int __init cbe_ptcal_init(void)
241 return -ENODEV; 247 return -ENODEV;
242 248
243 ret = register_reboot_notifier(&cbe_ptcal_reboot_notifier); 249 ret = register_reboot_notifier(&cbe_ptcal_reboot_notifier);
244 if (ret) { 250 if (ret)
245 printk(KERN_ERR "Can't disable PTCAL, so not enabling\n"); 251 goto out1;
246 return ret; 252
247 } 253 ret = crash_shutdown_register(&cbe_ptcal_crash_shutdown);
254 if (ret)
255 goto out2;
248 256
249 return cbe_ptcal_enable(); 257 return cbe_ptcal_enable();
258
259out2:
260 unregister_reboot_notifier(&cbe_ptcal_reboot_notifier);
261out1:
262 printk(KERN_ERR "Can't disable PTCAL, so not enabling\n");
263 return ret;
250} 264}
251 265
252arch_initcall(cbe_ptcal_init); 266arch_initcall(cbe_ptcal_init);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 3f4b4aef756d..4e5655624ae8 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -300,7 +300,7 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
300 panic("spider_pic: can't map registers !"); 300 panic("spider_pic: can't map registers !");
301 301
302 /* Allocate a host */ 302 /* Allocate a host */
303 pic->host = irq_alloc_host(of_node_get(of_node), IRQ_HOST_MAP_LINEAR, 303 pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR,
304 SPIDER_SRC_COUNT, &spider_host_ops, 304 SPIDER_SRC_COUNT, &spider_host_ops,
305 SPIDER_IRQ_INVALID); 305 SPIDER_IRQ_INVALID);
306 if (pic->host == NULL) 306 if (pic->host == NULL)
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 70c660121ec4..78f905bc6a42 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -219,15 +219,25 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
219extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX 219extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX
220static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) 220static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
221{ 221{
222 int ret;
223
222 pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea); 224 pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea);
223 225
224 /* Handle kernel space hash faults immediately. 226 /*
225 User hash faults need to be deferred to process context. */ 227 * Handle kernel space hash faults immediately. User hash
226 if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) 228 * faults need to be deferred to process context.
227 && REGION_ID(ea) != USER_REGION_ID 229 */
228 && hash_page(ea, _PAGE_PRESENT, 0x300) == 0) { 230 if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) &&
229 spu_restart_dma(spu); 231 (REGION_ID(ea) != USER_REGION_ID)) {
230 return 0; 232
233 spin_unlock(&spu->register_lock);
234 ret = hash_page(ea, _PAGE_PRESENT, 0x300);
235 spin_lock(&spu->register_lock);
236
237 if (!ret) {
238 spu_restart_dma(spu);
239 return 0;
240 }
231 } 241 }
232 242
233 spu->class_1_dar = ea; 243 spu->class_1_dar = ea;
@@ -324,17 +334,13 @@ spu_irq_class_0(int irq, void *data)
324 stat = spu_int_stat_get(spu, 0) & mask; 334 stat = spu_int_stat_get(spu, 0) & mask;
325 335
326 spu->class_0_pending |= stat; 336 spu->class_0_pending |= stat;
327 spu->class_0_dsisr = spu_mfc_dsisr_get(spu);
328 spu->class_0_dar = spu_mfc_dar_get(spu); 337 spu->class_0_dar = spu_mfc_dar_get(spu);
329 spin_unlock(&spu->register_lock);
330
331 spu->stop_callback(spu, 0); 338 spu->stop_callback(spu, 0);
332
333 spu->class_0_pending = 0; 339 spu->class_0_pending = 0;
334 spu->class_0_dsisr = 0;
335 spu->class_0_dar = 0; 340 spu->class_0_dar = 0;
336 341
337 spu_int_stat_clear(spu, 0, stat); 342 spu_int_stat_clear(spu, 0, stat);
343 spin_unlock(&spu->register_lock);
338 344
339 return IRQ_HANDLED; 345 return IRQ_HANDLED;
340} 346}
@@ -357,13 +363,12 @@ spu_irq_class_1(int irq, void *data)
357 spu_mfc_dsisr_set(spu, 0ul); 363 spu_mfc_dsisr_set(spu, 0ul);
358 spu_int_stat_clear(spu, 1, stat); 364 spu_int_stat_clear(spu, 1, stat);
359 365
360 if (stat & CLASS1_SEGMENT_FAULT_INTR)
361 __spu_trap_data_seg(spu, dar);
362
363 spin_unlock(&spu->register_lock);
364 pr_debug("%s: %lx %lx %lx %lx\n", __func__, mask, stat, 366 pr_debug("%s: %lx %lx %lx %lx\n", __func__, mask, stat,
365 dar, dsisr); 367 dar, dsisr);
366 368
369 if (stat & CLASS1_SEGMENT_FAULT_INTR)
370 __spu_trap_data_seg(spu, dar);
371
367 if (stat & CLASS1_STORAGE_FAULT_INTR) 372 if (stat & CLASS1_STORAGE_FAULT_INTR)
368 __spu_trap_data_map(spu, dar, dsisr); 373 __spu_trap_data_map(spu, dar, dsisr);
369 374
@@ -376,6 +381,8 @@ spu_irq_class_1(int irq, void *data)
376 spu->class_1_dsisr = 0; 381 spu->class_1_dsisr = 0;
377 spu->class_1_dar = 0; 382 spu->class_1_dar = 0;
378 383
384 spin_unlock(&spu->register_lock);
385
379 return stat ? IRQ_HANDLED : IRQ_NONE; 386 return stat ? IRQ_HANDLED : IRQ_NONE;
380} 387}
381 388
@@ -394,14 +401,12 @@ spu_irq_class_2(int irq, void *data)
394 mask = spu_int_mask_get(spu, 2); 401 mask = spu_int_mask_get(spu, 2);
395 /* ignore interrupts we're not waiting for */ 402 /* ignore interrupts we're not waiting for */
396 stat &= mask; 403 stat &= mask;
397
398 /* mailbox interrupts are level triggered. mask them now before 404 /* mailbox interrupts are level triggered. mask them now before
399 * acknowledging */ 405 * acknowledging */
400 if (stat & mailbox_intrs) 406 if (stat & mailbox_intrs)
401 spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs)); 407 spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs));
402 /* acknowledge all interrupts before the callbacks */ 408 /* acknowledge all interrupts before the callbacks */
403 spu_int_stat_clear(spu, 2, stat); 409 spu_int_stat_clear(spu, 2, stat);
404 spin_unlock(&spu->register_lock);
405 410
406 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); 411 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);
407 412
@@ -421,6 +426,9 @@ spu_irq_class_2(int irq, void *data)
421 spu->wbox_callback(spu); 426 spu->wbox_callback(spu);
422 427
423 spu->stats.class2_intr++; 428 spu->stats.class2_intr++;
429
430 spin_unlock(&spu->register_lock);
431
424 return stat ? IRQ_HANDLED : IRQ_NONE; 432 return stat ? IRQ_HANDLED : IRQ_NONE;
425} 433}
426 434
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 177735f79317..6653ddbed048 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -130,17 +130,17 @@ void spu_unmap_mappings(struct spu_context *ctx)
130 if (ctx->local_store) 130 if (ctx->local_store)
131 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); 131 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
132 if (ctx->mfc) 132 if (ctx->mfc)
133 unmap_mapping_range(ctx->mfc, 0, 0x1000, 1); 133 unmap_mapping_range(ctx->mfc, 0, SPUFS_MFC_MAP_SIZE, 1);
134 if (ctx->cntl) 134 if (ctx->cntl)
135 unmap_mapping_range(ctx->cntl, 0, 0x1000, 1); 135 unmap_mapping_range(ctx->cntl, 0, SPUFS_CNTL_MAP_SIZE, 1);
136 if (ctx->signal1) 136 if (ctx->signal1)
137 unmap_mapping_range(ctx->signal1, 0, PAGE_SIZE, 1); 137 unmap_mapping_range(ctx->signal1, 0, SPUFS_SIGNAL_MAP_SIZE, 1);
138 if (ctx->signal2) 138 if (ctx->signal2)
139 unmap_mapping_range(ctx->signal2, 0, PAGE_SIZE, 1); 139 unmap_mapping_range(ctx->signal2, 0, SPUFS_SIGNAL_MAP_SIZE, 1);
140 if (ctx->mss) 140 if (ctx->mss)
141 unmap_mapping_range(ctx->mss, 0, 0x1000, 1); 141 unmap_mapping_range(ctx->mss, 0, SPUFS_MSS_MAP_SIZE, 1);
142 if (ctx->psmap) 142 if (ctx->psmap)
143 unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); 143 unmap_mapping_range(ctx->psmap, 0, SPUFS_PS_MAP_SIZE, 1);
144 mutex_unlock(&ctx->mapping_lock); 144 mutex_unlock(&ctx->mapping_lock);
145} 145}
146 146
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index c81341ff75b5..99c73066b82f 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -238,11 +238,13 @@ spufs_mem_write(struct file *file, const char __user *buffer,
238 return size; 238 return size;
239} 239}
240 240
241static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, 241static int
242 unsigned long address) 242spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
243{ 243{
244 struct spu_context *ctx = vma->vm_file->private_data; 244 struct spu_context *ctx = vma->vm_file->private_data;
245 unsigned long pfn, offset, addr0 = address; 245 unsigned long address = (unsigned long)vmf->virtual_address;
246 unsigned long pfn, offset;
247
246#ifdef CONFIG_SPU_FS_64K_LS 248#ifdef CONFIG_SPU_FS_64K_LS
247 struct spu_state *csa = &ctx->csa; 249 struct spu_state *csa = &ctx->csa;
248 int psize; 250 int psize;
@@ -260,15 +262,15 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
260 } 262 }
261#endif /* CONFIG_SPU_FS_64K_LS */ 263#endif /* CONFIG_SPU_FS_64K_LS */
262 264
263 offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); 265 offset = vmf->pgoff << PAGE_SHIFT;
264 if (offset >= LS_SIZE) 266 if (offset >= LS_SIZE)
265 return NOPFN_SIGBUS; 267 return VM_FAULT_SIGBUS;
266 268
267 pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", 269 pr_debug("spufs_mem_mmap_fault address=0x%lx, offset=0x%lx\n",
268 addr0, address, offset); 270 address, offset);
269 271
270 if (spu_acquire(ctx)) 272 if (spu_acquire(ctx))
271 return NOPFN_REFAULT; 273 return VM_FAULT_NOPAGE;
272 274
273 if (ctx->state == SPU_STATE_SAVED) { 275 if (ctx->state == SPU_STATE_SAVED) {
274 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 276 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
@@ -283,12 +285,12 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
283 285
284 spu_release(ctx); 286 spu_release(ctx);
285 287
286 return NOPFN_REFAULT; 288 return VM_FAULT_NOPAGE;
287} 289}
288 290
289 291
290static struct vm_operations_struct spufs_mem_mmap_vmops = { 292static struct vm_operations_struct spufs_mem_mmap_vmops = {
291 .nopfn = spufs_mem_mmap_nopfn, 293 .fault = spufs_mem_mmap_fault,
292}; 294};
293 295
294static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) 296static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
@@ -351,20 +353,19 @@ static const struct file_operations spufs_mem_fops = {
351#endif 353#endif
352}; 354};
353 355
354static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, 356static int spufs_ps_fault(struct vm_area_struct *vma,
355 unsigned long address, 357 struct vm_fault *vmf,
356 unsigned long ps_offs, 358 unsigned long ps_offs,
357 unsigned long ps_size) 359 unsigned long ps_size)
358{ 360{
359 struct spu_context *ctx = vma->vm_file->private_data; 361 struct spu_context *ctx = vma->vm_file->private_data;
360 unsigned long area, offset = address - vma->vm_start; 362 unsigned long area, offset = vmf->pgoff << PAGE_SHIFT;
361 int ret = 0; 363 int ret = 0;
362 364
363 spu_context_nospu_trace(spufs_ps_nopfn__enter, ctx); 365 spu_context_nospu_trace(spufs_ps_fault__enter, ctx);
364 366
365 offset += vma->vm_pgoff << PAGE_SHIFT;
366 if (offset >= ps_size) 367 if (offset >= ps_size)
367 return NOPFN_SIGBUS; 368 return VM_FAULT_SIGBUS;
368 369
369 /* 370 /*
370 * Because we release the mmap_sem, the context may be destroyed while 371 * Because we release the mmap_sem, the context may be destroyed while
@@ -378,7 +379,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
378 * pages to hand out to the user, but we don't want to wait 379 * pages to hand out to the user, but we don't want to wait
379 * with the mmap_sem held. 380 * with the mmap_sem held.
380 * It is possible to drop the mmap_sem here, but then we need 381 * It is possible to drop the mmap_sem here, but then we need
381 * to return NOPFN_REFAULT because the mappings may have 382 * to return VM_FAULT_NOPAGE because the mappings may have
382 * hanged. 383 * hanged.
383 */ 384 */
384 if (spu_acquire(ctx)) 385 if (spu_acquire(ctx))
@@ -386,14 +387,15 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
386 387
387 if (ctx->state == SPU_STATE_SAVED) { 388 if (ctx->state == SPU_STATE_SAVED) {
388 up_read(&current->mm->mmap_sem); 389 up_read(&current->mm->mmap_sem);
389 spu_context_nospu_trace(spufs_ps_nopfn__sleep, ctx); 390 spu_context_nospu_trace(spufs_ps_fault__sleep, ctx);
390 ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); 391 ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
391 spu_context_trace(spufs_ps_nopfn__wake, ctx, ctx->spu); 392 spu_context_trace(spufs_ps_fault__wake, ctx, ctx->spu);
392 down_read(&current->mm->mmap_sem); 393 down_read(&current->mm->mmap_sem);
393 } else { 394 } else {
394 area = ctx->spu->problem_phys + ps_offs; 395 area = ctx->spu->problem_phys + ps_offs;
395 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); 396 vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
396 spu_context_trace(spufs_ps_nopfn__insert, ctx, ctx->spu); 397 (area + offset) >> PAGE_SHIFT);
398 spu_context_trace(spufs_ps_fault__insert, ctx, ctx->spu);
397 } 399 }
398 400
399 if (!ret) 401 if (!ret)
@@ -401,18 +403,18 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
401 403
402refault: 404refault:
403 put_spu_context(ctx); 405 put_spu_context(ctx);
404 return NOPFN_REFAULT; 406 return VM_FAULT_NOPAGE;
405} 407}
406 408
407#if SPUFS_MMAP_4K 409#if SPUFS_MMAP_4K
408static unsigned long spufs_cntl_mmap_nopfn(struct vm_area_struct *vma, 410static int spufs_cntl_mmap_fault(struct vm_area_struct *vma,
409 unsigned long address) 411 struct vm_fault *vmf)
410{ 412{
411 return spufs_ps_nopfn(vma, address, 0x4000, 0x1000); 413 return spufs_ps_fault(vma, vmf, 0x4000, SPUFS_CNTL_MAP_SIZE);
412} 414}
413 415
414static struct vm_operations_struct spufs_cntl_mmap_vmops = { 416static struct vm_operations_struct spufs_cntl_mmap_vmops = {
415 .nopfn = spufs_cntl_mmap_nopfn, 417 .fault = spufs_cntl_mmap_fault,
416}; 418};
417 419
418/* 420/*
@@ -1097,23 +1099,23 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
1097 return 4; 1099 return 4;
1098} 1100}
1099 1101
1100static unsigned long spufs_signal1_mmap_nopfn(struct vm_area_struct *vma, 1102static int
1101 unsigned long address) 1103spufs_signal1_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1102{ 1104{
1103#if PAGE_SIZE == 0x1000 1105#if SPUFS_SIGNAL_MAP_SIZE == 0x1000
1104 return spufs_ps_nopfn(vma, address, 0x14000, 0x1000); 1106 return spufs_ps_fault(vma, vmf, 0x14000, SPUFS_SIGNAL_MAP_SIZE);
1105#elif PAGE_SIZE == 0x10000 1107#elif SPUFS_SIGNAL_MAP_SIZE == 0x10000
1106 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole 1108 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole
1107 * signal 1 and 2 area 1109 * signal 1 and 2 area
1108 */ 1110 */
1109 return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); 1111 return spufs_ps_fault(vma, vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE);
1110#else 1112#else
1111#error unsupported page size 1113#error unsupported page size
1112#endif 1114#endif
1113} 1115}
1114 1116
1115static struct vm_operations_struct spufs_signal1_mmap_vmops = { 1117static struct vm_operations_struct spufs_signal1_mmap_vmops = {
1116 .nopfn = spufs_signal1_mmap_nopfn, 1118 .fault = spufs_signal1_mmap_fault,
1117}; 1119};
1118 1120
1119static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) 1121static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1234,23 +1236,23 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
1234} 1236}
1235 1237
1236#if SPUFS_MMAP_4K 1238#if SPUFS_MMAP_4K
1237static unsigned long spufs_signal2_mmap_nopfn(struct vm_area_struct *vma, 1239static int
1238 unsigned long address) 1240spufs_signal2_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1239{ 1241{
1240#if PAGE_SIZE == 0x1000 1242#if SPUFS_SIGNAL_MAP_SIZE == 0x1000
1241 return spufs_ps_nopfn(vma, address, 0x1c000, 0x1000); 1243 return spufs_ps_fault(vma, vmf, 0x1c000, SPUFS_SIGNAL_MAP_SIZE);
1242#elif PAGE_SIZE == 0x10000 1244#elif SPUFS_SIGNAL_MAP_SIZE == 0x10000
1243 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole 1245 /* For 64k pages, both signal1 and signal2 can be used to mmap the whole
1244 * signal 1 and 2 area 1246 * signal 1 and 2 area
1245 */ 1247 */
1246 return spufs_ps_nopfn(vma, address, 0x10000, 0x10000); 1248 return spufs_ps_fault(vma, vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE);
1247#else 1249#else
1248#error unsupported page size 1250#error unsupported page size
1249#endif 1251#endif
1250} 1252}
1251 1253
1252static struct vm_operations_struct spufs_signal2_mmap_vmops = { 1254static struct vm_operations_struct spufs_signal2_mmap_vmops = {
1253 .nopfn = spufs_signal2_mmap_nopfn, 1255 .fault = spufs_signal2_mmap_fault,
1254}; 1256};
1255 1257
1256static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) 1258static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1362,14 +1364,14 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
1362 spufs_signal2_type_set, "%llu\n", SPU_ATTR_ACQUIRE); 1364 spufs_signal2_type_set, "%llu\n", SPU_ATTR_ACQUIRE);
1363 1365
1364#if SPUFS_MMAP_4K 1366#if SPUFS_MMAP_4K
1365static unsigned long spufs_mss_mmap_nopfn(struct vm_area_struct *vma, 1367static int
1366 unsigned long address) 1368spufs_mss_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1367{ 1369{
1368 return spufs_ps_nopfn(vma, address, 0x0000, 0x1000); 1370 return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_MSS_MAP_SIZE);
1369} 1371}
1370 1372
1371static struct vm_operations_struct spufs_mss_mmap_vmops = { 1373static struct vm_operations_struct spufs_mss_mmap_vmops = {
1372 .nopfn = spufs_mss_mmap_nopfn, 1374 .fault = spufs_mss_mmap_fault,
1373}; 1375};
1374 1376
1375/* 1377/*
@@ -1424,14 +1426,14 @@ static const struct file_operations spufs_mss_fops = {
1424 .mmap = spufs_mss_mmap, 1426 .mmap = spufs_mss_mmap,
1425}; 1427};
1426 1428
1427static unsigned long spufs_psmap_mmap_nopfn(struct vm_area_struct *vma, 1429static int
1428 unsigned long address) 1430spufs_psmap_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1429{ 1431{
1430 return spufs_ps_nopfn(vma, address, 0x0000, 0x20000); 1432 return spufs_ps_fault(vma, vmf, 0x0000, SPUFS_PS_MAP_SIZE);
1431} 1433}
1432 1434
1433static struct vm_operations_struct spufs_psmap_mmap_vmops = { 1435static struct vm_operations_struct spufs_psmap_mmap_vmops = {
1434 .nopfn = spufs_psmap_mmap_nopfn, 1436 .fault = spufs_psmap_mmap_fault,
1435}; 1437};
1436 1438
1437/* 1439/*
@@ -1484,14 +1486,14 @@ static const struct file_operations spufs_psmap_fops = {
1484 1486
1485 1487
1486#if SPUFS_MMAP_4K 1488#if SPUFS_MMAP_4K
1487static unsigned long spufs_mfc_mmap_nopfn(struct vm_area_struct *vma, 1489static int
1488 unsigned long address) 1490spufs_mfc_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1489{ 1491{
1490 return spufs_ps_nopfn(vma, address, 0x3000, 0x1000); 1492 return spufs_ps_fault(vma, vmf, 0x3000, SPUFS_MFC_MAP_SIZE);
1491} 1493}
1492 1494
1493static struct vm_operations_struct spufs_mfc_mmap_vmops = { 1495static struct vm_operations_struct spufs_mfc_mmap_vmops = {
1494 .nopfn = spufs_mfc_mmap_nopfn, 1496 .fault = spufs_mfc_mmap_fault,
1495}; 1497};
1496 1498
1497/* 1499/*
@@ -2553,22 +2555,74 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
2553 wake_up(&ctx->switch_log->wait); 2555 wake_up(&ctx->switch_log->wait);
2554} 2556}
2555 2557
2556struct tree_descr spufs_dir_contents[] = { 2558static int spufs_show_ctx(struct seq_file *s, void *private)
2559{
2560 struct spu_context *ctx = s->private;
2561 u64 mfc_control_RW;
2562
2563 mutex_lock(&ctx->state_mutex);
2564 if (ctx->spu) {
2565 struct spu *spu = ctx->spu;
2566 struct spu_priv2 __iomem *priv2 = spu->priv2;
2567
2568 spin_lock_irq(&spu->register_lock);
2569 mfc_control_RW = in_be64(&priv2->mfc_control_RW);
2570 spin_unlock_irq(&spu->register_lock);
2571 } else {
2572 struct spu_state *csa = &ctx->csa;
2573
2574 mfc_control_RW = csa->priv2.mfc_control_RW;
2575 }
2576
2577 seq_printf(s, "%c flgs(%lx) sflgs(%lx) pri(%d) ts(%d) spu(%02d)"
2578 " %c %lx %lx %lx %lx %x %x\n",
2579 ctx->state == SPU_STATE_SAVED ? 'S' : 'R',
2580 ctx->flags,
2581 ctx->sched_flags,
2582 ctx->prio,
2583 ctx->time_slice,
2584 ctx->spu ? ctx->spu->number : -1,
2585 !list_empty(&ctx->rq) ? 'q' : ' ',
2586 ctx->csa.class_0_pending,
2587 ctx->csa.class_0_dar,
2588 ctx->csa.class_1_dsisr,
2589 mfc_control_RW,
2590 ctx->ops->runcntl_read(ctx),
2591 ctx->ops->status_read(ctx));
2592
2593 mutex_unlock(&ctx->state_mutex);
2594
2595 return 0;
2596}
2597
2598static int spufs_ctx_open(struct inode *inode, struct file *file)
2599{
2600 return single_open(file, spufs_show_ctx, SPUFS_I(inode)->i_ctx);
2601}
2602
2603static const struct file_operations spufs_ctx_fops = {
2604 .open = spufs_ctx_open,
2605 .read = seq_read,
2606 .llseek = seq_lseek,
2607 .release = single_release,
2608};
2609
2610struct spufs_tree_descr spufs_dir_contents[] = {
2557 { "capabilities", &spufs_caps_fops, 0444, }, 2611 { "capabilities", &spufs_caps_fops, 0444, },
2558 { "mem", &spufs_mem_fops, 0666, }, 2612 { "mem", &spufs_mem_fops, 0666, LS_SIZE, },
2559 { "regs", &spufs_regs_fops, 0666, }, 2613 { "regs", &spufs_regs_fops, 0666, sizeof(struct spu_reg128[128]), },
2560 { "mbox", &spufs_mbox_fops, 0444, }, 2614 { "mbox", &spufs_mbox_fops, 0444, },
2561 { "ibox", &spufs_ibox_fops, 0444, }, 2615 { "ibox", &spufs_ibox_fops, 0444, },
2562 { "wbox", &spufs_wbox_fops, 0222, }, 2616 { "wbox", &spufs_wbox_fops, 0222, },
2563 { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, 2617 { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), },
2564 { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, 2618 { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), },
2565 { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, 2619 { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), },
2566 { "signal1", &spufs_signal1_fops, 0666, }, 2620 { "signal1", &spufs_signal1_fops, 0666, },
2567 { "signal2", &spufs_signal2_fops, 0666, }, 2621 { "signal2", &spufs_signal2_fops, 0666, },
2568 { "signal1_type", &spufs_signal1_type, 0666, }, 2622 { "signal1_type", &spufs_signal1_type, 0666, },
2569 { "signal2_type", &spufs_signal2_type, 0666, }, 2623 { "signal2_type", &spufs_signal2_type, 0666, },
2570 { "cntl", &spufs_cntl_fops, 0666, }, 2624 { "cntl", &spufs_cntl_fops, 0666, },
2571 { "fpcr", &spufs_fpcr_fops, 0666, }, 2625 { "fpcr", &spufs_fpcr_fops, 0666, sizeof(struct spu_reg128), },
2572 { "lslr", &spufs_lslr_ops, 0444, }, 2626 { "lslr", &spufs_lslr_ops, 0444, },
2573 { "mfc", &spufs_mfc_fops, 0666, }, 2627 { "mfc", &spufs_mfc_fops, 0666, },
2574 { "mss", &spufs_mss_fops, 0666, }, 2628 { "mss", &spufs_mss_fops, 0666, },
@@ -2578,29 +2632,31 @@ struct tree_descr spufs_dir_contents[] = {
2578 { "decr_status", &spufs_decr_status_ops, 0666, }, 2632 { "decr_status", &spufs_decr_status_ops, 0666, },
2579 { "event_mask", &spufs_event_mask_ops, 0666, }, 2633 { "event_mask", &spufs_event_mask_ops, 0666, },
2580 { "event_status", &spufs_event_status_ops, 0444, }, 2634 { "event_status", &spufs_event_status_ops, 0444, },
2581 { "psmap", &spufs_psmap_fops, 0666, }, 2635 { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, },
2582 { "phys-id", &spufs_id_ops, 0666, }, 2636 { "phys-id", &spufs_id_ops, 0666, },
2583 { "object-id", &spufs_object_id_ops, 0666, }, 2637 { "object-id", &spufs_object_id_ops, 0666, },
2584 { "mbox_info", &spufs_mbox_info_fops, 0444, }, 2638 { "mbox_info", &spufs_mbox_info_fops, 0444, sizeof(u32), },
2585 { "ibox_info", &spufs_ibox_info_fops, 0444, }, 2639 { "ibox_info", &spufs_ibox_info_fops, 0444, sizeof(u32), },
2586 { "wbox_info", &spufs_wbox_info_fops, 0444, }, 2640 { "wbox_info", &spufs_wbox_info_fops, 0444, sizeof(u32), },
2587 { "dma_info", &spufs_dma_info_fops, 0444, }, 2641 { "dma_info", &spufs_dma_info_fops, 0444,
2588 { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, 2642 sizeof(struct spu_dma_info), },
2643 { "proxydma_info", &spufs_proxydma_info_fops, 0444,
2644 sizeof(struct spu_proxydma_info)},
2589 { "tid", &spufs_tid_fops, 0444, }, 2645 { "tid", &spufs_tid_fops, 0444, },
2590 { "stat", &spufs_stat_fops, 0444, }, 2646 { "stat", &spufs_stat_fops, 0444, },
2591 { "switch_log", &spufs_switch_log_fops, 0444 }, 2647 { "switch_log", &spufs_switch_log_fops, 0444 },
2592 {}, 2648 {},
2593}; 2649};
2594 2650
2595struct tree_descr spufs_dir_nosched_contents[] = { 2651struct spufs_tree_descr spufs_dir_nosched_contents[] = {
2596 { "capabilities", &spufs_caps_fops, 0444, }, 2652 { "capabilities", &spufs_caps_fops, 0444, },
2597 { "mem", &spufs_mem_fops, 0666, }, 2653 { "mem", &spufs_mem_fops, 0666, LS_SIZE, },
2598 { "mbox", &spufs_mbox_fops, 0444, }, 2654 { "mbox", &spufs_mbox_fops, 0444, },
2599 { "ibox", &spufs_ibox_fops, 0444, }, 2655 { "ibox", &spufs_ibox_fops, 0444, },
2600 { "wbox", &spufs_wbox_fops, 0222, }, 2656 { "wbox", &spufs_wbox_fops, 0222, },
2601 { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, 2657 { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), },
2602 { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, 2658 { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), },
2603 { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, 2659 { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), },
2604 { "signal1", &spufs_signal1_nosched_fops, 0222, }, 2660 { "signal1", &spufs_signal1_nosched_fops, 0222, },
2605 { "signal2", &spufs_signal2_nosched_fops, 0222, }, 2661 { "signal2", &spufs_signal2_nosched_fops, 0222, },
2606 { "signal1_type", &spufs_signal1_type, 0666, }, 2662 { "signal1_type", &spufs_signal1_type, 0666, },
@@ -2609,7 +2665,7 @@ struct tree_descr spufs_dir_nosched_contents[] = {
2609 { "mfc", &spufs_mfc_fops, 0666, }, 2665 { "mfc", &spufs_mfc_fops, 0666, },
2610 { "cntl", &spufs_cntl_fops, 0666, }, 2666 { "cntl", &spufs_cntl_fops, 0666, },
2611 { "npc", &spufs_npc_ops, 0666, }, 2667 { "npc", &spufs_npc_ops, 0666, },
2612 { "psmap", &spufs_psmap_fops, 0666, }, 2668 { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, },
2613 { "phys-id", &spufs_id_ops, 0666, }, 2669 { "phys-id", &spufs_id_ops, 0666, },
2614 { "object-id", &spufs_object_id_ops, 0666, }, 2670 { "object-id", &spufs_object_id_ops, 0666, },
2615 { "tid", &spufs_tid_fops, 0444, }, 2671 { "tid", &spufs_tid_fops, 0444, },
@@ -2617,6 +2673,11 @@ struct tree_descr spufs_dir_nosched_contents[] = {
2617 {}, 2673 {},
2618}; 2674};
2619 2675
2676struct spufs_tree_descr spufs_dir_debug_contents[] = {
2677 { ".ctx", &spufs_ctx_fops, 0444, },
2678 {},
2679};
2680
2620struct spufs_coredump_reader spufs_coredump_read[] = { 2681struct spufs_coredump_reader spufs_coredump_read[] = {
2621 { "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])}, 2682 { "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])},
2622 { "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) }, 2683 { "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) },
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index f407b2471855..7123472801d9 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -42,10 +42,19 @@
42 42
43#include "spufs.h" 43#include "spufs.h"
44 44
45struct spufs_sb_info {
46 int debug;
47};
48
45static struct kmem_cache *spufs_inode_cache; 49static struct kmem_cache *spufs_inode_cache;
46char *isolated_loader; 50char *isolated_loader;
47static int isolated_loader_size; 51static int isolated_loader_size;
48 52
53static struct spufs_sb_info *spufs_get_sb_info(struct super_block *sb)
54{
55 return sb->s_fs_info;
56}
57
49static struct inode * 58static struct inode *
50spufs_alloc_inode(struct super_block *sb) 59spufs_alloc_inode(struct super_block *sb)
51{ 60{
@@ -109,7 +118,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
109static int 118static int
110spufs_new_file(struct super_block *sb, struct dentry *dentry, 119spufs_new_file(struct super_block *sb, struct dentry *dentry,
111 const struct file_operations *fops, int mode, 120 const struct file_operations *fops, int mode,
112 struct spu_context *ctx) 121 size_t size, struct spu_context *ctx)
113{ 122{
114 static struct inode_operations spufs_file_iops = { 123 static struct inode_operations spufs_file_iops = {
115 .setattr = spufs_setattr, 124 .setattr = spufs_setattr,
@@ -125,6 +134,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry,
125 ret = 0; 134 ret = 0;
126 inode->i_op = &spufs_file_iops; 135 inode->i_op = &spufs_file_iops;
127 inode->i_fop = fops; 136 inode->i_fop = fops;
137 inode->i_size = size;
128 inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); 138 inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx);
129 d_add(dentry, inode); 139 d_add(dentry, inode);
130out: 140out:
@@ -177,7 +187,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir)
177 return simple_rmdir(parent, dir); 187 return simple_rmdir(parent, dir);
178} 188}
179 189
180static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, 190static int spufs_fill_dir(struct dentry *dir, struct spufs_tree_descr *files,
181 int mode, struct spu_context *ctx) 191 int mode, struct spu_context *ctx)
182{ 192{
183 struct dentry *dentry, *tmp; 193 struct dentry *dentry, *tmp;
@@ -189,7 +199,7 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
189 if (!dentry) 199 if (!dentry)
190 goto out; 200 goto out;
191 ret = spufs_new_file(dir->d_sb, dentry, files->ops, 201 ret = spufs_new_file(dir->d_sb, dentry, files->ops,
192 files->mode & mode, ctx); 202 files->mode & mode, files->size, ctx);
193 if (ret) 203 if (ret)
194 goto out; 204 goto out;
195 files++; 205 files++;
@@ -279,6 +289,13 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
279 if (ret) 289 if (ret)
280 goto out_free_ctx; 290 goto out_free_ctx;
281 291
292 if (spufs_get_sb_info(dir->i_sb)->debug)
293 ret = spufs_fill_dir(dentry, spufs_dir_debug_contents,
294 mode, ctx);
295
296 if (ret)
297 goto out_free_ctx;
298
282 d_instantiate(dentry, inode); 299 d_instantiate(dentry, inode);
283 dget(dentry); 300 dget(dentry);
284 dir->i_nlink++; 301 dir->i_nlink++;
@@ -639,18 +656,19 @@ out:
639 656
640/* File system initialization */ 657/* File system initialization */
641enum { 658enum {
642 Opt_uid, Opt_gid, Opt_mode, Opt_err, 659 Opt_uid, Opt_gid, Opt_mode, Opt_debug, Opt_err,
643}; 660};
644 661
645static match_table_t spufs_tokens = { 662static match_table_t spufs_tokens = {
646 { Opt_uid, "uid=%d" }, 663 { Opt_uid, "uid=%d" },
647 { Opt_gid, "gid=%d" }, 664 { Opt_gid, "gid=%d" },
648 { Opt_mode, "mode=%o" }, 665 { Opt_mode, "mode=%o" },
649 { Opt_err, NULL }, 666 { Opt_debug, "debug" },
667 { Opt_err, NULL },
650}; 668};
651 669
652static int 670static int
653spufs_parse_options(char *options, struct inode *root) 671spufs_parse_options(struct super_block *sb, char *options, struct inode *root)
654{ 672{
655 char *p; 673 char *p;
656 substring_t args[MAX_OPT_ARGS]; 674 substring_t args[MAX_OPT_ARGS];
@@ -678,6 +696,9 @@ spufs_parse_options(char *options, struct inode *root)
678 return 0; 696 return 0;
679 root->i_mode = option | S_IFDIR; 697 root->i_mode = option | S_IFDIR;
680 break; 698 break;
699 case Opt_debug:
700 spufs_get_sb_info(sb)->debug = 1;
701 break;
681 default: 702 default:
682 return 0; 703 return 0;
683 } 704 }
@@ -736,7 +757,7 @@ spufs_create_root(struct super_block *sb, void *data)
736 SPUFS_I(inode)->i_ctx = NULL; 757 SPUFS_I(inode)->i_ctx = NULL;
737 758
738 ret = -EINVAL; 759 ret = -EINVAL;
739 if (!spufs_parse_options(data, inode)) 760 if (!spufs_parse_options(sb, data, inode))
740 goto out_iput; 761 goto out_iput;
741 762
742 ret = -ENOMEM; 763 ret = -ENOMEM;
@@ -754,6 +775,7 @@ out:
754static int 775static int
755spufs_fill_super(struct super_block *sb, void *data, int silent) 776spufs_fill_super(struct super_block *sb, void *data, int silent)
756{ 777{
778 struct spufs_sb_info *info;
757 static struct super_operations s_ops = { 779 static struct super_operations s_ops = {
758 .alloc_inode = spufs_alloc_inode, 780 .alloc_inode = spufs_alloc_inode,
759 .destroy_inode = spufs_destroy_inode, 781 .destroy_inode = spufs_destroy_inode,
@@ -765,11 +787,16 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
765 787
766 save_mount_options(sb, data); 788 save_mount_options(sb, data);
767 789
790 info = kzalloc(sizeof(*info), GFP_KERNEL);
791 if (!info)
792 return -ENOMEM;
793
768 sb->s_maxbytes = MAX_LFS_FILESIZE; 794 sb->s_maxbytes = MAX_LFS_FILESIZE;
769 sb->s_blocksize = PAGE_CACHE_SIZE; 795 sb->s_blocksize = PAGE_CACHE_SIZE;
770 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 796 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
771 sb->s_magic = SPUFS_MAGIC; 797 sb->s_magic = SPUFS_MAGIC;
772 sb->s_op = &s_ops; 798 sb->s_op = &s_ops;
799 sb->s_fs_info = info;
773 800
774 return spufs_create_root(sb, data); 801 return spufs_create_root(sb, data);
775} 802}
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index b7493b865812..f7edba6cb795 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -27,7 +27,6 @@ void spufs_stop_callback(struct spu *spu, int irq)
27 switch(irq) { 27 switch(irq) {
28 case 0 : 28 case 0 :
29 ctx->csa.class_0_pending = spu->class_0_pending; 29 ctx->csa.class_0_pending = spu->class_0_pending;
30 ctx->csa.class_0_dsisr = spu->class_0_dsisr;
31 ctx->csa.class_0_dar = spu->class_0_dar; 30 ctx->csa.class_0_dar = spu->class_0_dar;
32 break; 31 break;
33 case 1 : 32 case 1 :
@@ -51,18 +50,22 @@ int spu_stopped(struct spu_context *ctx, u32 *stat)
51 u64 dsisr; 50 u64 dsisr;
52 u32 stopped; 51 u32 stopped;
53 52
54 *stat = ctx->ops->status_read(ctx);
55
56 if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
57 return 1;
58
59 stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP | 53 stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP |
60 SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; 54 SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP;
61 if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped)) 55
56top:
57 *stat = ctx->ops->status_read(ctx);
58 if (*stat & stopped) {
59 /*
60 * If the spu hasn't finished stopping, we need to
61 * re-read the register to get the stopped value.
62 */
63 if (*stat & SPU_STATUS_RUNNING)
64 goto top;
62 return 1; 65 return 1;
66 }
63 67
64 dsisr = ctx->csa.class_0_dsisr; 68 if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
65 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
66 return 1; 69 return 1;
67 70
68 dsisr = ctx->csa.class_1_dsisr; 71 dsisr = ctx->csa.class_1_dsisr;
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 745dd51ec37f..34654743363d 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -230,19 +230,23 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
230 ctx->stats.slb_flt_base = spu->stats.slb_flt; 230 ctx->stats.slb_flt_base = spu->stats.slb_flt;
231 ctx->stats.class2_intr_base = spu->stats.class2_intr; 231 ctx->stats.class2_intr_base = spu->stats.class2_intr;
232 232
233 spu_associate_mm(spu, ctx->owner);
234
235 spin_lock_irq(&spu->register_lock);
233 spu->ctx = ctx; 236 spu->ctx = ctx;
234 spu->flags = 0; 237 spu->flags = 0;
235 ctx->spu = spu; 238 ctx->spu = spu;
236 ctx->ops = &spu_hw_ops; 239 ctx->ops = &spu_hw_ops;
237 spu->pid = current->pid; 240 spu->pid = current->pid;
238 spu->tgid = current->tgid; 241 spu->tgid = current->tgid;
239 spu_associate_mm(spu, ctx->owner);
240 spu->ibox_callback = spufs_ibox_callback; 242 spu->ibox_callback = spufs_ibox_callback;
241 spu->wbox_callback = spufs_wbox_callback; 243 spu->wbox_callback = spufs_wbox_callback;
242 spu->stop_callback = spufs_stop_callback; 244 spu->stop_callback = spufs_stop_callback;
243 spu->mfc_callback = spufs_mfc_callback; 245 spu->mfc_callback = spufs_mfc_callback;
244 mb(); 246 spin_unlock_irq(&spu->register_lock);
247
245 spu_unmap_mappings(ctx); 248 spu_unmap_mappings(ctx);
249
246 spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0); 250 spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0);
247 spu_restore(&ctx->csa, spu); 251 spu_restore(&ctx->csa, spu);
248 spu->timestamp = jiffies; 252 spu->timestamp = jiffies;
@@ -403,6 +407,8 @@ static int has_affinity(struct spu_context *ctx)
403 */ 407 */
404static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) 408static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
405{ 409{
410 u32 status;
411
406 spu_context_trace(spu_unbind_context__enter, ctx, spu); 412 spu_context_trace(spu_unbind_context__enter, ctx, spu);
407 413
408 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 414 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
@@ -423,18 +429,22 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
423 spu_unmap_mappings(ctx); 429 spu_unmap_mappings(ctx);
424 spu_save(&ctx->csa, spu); 430 spu_save(&ctx->csa, spu);
425 spu_switch_log_notify(spu, ctx, SWITCH_LOG_STOP, 0); 431 spu_switch_log_notify(spu, ctx, SWITCH_LOG_STOP, 0);
432
433 spin_lock_irq(&spu->register_lock);
426 spu->timestamp = jiffies; 434 spu->timestamp = jiffies;
427 ctx->state = SPU_STATE_SAVED; 435 ctx->state = SPU_STATE_SAVED;
428 spu->ibox_callback = NULL; 436 spu->ibox_callback = NULL;
429 spu->wbox_callback = NULL; 437 spu->wbox_callback = NULL;
430 spu->stop_callback = NULL; 438 spu->stop_callback = NULL;
431 spu->mfc_callback = NULL; 439 spu->mfc_callback = NULL;
432 spu_associate_mm(spu, NULL);
433 spu->pid = 0; 440 spu->pid = 0;
434 spu->tgid = 0; 441 spu->tgid = 0;
435 ctx->ops = &spu_backing_ops; 442 ctx->ops = &spu_backing_ops;
436 spu->flags = 0; 443 spu->flags = 0;
437 spu->ctx = NULL; 444 spu->ctx = NULL;
445 spin_unlock_irq(&spu->register_lock);
446
447 spu_associate_mm(spu, NULL);
438 448
439 ctx->stats.slb_flt += 449 ctx->stats.slb_flt +=
440 (spu->stats.slb_flt - ctx->stats.slb_flt_base); 450 (spu->stats.slb_flt - ctx->stats.slb_flt_base);
@@ -444,6 +454,9 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
444 /* This maps the underlying spu state to idle */ 454 /* This maps the underlying spu state to idle */
445 spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); 455 spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED);
446 ctx->spu = NULL; 456 ctx->spu = NULL;
457
458 if (spu_stopped(ctx, &status))
459 wake_up_all(&ctx->stop_wq);
447} 460}
448 461
449/** 462/**
@@ -886,7 +899,8 @@ static noinline void spusched_tick(struct spu_context *ctx)
886 spu_add_to_rq(ctx); 899 spu_add_to_rq(ctx);
887 } else { 900 } else {
888 spu_context_nospu_trace(spusched_tick__newslice, ctx); 901 spu_context_nospu_trace(spusched_tick__newslice, ctx);
889 ctx->time_slice++; 902 if (!ctx->time_slice)
903 ctx->time_slice++;
890 } 904 }
891out: 905out:
892 spu_release(ctx); 906 spu_release(ctx);
@@ -980,6 +994,7 @@ void spuctx_switch_state(struct spu_context *ctx,
980 struct timespec ts; 994 struct timespec ts;
981 struct spu *spu; 995 struct spu *spu;
982 enum spu_utilization_state old_state; 996 enum spu_utilization_state old_state;
997 int node;
983 998
984 ktime_get_ts(&ts); 999 ktime_get_ts(&ts);
985 curtime = timespec_to_ns(&ts); 1000 curtime = timespec_to_ns(&ts);
@@ -1001,6 +1016,11 @@ void spuctx_switch_state(struct spu_context *ctx,
1001 spu->stats.times[old_state] += delta; 1016 spu->stats.times[old_state] += delta;
1002 spu->stats.util_state = new_state; 1017 spu->stats.util_state = new_state;
1003 spu->stats.tstamp = curtime; 1018 spu->stats.tstamp = curtime;
1019 node = spu->node;
1020 if (old_state == SPU_UTIL_USER)
1021 atomic_dec(&cbe_spu_info[node].busy_spus);
1022 if (new_state == SPU_UTIL_USER);
1023 atomic_inc(&cbe_spu_info[node].busy_spus);
1004 } 1024 }
1005} 1025}
1006 1026
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 454c277c1457..8ae8ef9dfc22 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -32,6 +32,13 @@
32#include <asm/spu_csa.h> 32#include <asm/spu_csa.h>
33#include <asm/spu_info.h> 33#include <asm/spu_info.h>
34 34
35#define SPUFS_PS_MAP_SIZE 0x20000
36#define SPUFS_MFC_MAP_SIZE 0x1000
37#define SPUFS_CNTL_MAP_SIZE 0x1000
38#define SPUFS_CNTL_MAP_SIZE 0x1000
39#define SPUFS_SIGNAL_MAP_SIZE PAGE_SIZE
40#define SPUFS_MSS_MAP_SIZE 0x1000
41
35/* The magic number for our file system */ 42/* The magic number for our file system */
36enum { 43enum {
37 SPUFS_MAGIC = 0x23c9b64e, 44 SPUFS_MAGIC = 0x23c9b64e,
@@ -228,8 +235,16 @@ struct spufs_inode_info {
228#define SPUFS_I(inode) \ 235#define SPUFS_I(inode) \
229 container_of(inode, struct spufs_inode_info, vfs_inode) 236 container_of(inode, struct spufs_inode_info, vfs_inode)
230 237
231extern struct tree_descr spufs_dir_contents[]; 238struct spufs_tree_descr {
232extern struct tree_descr spufs_dir_nosched_contents[]; 239 const char *name;
240 const struct file_operations *ops;
241 int mode;
242 size_t size;
243};
244
245extern struct spufs_tree_descr spufs_dir_contents[];
246extern struct spufs_tree_descr spufs_dir_nosched_contents[];
247extern struct spufs_tree_descr spufs_dir_debug_contents[];
233 248
234/* system call implementation */ 249/* system call implementation */
235extern struct spufs_calls spufs_calls; 250extern struct spufs_calls spufs_calls;
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
index 53202422ba72..8c0e95766a62 100644
--- a/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -182,10 +182,10 @@ struct spu_probe spu_probes[] = {
182 { "spu_yield__enter", "ctx %p", spu_context_nospu_event }, 182 { "spu_yield__enter", "ctx %p", spu_context_nospu_event },
183 { "spu_deactivate__enter", "ctx %p", spu_context_nospu_event }, 183 { "spu_deactivate__enter", "ctx %p", spu_context_nospu_event },
184 { "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event }, 184 { "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event },
185 { "spufs_ps_nopfn__enter", "ctx %p", spu_context_nospu_event }, 185 { "spufs_ps_fault__enter", "ctx %p", spu_context_nospu_event },
186 { "spufs_ps_nopfn__sleep", "ctx %p", spu_context_nospu_event }, 186 { "spufs_ps_fault__sleep", "ctx %p", spu_context_nospu_event },
187 { "spufs_ps_nopfn__wake", "ctx %p spu %p", spu_context_event }, 187 { "spufs_ps_fault__wake", "ctx %p spu %p", spu_context_event },
188 { "spufs_ps_nopfn__insert", "ctx %p spu %p", spu_context_event }, 188 { "spufs_ps_fault__insert", "ctx %p spu %p", spu_context_event },
189 { "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event }, 189 { "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event },
190 { "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event }, 190 { "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event },
191 { "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event }, 191 { "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event },
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 116babbaaf81..1ba7ce5aafae 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -63,13 +63,6 @@ static struct mpic *chrp_mpic;
63DEFINE_PER_CPU(struct timer_list, heartbeat_timer); 63DEFINE_PER_CPU(struct timer_list, heartbeat_timer);
64unsigned long event_scan_interval; 64unsigned long event_scan_interval;
65 65
66/*
67 * XXX this should be in xmon.h, but putting it there means xmon.h
68 * has to include <linux/interrupt.h> (to get irqreturn_t), which
69 * causes all sorts of problems. -- paulus
70 */
71extern irqreturn_t xmon_irq(int, void *);
72
73extern unsigned long loops_per_jiffy; 66extern unsigned long loops_per_jiffy;
74 67
75/* To be replaced by RTAS when available */ 68/* To be replaced by RTAS when available */
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 429088967813..4f9f8184d164 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -59,6 +59,16 @@ config PPC_PRPMC2800
59 help 59 help
60 This option enables support for the Motorola PrPMC2800 board 60 This option enables support for the Motorola PrPMC2800 board
61 61
62config PPC_C2K
63 bool "SBS/GEFanuc C2K board"
64 depends on EMBEDDED6xx
65 select MV64X60
66 select NOT_COHERENT_CACHE
67 select MTD_CFI_I4
68 help
69 This option enables support for the GE Fanuc C2K board (formerly
70 an SBS board).
71
62config TSI108_BRIDGE 72config TSI108_BRIDGE
63 bool 73 bool
64 select PCI 74 select PCI
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index 06524d3ffd2e..0773c08bd444 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
6obj-$(CONFIG_STORCENTER) += storcenter.o 6obj-$(CONFIG_STORCENTER) += storcenter.o
7obj-$(CONFIG_PPC_HOLLY) += holly.o 7obj-$(CONFIG_PPC_HOLLY) += holly.o
8obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o 8obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
9obj-$(CONFIG_PPC_C2K) += c2k.o
diff --git a/arch/powerpc/platforms/embedded6xx/c2k.c b/arch/powerpc/platforms/embedded6xx/c2k.c
new file mode 100644
index 000000000000..d0b25b8c39d1
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/c2k.c
@@ -0,0 +1,158 @@
1/*
2 * Board setup routines for the GEFanuc C2K board
3 *
4 * Author: Remi Machet <rmachet@slac.stanford.edu>
5 *
6 * Originated from prpmc2800.c
7 *
8 * 2008 (c) Stanford University
9 * 2007 (c) MontaVista, Software, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation.
14 */
15
16#include <linux/stddef.h>
17#include <linux/kernel.h>
18#include <linux/delay.h>
19#include <linux/interrupt.h>
20#include <linux/seq_file.h>
21#include <linux/time.h>
22#include <linux/of.h>
23#include <linux/kexec.h>
24
25#include <asm/machdep.h>
26#include <asm/prom.h>
27#include <asm/system.h>
28#include <asm/time.h>
29
30#include <mm/mmu_decl.h>
31
32#include <sysdev/mv64x60.h>
33
34#define MV64x60_MPP_CNTL_0 0x0000
35#define MV64x60_MPP_CNTL_2 0x0008
36
37#define MV64x60_GPP_IO_CNTL 0x0000
38#define MV64x60_GPP_LEVEL_CNTL 0x0010
39#define MV64x60_GPP_VALUE_SET 0x0018
40
41static void __iomem *mv64x60_mpp_reg_base;
42static void __iomem *mv64x60_gpp_reg_base;
43
44static void __init c2k_setup_arch(void)
45{
46 struct device_node *np;
47 phys_addr_t paddr;
48 const unsigned int *reg;
49
50 /*
51 * ioremap mpp and gpp registers in case they are later
52 * needed by c2k_reset_board().
53 */
54 np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
55 reg = of_get_property(np, "reg", NULL);
56 paddr = of_translate_address(np, reg);
57 of_node_put(np);
58 mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
59
60 np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
61 reg = of_get_property(np, "reg", NULL);
62 paddr = of_translate_address(np, reg);
63 of_node_put(np);
64 mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
65
66#ifdef CONFIG_PCI
67 mv64x60_pci_init();
68#endif
69}
70
71static void c2k_reset_board(void)
72{
73 u32 temp;
74
75 local_irq_disable();
76
77 temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
78 temp &= 0xFFFF0FFF;
79 out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
80
81 temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
82 temp |= 0x00000004;
83 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
84
85 temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
86 temp |= 0x00000004;
87 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
88
89 temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
90 temp &= 0xFFFF0FFF;
91 out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
92
93 temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
94 temp |= 0x00080000;
95 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
96
97 temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
98 temp |= 0x00080000;
99 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
100
101 out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
102}
103
104static void c2k_restart(char *cmd)
105{
106 c2k_reset_board();
107 msleep(100);
108 panic("restart failed\n");
109}
110
111#ifdef CONFIG_NOT_COHERENT_CACHE
112#define COHERENCY_SETTING "off"
113#else
114#define COHERENCY_SETTING "on"
115#endif
116
117void c2k_show_cpuinfo(struct seq_file *m)
118{
119 uint memsize = total_memory;
120
121 seq_printf(m, "Vendor\t\t: GEFanuc\n");
122 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
123 seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING);
124}
125
126/*
127 * Called very early, device-tree isn't unflattened
128 */
129static int __init c2k_probe(void)
130{
131 unsigned long root = of_get_flat_dt_root();
132
133 if (!of_flat_dt_is_compatible(root, "GEFanuc,C2K"))
134 return 0;
135
136 printk(KERN_INFO "Detected a GEFanuc C2K board\n");
137
138 _set_L2CR(0);
139 _set_L2CR(L2CR_L2E | L2CR_L2PE | L2CR_L2I);
140 return 1;
141}
142
143define_machine(c2k) {
144 .name = "C2K",
145 .probe = c2k_probe,
146 .setup_arch = c2k_setup_arch,
147 .init_early = mv64x60_init_early,
148 .show_cpuinfo = c2k_show_cpuinfo,
149 .init_IRQ = mv64x60_init_irq,
150 .get_irq = mv64x60_get_irq,
151 .restart = c2k_restart,
152 .calibrate_decr = generic_calibrate_decr,
153#ifdef CONFIG_KEXEC
154 .machine_kexec = default_machine_kexec,
155 .machine_kexec_prepare = default_machine_kexec_prepare,
156 .machine_crash_shutdown = default_machine_crash_shutdown,
157#endif
158};
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 11fa3c772ed5..ab5d8687c3cf 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -214,13 +214,13 @@ dma_addr_t iseries_hv_map(void *vaddr, size_t size,
214 enum dma_data_direction direction) 214 enum dma_data_direction direction)
215{ 215{
216 return iommu_map_single(NULL, &vio_iommu_table, vaddr, size, 216 return iommu_map_single(NULL, &vio_iommu_table, vaddr, size,
217 DMA_32BIT_MASK, direction); 217 DMA_32BIT_MASK, direction, NULL);
218} 218}
219 219
220void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, 220void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
221 enum dma_data_direction direction) 221 enum dma_data_direction direction)
222{ 222{
223 iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); 223 iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction, NULL);
224} 224}
225 225
226void __init iommu_vio_init(void) 226void __init iommu_vio_init(void)
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 9f7579b38c72..53bca132fb48 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -41,8 +41,6 @@
41#define DBG(x...) 41#define DBG(x...)
42#endif 42#endif
43 43
44extern void GregorianDay(struct rtc_time * tm);
45
46static int maple_rtc_addr; 44static int maple_rtc_addr;
47 45
48static int maple_clock_read(int addr) 46static int maple_clock_read(int addr)
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index 4d72c8f72159..89774177b209 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -1,5 +1,10 @@
1CFLAGS_bootx_init.o += -fPIC 1CFLAGS_bootx_init.o += -fPIC
2 2
3ifdef CONFIG_FTRACE
4# Do not trace early boot code
5CFLAGS_REMOVE_bootx_init.o = -pg
6endif
7
3obj-y += pic.o setup.o time.o feature.o pci.o \ 8obj-y += pic.o setup.o time.o feature.o pci.o \
4 sleep.o low_i2c.o cache.o pfunc_core.o \ 9 sleep.o low_i2c.o cache.o pfunc_core.o \
5 pfunc_base.o 10 pfunc_base.o
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 829b8b02527b..6d149ae8ffa7 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -34,16 +34,10 @@
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/pmac_feature.h> 35#include <asm/pmac_feature.h>
36#include <asm/mpic.h> 36#include <asm/mpic.h>
37#include <asm/xmon.h>
37 38
38#include "pmac.h" 39#include "pmac.h"
39 40
40/*
41 * XXX this should be in xmon.h, but putting it there means xmon.h
42 * has to include <linux/interrupt.h> (to get irqreturn_t), which
43 * causes all sorts of problems. -- paulus
44 */
45extern irqreturn_t xmon_irq(int, void *);
46
47#ifdef CONFIG_PPC32 41#ifdef CONFIG_PPC32
48struct pmac_irq_hw { 42struct pmac_irq_hw {
49 unsigned int event; 43 unsigned int event;
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index cb2d894541c6..4ae3d00e0bdd 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -36,6 +36,7 @@
36 36
37#include <asm/ptrace.h> 37#include <asm/ptrace.h>
38#include <asm/atomic.h> 38#include <asm/atomic.h>
39#include <asm/code-patching.h>
39#include <asm/irq.h> 40#include <asm/irq.h>
40#include <asm/page.h> 41#include <asm/page.h>
41#include <asm/pgtable.h> 42#include <asm/pgtable.h>
@@ -786,8 +787,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
786{ 787{
787 unsigned int save_vector; 788 unsigned int save_vector;
788 unsigned long target, flags; 789 unsigned long target, flags;
789 volatile unsigned int *vector 790 unsigned int *vector = (unsigned int *)(KERNELBASE+0x100);
790 = ((volatile unsigned int *)(KERNELBASE+0x100));
791 791
792 if (nr < 0 || nr > 3) 792 if (nr < 0 || nr > 3)
793 return; 793 return;
@@ -804,7 +804,7 @@ static void __devinit smp_core99_kick_cpu(int nr)
804 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE 804 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
805 */ 805 */
806 target = (unsigned long) __secondary_start_pmac_0 + nr * 8; 806 target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
807 create_branch((unsigned long)vector, target, BRANCH_SET_LINK); 807 patch_branch(vector, target, BRANCH_SET_LINK);
808 808
809 /* Put some life in our friend */ 809 /* Put some life in our friend */
810 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); 810 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index f0b12f212363..a0927a3bacb7 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -105,9 +105,10 @@ static void __init ps3_smp_setup_cpu(int cpu)
105 * to index needs to be setup. 105 * to index needs to be setup.
106 */ 106 */
107 107
108 BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0); 108 BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0);
109 BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1); 109 BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1);
110 BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); 110 BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2);
111 BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);
111 112
112 for (i = 0; i < MSG_COUNT; i++) { 113 for (i = 0; i < MSG_COUNT; i++) {
113 result = ps3_event_receive_port_setup(cpu, &virqs[i]); 114 result = ps3_event_receive_port_setup(cpu, &virqs[i]);
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 43c493fca2d0..d66c3628a112 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -349,9 +349,14 @@ static int ps3_system_bus_match(struct device *_dev,
349 349
350 result = dev->match_id == drv->match_id; 350 result = dev->match_id == drv->match_id;
351 351
352 pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__, 352 if (result)
353 dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name, 353 pr_info("%s:%d: dev=%u(%s), drv=%u(%s): match\n", __func__,
354 (result ? "match" : "miss")); 354 __LINE__, dev->match_id, dev->core.bus_id,
355 drv->match_id, drv->core.name);
356 else
357 pr_debug("%s:%d: dev=%u(%s), drv=%u(%s): miss\n", __func__,
358 __LINE__, dev->match_id, dev->core.bus_id,
359 drv->match_id, drv->core.name);
355 return result; 360 return result;
356} 361}
357 362
@@ -362,7 +367,7 @@ static int ps3_system_bus_probe(struct device *_dev)
362 struct ps3_system_bus_driver *drv; 367 struct ps3_system_bus_driver *drv;
363 368
364 BUG_ON(!dev); 369 BUG_ON(!dev);
365 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); 370 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
366 371
367 drv = ps3_system_bus_dev_to_system_bus_drv(dev); 372 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
368 BUG_ON(!drv); 373 BUG_ON(!drv);
@@ -370,10 +375,10 @@ static int ps3_system_bus_probe(struct device *_dev)
370 if (drv->probe) 375 if (drv->probe)
371 result = drv->probe(dev); 376 result = drv->probe(dev);
372 else 377 else
373 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, 378 pr_debug("%s:%d: %s no probe method\n", __func__, __LINE__,
374 dev->core.bus_id); 379 dev->core.bus_id);
375 380
376 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); 381 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
377 return result; 382 return result;
378} 383}
379 384
@@ -384,7 +389,7 @@ static int ps3_system_bus_remove(struct device *_dev)
384 struct ps3_system_bus_driver *drv; 389 struct ps3_system_bus_driver *drv;
385 390
386 BUG_ON(!dev); 391 BUG_ON(!dev);
387 pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id); 392 pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
388 393
389 drv = ps3_system_bus_dev_to_system_bus_drv(dev); 394 drv = ps3_system_bus_dev_to_system_bus_drv(dev);
390 BUG_ON(!drv); 395 BUG_ON(!drv);
@@ -395,7 +400,7 @@ static int ps3_system_bus_remove(struct device *_dev)
395 dev_dbg(&dev->core, "%s:%d %s: no remove method\n", 400 dev_dbg(&dev->core, "%s:%d %s: no remove method\n",
396 __func__, __LINE__, drv->core.name); 401 __func__, __LINE__, drv->core.name);
397 402
398 pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id); 403 pr_debug(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
399 return result; 404 return result;
400} 405}
401 406
@@ -550,7 +555,7 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
550 */ 555 */
551 556
552static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size, 557static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
553 enum dma_data_direction direction) 558 enum dma_data_direction direction, struct dma_attrs *attrs)
554{ 559{
555 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 560 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
556 int result; 561 int result;
@@ -570,7 +575,8 @@ static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
570 575
571static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, 576static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
572 size_t size, 577 size_t size,
573 enum dma_data_direction direction) 578 enum dma_data_direction direction,
579 struct dma_attrs *attrs)
574{ 580{
575 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 581 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
576 int result; 582 int result;
@@ -603,7 +609,7 @@ static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
603} 609}
604 610
605static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, 611static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
606 size_t size, enum dma_data_direction direction) 612 size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
607{ 613{
608 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 614 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
609 int result; 615 int result;
@@ -617,7 +623,7 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
617} 623}
618 624
619static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl, 625static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
620 int nents, enum dma_data_direction direction) 626 int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
621{ 627{
622#if defined(CONFIG_PS3_DYNAMIC_DMA) 628#if defined(CONFIG_PS3_DYNAMIC_DMA)
623 BUG_ON("do"); 629 BUG_ON("do");
@@ -646,14 +652,15 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
646 652
647static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg, 653static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
648 int nents, 654 int nents,
649 enum dma_data_direction direction) 655 enum dma_data_direction direction,
656 struct dma_attrs *attrs)
650{ 657{
651 BUG(); 658 BUG();
652 return 0; 659 return 0;
653} 660}
654 661
655static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg, 662static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
656 int nents, enum dma_data_direction direction) 663 int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
657{ 664{
658#if defined(CONFIG_PS3_DYNAMIC_DMA) 665#if defined(CONFIG_PS3_DYNAMIC_DMA)
659 BUG_ON("do"); 666 BUG_ON("do");
@@ -661,7 +668,8 @@ static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
661} 668}
662 669
663static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg, 670static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
664 int nents, enum dma_data_direction direction) 671 int nents, enum dma_data_direction direction,
672 struct dma_attrs *attrs)
665{ 673{
666 BUG(); 674 BUG();
667} 675}
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 6f544ba4b37f..c027f0a70a04 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -812,6 +812,7 @@ int rtas_set_slot_reset(struct pci_dn *pdn)
812static inline void __restore_bars (struct pci_dn *pdn) 812static inline void __restore_bars (struct pci_dn *pdn)
813{ 813{
814 int i; 814 int i;
815 u32 cmd;
815 816
816 if (NULL==pdn->phb) return; 817 if (NULL==pdn->phb) return;
817 for (i=4; i<10; i++) { 818 for (i=4; i<10; i++) {
@@ -832,6 +833,19 @@ static inline void __restore_bars (struct pci_dn *pdn)
832 833
833 /* max latency, min grant, interrupt pin and line */ 834 /* max latency, min grant, interrupt pin and line */
834 rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]); 835 rtas_write_config(pdn, 15*4, 4, pdn->config_space[15]);
836
837 /* Restore PERR & SERR bits, some devices require it,
838 don't touch the other command bits */
839 rtas_read_config(pdn, PCI_COMMAND, 4, &cmd);
840 if (pdn->config_space[1] & PCI_COMMAND_PARITY)
841 cmd |= PCI_COMMAND_PARITY;
842 else
843 cmd &= ~PCI_COMMAND_PARITY;
844 if (pdn->config_space[1] & PCI_COMMAND_SERR)
845 cmd |= PCI_COMMAND_SERR;
846 else
847 cmd &= ~PCI_COMMAND_SERR;
848 rtas_write_config(pdn, PCI_COMMAND, 4, cmd);
835} 849}
836 850
837/** 851/**
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 68ea5eee39a8..8c1ca477c52c 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -42,17 +42,20 @@ static inline const char * pcid_name (struct pci_dev *pdev)
42} 42}
43 43
44#ifdef DEBUG 44#ifdef DEBUG
45static void print_device_node_tree (struct pci_dn *pdn, int dent) 45static void print_device_node_tree(struct pci_dn *pdn, int dent)
46{ 46{
47 int i; 47 int i;
48 if (!pdn) return; 48 struct device_node *pc;
49 for (i=0;i<dent; i++) 49
50 if (!pdn)
51 return;
52 for (i = 0; i < dent; i++)
50 printk(" "); 53 printk(" ");
51 printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n", 54 printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
52 pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr, 55 pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
53 pdn->eeh_pe_config_addr, pdn->node->full_name); 56 pdn->eeh_pe_config_addr, pdn->node->full_name);
54 dent += 3; 57 dent += 3;
55 struct device_node *pc = pdn->node->child; 58 pc = pdn->node->child;
56 while (pc) { 59 while (pc) {
57 print_device_node_tree(PCI_DN(pc), dent); 60 print_device_node_tree(PCI_DN(pc), dent);
58 pc = pc->sibling; 61 pc = pc->sibling;
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 9d3a40f45974..5a707da3f5c2 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -26,6 +26,7 @@
26#include <asm/prom.h> 26#include <asm/prom.h>
27#include <asm/udbg.h> 27#include <asm/udbg.h>
28 28
29#include "pseries.h"
29 30
30typedef struct { 31typedef struct {
31 unsigned long val; 32 unsigned long val;
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 3c5727dd5aa5..a1a368dd2d99 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -15,34 +15,13 @@
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16#include <asm/pSeries_reconfig.h> 16#include <asm/pSeries_reconfig.h>
17 17
18static int pseries_remove_memory(struct device_node *np) 18static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
19{ 19{
20 const char *type; 20 unsigned long start, start_pfn;
21 const unsigned int *my_index;
22 const unsigned int *regs;
23 u64 start_pfn, start;
24 struct zone *zone; 21 struct zone *zone;
25 int ret = -EINVAL; 22 int ret;
26
27 /*
28 * Check to see if we are actually removing memory
29 */
30 type = of_get_property(np, "device_type", NULL);
31 if (type == NULL || strcmp(type, "memory") != 0)
32 return 0;
33 23
34 /* 24 start_pfn = base >> PFN_SECTION_SHIFT;
35 * Find the memory index and size of the removing section
36 */
37 my_index = of_get_property(np, "ibm,my-drc-index", NULL);
38 if (!my_index)
39 return ret;
40
41 regs = of_get_property(np, "reg", NULL);
42 if (!regs)
43 return ret;
44
45 start_pfn = section_nr_to_pfn(*my_index & 0xffff);
46 zone = page_zone(pfn_to_page(start_pfn)); 25 zone = page_zone(pfn_to_page(start_pfn));
47 26
48 /* 27 /*
@@ -54,56 +33,111 @@ static int pseries_remove_memory(struct device_node *np)
54 * to sysfs "state" file and we can't remove sysfs entries 33 * to sysfs "state" file and we can't remove sysfs entries
55 * while writing to it. So we have to defer it to here. 34 * while writing to it. So we have to defer it to here.
56 */ 35 */
57 ret = __remove_pages(zone, start_pfn, regs[3] >> PAGE_SHIFT); 36 ret = __remove_pages(zone, start_pfn, lmb_size >> PAGE_SHIFT);
58 if (ret) 37 if (ret)
59 return ret; 38 return ret;
60 39
61 /* 40 /*
62 * Update memory regions for memory remove 41 * Update memory regions for memory remove
63 */ 42 */
64 lmb_remove(start_pfn << PAGE_SHIFT, regs[3]); 43 lmb_remove(base, lmb_size);
65 44
66 /* 45 /*
67 * Remove htab bolted mappings for this section of memory 46 * Remove htab bolted mappings for this section of memory
68 */ 47 */
69 start = (unsigned long)__va(start_pfn << PAGE_SHIFT); 48 start = (unsigned long)__va(base);
70 ret = remove_section_mapping(start, start + regs[3]); 49 ret = remove_section_mapping(start, start + lmb_size);
71 return ret; 50 return ret;
72} 51}
73 52
74static int pseries_add_memory(struct device_node *np) 53static int pseries_remove_memory(struct device_node *np)
75{ 54{
76 const char *type; 55 const char *type;
77 const unsigned int *my_index;
78 const unsigned int *regs; 56 const unsigned int *regs;
79 u64 start_pfn; 57 unsigned long base;
58 unsigned int lmb_size;
80 int ret = -EINVAL; 59 int ret = -EINVAL;
81 60
82 /* 61 /*
83 * Check to see if we are actually adding memory 62 * Check to see if we are actually removing memory
84 */ 63 */
85 type = of_get_property(np, "device_type", NULL); 64 type = of_get_property(np, "device_type", NULL);
86 if (type == NULL || strcmp(type, "memory") != 0) 65 if (type == NULL || strcmp(type, "memory") != 0)
87 return 0; 66 return 0;
88 67
89 /* 68 /*
90 * Find the memory index and size of the added section 69 * Find the bae address and size of the lmb
91 */ 70 */
92 my_index = of_get_property(np, "ibm,my-drc-index", NULL); 71 regs = of_get_property(np, "reg", NULL);
93 if (!my_index) 72 if (!regs)
94 return ret; 73 return ret;
95 74
75 base = *(unsigned long *)regs;
76 lmb_size = regs[3];
77
78 ret = pseries_remove_lmb(base, lmb_size);
79 return ret;
80}
81
82static int pseries_add_memory(struct device_node *np)
83{
84 const char *type;
85 const unsigned int *regs;
86 unsigned long base;
87 unsigned int lmb_size;
88 int ret = -EINVAL;
89
90 /*
91 * Check to see if we are actually adding memory
92 */
93 type = of_get_property(np, "device_type", NULL);
94 if (type == NULL || strcmp(type, "memory") != 0)
95 return 0;
96
97 /*
98 * Find the base and size of the lmb
99 */
96 regs = of_get_property(np, "reg", NULL); 100 regs = of_get_property(np, "reg", NULL);
97 if (!regs) 101 if (!regs)
98 return ret; 102 return ret;
99 103
100 start_pfn = section_nr_to_pfn(*my_index & 0xffff); 104 base = *(unsigned long *)regs;
105 lmb_size = regs[3];
101 106
102 /* 107 /*
103 * Update memory region to represent the memory add 108 * Update memory region to represent the memory add
104 */ 109 */
105 lmb_add(start_pfn << PAGE_SHIFT, regs[3]); 110 ret = lmb_add(base, lmb_size);
106 return 0; 111 return (ret < 0) ? -EINVAL : 0;
112}
113
114static int pseries_drconf_memory(unsigned long *base, unsigned int action)
115{
116 struct device_node *np;
117 const unsigned long *lmb_size;
118 int rc;
119
120 np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
121 if (!np)
122 return -EINVAL;
123
124 lmb_size = of_get_property(np, "ibm,lmb-size", NULL);
125 if (!lmb_size) {
126 of_node_put(np);
127 return -EINVAL;
128 }
129
130 if (action == PSERIES_DRCONF_MEM_ADD) {
131 rc = lmb_add(*base, *lmb_size);
132 rc = (rc < 0) ? -EINVAL : 0;
133 } else if (action == PSERIES_DRCONF_MEM_REMOVE) {
134 rc = pseries_remove_lmb(*base, *lmb_size);
135 } else {
136 rc = -EINVAL;
137 }
138
139 of_node_put(np);
140 return rc;
107} 141}
108 142
109static int pseries_memory_notifier(struct notifier_block *nb, 143static int pseries_memory_notifier(struct notifier_block *nb,
@@ -120,6 +154,11 @@ static int pseries_memory_notifier(struct notifier_block *nb,
120 if (pseries_remove_memory(node)) 154 if (pseries_remove_memory(node))
121 err = NOTIFY_BAD; 155 err = NOTIFY_BAD;
122 break; 156 break;
157 case PSERIES_DRCONF_MEM_ADD:
158 case PSERIES_DRCONF_MEM_REMOVE:
159 if (pseries_drconf_memory(node, action))
160 err = NOTIFY_BAD;
161 break;
123 default: 162 default:
124 err = NOTIFY_DONE; 163 err = NOTIFY_DONE;
125 break; 164 break;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 176f1f39d2d5..9a12908510fb 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -135,9 +135,10 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
135 u64 rpn; 135 u64 rpn;
136 long l, limit; 136 long l, limit;
137 137
138 if (npages == 1) 138 if (npages == 1) {
139 return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, 139 tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction);
140 direction); 140 return;
141 }
141 142
142 tcep = __get_cpu_var(tce_page); 143 tcep = __get_cpu_var(tce_page);
143 144
@@ -147,9 +148,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
147 if (!tcep) { 148 if (!tcep) {
148 tcep = (u64 *)__get_free_page(GFP_ATOMIC); 149 tcep = (u64 *)__get_free_page(GFP_ATOMIC);
149 /* If allocation fails, fall back to the loop implementation */ 150 /* If allocation fails, fall back to the loop implementation */
150 if (!tcep) 151 if (!tcep) {
151 return tce_build_pSeriesLP(tbl, tcenum, npages, 152 tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
152 uaddr, direction); 153 direction);
154 return;
155 }
153 __get_cpu_var(tce_page) = tcep; 156 __get_cpu_var(tce_page) = tcep;
154 } 157 }
155 158
diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c
index e9dd5fe081c9..53cbd53d8740 100644
--- a/arch/powerpc/platforms/pseries/kexec.c
+++ b/arch/powerpc/platforms/pseries/kexec.c
@@ -70,4 +70,4 @@ static int __init pseries_kexec_setup(void)
70 70
71 return 0; 71 return 0;
72} 72}
73__initcall(pseries_kexec_setup); 73machine_device_initcall(pseries, pseries_kexec_setup);
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 2cbaedb17f3e..52a80e5840e8 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -52,7 +52,7 @@ EXPORT_SYMBOL(plpar_hcall_norets);
52extern void pSeries_find_serial_port(void); 52extern void pSeries_find_serial_port(void);
53 53
54 54
55int vtermno; /* virtual terminal# for udbg */ 55static int vtermno; /* virtual terminal# for udbg */
56 56
57#define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) 57#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
58static void udbg_hvsi_putc(char c) 58static void udbg_hvsi_putc(char c)
@@ -305,7 +305,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
305 flags = 0; 305 flags = 0;
306 306
307 /* Make pHyp happy */ 307 /* Make pHyp happy */
308 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) 308 if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))
309 hpte_r &= ~_PAGE_COHERENT; 309 hpte_r &= ~_PAGE_COHERENT;
310 310
311 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot); 311 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index f68903e15bd5..42f7e384e6c4 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -131,8 +131,10 @@ int __init pSeries_nvram_init(void)
131 return -ENODEV; 131 return -ENODEV;
132 132
133 nbytes_p = of_get_property(nvram, "#bytes", &proplen); 133 nbytes_p = of_get_property(nvram, "#bytes", &proplen);
134 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) 134 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) {
135 of_node_put(nvram);
135 return -EIO; 136 return -EIO;
137 }
136 138
137 nvram_size = *nbytes_p; 139 nvram_size = *nbytes_p;
138 140
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 2b548afd1003..d20b96e22c2e 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -55,7 +55,7 @@
55static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; 55static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX];
56static DEFINE_SPINLOCK(ras_log_buf_lock); 56static DEFINE_SPINLOCK(ras_log_buf_lock);
57 57
58char mce_data_buf[RTAS_ERROR_LOG_MAX]; 58static char mce_data_buf[RTAS_ERROR_LOG_MAX];
59 59
60static int ras_get_sensor_state_token; 60static int ras_get_sensor_state_token;
61static int ras_check_exception_token; 61static int ras_check_exception_token;
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 75769aae41d5..7637bd38c795 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -365,7 +365,7 @@ static char *parse_node(char *buf, size_t bufsize, struct device_node **npp)
365 *buf = '\0'; 365 *buf = '\0';
366 buf++; 366 buf++;
367 367
368 handle = simple_strtoul(handle_str, NULL, 10); 368 handle = simple_strtoul(handle_str, NULL, 0);
369 369
370 *npp = of_find_node_by_phandle(handle); 370 *npp = of_find_node_by_phandle(handle);
371 return buf; 371 return buf;
@@ -422,8 +422,8 @@ static int do_update_property(char *buf, size_t bufsize)
422{ 422{
423 struct device_node *np; 423 struct device_node *np;
424 unsigned char *value; 424 unsigned char *value;
425 char *name, *end; 425 char *name, *end, *next_prop;
426 int length; 426 int rc, length;
427 struct property *newprop, *oldprop; 427 struct property *newprop, *oldprop;
428 buf = parse_node(buf, bufsize, &np); 428 buf = parse_node(buf, bufsize, &np);
429 end = buf + bufsize; 429 end = buf + bufsize;
@@ -431,7 +431,8 @@ static int do_update_property(char *buf, size_t bufsize)
431 if (!np) 431 if (!np)
432 return -ENODEV; 432 return -ENODEV;
433 433
434 if (parse_next_property(buf, end, &name, &length, &value) == NULL) 434 next_prop = parse_next_property(buf, end, &name, &length, &value);
435 if (!next_prop)
435 return -EINVAL; 436 return -EINVAL;
436 437
437 newprop = new_property(name, length, value, NULL); 438 newprop = new_property(name, length, value, NULL);
@@ -442,7 +443,34 @@ static int do_update_property(char *buf, size_t bufsize)
442 if (!oldprop) 443 if (!oldprop)
443 return -ENODEV; 444 return -ENODEV;
444 445
445 return prom_update_property(np, newprop, oldprop); 446 rc = prom_update_property(np, newprop, oldprop);
447 if (rc)
448 return rc;
449
450 /* For memory under the ibm,dynamic-reconfiguration-memory node
451 * of the device tree, adding and removing memory is just an update
452 * to the ibm,dynamic-memory property instead of adding/removing a
453 * memory node in the device tree. For these cases we still need to
454 * involve the notifier chain.
455 */
456 if (!strcmp(name, "ibm,dynamic-memory")) {
457 int action;
458
459 next_prop = parse_next_property(next_prop, end, &name,
460 &length, &value);
461 if (!next_prop)
462 return -EINVAL;
463
464 if (!strcmp(name, "add"))
465 action = PSERIES_DRCONF_MEM_ADD;
466 else
467 action = PSERIES_DRCONF_MEM_REMOVE;
468
469 blocking_notifier_call_chain(&pSeries_reconfig_chain,
470 action, value);
471 }
472
473 return 0;
446} 474}
447 475
448/** 476/**
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index 7d3e2b0bd4d2..c9ffd8c225f1 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -32,7 +32,7 @@
32 32
33static DEFINE_SPINLOCK(rtasd_log_lock); 33static DEFINE_SPINLOCK(rtasd_log_lock);
34 34
35DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait); 35static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
36 36
37static char *rtas_log_buf; 37static char *rtas_log_buf;
38static unsigned long rtas_log_start; 38static unsigned long rtas_log_start;
@@ -329,7 +329,7 @@ static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
329 return 0; 329 return 0;
330} 330}
331 331
332const struct file_operations proc_rtas_log_operations = { 332static const struct file_operations proc_rtas_log_operations = {
333 .read = rtas_log_read, 333 .read = rtas_log_read,
334 .poll = rtas_log_poll, 334 .poll = rtas_log_poll,
335 .open = rtas_log_open, 335 .open = rtas_log_open,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index f5d29f5b13c1..90beb444e1dd 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -109,7 +109,7 @@ static void __init fwnmi_init(void)
109 fwnmi_active = 1; 109 fwnmi_active = 1;
110} 110}
111 111
112void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc) 112static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
113{ 113{
114 unsigned int cascade_irq = i8259_irq(); 114 unsigned int cascade_irq = i8259_irq();
115 if (cascade_irq != NO_IRQ) 115 if (cascade_irq != NO_IRQ)
@@ -482,7 +482,7 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
482 * possible with power button press. If ibm,power-off-ups token is used 482 * possible with power button press. If ibm,power-off-ups token is used
483 * it will allow auto poweron after power is restored. 483 * it will allow auto poweron after power is restored.
484 */ 484 */
485void pSeries_power_off(void) 485static void pSeries_power_off(void)
486{ 486{
487 int rc; 487 int rc;
488 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups"); 488 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index ebebc28fe895..0fc830f576f5 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -383,13 +383,11 @@ static irqreturn_t xics_ipi_dispatch(int cpu)
383 mb(); 383 mb();
384 smp_message_recv(PPC_MSG_RESCHEDULE); 384 smp_message_recv(PPC_MSG_RESCHEDULE);
385 } 385 }
386#if 0 386 if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE,
387 if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK,
388 &xics_ipi_message[cpu].value)) { 387 &xics_ipi_message[cpu].value)) {
389 mb(); 388 mb();
390 smp_message_recv(PPC_MSG_MIGRATE_TASK); 389 smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE);
391 } 390 }
392#endif
393#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) 391#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
394 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, 392 if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK,
395 &xics_ipi_message[cpu].value)) { 393 &xics_ipi_message[cpu].value)) {