summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-06-29 09:16:13 +0200
committerIngo Molnar <mingo@elte.hu>2009-06-29 09:16:25 +0200
commit348b346b238d9c0e5694c8d0b835a099cb383835 (patch)
tree967d9c72a1d6d33a408a1ff0d732296dbe8d3674 /arch/powerpc/platforms
parent6c697bdf08a09ce461e305a22362973036e95db3 (diff)
parent52989765629e7d182b4f146050ebba0abf2cb0b7 (diff)
Merge branch 'linus' into sched/core
Merge reason: we will merge a dependent patch. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/40x/Kconfig2
-rw-r--r--arch/powerpc/platforms/40x/Makefile2
-rw-r--r--arch/powerpc/platforms/40x/kilauea.c60
-rw-r--r--arch/powerpc/platforms/40x/makalu.c60
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c5
-rw-r--r--arch/powerpc/platforms/40x/virtex.c2
-rw-r--r--arch/powerpc/platforms/44x/Kconfig13
-rw-r--r--arch/powerpc/platforms/44x/Makefile1
-rw-r--r--arch/powerpc/platforms/44x/virtex.c2
-rw-r--r--arch/powerpc/platforms/44x/virtex_ml510.c29
-rw-r--r--arch/powerpc/platforms/44x/warp.c124
-rw-r--r--arch/powerpc/platforms/512x/clock.c10
-rw-r--r--arch/powerpc/platforms/512x/mpc512x.h1
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c23
-rw-r--r--arch/powerpc/platforms/52xx/efika.c4
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c32
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c4
-rw-r--r--arch/powerpc/platforms/82xx/ep8248e.c9
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads.h13
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig7
-rw-r--r--arch/powerpc/platforms/83xx/Makefile1
-rw-r--r--arch/powerpc/platforms/83xx/kmeter1.c191
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h4
-rw-r--r--arch/powerpc/platforms/83xx/usb.c10
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig14
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/mpc8536_ds.c17
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c62
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c73
-rw-r--r--arch/powerpc/platforms/85xx/smp.c9
-rw-r--r--arch/powerpc/platforms/85xx/socrates.c6
-rw-r--r--arch/powerpc/platforms/85xx/xes_mpc85xx.c281
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c1
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c1
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c5
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c16
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_smp.c8
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c1
-rw-r--r--arch/powerpc/platforms/8xx/mpc885ads.h4
-rw-r--r--arch/powerpc/platforms/Kconfig4
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype39
-rw-r--r--arch/powerpc/platforms/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c4
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.c10
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_epci.c13
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_pciex.c12
-rw-r--r--arch/powerpc/platforms/cell/iommu.c37
-rw-r--r--arch/powerpc/platforms/cell/ras.c4
-rw-r--r--arch/powerpc/platforms/cell/smp.c30
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c11
-rw-r--r--arch/powerpc/platforms/cell/spu_fault.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c6
-rw-r--r--arch/powerpc/platforms/chrp/pci.c8
-rw-r--r--arch/powerpc/platforms/chrp/smp.c33
-rw-r--r--arch/powerpc/platforms/fsl_uli1575.c24
-rw-r--r--arch/powerpc/platforms/iseries/dt.c3
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c2
-rw-r--r--arch/powerpc/platforms/iseries/mf.c3
-rw-r--r--arch/powerpc/platforms/iseries/pci.c8
-rw-r--r--arch/powerpc/platforms/maple/setup.c59
-rw-r--r--arch/powerpc/platforms/pasemi/gpio_mdio.c32
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c15
-rw-r--r--arch/powerpc/platforms/powermac/pic.c2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c43
-rw-r--r--arch/powerpc/platforms/powermac/smp.c166
-rw-r--r--arch/powerpc/platforms/ps3/mm.c12
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c142
-rw-r--r--arch/powerpc/platforms/ps3/platform.h10
-rw-r--r--arch/powerpc/platforms/ps3/setup.c1
-rw-r--r--arch/powerpc/platforms/ps3/smp.c16
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c15
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c38
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c52
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c76
-rw-r--r--arch/powerpc/platforms/pseries/setup.c25
-rw-r--r--arch/powerpc/platforms/pseries/smp.c30
79 files changed, 1301 insertions, 802 deletions
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index f39c953d535..a6e43cb6f82 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -45,6 +45,7 @@ config KILAUEA
depends on 40x
default n
select 405EX
+ select PPC40x_SIMPLE
select PPC4xx_PCI_EXPRESS
help
This option enables support for the AMCC PPC405EX evaluation board.
@@ -56,6 +57,7 @@ config MAKALU
select 405EX
select PCI
select PPC4xx_PCI_EXPRESS
+ select PPC40x_SIMPLE
help
This option enables support for the AMCC PPC405EX board.
diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile
index 9bab76a652a..56e89004c46 100644
--- a/arch/powerpc/platforms/40x/Makefile
+++ b/arch/powerpc/platforms/40x/Makefile
@@ -1,6 +1,4 @@
-obj-$(CONFIG_KILAUEA) += kilauea.o
obj-$(CONFIG_HCU4) += hcu4.o
-obj-$(CONFIG_MAKALU) += makalu.o
obj-$(CONFIG_WALNUT) += walnut.o
obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o
obj-$(CONFIG_EP405) += ep405.o
diff --git a/arch/powerpc/platforms/40x/kilauea.c b/arch/powerpc/platforms/40x/kilauea.c
deleted file mode 100644
index fd7d934dac8..00000000000
--- a/arch/powerpc/platforms/40x/kilauea.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Kilauea board specific routines
- *
- * Copyright 2007-2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Walnut code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/init.h>
-#include <linux/of_platform.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id kilauea_of_bus[] = {
- { .compatible = "ibm,plb4", },
- { .compatible = "ibm,opb", },
- { .compatible = "ibm,ebc", },
- {},
-};
-
-static int __init kilauea_device_probe(void)
-{
- of_platform_bus_probe(NULL, kilauea_of_bus, NULL);
-
- return 0;
-}
-machine_device_initcall(kilauea, kilauea_device_probe);
-
-static int __init kilauea_probe(void)
-{
- unsigned long root = of_get_flat_dt_root();
-
- if (!of_flat_dt_is_compatible(root, "amcc,kilauea"))
- return 0;
-
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
-
- return 1;
-}
-
-define_machine(kilauea) {
- .name = "Kilauea",
- .probe = kilauea_probe,
- .progress = udbg_progress,
- .init_IRQ = uic_init_tree,
- .get_irq = uic_get_irq,
- .restart = ppc4xx_reset_system,
- .calibrate_decr = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/40x/makalu.c b/arch/powerpc/platforms/40x/makalu.c
deleted file mode 100644
index a6a1d6017b7..00000000000
--- a/arch/powerpc/platforms/40x/makalu.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Makalu board specific routines
- *
- * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Walnut code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/init.h>
-#include <linux/of_platform.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id makalu_of_bus[] = {
- { .compatible = "ibm,plb4", },
- { .compatible = "ibm,opb", },
- { .compatible = "ibm,ebc", },
- {},
-};
-
-static int __init makalu_device_probe(void)
-{
- of_platform_bus_probe(NULL, makalu_of_bus, NULL);
-
- return 0;
-}
-machine_device_initcall(makalu, makalu_device_probe);
-
-static int __init makalu_probe(void)
-{
- unsigned long root = of_get_flat_dt_root();
-
- if (!of_flat_dt_is_compatible(root, "amcc,makalu"))
- return 0;
-
- ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
- return 1;
-}
-
-define_machine(makalu) {
- .name = "Makalu",
- .probe = makalu_probe,
- .progress = udbg_progress,
- .init_IRQ = uic_init_tree,
- .get_irq = uic_get_irq,
- .restart = ppc4xx_reset_system,
- .calibrate_decr = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index f40ac9b8f99..5fd5a597400 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -51,7 +51,10 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
* board.c file for it rather than adding it to this list.
*/
static char *board[] __initdata = {
- "amcc,acadia"
+ "amcc,acadia",
+ "amcc,haleakala",
+ "amcc,kilauea",
+ "amcc,makalu"
};
static int __init ppc40x_probe(void)
diff --git a/arch/powerpc/platforms/40x/virtex.c b/arch/powerpc/platforms/40x/virtex.c
index fc7fb001276..d0fc6866b00 100644
--- a/arch/powerpc/platforms/40x/virtex.c
+++ b/arch/powerpc/platforms/40x/virtex.c
@@ -14,6 +14,7 @@
#include <asm/prom.h>
#include <asm/time.h>
#include <asm/xilinx_intc.h>
+#include <asm/xilinx_pci.h>
#include <asm/ppc4xx.h>
static struct of_device_id xilinx_of_bus_ids[] __initdata = {
@@ -47,6 +48,7 @@ static int __init virtex_probe(void)
define_machine(virtex) {
.name = "Xilinx Virtex",
.probe = virtex_probe,
+ .setup_arch = xilinx_pci_init,
.init_IRQ = xilinx_intc_init_tree,
.get_irq = xilinx_intc_get_irq,
.restart = ppc4xx_reset_system,
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 0d83a6a0397..90e3192611a 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -156,7 +156,7 @@ config YOSEMITE
# This option enables support for the IBM PPC440GX evaluation board.
config XILINX_VIRTEX440_GENERIC_BOARD
- bool "Generic Xilinx Virtex 440 board"
+ bool "Generic Xilinx Virtex 5 FXT board support"
depends on 44x
default n
select XILINX_VIRTEX_5_FXT
@@ -171,6 +171,17 @@ config XILINX_VIRTEX440_GENERIC_BOARD
Most Virtex 5 designs should use this unless it needs to do some
special configuration at board probe time.
+config XILINX_ML510
+ bool "Xilinx ML510 extra support"
+ depends on XILINX_VIRTEX440_GENERIC_BOARD
+ select PPC_PCI_CHOICE
+ select XILINX_PCI if PCI
+ select PPC_INDIRECT_PCI if PCI
+ select PPC_I8259 if PCI
+ help
+ This option enables extra support for features on the Xilinx ML510
+ board. The ML510 has a PCI bus with ALI south bridge.
+
config PPC44x_SIMPLE
bool "Simple PowerPC 44x board support"
depends on 44x
diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
index 01f51daace1..ee6185aeaa3 100644
--- a/arch/powerpc/platforms/44x/Makefile
+++ b/arch/powerpc/platforms/44x/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_EBONY) += ebony.o
obj-$(CONFIG_SAM440EP) += sam440ep.o
obj-$(CONFIG_WARP) += warp.o
obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
+obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
diff --git a/arch/powerpc/platforms/44x/virtex.c b/arch/powerpc/platforms/44x/virtex.c
index 68637faf70a..cf96ccaa760 100644
--- a/arch/powerpc/platforms/44x/virtex.c
+++ b/arch/powerpc/platforms/44x/virtex.c
@@ -16,6 +16,7 @@
#include <asm/prom.h>
#include <asm/time.h>
#include <asm/xilinx_intc.h>
+#include <asm/xilinx_pci.h>
#include <asm/reg.h>
#include <asm/ppc4xx.h>
#include "44x.h"
@@ -53,6 +54,7 @@ static int __init virtex_probe(void)
define_machine(virtex) {
.name = "Xilinx Virtex440",
.probe = virtex_probe,
+ .setup_arch = xilinx_pci_init,
.init_IRQ = xilinx_intc_init_tree,
.get_irq = xilinx_intc_get_irq,
.calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/44x/virtex_ml510.c b/arch/powerpc/platforms/44x/virtex_ml510.c
new file mode 100644
index 00000000000..ba4a6e388a4
--- /dev/null
+++ b/arch/powerpc/platforms/44x/virtex_ml510.c
@@ -0,0 +1,29 @@
+#include <asm/i8259.h>
+#include <linux/pci.h>
+#include "44x.h"
+
+/**
+ * ml510_ail_quirk
+ */
+static void __devinit ml510_ali_quirk(struct pci_dev *dev)
+{
+ /* Enable the IDE controller */
+ pci_write_config_byte(dev, 0x58, 0x4c);
+ /* Assign irq 14 to the primary ide channel */
+ pci_write_config_byte(dev, 0x44, 0x0d);
+ /* Assign irq 15 to the secondary ide channel */
+ pci_write_config_byte(dev, 0x75, 0x0f);
+ /* Set the ide controller in native mode */
+ pci_write_config_byte(dev, 0x09, 0xff);
+
+ /* INTB = disabled, INTA = disabled */
+ pci_write_config_byte(dev, 0x48, 0x00);
+ /* INTD = disabled, INTC = disabled */
+ pci_write_config_byte(dev, 0x4a, 0x00);
+ /* Audio = INT7, Modem = disabled. */
+ pci_write_config_byte(dev, 0x4b, 0x60);
+ /* USB = INT7 */
+ pci_write_config_byte(dev, 0x74, 0x06);
+}
+DECLARE_PCI_FIXUP_EARLY(0x10b9, 0x1533, ml510_ali_quirk);
+
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index 960edf89be5..0362c88f47d 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -1,7 +1,7 @@
/*
* PIKA Warp(tm) board specific routines
*
- * Copyright (c) 2008 PIKA Technologies
+ * Copyright (c) 2008-2009 PIKA Technologies
* Sean MacLennan <smaclennan@pikatech.com>
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,6 +15,8 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/of_i2c.h>
#include <asm/machdep.h>
#include <asm/prom.h>
@@ -23,6 +25,7 @@
#include <asm/uic.h>
#include <asm/ppc4xx.h>
+
static __initdata struct of_device_id warp_of_bus[] = {
{ .compatible = "ibm,plb4", },
{ .compatible = "ibm,opb", },
@@ -41,7 +44,13 @@ static int __init warp_probe(void)
{
unsigned long root = of_get_flat_dt_root();
- return of_flat_dt_is_compatible(root, "pika,warp");
+ if (!of_flat_dt_is_compatible(root, "pika,warp"))
+ return 0;
+
+ /* For __dma_alloc_coherent */
+ ISA_DMA_THRESHOLD = ~0L;
+
+ return 1;
}
define_machine(warp) {
@@ -55,7 +64,8 @@ define_machine(warp) {
};
-/* I am not sure this is the best place for this... */
+static u32 post_info;
+
static int __init warp_post_info(void)
{
struct device_node *np;
@@ -77,21 +87,21 @@ static int __init warp_post_info(void)
iounmap(fpga);
- if (post1 || post2)
+ if (post1 || post2) {
printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
- else
+ post_info = 1;
+ } else
printk(KERN_INFO "Warp POST OK\n");
return 0;
}
-machine_late_initcall(warp, warp_post_info);
#ifdef CONFIG_SENSORS_AD7414
static LIST_HEAD(dtm_shutdown_list);
static void __iomem *dtm_fpga;
-static void __iomem *gpio_base;
+static unsigned green_led, red_led;
struct dtm_shutdown {
@@ -134,14 +144,17 @@ int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
static irqreturn_t temp_isr(int irq, void *context)
{
struct dtm_shutdown *shutdown;
+ int value = 1;
local_irq_disable();
+ gpio_set_value(green_led, 0);
+
/* Run through the shutdown list. */
list_for_each_entry(shutdown, &dtm_shutdown_list, list)
shutdown->func(shutdown->arg);
- printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+ printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n");
while (1) {
if (dtm_fpga) {
@@ -149,59 +162,41 @@ static irqreturn_t temp_isr(int irq, void *context)
out_be32(dtm_fpga + 0x14, reset);
}
- if (gpio_base) {
- unsigned leds = in_be32(gpio_base);
-
- /* green off, red toggle */
- leds &= ~0x80000000;
- leds ^= 0x40000000;
-
- out_be32(gpio_base, leds);
- }
-
+ gpio_set_value(red_led, value);
+ value ^= 1;
mdelay(500);
}
}
static int pika_setup_leds(void)
{
- struct device_node *np;
- const u32 *gpios;
- int len;
+ struct device_node *np, *child;
- np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+ np = of_find_compatible_node(NULL, NULL, "gpio-leds");
if (!np) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
+ printk(KERN_ERR __FILE__ ": Unable to find leds\n");
return -ENOENT;
}
- gpios = of_get_property(np, "gpios", &len);
- of_node_put(np);
- if (!gpios || len < 4) {
- printk(KERN_ERR __FILE__
- ": Unable to get gpios property (%d)\n", len);
- return -ENOENT;
- }
-
- np = of_find_node_by_phandle(gpios[0]);
- if (!np) {
- printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
- return -ENOENT;
- }
+ for_each_child_of_node(np, child)
+ if (strcmp(child->name, "green") == 0) {
+ green_led = of_get_gpio(child, 0);
+ /* Turn back on the green LED */
+ gpio_set_value(green_led, 1);
+ } else if (strcmp(child->name, "red") == 0) {
+ red_led = of_get_gpio(child, 0);
+ /* Set based on post */
+ gpio_set_value(red_led, post_info);
+ }
- gpio_base = of_iomap(np, 0);
of_node_put(np);
- if (!gpio_base) {
- printk(KERN_ERR __FILE__ ": Unable to map gpio");
- return -ENOMEM;
- }
return 0;
}
-static void pika_setup_critical_temp(struct i2c_client *client)
+static void pika_setup_critical_temp(struct device_node *np,
+ struct i2c_client *client)
{
- struct device_node *np;
int irq, rc;
/* Do this before enabling critical temp interrupt since we
@@ -213,14 +208,7 @@ static void pika_setup_critical_temp(struct i2c_client *client)
i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */
i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */
- np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
- if (np == NULL) {
- printk(KERN_ERR __FILE__ ": Unable to find ad7414\n");
- return;
- }
-
irq = irq_of_parse_and_map(np, 0);
- of_node_put(np);
if (irq == NO_IRQ) {
printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n");
return;
@@ -249,32 +237,24 @@ static inline void pika_dtm_check_fan(void __iomem *fpga)
static int pika_dtm_thread(void __iomem *fpga)
{
- struct i2c_adapter *adap;
+ struct device_node *np;
struct i2c_client *client;
- /* We loop in case either driver was compiled as a module and
- * has not been insmoded yet.
- */
- while (!(adap = i2c_get_adapter(0))) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ);
- }
-
- while (1) {
- list_for_each_entry(client, &adap->clients, list)
- if (client->addr == 0x4a)
- goto found_it;
+ np = of_find_compatible_node(NULL, NULL, "adi,ad7414");
+ if (np == NULL)
+ return -ENOENT;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ);
+ client = of_find_i2c_device_by_node(np);
+ if (client == NULL) {
+ of_node_put(np);
+ return -ENOENT;
}
-found_it:
- i2c_put_adapter(adap);
+ pika_setup_critical_temp(np, client);
- pika_setup_critical_temp(client);
+ of_node_put(np);
- printk(KERN_INFO "PIKA DTM thread running.\n");
+ printk(KERN_INFO "Warp DTM thread running.\n");
while (!kthread_should_stop()) {
int val;
@@ -296,7 +276,6 @@ found_it:
return 0;
}
-
static int __init pika_dtm_start(void)
{
struct task_struct *dtm_thread;
@@ -311,6 +290,9 @@ static int __init pika_dtm_start(void)
if (dtm_fpga == NULL)
return -ENOENT;
+ /* Must get post info before thread starts. */
+ warp_post_info();
+
dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
if (IS_ERR(dtm_thread)) {
iounmap(dtm_fpga);
@@ -333,6 +315,8 @@ int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
return 0;
}
+machine_late_initcall(warp, warp_post_info);
+
#endif
EXPORT_SYMBOL(pika_dtm_register_shutdown);
diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c
index 1bcff94eb92..84544d07204 100644
--- a/arch/powerpc/platforms/512x/clock.c
+++ b/arch/powerpc/platforms/512x/clock.c
@@ -24,7 +24,7 @@
#include <linux/io.h>
#include <linux/of_platform.h>
-#include <asm/mpc512x.h>
+#include <asm/mpc5xxx.h>
#include <asm/clk_interface.h>
#undef CLK_DEBUG
@@ -83,13 +83,13 @@ static void dump_clocks(void)
mutex_lock(&clocks_mutex);
printk(KERN_INFO "CLOCKS:\n");
list_for_each_entry(p, &clocks, node) {
- printk(KERN_INFO " %s %ld", p->name, p->rate);
+ pr_info(" %s=%ld", p->name, p->rate);
if (p->parent)
- printk(KERN_INFO " %s %ld", p->parent->name,
+ pr_cont(" %s=%ld", p->parent->name,
p->parent->rate);
if (p->flags & CLK_HAS_CTRL)
- printk(KERN_INFO " reg/bit %d/%d", p->reg, p->bit);
- printk("\n");
+ pr_cont(" reg/bit=%d/%d", p->reg, p->bit);
+ pr_cont("\n");
}
mutex_unlock(&clocks_mutex);
}
diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h
index 9c03693cb00..22a5352407e 100644
--- a/arch/powerpc/platforms/512x/mpc512x.h
+++ b/arch/powerpc/platforms/512x/mpc512x.h
@@ -11,7 +11,6 @@
#ifndef __MPC512X_H__
#define __MPC512X_H__
-extern unsigned long mpc512x_find_ips_freq(struct device_node *node);
extern void __init mpc512x_init_IRQ(void);
void __init mpc512x_declare_of_platform_devices(void);
#endif /* __MPC512X_H__ */
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index d8cd579f319..434d683df5a 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -24,29 +24,6 @@
#include "mpc512x.h"
-unsigned long
-mpc512x_find_ips_freq(struct device_node *node)
-{
- struct device_node *np;
- const unsigned int *p_ips_freq = NULL;
-
- of_node_get(node);
- while (node) {
- p_ips_freq = of_get_property(node, "bus-frequency", NULL);
- if (p_ips_freq)
- break;
-
- np = of_get_parent(node);
- of_node_put(node);
- node = np;
- }
- if (node)
- of_node_put(node);
-
- return p_ips_freq ? *p_ips_freq : 0;
-}
-EXPORT_SYMBOL(mpc512x_find_ips_freq);
-
void __init mpc512x_init_IRQ(void)
{
struct device_node *np;
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index a2068faef6e..bcc69e1f77c 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -34,7 +34,7 @@
static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 * val)
{
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
| (((bus->number - hose->first_busno) & 0xff) << 16)
| (hose->global_number << 24);
@@ -49,7 +49,7 @@ static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
| (((bus->number - hose->first_busno) & 0xff) << 16)
| (hose->global_number << 24);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 8e3dd5a0f22..a46bad0c233 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -47,36 +47,6 @@ static DEFINE_SPINLOCK(mpc52xx_lock);
static struct mpc52xx_gpt __iomem *mpc52xx_wdt;
static struct mpc52xx_cdm __iomem *mpc52xx_cdm;
-/**
- * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
- * @node: device node
- *
- * Returns IPB bus frequency, or 0 if the bus frequency cannot be found.
- */
-unsigned int
-mpc52xx_find_ipb_freq(struct device_node *node)
-{
- struct device_node *np;
- const unsigned int *p_ipb_freq = NULL;
-
- of_node_get(node);
- while (node) {
- p_ipb_freq = of_get_property(node, "bus-frequency", NULL);
- if (p_ipb_freq)
- break;
-
- np = of_get_parent(node);
- of_node_put(node);
- node = np;
- }
- if (node)
- of_node_put(node);
-
- return p_ipb_freq ? *p_ipb_freq : 0;
-}
-EXPORT_SYMBOL(mpc52xx_find_ipb_freq);
-
-
/*
* Configure the XLB arbiter settings to match what Linux expects.
*/
@@ -221,7 +191,7 @@ unsigned int mpc52xx_get_xtal_freq(struct device_node *node)
if (!mpc52xx_cdm)
return 0;
- freq = mpc52xx_find_ipb_freq(node);
+ freq = mpc5xxx_get_bus_frequency(node);
if (!freq)
return 0;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 87ff522f28b..dd43114e968 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -107,7 +107,7 @@ static int
mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 *val)
{
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
u32 value;
if (ppc_md.pci_exclude_device)
@@ -164,7 +164,7 @@ static int
mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int len, u32 val)
{
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
u32 value, mask;
if (ppc_md.pci_exclude_device)
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c
index 0eb6d7f6224..51fcae41f08 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
#include <linux/fsl_devices.h>
#include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#include <asm/io.h>
@@ -115,7 +116,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
struct mii_bus *bus;
struct resource res;
struct device_node *node;
- int ret, i;
+ int ret;
node = of_get_parent(ofdev->node);
of_node_put(node);
@@ -130,17 +131,13 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
if (!bus)
return -ENOMEM;
- bus->phy_mask = 0;
bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
- for (i = 0; i < PHY_MAX_ADDR; i++)
- bus->irq[i] = -1;
-
bus->name = "ep8248e-mdio-bitbang";
bus->parent = &ofdev->dev;
snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
- return mdiobus_register(bus);
+ return of_mdiobus_register(bus, ofdev->node);
}
static int ep8248e_mdio_remove(struct of_device *ofdev)
diff --git a/arch/powerpc/platforms/82xx/pq2ads.h b/arch/powerpc/platforms/82xx/pq2ads.h
index 984db42cc8e..6cf0f97486e 100644
--- a/arch/powerpc/platforms/82xx/pq2ads.h
+++ b/arch/powerpc/platforms/82xx/pq2ads.h
@@ -24,10 +24,6 @@
#include <linux/seq_file.h>
-/* Backword-compatibility stuff for the drivers */
-#define CPM_MAP_ADDR ((uint)0xf0000000)
-#define CPM_IRQ_OFFSET 0
-
/* The ADS8260 has 16, 32-bit wide control/status registers, accessed
* only on word boundaries.
* Not all are used (yet), or are interesting to us (yet).
@@ -44,14 +40,5 @@
#define BCSR3_FETHIEN2 ((uint)0x10000000) /* 0 == enable*/
#define BCSR3_FETH2_RST ((uint)0x80000000) /* 0 == reset */
-/* cpm serial driver works with constants below */
-
-#define SIU_INT_SMC1 ((uint)0x04+CPM_IRQ_OFFSET)
-#define SIU_INT_SMC2 ((uint)0x05+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC1 ((uint)0x28+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC2 ((uint)0x29+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC3 ((uint)0x2a+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC4 ((uint)0x2b+CPM_IRQ_OFFSET)
-
#endif /* __MACH_ADS8260_DEFS */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 437d29a59d7..083ebee9a16 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -96,6 +96,13 @@ config ASP834x
This enables support for the Analogue & Micro ASP 83xx
board.
+config KMETER1
+ bool "Keymile KMETER1"
+ select DEFAULT_UIMAGE
+ select QUICC_ENGINE
+ help
+ This enables support for the Keymile KMETER1 board.
+
endif
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 051777c542c..e139c36572e 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
obj-$(CONFIG_SBC834x) += sbc834x.o
obj-$(CONFIG_MPC837x_RDB) += mpc837x_rdb.o
obj-$(CONFIG_ASP834x) += asp834x.o
+obj-$(CONFIG_KMETER1) += kmeter1.o
diff --git a/arch/powerpc/platforms/83xx/kmeter1.c b/arch/powerpc/platforms/83xx/kmeter1.c
new file mode 100644
index 00000000000..903acfd851a
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/kmeter1.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2008 DENX Software Engineering GmbH
+ * Author: Heiko Schocher <hs@denx.de>
+ *
+ * Description:
+ * Keymile KMETER1 board specific routines.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+
+#include "mpc83xx.h"
+
+#define SVR_REV(svr) (((svr) >> 0) & 0xFFFF) /* Revision field */
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init kmeter1_setup_arch(void)
+{
+ struct device_node *np;
+
+ if (ppc_md.progress)
+ ppc_md.progress("kmeter1_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+ for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
+ mpc83xx_add_bridge(np);
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+ qe_reset();
+
+ np = of_find_node_by_name(NULL, "par_io");
+ if (np != NULL) {
+ par_io_init(np);
+ of_node_put(np);
+
+ for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
+ par_io_of_config(np);
+ }
+
+ np = of_find_compatible_node(NULL, "network", "ucc_geth");
+ if (np != NULL) {
+ uint svid;
+
+ /* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */
+ svid = mfspr(SPRN_SVR);
+ if (SVR_REV(svid) == 0x0021) {
+ struct device_node *np_par;
+ struct resource res;
+ void __iomem *base;
+ int ret;
+
+ np_par = of_find_node_by_name(NULL, "par_io");
+ if (np_par == NULL) {
+ printk(KERN_WARNING "%s couldn;t find par_io node\n",
+ __func__);
+ return;
+ }
+ /* Map Parallel I/O ports registers */
+ ret = of_address_to_resource(np_par, 0, &res);
+ if (ret) {
+ printk(KERN_WARNING "%s couldn;t map par_io registers\n",
+ __func__);
+ return;
+ }
+ base = ioremap(res.start, res.end - res.start + 1);
+
+ /*
+ * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
+ * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
+ */
+ setbits32((base + 0xa8), 0x0c003000);
+
+ /*
+ * IMMR + 0x14AC[20:27] = 10101010
+ * (data delay for both UCC's)
+ */
+ clrsetbits_be32((base + 0xac), 0xff0, 0xaa0);
+ iounmap(base);
+ of_node_put(np_par);
+ }
+ of_node_put(np);
+ }
+#endif /* CONFIG_QUICC_ENGINE */
+}
+
+static struct of_device_id kmeter_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .compatible = "simple-bus", },
+ { .type = "qe", },
+ { .compatible = "fsl,qe", },
+ {},
+};
+
+static int __init kmeter_declare_of_platform_devices(void)
+{
+ /* Publish the QE devices */
+ of_platform_bus_probe(NULL, kmeter_ids, NULL);
+
+ return 0;
+}
+machine_device_initcall(kmeter1, kmeter_declare_of_platform_devices);
+
+static void __init kmeter1_init_IRQ(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,pq2pro-pic");
+ if (!np) {
+ np = of_find_node_by_type(NULL, "ipic");
+ if (!np)
+ return;
+ }
+
+ ipic_init(np, 0);
+
+ /* Initialize the default interrupt mapping priorities,
+ * in case the boot rom changed something on us.
+ */
+ ipic_set_default_priority();
+ of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+ np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
+ if (!np) {
+ np = of_find_node_by_type(NULL, "qeic");
+ if (!np)
+ return;
+ }
+ qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic);
+ of_node_put(np);
+#endif /* CONFIG_QUICC_ENGINE */
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init kmeter1_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "keymile,KMETER1");
+}
+
+define_machine(kmeter1) {
+ .name = "KMETER1",
+ .probe = kmeter1_probe,
+ .setup_arch = kmeter1_setup_arch,
+ .init_IRQ = kmeter1_init_IRQ,
+ .get_irq = ipic_get_irq,
+ .restart = mpc83xx_restart,
+ .time_init = mpc83xx_time_init,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 83cfe51526e..d1dc5b0b4fb 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -22,8 +22,8 @@
/* system i/o configuration register low */
#define MPC83XX_SICRL_OFFS 0x114
#define MPC834X_SICRL_USB_MASK 0x60000000
-#define MPC834X_SICRL_USB0 0x40000000
-#define MPC834X_SICRL_USB1 0x20000000
+#define MPC834X_SICRL_USB0 0x20000000
+#define MPC834X_SICRL_USB1 0x40000000
#define MPC831X_SICRL_USB_MASK 0x00000c00
#define MPC831X_SICRL_USB_ULPI 0x00000800
#define MPC8315_SICRL_USB_MASK 0x000000fc
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
index 11e1fac17c7..3ba4bb7d41b 100644
--- a/arch/powerpc/platforms/83xx/usb.c
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -47,25 +47,25 @@ int mpc834x_usb_cfg(void)
sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */
prop = of_get_property(np, "phy_type", NULL);
+ port1_is_dr = 1;
if (prop && (!strcmp(prop, "utmi") ||
!strcmp(prop, "utmi_wide"))) {
sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
sicrh |= MPC834X_SICRH_USB_UTMI;
- port1_is_dr = 1;
+ port0_is_dr = 1;
} else if (prop && !strcmp(prop, "serial")) {
dr_mode = of_get_property(np, "dr_mode", NULL);
if (dr_mode && !strcmp(dr_mode, "otg")) {
sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
- port1_is_dr = 1;
+ port0_is_dr = 1;
} else {
- sicrl |= MPC834X_SICRL_USB0;
+ sicrl |= MPC834X_SICRL_USB1;
}
} else if (prop && !strcmp(prop, "ulpi")) {
- sicrl |= MPC834X_SICRL_USB0;
+ sicrl |= MPC834X_SICRL_USB1;
} else {
printk(KERN_WARNING "834x USB PHY type not supported\n");
}
- port0_is_dr = 1;
of_node_put(np);
}
np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph");
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 7f066adc068..a9b41668897 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -34,12 +34,15 @@ config MPC85xx_MDS
bool "Freescale MPC85xx MDS"
select DEFAULT_UIMAGE
select PHYLIB
+ select HAS_RAPIDIO
+ select SWIOTLB
help
This option enables support for the MPC85xx MDS board
config MPC8536_DS
bool "Freescale MPC8536 DS"
select DEFAULT_UIMAGE
+ select SWIOTLB
help
This option enables support for the MPC8536 DS board
@@ -48,6 +51,7 @@ config MPC85xx_DS
select PPC_I8259
select DEFAULT_UIMAGE
select FSL_ULI1575
+ select SWIOTLB
help
This option enables support for the MPC85xx DS (MPC8544 DS) board
@@ -63,6 +67,16 @@ config KSI8560
help
This option enables support for the Emerson KSI8560 board
+config XES_MPC85xx
+ bool "X-ES single-board computer"
+ select DEFAULT_UIMAGE
+ help
+ This option enables support for the various single-board
+ computers from Extreme Engineering Solutions (X-ES) based on
+ Freescale MPC85xx processors.
+ Manufacturer: Extreme Engineering Solutions, Inc.
+ URL: <http://www.xes-inc.com/>
+
config STX_GP3
bool "Silicon Turnkey Express GP3"
help
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index a857b35b982..835733f2b12 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_SBC8560) += sbc8560.o
obj-$(CONFIG_SBC8548) += sbc8548.o
obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o
obj-$(CONFIG_KSI8560) += ksi8560.o
+obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o \ No newline at end of file
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index 63efca20d7b..055ff417bae 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -17,6 +17,7 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
+#include <linux/lmb.h>
#include <asm/system.h>
#include <asm/time.h>
@@ -26,6 +27,7 @@
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/mpic.h>
+#include <asm/swiotlb.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
@@ -65,7 +67,9 @@ static void __init mpc8536_ds_setup_arch(void)
{
#ifdef CONFIG_PCI
struct device_node *np;
+ struct pci_controller *hose;
#endif
+ dma_addr_t max = 0xffffffff;
if (ppc_md.progress)
ppc_md.progress("mpc8536_ds_setup_arch()", 0);
@@ -80,11 +84,22 @@ static void __init mpc8536_ds_setup_arch(void)
fsl_add_bridge(np, 1);
else
fsl_add_bridge(np, 0);
+
+ hose = pci_find_hose_for_OF_device(np);
+ max = min(max, hose->dma_window_base_cur +
+ hose->dma_window_size);
}
}
#endif
+#ifdef CONFIG_SWIOTLB
+ if (lmb_end_of_DRAM() > max) {
+ ppc_swiotlb_enable = 1;
+ set_pci_dma_ops(&swiotlb_pci_dma_ops);
+ }
+#endif
+
printk("MPC8536 DS board from Freescale Semiconductor\n");
}
@@ -102,6 +117,8 @@ static int __init mpc8536_ds_publish_devices(void)
}
machine_device_initcall(mpc8536_ds, mpc8536_ds_publish_devices);
+machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier);
+
/*
* Called very early, device-tree isn't unflattened
*/
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index de66de7a9ca..849c0ac0025 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -20,6 +20,7 @@
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of_platform.h>
+#include <linux/lmb.h>
#include <asm/system.h>
#include <asm/time.h>
@@ -30,6 +31,7 @@
#include <asm/udbg.h>
#include <asm/mpic.h>
#include <asm/i8259.h>
+#include <asm/swiotlb.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
@@ -155,7 +157,9 @@ static void __init mpc85xx_ds_setup_arch(void)
{
#ifdef CONFIG_PCI
struct device_node *np;
+ struct pci_controller *hose;
#endif
+ dma_addr_t max = 0xffffffff;
if (ppc_md.progress)
ppc_md.progress("mpc85xx_ds_setup_arch()", 0);
@@ -163,13 +167,18 @@ static void __init mpc85xx_ds_setup_arch(void)
#ifdef CONFIG_PCI
for_each_node_by_type(np, "pci") {
if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
- of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
+ of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
+ of_device_is_compatible(np, "fsl,p2020-pcie")) {
struct resource rsrc;
of_address_to_resource(np, 0, &rsrc);
if ((rsrc.start & 0xfffff) == primary_phb_addr)
fsl_add_bridge(np, 1);
else
fsl_add_bridge(np, 0);
+
+ hose = pci_find_hose_for_OF_device(np);
+ max = min(max, hose->dma_window_base_cur +
+ hose->dma_window_size);
}
}
@@ -180,6 +189,13 @@ static void __init mpc85xx_ds_setup_arch(void)
mpc85xx_smp_init();
#endif
+#ifdef CONFIG_SWIOTLB
+ if (lmb_end_of_DRAM() > max) {
+ ppc_swiotlb_enable = 1;
+ set_pci_dma_ops(&swiotlb_pci_dma_ops);
+ }
+#endif
+
printk("MPC85xx DS board from Freescale Semiconductor\n");
}
@@ -195,9 +211,9 @@ static int __init mpc8544_ds_probe(void)
primary_phb_addr = 0xb000;
#endif
return 1;
- } else {
- return 0;
}
+
+ return 0;
}
static struct of_device_id __initdata mpc85xxds_ids[] = {
@@ -214,6 +230,11 @@ static int __init mpc85xxds_publish_devices(void)
}
machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices);
machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices);
+machine_device_initcall(p2020_ds, mpc85xxds_publish_devices);
+
+machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier);
+machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier);
+machine_arch_initcall(p2020_ds, swiotlb_setup_bus_notifier);
/*
* Called very early, device-tree isn't unflattened
@@ -227,9 +248,26 @@ static int __init mpc8572_ds_probe(void)
primary_phb_addr = 0x8000;
#endif
return 1;
- } else {
- return 0;
}
+
+ return 0;
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p2020_ds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "fsl,P2020DS")) {
+#ifdef CONFIG_PCI
+ primary_phb_addr = 0x9000;
+#endif
+ return 1;
+ }
+
+ return 0;
}
define_machine(mpc8544_ds) {
@@ -259,3 +297,17 @@ define_machine(mpc8572_ds) {
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
+
+define_machine(p2020_ds) {
+ .name = "P2020 DS",
+ .probe = p2020_ds_probe,
+ .setup_arch = mpc85xx_ds_setup_arch,
+ .init_IRQ = mpc85xx_ds_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 7dd029034ae..60ed9c067b1 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -33,6 +33,7 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/phy.h>
+#include <linux/lmb.h>
#include <asm/system.h>
#include <asm/atomic.h>
@@ -49,6 +50,7 @@
#include <asm/qe.h>
#include <asm/qe_ic.h>
#include <asm/mpic.h>
+#include <asm/swiotlb.h>
#undef DEBUG
#ifdef DEBUG
@@ -155,6 +157,10 @@ static void __init mpc85xx_mds_setup_arch(void)
{
struct device_node *np;
static u8 __iomem *bcsr_regs = NULL;
+#ifdef CONFIG_PCI
+ struct pci_controller *hose;
+#endif
+ dma_addr_t max = 0xffffffff;
if (ppc_md.progress)
ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
@@ -179,6 +185,10 @@ static void __init mpc85xx_mds_setup_arch(void)
fsl_add_bridge(np, 1);
else
fsl_add_bridge(np, 0);
+
+ hose = pci_find_hose_for_OF_device(np);
+ max = min(max, hose->dma_window_base_cur +
+ hose->dma_window_size);
}
}
#endif
@@ -206,26 +216,34 @@ static void __init mpc85xx_mds_setup_arch(void)
}
if (bcsr_regs) {
+ if (machine_is(mpc8568_mds)) {
#define BCSR_UCC1_GETH_EN (0x1 << 7)
#define BCSR_UCC2_GETH_EN (0x1 << 7)
#define BCSR_UCC1_MODE_MSK (0x3 << 4)
#define BCSR_UCC2_MODE_MSK (0x3 << 0)
- /* Turn off UCC1 & UCC2 */
- clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
- clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+ /* Turn off UCC1 & UCC2 */
+ clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+ clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
- /* Mode is RGMII, all bits clear */
- clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
- BCSR_UCC2_MODE_MSK);
-
- /* Turn UCC1 & UCC2 on */
- setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
- setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+ /* Mode is RGMII, all bits clear */
+ clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
+ BCSR_UCC2_MODE_MSK);
+ /* Turn UCC1 & UCC2 on */
+ setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+ setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+ }
iounmap(bcsr_regs);
}
#endif /* CONFIG_QUICC_ENGINE */
+
+#ifdef CONFIG_SWIOTLB
+ if (lmb_end_of_DRAM() > max) {
+ ppc_swiotlb_enable = 1;
+ set_pci_dma_ops(&swiotlb_pci_dma_ops);
+ }
+#endif
}
@@ -257,7 +275,8 @@ static int __init board_fixups(void)
return 0;
}
-machine_arch_initcall(mpc85xx_mds, board_fixups);
+machine_arch_initcall(mpc8568_mds, board_fixups);
+machine_arch_initcall(mpc8569_mds, board_fixups);
static struct of_device_id mpc85xx_ids[] = {
{ .type = "soc", },
@@ -266,6 +285,7 @@ static struct of_device_id mpc85xx_ids[] = {
{ .type = "qe", },
{ .compatible = "fsl,qe", },
{ .compatible = "gianfar", },
+ { .compatible = "fsl,rapidio-delta", },
{},
};
@@ -276,7 +296,11 @@ static int __init mpc85xx_publish_devices(void)
return 0;
}
-machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
+
+machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier);
+machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier);
static void __init mpc85xx_mds_pic_init(void)
{
@@ -321,8 +345,8 @@ static int __init mpc85xx_mds_probe(void)
return of_flat_dt_is_compatible(root, "MPC85xxMDS");
}
-define_machine(mpc85xx_mds) {
- .name = "MPC85xx MDS",
+define_machine(mpc8568_mds) {
+ .name = "MPC8568 MDS",
.probe = mpc85xx_mds_probe,
.setup_arch = mpc85xx_mds_setup_arch,
.init_IRQ = mpc85xx_mds_pic_init,
@@ -334,3 +358,24 @@ define_machine(mpc85xx_mds) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
};
+
+static int __init mpc8569_mds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
+}
+
+define_machine(mpc8569_mds) {
+ .name = "MPC8569 MDS",
+ .probe = mpc8569_mds_probe,
+ .setup_arch = mpc85xx_mds_setup_arch,
+ .init_IRQ = mpc85xx_mds_pic_init,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index cc0b0db8a6f..62c592ede64 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -52,20 +52,19 @@ smp_85xx_kick_cpu(int nr)
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
- local_irq_save(flags);
-
np = of_get_cpu_node(nr, NULL);
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
if (cpu_rel_addr == NULL) {
printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
- local_irq_restore(flags);
return;
}
/* Map the spin table */
bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
+ local_irq_save(flags);
+
out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
@@ -73,10 +72,10 @@ smp_85xx_kick_cpu(int nr)
while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
mdelay(1);
- iounmap(bptr_vaddr);
-
local_irq_restore(flags);
+ iounmap(bptr_vaddr);
+
pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
}
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c
index d0e8443b12c..747d8fb3ab8 100644
--- a/arch/powerpc/platforms/85xx/socrates.c
+++ b/arch/powerpc/platforms/85xx/socrates.c
@@ -102,10 +102,11 @@ static struct of_device_id __initdata socrates_of_bus_ids[] = {
{},
};
-static void __init socrates_init(void)
+static int __init socrates_publish_devices(void)
{
- of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL);
+ return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL);
}
+machine_device_initcall(socrates, socrates_publish_devices);
/*
* Called very early, device-tree isn't unflattened
@@ -124,7 +125,6 @@ define_machine(socrates) {
.name = "Socrates",
.probe = socrates_probe,
.setup_arch = socrates_setup_arch,
- .init = socrates_init,
.init_IRQ = socrates_pic_init,
.get_irq = mpic_get_irq,
.restart = fsl_rstcr_restart,
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
new file mode 100644
index 00000000000..1b426050a2f
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2009 Extreme Engineering Solutions, Inc.
+ *
+ * X-ES board-specific functionality
+ *
+ * Based on mpc85xx_ds code from Freescale Semiconductor, Inc.
+ *
+ * Author: Nate Case <ncase@xes-inc.com>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+/* A few bit definitions needed for fixups on some boards */
+#define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */
+#define MPC85xx_L2CTL_L2I 0x40000000 /* L2 flash invalidate */
+#define MPC85xx_L2CTL_L2SIZ_MASK 0x30000000 /* L2 SRAM size (R/O) */
+
+void __init xes_mpc85xx_pic_init(void)
+{
+ struct mpic *mpic;
+ struct resource r;
+ struct device_node *np;
+
+ np = of_find_node_by_type(NULL, "open-pic");
+ if (np == NULL) {
+ printk(KERN_ERR "Could not find open-pic node\n");
+ return;
+ }
+
+ if (of_address_to_resource(np, 0, &r)) {
+ printk(KERN_ERR "Failed to map mpic register space\n");
+ of_node_put(np);
+ return;
+ }
+
+ mpic = mpic_alloc(np, r.start,
+ MPIC_PRIMARY | MPIC_WANTS_RESET |
+ MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
+ 0, 256, " OpenPIC ");
+ BUG_ON(mpic == NULL);
+ of_node_put(np);
+
+ mpic_init(mpic);
+}
+
+static void xes_mpc85xx_configure_l2(void __iomem *l2_base)
+{
+ volatile uint32_t ctl, tmp;
+
+ asm volatile("msync; isync");
+ tmp = in_be32(l2_base);
+
+ /*
+ * xMon may have enabled part of L2 as SRAM, so we need to set it
+ * up for all cache mode just to be safe.
+ */
+ printk(KERN_INFO "xes_mpc85xx: Enabling L2 as cache\n");
+
+ ctl = MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2I;
+ if (machine_is_compatible("MPC8540") ||
+ machine_is_compatible("MPC8560"))
+ /*
+ * Assume L2 SRAM is used fully for cache, so set
+ * L2BLKSZ (bits 4:5) to match L2SIZ (bits 2:3).
+ */
+ ctl |= (tmp & MPC85xx_L2CTL_L2SIZ_MASK) >> 2;
+
+ asm volatile("msync; isync");
+ out_be32(l2_base, ctl);
+ asm volatile("msync; isync");
+}
+
+static void xes_mpc85xx_fixups(void)
+{
+ struct device_node *np;
+ int err;
+
+ /*
+ * Legacy xMon firmware on some X-ES boards does not enable L2
+ * as cache. We must ensure that they get enabled here.
+ */
+ for_each_node_by_name(np, "l2-cache-controller") {
+ struct resource r[2];
+ void __iomem *l2_base;
+
+ /* Only MPC8548, MPC8540, and MPC8560 boards are affected */
+ if (!of_device_is_compatible(np,
+ "fsl,mpc8548-l2-cache-controller") &&
+ !of_device_is_compatible(np,
+ "fsl,mpc8540-l2-cache-controller") &&
+ !of_device_is_compatible(np,
+ "fsl,mpc8560-l2-cache-controller"))
+ continue;
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ if (err) {
+ printk(KERN_WARNING "xes_mpc85xx: Could not get "
+ "resource for device tree node '%s'",
+ np->full_name);
+ continue;
+ }
+
+ l2_base = ioremap(r[0].start, r[0].end - r[0].start + 1);
+
+ xes_mpc85xx_configure_l2(l2_base);
+ }
+}
+
+#ifdef CONFIG_PCI
+static int primary_phb_addr;
+#endif
+
+/*
+ * Setup the architecture
+ */
+#ifdef CONFIG_SMP
+extern void __init mpc85xx_smp_init(void);
+#endif
+static void __init xes_mpc85xx_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+ struct device_node *np;
+#endif
+ struct device_node *root;
+ const char *model = "Unknown";
+
+ root = of_find_node_by_path("/");
+ if (root == NULL)
+ return;
+
+ model = of_get_property(root, "model", NULL);
+
+ printk(KERN_INFO "X-ES MPC85xx-based single-board computer: %s\n",
+ model + strlen("xes,"));
+
+ xes_mpc85xx_fixups();
+
+#ifdef CONFIG_PCI
+ for_each_node_by_type(np, "pci") {
+ if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
+ of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
+ struct resource rsrc;
+ of_address_to_resource(np, 0, &rsrc);
+ if ((rsrc.start & 0xfffff) == primary_phb_addr)
+ fsl_add_bridge(np, 1);
+ else
+ fsl_add_bridge(np, 0);
+ }
+ }
+#endif
+
+#ifdef CONFIG_SMP
+ mpc85xx_smp_init();
+#endif
+}
+
+static struct of_device_id __initdata xes_mpc85xx_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ { .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
+ {},
+};
+
+static int __init xes_mpc85xx_publish_devices(void)
+{
+ return of_platform_bus_probe(NULL, xes_mpc85xx_ids, NULL);
+}
+machine_device_initcall(xes_mpc8572, xes_mpc85xx_publish_devices);
+machine_device_initcall(xes_mpc8548, xes_mpc85xx_publish_devices);
+machine_device_initcall(xes_mpc8540, xes_mpc85xx_publish_devices);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init xes_mpc8572_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "xes,MPC8572")) {
+#ifdef CONFIG_PCI
+ primary_phb_addr = 0x8000;
+#endif
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int __init xes_mpc8548_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "xes,MPC8548")) {
+#ifdef CONFIG_PCI
+ primary_phb_addr = 0xb000;
+#endif
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int __init xes_mpc8540_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "xes,MPC8540")) {
+#ifdef CONFIG_PCI
+ primary_phb_addr = 0xb000;
+#endif
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+define_machine(xes_mpc8572) {
+ .name = "X-ES MPC8572",
+ .probe = xes_mpc8572_probe,
+ .setup_arch = xes_mpc85xx_setup_arch,
+ .init_IRQ = xes_mpc85xx_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
+
+define_machine(xes_mpc8548) {
+ .name = "X-ES MPC8548",
+ .probe = xes_mpc8548_probe,
+ .setup_arch = xes_mpc85xx_setup_arch,
+ .init_IRQ = xes_mpc85xx_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
+
+define_machine(xes_mpc8540) {
+ .name = "X-ES MPC8540",
+ .probe = xes_mpc8540_probe,
+ .setup_arch = xes_mpc85xx_setup_arch,
+ .init_IRQ = xes_mpc85xx_pic_init,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index fdaf4ddaa95..9c7b64a3402 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -15,6 +15,7 @@ config MPC8641_HPCN
select DEFAULT_UIMAGE
select FSL_ULI1575
select HAS_RAPIDIO
+ select SWIOTLB
help
This option enables support for the MPC8641 HPCN board.
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index d79104669cd..2efa052975e 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
index af14f852d74..90754e752bd 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc310.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index ea236063965..72b31a6010a 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 3f49a6f893a..627908a4cd7 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -28,7 +28,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
@@ -38,6 +37,7 @@
#include <linux/of_platform.h>
#include <sysdev/fsl_pci.h>
#include <sysdev/fsl_soc.h>
+#include <sysdev/simple_gpio.h>
#include "mpc86xx.h"
@@ -52,6 +52,9 @@ static struct of_device_id __initdata mpc8610_ids[] = {
static int __init mpc8610_declare_of_platform_devices(void)
{
+ /* Firstly, register PIXIS GPIOs. */
+ simple_gpiochip_init("fsl,fpga-pixis-gpio-bank");
+
/* Without this call, the SSI device driver won't get probed. */
of_platform_bus_probe(NULL, mpc8610_ids, NULL);
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index c4ec49b5f7f..66327024a6a 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -19,15 +19,16 @@
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/of_platform.h>
+#include <linux/lmb.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
+#include <asm/swiotlb.h>
#include <asm/mpic.h>
@@ -71,7 +72,9 @@ mpc86xx_hpcn_setup_arch(void)
{
#ifdef CONFIG_PCI
struct device_node *np;
+ struct pci_controller *hose;
#endif
+ dma_addr_t max = 0xffffffff;
if (ppc_md.progress)
ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0);
@@ -84,6 +87,9 @@ mpc86xx_hpcn_setup_arch(void)
fsl_add_bridge(np, 1);
else
fsl_add_bridge(np, 0);
+ hose = pci_find_hose_for_OF_device(np);
+ max = min(max, hose->dma_window_base_cur +
+ hose->dma_window_size);
}
ppc_md.pci_exclude_device = mpc86xx_exclude_device;
@@ -95,6 +101,13 @@ mpc86xx_hpcn_setup_arch(void)
#ifdef CONFIG_SMP
mpc86xx_smp_init();
#endif
+
+#ifdef CONFIG_SWIOTLB
+ if (lmb_end_of_DRAM() > max) {
+ ppc_swiotlb_enable = 1;
+ set_pci_dma_ops(&swiotlb_pci_dma_ops);
+ }
+#endif
}
@@ -159,6 +172,7 @@ static int __init declare_of_platform_devices(void)
return 0;
}
machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices);
+machine_arch_initcall(mpc86xx_hpcn, swiotlb_setup_bus_notifier);
define_machine(mpc86xx_hpcn) {
.name = "MPC86xx HPCN",
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
index 014e26cda08..d84bbb508ee 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
@@ -20,7 +20,6 @@
#include <asm/pgtable.h>
#include <asm/pci-bridge.h>
#include <asm/mpic.h>
-#include <asm/mpc86xx.h>
#include <asm/cacheflush.h>
#include <sysdev/fsl_soc.h>
@@ -30,6 +29,11 @@
extern void __secondary_start_mpc86xx(void);
extern unsigned long __secondary_hold_acknowledge;
+#define MCM_PORT_CONFIG_OFFSET 0x10
+
+/* Offset from CCSRBAR */
+#define MPC86xx_MCM_OFFSET (0x1000)
+#define MPC86xx_MCM_SIZE (0x1000)
static void __init
smp_86xx_release_core(int nr)
@@ -48,6 +52,8 @@ smp_86xx_release_core(int nr)
pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2));
pcr |= 1 << (nr + 24);
out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr);
+
+ iounmap(mcm_vaddr);
}
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 2886a36fc08..51c8f331b67 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -25,7 +25,6 @@
#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/8xx/mpc885ads.h b/arch/powerpc/platforms/8xx/mpc885ads.h
index a5076668bad..19412f76fa3 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads.h
+++ b/arch/powerpc/platforms/8xx/mpc885ads.h
@@ -17,10 +17,6 @@
#include <sysdev/fsl_soc.h>
-#define MPC8xx_CPM_OFFSET (0x9c0)
-#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET)
-#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver
-
/* Bits of interest in the BCSRs.
*/
#define BCSR1_ETHEN ((uint)0x20000000)
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index e3e87078d03..04a8061045c 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -329,4 +329,8 @@ config MCU_MPC8349EMITX
also register MCU GPIOs with the generic GPIO API, so you'll able
to use MCU pins as GPIOs.
+config XILINX_PCI
+ bool "Xilinx PCI host bridge support"
+ depends on PCI && XILINX_VIRTEX
+
endmenu
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 732ee93a8e9..61187bec750 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -1,7 +1,7 @@
config PPC64
bool "64-bit kernel"
default n
- select HAVE_PERF_COUNTERS
+ select PPC_HAVE_PMU_SUPPORT
help
This option selects whether a 32-bit or a 64-bit kernel
will be built.
@@ -10,7 +10,6 @@ menu "Processor support"
choice
prompt "Processor Type"
depends on PPC32
- default 6xx
help
There are five families of 32 bit PowerPC chips supported.
The most common ones are the desktop and server CPUs (601, 603,
@@ -22,7 +21,7 @@ choice
If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
-config 6xx
+config PPC_BOOK3S_32
bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
select PPC_FPU
@@ -58,13 +57,14 @@ config E200
endchoice
-# Until we have a choice of exclusive CPU types on 64-bit, we always
-# use PPC_BOOK3S. On 32-bit, this is equivalent to 6xx which is
-# "classic" MMU
+config PPC_BOOK3S_64
+ def_bool y
+ depends on PPC64
+ select PPC_FPU
config PPC_BOOK3S
- def_bool y
- depends on PPC64 || 6xx
+ def_bool y
+ depends on PPC_BOOK3S_32 || PPC_BOOK3S_64
config POWER4_ONLY
bool "Optimize for POWER4"
@@ -75,6 +75,11 @@ config POWER4_ONLY
The resulting binary will not work on POWER3 or RS64 processors
when compiled with binutils 2.15 or later.
+config 6xx
+ def_bool y
+ depends on PPC32 && PPC_BOOK3S
+ select PPC_HAVE_PMU_SUPPORT
+
config POWER3
bool
depends on PPC64 && PPC_BOOK3S
@@ -203,9 +208,8 @@ config SPE
If in doubt, say Y here.
config PPC_STD_MMU
- bool
- depends on 6xx || PPC64
- default y
+ def_bool y
+ depends on PPC_BOOK3S
config PPC_STD_MMU_32
def_bool y
@@ -243,6 +247,15 @@ config VIRT_CPU_ACCOUNTING
If in doubt, say Y here.
+config PPC_HAVE_PMU_SUPPORT
+ bool
+
+config PPC_PERF_CTRS
+ def_bool y
+ depends on PERF_COUNTERS && PPC_HAVE_PMU_SUPPORT
+ help
+ This enables the powerpc-specific perf_counter back-end.
+
config SMP
depends on PPC_STD_MMU || FSL_BOOKE
bool "Symmetric multi-processing support"
@@ -263,8 +276,8 @@ config SMP
If you don't know what to do here, say N.
config NR_CPUS
- int "Maximum number of CPUs (2-1024)"
- range 2 1024
+ int "Maximum number of CPUs (2-8192)"
+ range 2 8192
depends on SMP
default "32" if PPC64
default "4"
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index f7419198e63..a6812ee0010 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -1,4 +1,6 @@
+subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+
obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o
obj-$(CONFIG_PPC_PMAC) += powermac/
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 0ce45c2b42f..c71498dbf21 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -329,7 +329,7 @@ static struct irq_host_ops msic_host_ops = {
static int axon_msi_shutdown(struct of_device *device)
{
- struct axon_msic *msic = device->dev.platform_data;
+ struct axon_msic *msic = dev_get_drvdata(&device->dev);
u32 tmp;
pr_debug("axon_msi: disabling %s\n",
@@ -416,7 +416,7 @@ static int axon_msi_probe(struct of_device *device,
msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG)
& MSIC_FIFO_SIZE_MASK;
- device->dev.platform_data = msic;
+ dev_set_drvdata(&device->dev, msic);
ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index f39a3b2a166..00eaaa71630 100644
--- a/arch/powerpc/platforms/cell/celleb_pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -162,8 +162,7 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
unsigned int devfn, int where, int size, u32 *val)
{
char *config;
- struct device_node *node;
- struct pci_controller *hose;
+ struct pci_controller *hose = pci_bus_to_host(bus);
unsigned int devno = devfn >> 3;
unsigned int fn = devfn & 0x7;
@@ -171,8 +170,6 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
BUG_ON(where % size);
pr_debug(" fake read: bus=0x%x, ", bus->number);
- node = (struct device_node *)bus->sysdata;
- hose = pci_find_hose_for_OF_device(node);
config = get_fake_config_start(hose, devno, fn);
pr_debug("devno=0x%x, where=0x%x, size=0x%x, ", devno, where, size);
@@ -192,8 +189,7 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
unsigned int devfn, int where, int size, u32 val)
{
char *config;
- struct device_node *node;
- struct pci_controller *hose;
+ struct pci_controller *hose = pci_bus_to_host(bus);
struct celleb_pci_resource *res;
unsigned int devno = devfn >> 3;
unsigned int fn = devfn & 0x7;
@@ -201,8 +197,6 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
/* allignment check */
BUG_ON(where % size);
- node = (struct device_node *)bus->sysdata;
- hose = pci_find_hose_for_OF_device(node);
config = get_fake_config_start(hose, devno, fn);
if (!config)
diff --git a/arch/powerpc/platforms/cell/celleb_scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c
index 48ec88a38a1..05b0db3ef63 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_epci.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c
@@ -134,15 +134,11 @@ static int celleb_epci_read_config(struct pci_bus *bus,
{
PCI_IO_ADDR epci_base;
PCI_IO_ADDR addr;
- struct device_node *node;
- struct pci_controller *hose;
+ struct pci_controller *hose = pci_bus_to_host(bus);
/* allignment check */
BUG_ON(where % size);
- node = (struct device_node *)bus->sysdata;
- hose = pci_find_hose_for_OF_device(node);
-
if (!celleb_epci_get_epci_cfg(hose))
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -198,16 +194,11 @@ static int celleb_epci_write_config(struct pci_bus *bus,
{
PCI_IO_ADDR epci_base;
PCI_IO_ADDR addr;
- struct device_node *node;
- struct pci_controller *hose;
+ struct pci_controller *hose = pci_bus_to_host(bus);
/* allignment check */
BUG_ON(where % size);
- node = (struct device_node *)bus->sysdata;
- hose = pci_find_hose_for_OF_device(node);
-
-
if (!celleb_epci_get_epci_cfg(hose))
return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 3e7e0f1568e..7fca09f990b 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -366,11 +366,7 @@ static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, unsigned int *val)
{
- struct device_node *dn;
- struct pci_controller *phb;
-
- dn = bus->sysdata;
- phb = pci_find_hose_for_OF_device(dn);
+ struct pci_controller *phb = pci_bus_to_host(bus);
if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
*val = ~0;
@@ -389,11 +385,7 @@ static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, unsigned int val)
{
- struct device_node *dn;
- struct pci_controller *phb;
-
- dn = bus->sysdata;
- phb = pci_find_hose_for_OF_device(dn);
+ struct pci_controller *phb = pci_bus_to_host(bus);
if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
return PCIBIOS_DEVICE_NOT_FOUND;
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index bed4690de39..5b34fc211f3 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -100,16 +100,6 @@
#define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */
#define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */
-/* Page table entries */
-#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
-#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
-#define IOPTE_M 0x2000000000000000ul /* coherency required */
-#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
-#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
-#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
-#define IOPTE_H 0x0000000000000800ul /* cache hint */
-#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
-
/* IOMMU sizing */
#define IO_SEGMENT_SHIFT 28
@@ -193,19 +183,21 @@ static int tce_build_cell(struct iommu_table *tbl, long index, long npages,
*/
const unsigned long prot = 0xc48;
base_pte =
- ((prot << (52 + 4 * direction)) & (IOPTE_PP_W | IOPTE_PP_R))
- | IOPTE_M | IOPTE_SO_RW | (window->ioid & IOPTE_IOID_Mask);
+ ((prot << (52 + 4 * direction)) &
+ (CBE_IOPTE_PP_W | CBE_IOPTE_PP_R)) |
+ CBE_IOPTE_M | CBE_IOPTE_SO_RW |
+ (window->ioid & CBE_IOPTE_IOID_Mask);
#else
- base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW |
- (window->ioid & IOPTE_IOID_Mask);
+ base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M |
+ CBE_IOPTE_SO_RW | (window->ioid & CBE_IOPTE_IOID_Mask);
#endif
if (unlikely(dma_get_attr(DMA_ATTR_WEAK_ORDERING, attrs)))
- base_pte &= ~IOPTE_SO_RW;
+ base_pte &= ~CBE_IOPTE_SO_RW;
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
- io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
+ io_pte[i] = base_pte | (__pa(uaddr) & CBE_IOPTE_RPN_Mask);
mb();
@@ -231,8 +223,9 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
#else
/* spider bridge does PCI reads after freeing - insert a mapping
* to a scratch page instead of an invalid entry */
- pte = IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | __pa(window->iommu->pad_page)
- | (window->ioid & IOPTE_IOID_Mask);
+ pte = CBE_IOPTE_PP_R | CBE_IOPTE_M | CBE_IOPTE_SO_RW |
+ __pa(window->iommu->pad_page) |
+ (window->ioid & CBE_IOPTE_IOID_Mask);
#endif
io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
@@ -1001,7 +994,7 @@ static void insert_16M_pte(unsigned long addr, unsigned long *ptab,
pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n",
addr, ptab, segment, offset);
- ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask);
+ ptab[offset] = base_pte | (__pa(addr) & CBE_IOPTE_RPN_Mask);
}
static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
@@ -1016,14 +1009,14 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
- base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M
- | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
+ base_pte = CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M |
+ (cell_iommu_get_ioid(np) & CBE_IOPTE_IOID_Mask);
if (iommu_fixed_is_weak)
pr_info("IOMMU: Using weak ordering for fixed mapping\n");
else {
pr_info("IOMMU: Using strong ordering for fixed mapping\n");
- base_pte |= IOPTE_SO_RW;
+ base_pte |= CBE_IOPTE_SO_RW;
}
for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c
index 296b5268754..5e0a191764f 100644
--- a/arch/powerpc/platforms/cell/ras.c
+++ b/arch/powerpc/platforms/cell/ras.c
@@ -122,8 +122,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order)
area->nid = nid;
area->order = order;
- area->pages = alloc_pages_node(area->nid, GFP_KERNEL | GFP_THISNODE,
- area->order);
+ area->pages = alloc_pages_exact_node(area->nid, GFP_KERNEL|GFP_THISNODE,
+ area->order);
if (!area->pages) {
printk(KERN_WARNING "%s: no page on node %d\n",
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index 9046803c827..bc97fada48c 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -36,7 +36,6 @@
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/paca.h>
-#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/firmware.h>
@@ -140,31 +139,6 @@ static void __devinit smp_cell_setup_cpu(int cpu)
mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
}
-static DEFINE_SPINLOCK(timebase_lock);
-static unsigned long timebase = 0;
-
-static void __devinit cell_give_timebase(void)
-{
- spin_lock(&timebase_lock);
- rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
- timebase = get_tb();
- spin_unlock(&timebase_lock);
-
- while (timebase)
- barrier();
- rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
-}
-
-static void __devinit cell_take_timebase(void)
-{
- while (!timebase)
- barrier();
- spin_lock(&timebase_lock);
- set_tb(timebase >> 32, timebase & 0xffffffff);
- timebase = 0;
- spin_unlock(&timebase_lock);
-}
-
static void __devinit smp_cell_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
@@ -224,8 +198,8 @@ void __init smp_init_cell(void)
/* Non-lpar has additional take/give timebase */
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
- smp_ops->give_timebase = cell_give_timebase;
- smp_ops->take_timebase = cell_take_timebase;
+ smp_ops->give_timebase = rtas_give_timebase;
+ smp_ops->take_timebase = rtas_take_timebase;
}
DBG(" <- smp_init_cell()\n");
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 9abd210d87c..8547e86bfb4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -752,17 +752,8 @@ static int __init init_spu_base(void)
goto out_unregister_sysdev_class;
}
- if (ret > 0) {
- /*
- * We cannot put the forward declaration in
- * <linux/linux_logo.h> because of conflicting session type
- * conflicts for const and __initdata with different compiler
- * versions
- */
- extern const struct linux_logo logo_spe_clut224;
-
+ if (ret > 0)
fb_append_extra_logo(&logo_spe_clut224, ret);
- }
mutex_lock(&spu_full_list_mutex);
xmon_register_spus(&spu_full_list);
diff --git a/arch/powerpc/platforms/cell/spu_fault.c b/arch/powerpc/platforms/cell/spu_fault.c
index 95d8dadf2d8..d06ba87f1a1 100644
--- a/arch/powerpc/platforms/cell/spu_fault.c
+++ b/arch/powerpc/platforms/cell/spu_fault.c
@@ -70,7 +70,7 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
}
ret = 0;
- *flt = handle_mm_fault(mm, vma, ea, is_write);
+ *flt = handle_mm_fault(mm, vma, ea, is_write ? FAULT_FLAG_WRITE : 0);
if (unlikely(*flt & VM_FAULT_ERROR)) {
if (*flt & VM_FAULT_OOM) {
ret = -ENOMEM;
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 706eb5c7e2e..24b30b6909c 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -631,10 +631,6 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
if (IS_ERR(dentry))
goto out_dir;
- ret = -EEXIST;
- if (dentry->d_inode)
- goto out_dput;
-
mode &= ~current_umask();
if (flags & SPU_CREATE_GANG)
@@ -648,8 +644,6 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
fsnotify_mkdir(nd->path.dentry->d_inode, dentry);
return ret;
-out_dput:
- dput(dentry);
out_dir:
mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
out:
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index f6b0c519d5a..8f67a394b2d 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -34,7 +34,7 @@ int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
int len, u32 *val)
{
volatile void __iomem *cfg_data;
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
if (bus->number > 7)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -61,7 +61,7 @@ int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
int len, u32 val)
{
volatile void __iomem *cfg_data;
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
if (bus->number > 7)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -96,7 +96,7 @@ static struct pci_ops gg2_pci_ops =
int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
{
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
| (((bus->number - hose->first_busno) & 0xff) << 16)
| (hose->global_number << 24);
@@ -111,7 +111,7 @@ int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 val)
{
- struct pci_controller *hose = bus->sysdata;
+ struct pci_controller *hose = pci_bus_to_host(bus);
unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
| (((bus->number - hose->first_busno) & 0xff) << 16)
| (hose->global_number << 24);
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c
index 10a4a4d063b..02cafecc90e 100644
--- a/arch/powerpc/platforms/chrp/smp.c
+++ b/arch/powerpc/platforms/chrp/smp.c
@@ -26,7 +26,6 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/smp.h>
-#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/mpic.h>
#include <asm/rtas.h>
@@ -42,40 +41,12 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr)
mpic_setup_this_cpu();
}
-static DEFINE_SPINLOCK(timebase_lock);
-static unsigned int timebase_upper = 0, timebase_lower = 0;
-
-void __devinit smp_chrp_give_timebase(void)
-{
- spin_lock(&timebase_lock);
- rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
- timebase_upper = get_tbu();
- timebase_lower = get_tbl();
- spin_unlock(&timebase_lock);
-
- while (timebase_upper || timebase_lower)
- barrier();
- rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
-}
-
-void __devinit smp_chrp_take_timebase(void)
-{
- while (!(timebase_upper || timebase_lower))
- barrier();
- spin_lock(&timebase_lock);
- set_tb(timebase_upper, timebase_lower);
- timebase_upper = 0;
- timebase_lower = 0;
- spin_unlock(&timebase_lock);
- printk("CPU %i taken timebase\n", smp_processor_id());
-}
-
/* CHRP with openpic */
struct smp_ops_t chrp_smp_ops = {
.message_pass = smp_mpic_message_pass,
.probe = smp_mpic_probe,
.kick_cpu = smp_chrp_kick_cpu,
.setup_cpu = smp_chrp_setup_cpu,
- .give_timebase = smp_chrp_give_timebase,
- .take_timebase = smp_chrp_take_timebase,
+ .give_timebase = rtas_give_timebase,
+ .take_timebase = rtas_take_timebase,
};
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
index 65a35f38e06..fd23a1d4b39 100644
--- a/arch/powerpc/platforms/fsl_uli1575.c
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -51,13 +51,20 @@ u8 uli_pirq_to_irq[8] = {
ULI_8259_NONE, /* PIRQH */
};
+static inline bool is_quirk_valid(void)
+{
+ return (machine_is(mpc86xx_hpcn) ||
+ machine_is(mpc8544_ds) ||
+ machine_is(p2020_ds) ||
+ machine_is(mpc8572_ds));
+}
+
/* Bridge */
static void __devinit early_uli5249(struct pci_dev *dev)
{
unsigned char temp;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO |
@@ -80,8 +87,7 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
{
int i;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
/*
@@ -149,8 +155,7 @@ static void __devinit quirk_final_uli1575(struct pci_dev *dev)
* IRQ 14: Edge
* IRQ 15: Edge
*/
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
outb(0xfa, 0x4d0);
@@ -176,8 +181,7 @@ static void __devinit quirk_uli5288(struct pci_dev *dev)
unsigned char c;
unsigned int d;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
/* read/write lock */
@@ -201,8 +205,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
{
unsigned short temp;
- if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
- !machine_is(mpc8572_ds))
+ if (!is_quirk_valid())
return;
pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE |
@@ -270,7 +273,6 @@ static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev)
static void __devinit hpcd_quirk_uli5288(struct pci_dev *dev)
{
unsigned char c;
- unsigned short temp;
if (!machine_is(mpc86xx_hpcd))
return;
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 4543c4bc3a5..c5a87a72057 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -204,7 +204,8 @@ static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
dt_prop(dt, name, &data, sizeof(u32));
}
-static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name,
+static void __init __maybe_unused dt_prop_u64(struct iseries_flat_dt *dt,
+ const char *name,
u64 data)
{
dt_prop(dt, name, &data, sizeof(u64));
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 40219823d9b..6c1e1011959 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -177,7 +177,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
{
struct iommu_table *tbl;
- struct device_node *dn = pdev->sysdata;
+ struct device_node *dn = pci_device_to_OF_node(pdev);
struct pci_dn *pdn = PCI_DN(dn);
const u32 *lsn = of_get_property(dn, "linux,logical-slot-number", NULL);
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index 3689c2413d2..fef4d515051 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -267,7 +267,8 @@ static struct pending_event *new_pending_event(void)
return ev;
}
-static int signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd)
+static int __maybe_unused
+signal_vsp_instruction(struct vsp_cmd_data *vsp_cmd)
{
struct pending_event *ev = new_pending_event();
int rc;
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 21cddc30220..175aac8ca7e 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -318,6 +318,7 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
{
struct resource *bar_res = &dev->resource[bar_num];
long bar_size = pci_resource_len(dev, bar_num);
+ struct device_node *dn = pci_device_to_OF_node(dev);
/*
* No space to allocate, quick exit, skip Allocation.
@@ -335,9 +336,9 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
* Allocate the number of table entries needed for BAR.
*/
while (bar_size > 0 ) {
- iomm_table[current_iomm_table_entry] = dev->sysdata;
+ iomm_table[current_iomm_table_entry] = dn;
ds_addr_table[current_iomm_table_entry] =
- iseries_ds_addr(dev->sysdata) | (bar_num << 24);
+ iseries_ds_addr(dn) | (bar_num << 24);
bar_size -= IOMM_TABLE_ENTRY_SIZE;
++current_iomm_table_entry;
}
@@ -410,7 +411,7 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
struct device_node *node;
int i;
- node = find_device_node(bus, pdev->devfn);
+ node = pci_device_to_OF_node(pdev);
pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
pci_name(pdev), pdev, node);
if (!node) {
@@ -441,7 +442,6 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
}
}
- pdev->sysdata = node;
allocate_device_bars(pdev);
iseries_device_information(pdev, bus, *sub_bus);
}
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index bfd60e4acce..0636a3df697 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -335,3 +335,62 @@ define_machine(maple) {
.progress = maple_progress,
.power_save = power4_idle,
};
+
+#ifdef CONFIG_EDAC
+/*
+ * Register a platform device for CPC925 memory controller on
+ * Motorola ATCA-6101 blade.
+ */
+#define MAPLE_CPC925_MODEL "Motorola,ATCA-6101"
+static int __init maple_cpc925_edac_setup(void)
+{
+ struct platform_device *pdev;
+ struct device_node *np = NULL;
+ struct resource r;
+ const unsigned char *model;
+ int ret;
+
+ np = of_find_node_by_path("/");
+ if (!np) {
+ printk(KERN_ERR "%s: Unable to get root node\n", __func__);
+ return -ENODEV;
+ }
+
+ model = (const unsigned char *)of_get_property(np, "model", NULL);
+ if (!model) {
+ printk(KERN_ERR "%s: Unabel to get model info\n", __func__);
+ return -ENODEV;
+ }
+
+ ret = strcmp(model, MAPLE_CPC925_MODEL);
+ of_node_put(np);
+
+ if (ret != 0)
+ return 0;
+
+ np = of_find_node_by_type(NULL, "memory-controller");
+ if (!np) {
+ printk(KERN_ERR "%s: Unable to find memory-controller node\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ ret = of_address_to_resource(np, 0, &r);
+ of_node_put(np);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: Unable to get memory-controller reg\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ pdev = platform_device_register_simple("cpc925_edac", 0, &r, 1);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ printk(KERN_INFO "%s: CPC925 platform device created\n", __func__);
+
+ return 0;
+}
+machine_device_initcall(maple, maple_cpc925_edac_setup);
+#endif
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index 75cc165d5be..3bf546797cb 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -29,7 +29,7 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/phy.h>
-#include <linux/platform_device.h>
+#include <linux/of_mdio.h>
#include <linux/of_platform.h>
#define DELAY 1
@@ -39,6 +39,7 @@ static void __iomem *gpio_regs;
struct gpio_priv {
int mdc_pin;
int mdio_pin;
+ int mdio_irqs[PHY_MAX_ADDR];
};
#define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin)
@@ -218,12 +219,11 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
struct device *dev = &ofdev->dev;
- struct device_node *phy_dn, *np = ofdev->node;
+ struct device_node *np = ofdev->node;
struct mii_bus *new_bus;
struct gpio_priv *priv;
const unsigned int *prop;
int err;
- int i;
err = -ENOMEM;
priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
@@ -244,27 +244,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
new_bus->priv = priv;
- new_bus->phy_mask = 0;
-
- new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-
- if (!new_bus->irq)
- goto out_free_bus;
-
- for (i = 0; i < PHY_MAX_ADDR; i++)
- new_bus->irq[i] = NO_IRQ;
-
- for (phy_dn = of_get_next_child(np, NULL);
- phy_dn != NULL;
- phy_dn = of_get_next_child(np, phy_dn)) {
- const unsigned int *ip, *regp;
-
- ip = of_get_property(phy_dn, "interrupts", NULL);
- regp = of_get_property(phy_dn, "reg", NULL);
- if (!ip || !regp || *regp >= PHY_MAX_ADDR)
- continue;
- new_bus->irq[*regp] = irq_create_mapping(NULL, *ip);
- }
+ new_bus->irq = priv->mdio_irqs;
prop = of_get_property(np, "mdc-pin", NULL);
priv->mdc_pin = *prop;
@@ -275,7 +255,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
new_bus->parent = dev;
dev_set_drvdata(dev, new_bus);
- err = mdiobus_register(new_bus);
+ err = of_mdiobus_register(new_bus, np);
if (err != 0) {
printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
@@ -286,8 +266,6 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
return 0;
out_free_irq:
- kfree(new_bus->irq);
-out_free_bus:
kfree(new_bus);
out_free_priv:
kfree(priv);
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 153051eb6d9..a4619347aa7 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -71,20 +71,25 @@ static void pas_restart(char *cmd)
}
#ifdef CONFIG_SMP
-static DEFINE_SPINLOCK(timebase_lock);
+static raw_spinlock_t timebase_lock;
static unsigned long timebase;
static void __devinit pas_give_timebase(void)
{
- spin_lock(&timebase_lock);
+ unsigned long flags;
+
+ local_irq_save(flags);
+ hard_irq_disable();
+ __raw_spin_lock(&timebase_lock);
mtspr(SPRN_TBCTL, TBCTL_FREEZE);
isync();
timebase = get_tb();
- spin_unlock(&timebase_lock);
+ __raw_spin_unlock(&timebase_lock);
while (timebase)
barrier();
mtspr(SPRN_TBCTL, TBCTL_RESTART);
+ local_irq_restore(flags);
}
static void __devinit pas_take_timebase(void)
@@ -92,10 +97,10 @@ static void __devinit pas_take_timebase(void)
while (!timebase)
smp_rmb();
- spin_lock(&timebase_lock);
+ __raw_spin_lock(&timebase_lock);
set_tb(timebase >> 32, timebase & 0xffffffff);
timebase = 0;
- spin_unlock(&timebase_lock);
+ __raw_spin_unlock(&timebase_lock);
}
struct smp_ops_t pas_smp_ops = {
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 7039d8f1d3b..dce73634910 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -221,7 +221,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id)
continue;
irq += __ilog2(bits);
spin_unlock_irqrestore(&pmac_pic_lock, flags);
- __do_IRQ(irq);
+ generic_handle_irq(irq);
spin_lock_irqsave(&pmac_pic_lock, flags);
rc = IRQ_HANDLED;
}
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 45936c9ed0e..c2052265636 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -103,11 +103,6 @@ unsigned long smu_cmdbuf_abs;
EXPORT_SYMBOL(smu_cmdbuf_abs);
#endif
-#ifdef CONFIG_SMP
-extern struct smp_ops_t psurge_smp_ops;
-extern struct smp_ops_t core99_smp_ops;
-#endif /* CONFIG_SMP */
-
static void pmac_show_cpuinfo(struct seq_file *m)
{
struct device_node *np;
@@ -341,34 +336,6 @@ static void __init pmac_setup_arch(void)
ROOT_DEV = DEFAULT_ROOT_DEVICE;
#endif
-#ifdef CONFIG_SMP
- /* Check for Core99 */
- ic = of_find_node_by_name(NULL, "uni-n");
- if (!ic)
- ic = of_find_node_by_name(NULL, "u3");
- if (!ic)
- ic = of_find_node_by_name(NULL, "u4");
- if (ic) {
- of_node_put(ic);
- smp_ops = &core99_smp_ops;
- }
-#ifdef CONFIG_PPC32
- else {
- /*
- * We have to set bits in cpu_possible_map here since the
- * secondary CPU(s) aren't in the device tree, and
- * setup_per_cpu_areas only allocates per-cpu data for
- * CPUs in the cpu_possible_map.
- */
- int cpu;
-
- for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
- cpu_set(cpu, cpu_possible_map);
- smp_ops = &psurge_smp_ops;
- }
-#endif
-#endif /* CONFIG_SMP */
-
#ifdef CONFIG_ADB
if (strstr(cmd_line, "adb_sync")) {
extern int __adb_probe_sync;
@@ -512,6 +479,14 @@ static void __init pmac_init_early(void)
#ifdef CONFIG_PPC64
iommu_init_early_dart();
#endif
+
+ /* SMP Init has to be done early as we need to patch up
+ * cpu_possible_map before interrupt stacks are allocated
+ * or kaboom...
+ */
+#ifdef CONFIG_SMP
+ pmac_setup_smp();
+#endif
}
static int __init pmac_declare_of_platform_devices(void)
@@ -655,7 +630,7 @@ static int __init pmac_probe(void)
/* Move that to pci.c */
static int pmac_pci_probe_mode(struct pci_bus *bus)
{
- struct device_node *node = bus->sysdata;
+ struct device_node *node = pci_bus_to_OF_node(bus);
/* We need to use normal PCI probing for the AGP bus,
* since the device for the AGP bridge isn't in the tree.
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index cf1dbe75889..6d4da7b46b4 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -64,10 +64,11 @@
extern void __secondary_start_pmac_0(void);
extern int pmac_pfunc_base_install(void);
-#ifdef CONFIG_PPC32
+static void (*pmac_tb_freeze)(int freeze);
+static u64 timebase;
+static int tb_req;
-/* Sync flag for HW tb sync */
-static volatile int sec_tb_reset = 0;
+#ifdef CONFIG_PPC32
/*
* Powersurge (old powermac SMP) support.
@@ -294,6 +295,9 @@ static int __init smp_psurge_probe(void)
psurge_quad_init();
/* All released cards using this HW design have 4 CPUs */
ncpus = 4;
+ /* No sure how timebase sync works on those, let's use SW */
+ smp_ops->give_timebase = smp_generic_give_timebase;
+ smp_ops->take_timebase = smp_generic_take_timebase;
} else {
iounmap(quad_base);
if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
@@ -308,18 +312,15 @@ static int __init smp_psurge_probe(void)
psurge_start = ioremap(PSURGE_START, 4);
psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
- /*
- * This is necessary because OF doesn't know about the
+ /* This is necessary because OF doesn't know about the
* secondary cpu(s), and thus there aren't nodes in the
* device tree for them, and smp_setup_cpu_maps hasn't
- * set their bits in cpu_possible_map and cpu_present_map.
+ * set their bits in cpu_present_map.
*/
if (ncpus > NR_CPUS)
ncpus = NR_CPUS;
- for (i = 1; i < ncpus ; ++i) {
+ for (i = 1; i < ncpus ; ++i)
cpu_set(i, cpu_present_map);
- set_hard_smp_processor_id(i, i);
- }
if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
@@ -329,8 +330,14 @@ static int __init smp_psurge_probe(void)
static void __init smp_psurge_kick_cpu(int nr)
{
unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
- unsigned long a;
- int i;
+ unsigned long a, flags;
+ int i, j;
+
+ /* Defining this here is evil ... but I prefer hiding that
+ * crap to avoid giving people ideas that they can do the
+ * same.
+ */
+ extern volatile unsigned int cpu_callin_map[NR_CPUS];
/* may need to flush here if secondary bats aren't setup */
for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
@@ -339,47 +346,52 @@ static void __init smp_psurge_kick_cpu(int nr)
if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
+ /* This is going to freeze the timeebase, we disable interrupts */
+ local_irq_save(flags);
+
out_be32(psurge_start, start);
mb();
psurge_set_ipi(nr);
+
/*
* We can't use udelay here because the timebase is now frozen.
*/
for (i = 0; i < 2000; ++i)
- barrier();
+ asm volatile("nop" : : : "memory");
psurge_clr_ipi(nr);
- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
-}
-
-/*
- * With the dual-cpu powersurge board, the decrementers and timebases
- * of both cpus are frozen after the secondary cpu is started up,
- * until we give the secondary cpu another interrupt. This routine
- * uses this to get the timebases synchronized.
- * -- paulus.
- */
-static void __init psurge_dual_sync_tb(int cpu_nr)
-{
- int t;
-
- set_dec(tb_ticks_per_jiffy);
- /* XXX fixme */
- set_tb(0, 0);
-
- if (cpu_nr > 0) {
+ /*
+ * Also, because the timebase is frozen, we must not return to the
+ * caller which will try to do udelay's etc... Instead, we wait -here-
+ * for the CPU to callin.
+ */
+ for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) {
+ for (j = 1; j < 10000; j++)
+ asm volatile("nop" : : : "memory");
+ asm volatile("sync" : : : "memory");
+ }
+ if (!cpu_callin_map[nr])
+ goto stuck;
+
+ /* And we do the TB sync here too for standard dual CPU cards */
+ if (psurge_type == PSURGE_DUAL) {
+ while(!tb_req)
+ barrier();
+ tb_req = 0;
+ mb();
+ timebase = get_tb();
+ mb();
+ while (timebase)
+ barrier();
mb();
- sec_tb_reset = 1;
- return;
}
+ stuck:
+ /* now interrupt the secondary, restarting both TBs */
+ if (psurge_type == PSURGE_DUAL)
+ psurge_set_ipi(1);
- /* wait for the secondary to have reset its TB before proceeding */
- for (t = 10000000; t > 0 && !sec_tb_reset; --t)
- ;
-
- /* now interrupt the secondary, starting both TBs */
- psurge_set_ipi(1);
+ if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
}
static struct irqaction psurge_irqaction = {
@@ -390,36 +402,35 @@ static struct irqaction psurge_irqaction = {
static void __init smp_psurge_setup_cpu(int cpu_nr)
{
+ if (cpu_nr != 0)
+ return;
- if (cpu_nr == 0) {
- /* If we failed to start the second CPU, we should still
- * send it an IPI to start the timebase & DEC or we might
- * have them stuck.
- */
- if (num_online_cpus() < 2) {
- if (psurge_type == PSURGE_DUAL)
- psurge_set_ipi(1);
- return;
- }
- /* reset the entry point so if we get another intr we won't
- * try to startup again */
- out_be32(psurge_start, 0x100);
- if (setup_irq(30, &psurge_irqaction))
- printk(KERN_ERR "Couldn't get primary IPI interrupt");
- }
-
- if (psurge_type == PSURGE_DUAL)
- psurge_dual_sync_tb(cpu_nr);
+ /* reset the entry point so if we get another intr we won't
+ * try to startup again */
+ out_be32(psurge_start, 0x100);
+ if (setup_irq(30, &psurge_irqaction))
+ printk(KERN_ERR "Couldn't get primary IPI interrupt");
}
void __init smp_psurge_take_timebase(void)
{
- /* Dummy implementation */
+ if (psurge_type != PSURGE_DUAL)
+ return;
+
+ tb_req = 1;
+ mb();
+ while (!timebase)
+ barrier();
+ mb();
+ set_tb(timebase >> 32, timebase & 0xffffffff);
+ timebase = 0;
+ mb();
+ set_dec(tb_ticks_per_jiffy/2);
}
void __init smp_psurge_give_timebase(void)
{
- /* Dummy implementation */
+ /* Nothing to do here */
}
/* PowerSurge-style Macs */
@@ -437,9 +448,6 @@ struct smp_ops_t psurge_smp_ops = {
* Core 99 and later support
*/
-static void (*pmac_tb_freeze)(int freeze);
-static u64 timebase;
-static int tb_req;
static void smp_core99_give_timebase(void)
{
@@ -478,7 +486,6 @@ static void __devinit smp_core99_take_timebase(void)
set_tb(timebase >> 32, timebase & 0xffffffff);
timebase = 0;
mb();
- set_dec(tb_ticks_per_jiffy/2);
local_irq_restore(flags);
}
@@ -920,3 +927,34 @@ struct smp_ops_t core99_smp_ops = {
# endif
#endif
};
+
+void __init pmac_setup_smp(void)
+{
+ struct device_node *np;
+
+ /* Check for Core99 */
+ np = of_find_node_by_name(NULL, "uni-n");
+ if (!np)
+ np = of_find_node_by_name(NULL, "u3");
+ if (!np)
+ np = of_find_node_by_name(NULL, "u4");
+ if (np) {
+ of_node_put(np);
+ smp_ops = &core99_smp_ops;
+ }
+#ifdef CONFIG_PPC32
+ else {
+ /* We have to set bits in cpu_possible_map here since the
+ * secondary CPU(s) aren't in the device tree. Various
+ * things won't be initialized for CPUs not in the possible
+ * map, so we really need to fix it up here.
+ */
+ int cpu;
+
+ for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
+ cpu_set(cpu, cpu_possible_map);
+ smp_ops = &psurge_smp_ops;
+ }
+#endif /* CONFIG_PPC32 */
+}
+
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 9a2b6d94861..846eb8b57fd 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -24,6 +24,7 @@
#include <linux/lmb.h>
#include <asm/firmware.h>
+#include <asm/iommu.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <asm/lv1call.h>
@@ -605,9 +606,8 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
r->ioid,
iopte_flag);
if (result) {
- printk(KERN_WARNING "%s:%d: lv1_map_device_dma_region "
- "failed: %s\n", __func__, __LINE__,
- ps3_result(result));
+ pr_warning("%s:%d: lv1_put_iopte failed: %s\n",
+ __func__, __LINE__, ps3_result(result));
goto fail_map;
}
DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
@@ -1001,7 +1001,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
if (len > r->len)
len = r->len;
result = dma_sb_map_area(r, virt_addr, len, &tmp,
- IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
+ CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_SO_RW |
+ CBE_IOPTE_M);
BUG_ON(result);
}
@@ -1014,7 +1015,8 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
else
len -= map.rm.size - r->offset;
result = dma_sb_map_area(r, virt_addr, len, &tmp,
- IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
+ CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_SO_RW |
+ CBE_IOPTE_M);
BUG_ON(result);
}
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index cf1cd0f8c18..d6487a9c801 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -226,6 +226,44 @@ static struct property property_av_multi_out = {
.value = &saved_params.av_multi_out,
};
+
+static DEFINE_MUTEX(os_area_flash_mutex);
+
+static const struct ps3_os_area_flash_ops *os_area_flash_ops;
+
+void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops)
+{
+ mutex_lock(&os_area_flash_mutex);
+ os_area_flash_ops = ops;
+ mutex_unlock(&os_area_flash_mutex);
+}
+EXPORT_SYMBOL_GPL(ps3_os_area_flash_register);
+
+static ssize_t os_area_flash_read(void *buf, size_t count, loff_t pos)
+{
+ ssize_t res = -ENODEV;
+
+ mutex_lock(&os_area_flash_mutex);
+ if (os_area_flash_ops)
+ res = os_area_flash_ops->read(buf, count, pos);
+ mutex_unlock(&os_area_flash_mutex);
+
+ return res;
+}
+
+static ssize_t os_area_flash_write(const void *buf, size_t count, loff_t pos)
+{
+ ssize_t res = -ENODEV;
+
+ mutex_lock(&os_area_flash_mutex);
+ if (os_area_flash_ops)
+ res = os_area_flash_ops->write(buf, count, pos);
+ mutex_unlock(&os_area_flash_mutex);
+
+ return res;
+}
+
+
/**
* os_area_set_property - Add or overwrite a saved_params value to the device tree.
*
@@ -352,12 +390,12 @@ static int db_verify(const struct os_area_db *db)
if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM,
sizeof(db->magic_num))) {
pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
- return -1;
+ return -EINVAL;
}
if (db->version != 1) {
pr_debug("%s:%d version failed\n", __func__, __LINE__);
- return -1;
+ return -EINVAL;
}
return 0;
@@ -578,59 +616,48 @@ static void os_area_db_init(struct os_area_db *db)
*
*/
-static void __maybe_unused update_flash_db(void)
+static int update_flash_db(void)
{
- int result;
- int file;
- off_t offset;
+ const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
+ struct os_area_header *header;
ssize_t count;
- static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
- const struct os_area_header *header;
+ int error;
+ loff_t pos;
struct os_area_db* db;
/* Read in header and db from flash. */
- file = sys_open("/dev/ps3flash", O_RDWR, 0);
-
- if (file < 0) {
- pr_debug("%s:%d sys_open failed\n", __func__, __LINE__);
- goto fail_open;
- }
-
header = kmalloc(buf_len, GFP_KERNEL);
-
if (!header) {
- pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__);
- goto fail_malloc;
+ pr_debug("%s: kmalloc failed\n", __func__);
+ return -ENOMEM;
}
- offset = sys_lseek(file, 0, SEEK_SET);
-
- if (offset != 0) {
- pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
- goto fail_header_seek;
+ count = os_area_flash_read(header, buf_len, 0);
+ if (count < 0) {
+ pr_debug("%s: os_area_flash_read failed %zd\n", __func__,
+ count);
+ error = count;
+ goto fail;
}
- count = sys_read(file, (char __user *)header, buf_len);
-
- result = count < OS_AREA_SEGMENT_SIZE || verify_header(header)
- || count < header->db_area_offset * OS_AREA_SEGMENT_SIZE;
-
- if (result) {
- pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
+ pos = header->db_area_offset * OS_AREA_SEGMENT_SIZE;
+ if (count < OS_AREA_SEGMENT_SIZE || verify_header(header) ||
+ count < pos) {
+ pr_debug("%s: verify_header failed\n", __func__);
dump_header(header);
- goto fail_header;
+ error = -EINVAL;
+ goto fail;
}
/* Now got a good db offset and some maybe good db data. */
- db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE;
+ db = (void *)header + pos;
- result = db_verify(db);
-
- if (result) {
- printk(KERN_NOTICE "%s:%d: Verify of flash database failed, "
- "formatting.\n", __func__, __LINE__);
+ error = db_verify(db);
+ if (error) {
+ pr_notice("%s: Verify of flash database failed, formatting.\n",
+ __func__);
dump_db(db);
os_area_db_init(db);
}
@@ -639,29 +666,16 @@ static void __maybe_unused update_flash_db(void)
db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff);
- offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE,
- SEEK_SET);
-
- if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) {
- pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
- goto fail_db_seek;
- }
-
- count = sys_write(file, (const char __user *)db,
- sizeof(struct os_area_db));
-
+ count = os_area_flash_write(db, sizeof(struct os_area_db), pos);
if (count < sizeof(struct os_area_db)) {
- pr_debug("%s:%d sys_write failed\n", __func__, __LINE__);
+ pr_debug("%s: os_area_flash_write failed %zd\n", __func__,
+ count);
+ error = count < 0 ? count : -EIO;
}
-fail_db_seek:
-fail_header:
-fail_header_seek:
+fail:
kfree(header);
-fail_malloc:
- sys_close(file);
-fail_open:
- return;
+ return error;
}
/**
@@ -674,11 +688,11 @@ fail_open:
static void os_area_queue_work_handler(struct work_struct *work)
{
struct device_node *node;
+ int error;
pr_debug(" -> %s:%d\n", __func__, __LINE__);
node = of_find_node_by_path("/");
-
if (node) {
os_area_set_property(node, &property_rtc_diff);
of_node_put(node);
@@ -686,12 +700,10 @@ static void os_area_queue_work_handler(struct work_struct *work)
pr_debug("%s:%d of_find_node_by_path failed\n",
__func__, __LINE__);
-#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
- update_flash_db();
-#else
- printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n",
- __func__, __LINE__);
-#endif
+ error = update_flash_db();
+ if (error)
+ pr_warning("%s: Could not update FLASH ROM\n", __func__);
+
pr_debug(" <- %s:%d\n", __func__, __LINE__);
}
@@ -808,7 +820,7 @@ u64 ps3_os_area_get_rtc_diff(void)
{
return saved_params.rtc_diff;
}
-EXPORT_SYMBOL(ps3_os_area_get_rtc_diff);
+EXPORT_SYMBOL_GPL(ps3_os_area_get_rtc_diff);
/**
* ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -824,7 +836,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_diff)
os_area_queue_work();
}
}
-EXPORT_SYMBOL(ps3_os_area_set_rtc_diff);
+EXPORT_SYMBOL_GPL(ps3_os_area_set_rtc_diff);
/**
* ps3_os_area_get_av_multi_out - Returns the default video mode.
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 136aa0637d9..9a196a88eda 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -232,14 +232,4 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
int ps3_repository_read_vuart_av_port(unsigned int *port);
int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
-/* Page table entries */
-#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
-#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
-#define IOPTE_M 0x2000000000000000ul /* coherency required */
-#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
-#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
-#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
-#define IOPTE_H 0x0000000000000800ul /* cache hint */
-#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
-
#endif
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 1a7b5ae0c83..149bea2ce58 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -32,6 +32,7 @@
#include <asm/udbg.h>
#include <asm/prom.h>
#include <asm/lv1call.h>
+#include <asm/ps3gpu.h>
#include "platform.h"
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index a0927a3bacb..f6e04bcc70e 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -32,12 +32,6 @@
#define DBG pr_debug
#endif
-static irqreturn_t ipi_function_handler(int irq, void *msg)
-{
- smp_message_recv((int)(long)msg);
- return IRQ_HANDLED;
-}
-
/**
* ps3_ipi_virqs - a per cpu array of virqs for ipi use
*/
@@ -45,13 +39,6 @@ static irqreturn_t ipi_function_handler(int irq, void *msg)
#define MSG_COUNT 4
static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
-static const char *names[MSG_COUNT] = {
- "ipi call",
- "ipi reschedule",
- "ipi migrate",
- "ipi debug brk"
-};
-
static void do_message_pass(int target, int msg)
{
int result;
@@ -119,8 +106,7 @@ static void __init ps3_smp_setup_cpu(int cpu)
DBG("%s:%d: (%d, %d) => virq %u\n",
__func__, __LINE__, cpu, i, virqs[i]);
- result = request_irq(virqs[i], ipi_function_handler,
- IRQF_DISABLED, names[i], (void*)(long)i);
+ result = smp_request_message_ipi(virqs[i], i);
if (result)
virqs[i] = NO_IRQ;
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 9a73d023863..9fead0faf38 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -27,6 +27,7 @@
#include <asm/udbg.h>
#include <asm/lv1call.h>
#include <asm/firmware.h>
+#include <asm/iommu.h>
#include "platform.h"
@@ -531,7 +532,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size,
}
result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
- IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
+ CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
+ CBE_IOPTE_SO_RW | CBE_IOPTE_M);
if (result) {
pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -575,7 +577,8 @@ static dma_addr_t ps3_sb_map_page(struct device *_dev, struct page *page,
result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
&bus_addr,
- IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M);
+ CBE_IOPTE_PP_R | CBE_IOPTE_PP_W |
+ CBE_IOPTE_SO_RW | CBE_IOPTE_M);
if (result) {
pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -596,16 +599,16 @@ static dma_addr_t ps3_ioc0_map_page(struct device *_dev, struct page *page,
u64 iopte_flag;
void *ptr = page_address(page) + offset;
- iopte_flag = IOPTE_M;
+ iopte_flag = CBE_IOPTE_M;
switch (direction) {
case DMA_BIDIRECTIONAL:
- iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW;
+ iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
break;
case DMA_TO_DEVICE:
- iopte_flag |= IOPTE_PP_R | IOPTE_SO_R;
+ iopte_flag |= CBE_IOPTE_PP_R | CBE_IOPTE_SO_R;
break;
case DMA_FROM_DEVICE:
- iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW;
+ iopte_flag |= CBE_IOPTE_PP_W | CBE_IOPTE_SO_RW;
break;
default:
/* not happned */
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 9a2a6e32f00..0e8db677125 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -122,7 +122,7 @@ static void eeh_enable_irq(struct pci_dev *dev)
* passed back in "userdata".
*/
-static void eeh_report_error(struct pci_dev *dev, void *userdata)
+static int eeh_report_error(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver;
@@ -130,19 +130,21 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
dev->error_state = pci_channel_io_frozen;
if (!driver)
- return;
+ return 0;
eeh_disable_irq(dev);
if (!driver->err_handler ||
!driver->err_handler->error_detected)
- return;
+ return 0;
rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
/* A driver that needs a reset trumps all others */
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+
+ return 0;
}
/**
@@ -153,7 +155,7 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
* Cumulative response passed back in "userdata".
*/
-static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
+static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver;
@@ -161,26 +163,28 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
if (!driver ||
!driver->err_handler ||
!driver->err_handler->mmio_enabled)
- return;
+ return 0;
rc = driver->err_handler->mmio_enabled (dev);
/* A driver that needs a reset trumps all others */
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
if (*res == PCI_ERS_RESULT_NONE) *res = rc;
+
+ return 0;
}
/**
* eeh_report_reset - tell device that slot has been reset
*/
-static void eeh_report_reset(struct pci_dev *dev, void *userdata)
+static int eeh_report_reset(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver;
if (!driver)
- return;
+ return 0;
dev->error_state = pci_channel_io_normal;
@@ -188,35 +192,39 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
if (!driver->err_handler ||
!driver->err_handler->slot_reset)
- return;
+ return 0;
rc = driver->err_handler->slot_reset(dev);
if ((*res == PCI_ERS_RESULT_NONE) ||
(*res == PCI_ERS_RESULT_RECOVERED)) *res = rc;
if (*res == PCI_ERS_RESULT_DISCONNECT &&
rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
+
+ return 0;
}
/**
* eeh_report_resume - tell device to resume normal operations
*/
-static void eeh_report_resume(struct pci_dev *dev, void *userdata)
+static int eeh_report_resume(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
dev->error_state = pci_channel_io_normal;
if (!driver)
- return;
+ return 0;
eeh_enable_irq(dev);
if (!driver->err_handler ||
!driver->err_handler->resume)
- return;
+ return 0;
driver->err_handler->resume(dev);
+
+ return 0;
}
/**
@@ -226,22 +234,24 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata)
* dead, and that no further recovery attempts will be made on it.
*/
-static void eeh_report_failure(struct pci_dev *dev, void *userdata)
+static int eeh_report_failure(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
dev->error_state = pci_channel_io_perm_failure;
if (!driver)
- return;
+ return 0;
eeh_disable_irq(dev);
if (!driver->err_handler ||
!driver->err_handler->error_detected)
- return;
+ return 0;
driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
+
+ return 0;
}
/* ------------------------------------------------------- */
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 3ee01b4f425..661c8e02bcb 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -388,7 +388,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
while (pci->phb->dma_window_size * children > 0x80000000ul)
pci->phb->dma_window_size >>= 1;
- pr_debug("No ISA/IDE, window size is 0x%lx\n",
+ pr_debug("No ISA/IDE, window size is 0x%llx\n",
pci->phb->dma_window_size);
pci->phb->dma_window_base_cur = 0;
@@ -414,7 +414,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
while (pci->phb->dma_window_size * children > 0x70000000ul)
pci->phb->dma_window_size >>= 1;
- pr_debug("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
+ pr_debug("ISA/IDE, window size is 0x%llx\n", pci->phb->dma_window_size);
}
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 52a80e5840e..e3139fa5e55 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -609,3 +609,55 @@ void __init hpte_init_lpar(void)
ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear;
}
+
+#ifdef CONFIG_PPC_SMLPAR
+#define CMO_FREE_HINT_DEFAULT 1
+static int cmo_free_hint_flag = CMO_FREE_HINT_DEFAULT;
+
+static int __init cmo_free_hint(char *str)
+{
+ char *parm;
+ parm = strstrip(str);
+
+ if (strcasecmp(parm, "no") == 0 || strcasecmp(parm, "off") == 0) {
+ printk(KERN_INFO "cmo_free_hint: CMO free page hinting is not active.\n");
+ cmo_free_hint_flag = 0;
+ return 1;
+ }
+
+ cmo_free_hint_flag = 1;
+ printk(KERN_INFO "cmo_free_hint: CMO free page hinting is active.\n");
+
+ if (strcasecmp(parm, "yes") == 0 || strcasecmp(parm, "on") == 0)
+ return 1;
+
+ return 0;
+}
+
+__setup("cmo_free_hint=", cmo_free_hint);
+
+static void pSeries_set_page_state(struct page *page, int order,
+ unsigned long state)
+{
+ int i, j;
+ unsigned long cmo_page_sz, addr;
+
+ cmo_page_sz = cmo_get_page_size();
+ addr = __pa((unsigned long)page_address(page));
+
+ for (i = 0; i < (1 << order); i++, addr += PAGE_SIZE) {
+ for (j = 0; j < PAGE_SIZE; j += cmo_page_sz)
+ plpar_hcall_norets(H_PAGE_INIT, state, addr + j, 0);
+ }
+}
+
+void arch_free_page(struct page *page, int order)
+{
+ if (!cmo_free_hint_flag || !firmware_has_feature(FW_FEATURE_CMO))
+ return;
+
+ pSeries_set_page_state(page, order, H_PAGE_SET_UNUSED);
+}
+EXPORT_SYMBOL(arch_free_page);
+
+#endif
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index afad9f5ac0a..b3cbac85592 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -19,7 +19,7 @@
#include <linux/vmalloc.h>
#include <linux/spinlock.h>
#include <linux/cpu.h>
-#include <linux/delay.h>
+#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -387,36 +387,51 @@ static void do_event_scan(void)
} while(error == 0);
}
-static void do_event_scan_all_cpus(long delay)
+static void rtas_event_scan(struct work_struct *w);
+DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
+
+/*
+ * Delay should be at least one second since some machines have problems if
+ * we call event-scan too quickly.
+ */
+static unsigned long event_scan_delay = 1*HZ;
+static int first_pass = 1;
+
+static void rtas_event_scan(struct work_struct *w)
{
- int cpu;
+ unsigned int cpu;
+
+ do_event_scan();
get_online_cpus();
- cpu = first_cpu(cpu_online_map);
- for (;;) {
- set_cpus_allowed(current, cpumask_of_cpu(cpu));
- do_event_scan();
- set_cpus_allowed(current, CPU_MASK_ALL);
-
- /* Drop hotplug lock, and sleep for the specified delay */
- put_online_cpus();
- msleep_interruptible(delay);
- get_online_cpus();
-
- cpu = next_cpu(cpu, cpu_online_map);
- if (cpu == NR_CPUS)
- break;
+
+ cpu = next_cpu(smp_processor_id(), cpu_online_map);
+ if (cpu == NR_CPUS) {
+ cpu = first_cpu(cpu_online_map);
+
+ if (first_pass) {
+ first_pass = 0;
+ event_scan_delay = 30*HZ/rtas_event_scan_rate;
+
+ if (surveillance_timeout != -1) {
+ pr_debug("rtasd: enabling surveillance\n");
+ enable_surveillance(surveillance_timeout);
+ pr_debug("rtasd: surveillance enabled\n");
+ }
+ }
}
+
+ schedule_delayed_work_on(cpu, &event_scan_work,
+ __round_jiffies_relative(event_scan_delay, cpu));
+
put_online_cpus();
}
-static int rtasd(void *unused)
+static void start_event_scan(void)
{
unsigned int err_type;
int rc;
- daemonize("rtasd");
-
printk(KERN_DEBUG "RTAS daemon started\n");
pr_debug("rtasd: will sleep for %d milliseconds\n",
(30000 / rtas_event_scan_rate));
@@ -434,22 +449,8 @@ static int rtasd(void *unused)
}
}
- /* First pass. */
- do_event_scan_all_cpus(1000);
-
- if (surveillance_timeout != -1) {
- pr_debug("rtasd: enabling surveillance\n");
- enable_surveillance(surveillance_timeout);
- pr_debug("rtasd: surveillance enabled\n");
- }
-
- /* Delay should be at least one second since some
- * machines have problems if we call event-scan too
- * quickly. */
- for (;;)
- do_event_scan_all_cpus(30000/rtas_event_scan_rate);
-
- return -EINVAL;
+ schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
+ event_scan_delay);
}
static int __init rtas_init(void)
@@ -487,8 +488,7 @@ static int __init rtas_init(void)
if (!entry)
printk(KERN_ERR "Failed to create error_log proc entry\n");
- if (kernel_thread(rtasd, NULL, CLONE_FS) < 0)
- printk(KERN_ERR "Failed to start RTAS daemon\n");
+ start_event_scan();
return 0;
}
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ec341707e41..8d75ea21296 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -63,6 +63,7 @@
#include <asm/smp.h>
#include <asm/firmware.h>
#include <asm/eeh.h>
+#include <asm/pSeries_reconfig.h>
#include "plpar_wrappers.h"
#include "pseries.h"
@@ -254,6 +255,29 @@ static void __init pseries_discover_pic(void)
" interrupt-controller\n");
}
+static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
+{
+ struct device_node *np = node;
+ struct pci_dn *pci = NULL;
+ int err = NOTIFY_OK;
+
+ switch (action) {
+ case PSERIES_RECONFIG_ADD:
+ pci = np->parent->data;
+ if (pci)
+ update_dn_pci_info(np, pci->phb);
+ break;
+ default:
+ err = NOTIFY_DONE;
+ break;
+ }
+ return err;
+}
+
+static struct notifier_block pci_dn_reconfig_nb = {
+ .notifier_call = pci_dn_reconfig_notifier,
+};
+
static void __init pSeries_setup_arch(void)
{
/* Discover PIC type and setup ppc_md accordingly */
@@ -271,6 +295,7 @@ static void __init pSeries_setup_arch(void)
/* Find and initialize PCI host bridges */
init_pci_config_tokens();
find_and_init_phbs();
+ pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
eeh_init();
pSeries_nvram_init();
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 1a231c389ba..1f8f6cfb94f 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -35,7 +35,6 @@
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/paca.h>
-#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/firmware.h>
@@ -118,31 +117,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
}
#endif /* CONFIG_XICS */
-static DEFINE_SPINLOCK(timebase_lock);
-static unsigned long timebase = 0;
-
-static void __devinit pSeries_give_timebase(void)
-{
- spin_lock(&timebase_lock);
- rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
- timebase = get_tb();
- spin_unlock(&timebase_lock);
-
- while (timebase)
- barrier();
- rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
-}
-
-static void __devinit pSeries_take_timebase(void)
-{
- while (!timebase)
- barrier();
- spin_lock(&timebase_lock);
- set_tb(timebase >> 32, timebase & 0xffffffff);
- timebase = 0;
- spin_unlock(&timebase_lock);
-}
-
static void __devinit smp_pSeries_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
@@ -209,8 +183,8 @@ static void __init smp_init_pseries(void)
/* Non-lpar has additional take/give timebase */
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
- smp_ops->give_timebase = pSeries_give_timebase;
- smp_ops->take_timebase = pSeries_take_timebase;
+ smp_ops->give_timebase = rtas_give_timebase;
+ smp_ops->take_timebase = rtas_take_timebase;
}
pr_debug(" <- smp_init_pSeries()\n");