diff options
Diffstat (limited to 'arch/powerpc/platforms')
53 files changed, 768 insertions, 801 deletions
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index 8883f2c01a1a..baae85584b1c 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -100,6 +100,16 @@ config XILINX_VIRTEX_GENERIC_BOARD Most Virtex designs should use this unless it needs to do some special configuration at board probe time. +config OBS600 + bool "OpenBlockS 600" + depends on 40x + default n + select 405EX + select PPC40x_SIMPLE + help + This option enables support for PlatHome OpenBlockS 600 server + + config PPC40x_SIMPLE bool "Simple PowerPC 40x board support" depends on 40x diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c index 2f8fde6521ea..97612068fae3 100644 --- a/arch/powerpc/platforms/40x/ppc40x_simple.c +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c @@ -56,7 +56,8 @@ static const char *board[] __initdata = { "amcc,kilauea", "amcc,makalu", "apm,klondike", - "est,hotfoot" + "est,hotfoot", + "plathome,obs600" }; static int __init ppc40x_probe(void) diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c index 19395f18b1db..5b8cdbb82f80 100644 --- a/arch/powerpc/platforms/44x/iss4xx.c +++ b/arch/powerpc/platforms/44x/iss4xx.c @@ -71,7 +71,7 @@ static void __init iss4xx_init_irq(void) /* The MPIC driver will get everything it needs from the * device-tree, just pass 0 to all arguments */ - struct mpic *mpic = mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0, + struct mpic *mpic = mpic_alloc(np, 0, 0, 0, 0, " MPIC "); BUG_ON(mpic == NULL); mpic_init(mpic); diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c index c48b66187dda..07e3e6c47371 100644 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/arch/powerpc/platforms/85xx/corenet_ds.c @@ -31,32 +31,18 @@ #include <linux/of_platform.h> #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> +#include "smp.h" void __init corenet_ds_pic_init(void) { struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - unsigned int flags = MPIC_PRIMARY | MPIC_BIG_ENDIAN | + unsigned int flags = MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU; - np = of_find_node_by_type(np, "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; - } - if (ppc_md.get_irq == mpic_get_coreint_irq) flags |= MPIC_ENABLE_COREINT; - mpic = mpic_alloc(np, r.start, flags, 0, 256, " OpenPIC "); + mpic = mpic_alloc(NULL, 0, flags, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); mpic_init(mpic); @@ -65,10 +51,6 @@ void __init corenet_ds_pic_init(void) /* * Setup the architecture */ -#ifdef CONFIG_SMP -void __init mpc85xx_smp_init(void); -#endif - void __init corenet_ds_setup_arch(void) { #ifdef CONFIG_PCI @@ -77,9 +59,7 @@ void __init corenet_ds_setup_arch(void) #endif dma_addr_t max = 0xffffffff; -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif #ifdef CONFIG_PCI for_each_node_by_type(np, "pci") { diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index 0f3e68832657..20f75d7819c6 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c @@ -57,29 +57,10 @@ static void machine_restart(char *cmd) static void __init ksi8560_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 "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); mpc85xx_cpm2_pic_init(); diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 9ee6455c2f1e..cf266826682e 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -36,29 +36,11 @@ void __init mpc8536_ds_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 | + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); } diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 986554b74d3f..3bebb5173bfc 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -50,28 +50,10 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, static void __init mpc85xx_ads_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(np, "open-pic"); - if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); mpc85xx_cpm2_pic_init(); diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index d993b66f1abf..40f03da616a9 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -188,30 +188,10 @@ static struct irqaction mpc85xxcds_8259_irqaction = { static void __init mpc85xx_cds_pic_init(void) { struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(np, "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 = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - - /* Return the mpic node */ - of_node_put(np); - mpic_init(mpic); } diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 2113120c5a7d..eefbb91e1d61 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -35,6 +35,7 @@ #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> +#include "smp.h" #include "mpc85xx.h" @@ -62,43 +63,27 @@ static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc) void __init mpc85xx_ds_pic_init(void) { struct mpic *mpic; - struct resource r; - struct device_node *np; #ifdef CONFIG_PPC_I8259 + struct device_node *np; struct device_node *cascade_node = NULL; int cascade_irq; #endif unsigned long root = of_get_flat_dt_root(); - 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; - } - if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) { - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | + mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); } else { - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | + mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); } BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); #ifdef CONFIG_PPC_I8259 @@ -154,9 +139,6 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, /* * Setup the architecture */ -#ifdef CONFIG_SMP -extern void __init mpc85xx_smp_init(void); -#endif static void __init mpc85xx_ds_setup_arch(void) { #ifdef CONFIG_PCI @@ -189,9 +171,7 @@ static void __init mpc85xx_ds_setup_arch(void) ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif #ifdef CONFIG_SWIOTLB if (memblock_end_of_DRAM() > max) { diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 495cfd988c1a..1d15a0cd2c82 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -51,6 +51,7 @@ #include <asm/qe_ic.h> #include <asm/mpic.h> #include <asm/swiotlb.h> +#include "smp.h" #include "mpc85xx.h" @@ -155,10 +156,6 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) * Setup the architecture * */ -#ifdef CONFIG_SMP -extern void __init mpc85xx_smp_init(void); -#endif - #ifdef CONFIG_QUICC_ENGINE static void __init mpc85xx_mds_reset_ucc_phys(void) { @@ -363,9 +360,7 @@ static void __init mpc85xx_mds_setup_arch(void) } #endif -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif mpc85xx_mds_qe_init(); @@ -439,26 +434,11 @@ machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier); static void __init mpc85xx_mds_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) - 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 | + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); mpic_init(mpic); mpc85xx_mds_qeic_init(); diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index 9feccbbd4d96..ccf520e890be 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -29,6 +29,7 @@ #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> +#include "smp.h" #include "mpc85xx.h" @@ -44,49 +45,28 @@ void __init mpc85xx_rdb_pic_init(void) { struct mpic *mpic; - struct resource r; - struct device_node *np; unsigned long root = of_get_flat_dt_root(); - 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; - } - if (of_flat_dt_is_compatible(root, "fsl,MPC85XXRDB-CAMP")) { - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | + mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); } else { - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | + mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); } BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); - } /* * Setup the architecture */ -#ifdef CONFIG_SMP -extern void __init mpc85xx_smp_init(void); -#endif static void __init mpc85xx_rdb_setup_arch(void) { #ifdef CONFIG_PCI @@ -104,10 +84,7 @@ static void __init mpc85xx_rdb_setup_arch(void) #endif -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif - printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); } diff --git a/arch/powerpc/platforms/85xx/p1010rdb.c b/arch/powerpc/platforms/85xx/p1010rdb.c index 2f479f88c1a0..894f1e84fef8 100644 --- a/arch/powerpc/platforms/85xx/p1010rdb.c +++ b/arch/powerpc/platforms/85xx/p1010rdb.c @@ -32,24 +32,9 @@ void __init p1010_rdb_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 | MPIC_SINGLE_DEST_CPU, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | + MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 2bf4342ab656..bb3d84f4046f 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -26,6 +26,7 @@ #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> #include <asm/fsl_guts.h> +#include "smp.h" #include "mpc85xx.h" @@ -240,38 +241,15 @@ p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port) void __init p1022_ds_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np; - - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) { - pr_err("Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - pr_err("Failed to map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); - BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); } -#ifdef CONFIG_SMP -void __init mpc85xx_smp_init(void); -#endif - /* * Setup the architecture */ @@ -311,9 +289,7 @@ static void __init p1022_ds_setup_arch(void) diu_ops.valid_monitor_port = p1022ds_valid_monitor_port; #endif -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif #ifdef CONFIG_SWIOTLB if (memblock_end_of_DRAM() > max) { diff --git a/arch/powerpc/platforms/85xx/p1023_rds.c b/arch/powerpc/platforms/85xx/p1023_rds.c index e76c4dceee23..e92a714d2f36 100644 --- a/arch/powerpc/platforms/85xx/p1023_rds.c +++ b/arch/powerpc/platforms/85xx/p1023_rds.c @@ -30,6 +30,7 @@ #include <asm/prom.h> #include <asm/udbg.h> #include <asm/mpic.h> +#include "smp.h" #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> @@ -41,10 +42,6 @@ * Setup the architecture * */ -#ifdef CONFIG_SMP -void __init mpc85xx_smp_init(void); -#endif - static void __init mpc85xx_rds_setup_arch(void) { struct device_node *np; @@ -89,33 +86,15 @@ static void __init mpc85xx_rds_setup_arch(void) fsl_add_bridge(np, 0); #endif -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif } machine_device_initcall(p1023_rds, mpc85xx_common_publish_devices); static void __init mpc85xx_rds_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) { - 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 | + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " OpenPIC "); diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index 845ed3b89462..184a50784617 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -54,31 +54,10 @@ static int sbc_rev; static void __init sbc8548_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(np, "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, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - - /* Return the mpic node */ - of_node_put(np); - mpic_init(mpic); } diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index e9a7ed228d73..940752e93051 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c @@ -41,28 +41,10 @@ static void __init sbc8560_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np = NULL; - - np = of_find_node_by_type(np, "open-pic"); - if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); mpc85xx_cpm2_pic_init(); diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 2df4785ffd4e..ff4249044a3c 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -27,6 +27,7 @@ #include <sysdev/fsl_soc.h> #include <sysdev/mpic.h> +#include "smp.h" extern void __early_start(void); diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h new file mode 100644 index 000000000000..e2b44933ff19 --- /dev/null +++ b/arch/powerpc/platforms/85xx/smp.h @@ -0,0 +1,15 @@ +#ifndef POWERPC_85XX_SMP_H_ +#define POWERPC_85XX_SMP_H_ 1 + +#include <linux/init.h> + +#ifdef CONFIG_SMP +void __init mpc85xx_smp_init(void); +#else +static inline void mpc85xx_smp_init(void) +{ + /* Nothing to do */ +} +#endif + +#endif /* not POWERPC_85XX_SMP_H_ */ diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c index fec496ad79c0..18f635906b27 100644 --- a/arch/powerpc/platforms/85xx/socrates.c +++ b/arch/powerpc/platforms/85xx/socrates.c @@ -46,28 +46,12 @@ static void __init socrates_pic_init(void) { - struct mpic *mpic; - struct resource r; struct device_node *np; - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic"); diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index b44c936c2653..e9e5234b4e76 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c @@ -48,28 +48,10 @@ static void __init stx_gp3_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np; - - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); mpc85xx_cpm2_pic_init(); diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 2418bf8d074b..bf7c89fb75bb 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c @@ -46,28 +46,10 @@ static void __init tqm85xx_pic_init(void) { - struct mpic *mpic; - struct resource r; - struct device_node *np; - - np = of_find_node_by_type(NULL, "open-pic"); - if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - - if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; - } - - mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); mpc85xx_cpm2_pic_init(); diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index 4632c1b27da7..3a69f8b77de6 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -32,6 +32,7 @@ #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> +#include "smp.h" #include "mpc85xx.h" @@ -42,29 +43,11 @@ 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 | + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, 0, 256, " OpenPIC "); BUG_ON(mpic == NULL); - of_node_put(np); - mpic_init(mpic); } @@ -138,9 +121,6 @@ static int primary_phb_addr; /* * 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 @@ -174,9 +154,7 @@ static void __init xes_mpc85xx_setup_arch(void) } #endif -#ifdef CONFIG_SMP mpc85xx_smp_init(); -#endif } machine_device_initcall(xes_mpc8572, mpc85xx_common_publish_devices); diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c index 8ef8960abda6..52bbfa031531 100644 --- a/arch/powerpc/platforms/86xx/pic.c +++ b/arch/powerpc/platforms/86xx/pic.c @@ -31,26 +31,16 @@ static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc) void __init mpc86xx_init_irq(void) { - struct mpic *mpic; - struct device_node *np; - struct resource res; #ifdef CONFIG_PPC_I8259 + struct device_node *np; struct device_node *cascade_node = NULL; int cascade_irq; #endif - /* Determine PIC address. */ - np = of_find_node_by_type(NULL, "open-pic"); - if (np == NULL) - return; - of_address_to_resource(np, 0, &res); - - mpic = mpic_alloc(np, res.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | - MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS | - MPIC_SINGLE_DEST_CPU, + struct mpic *mpic = mpic_alloc(NULL, 0, + MPIC_WANTS_RESET | MPIC_BIG_ENDIAN | + MPIC_BROKEN_FRR_NIRQS | MPIC_SINGLE_DEST_CPU, 0, 256, " MPIC "); - of_node_put(np); BUG_ON(mpic == NULL); mpic_init(mpic); diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 3fe6d927ad70..31e1adeaa92a 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -211,6 +211,12 @@ config PPC_PASEMI_CPUFREQ endmenu +menu "CPUIdle driver" + +source "drivers/cpuidle/Kconfig" + +endmenu + config PPC601_SYNC_FIX bool "Workarounds for PPC601 bugs" depends on 6xx && (PPC_PREP || PPC_PMAC) diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 836b44286b3e..425db18580a2 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -174,7 +174,6 @@ config BOOKE config FSL_BOOKE bool depends on (E200 || E500) && PPC32 - select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT default y # this is for common code between PPC32 & PPC64 FSL BOOKE @@ -182,6 +181,7 @@ config PPC_FSL_BOOK3E bool select FSL_EMB_PERFMON select PPC_SMP_MUXED_IPI + select SYS_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64 default y if FSL_BOOKE config PTE_64BIT @@ -309,7 +309,7 @@ config PPC_BOOK3E_MMU config PPC_MM_SLICES bool - default y if (PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) + default y if (!PPC_FSL_BOOK3E && PPC64 && HUGETLB_PAGE) || (PPC_STD_MMU_64 && PPC_64K_PAGES) default n config VIRT_CPU_ACCOUNTING diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 0fc9b7256126..62002a7edfed 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -184,24 +184,10 @@ static int __init cell_publish_devices(void) } machine_subsys_initcall(cell, cell_publish_devices); -static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - struct mpic *mpic = irq_desc_get_handler_data(desc); - unsigned int virq; - - virq = mpic_get_one_irq(mpic); - if (virq != NO_IRQ) - generic_handle_irq(virq); - - chip->irq_eoi(&desc->irq_data); -} - static void __init mpic_init_IRQ(void) { struct device_node *dn; struct mpic *mpic; - unsigned int virq; for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { @@ -211,19 +197,10 @@ static void __init mpic_init_IRQ(void) /* The MPIC driver will get everything it needs from the * device-tree, just pass 0 to all arguments */ - mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC "); + mpic = mpic_alloc(dn, 0, MPIC_SECONDARY, 0, 0, " MPIC "); if (mpic == NULL) continue; mpic_init(mpic); - - virq = irq_of_parse_and_map(dn, 0); - if (virq == NO_IRQ) - continue; - - printk(KERN_INFO "%s : hooking up to IRQ %d\n", - dn->full_name, virq); - irq_set_handler_data(virq, mpic); - irq_set_chained_handler(virq, cell_mpic_cascade); } } diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 122786498419..f1f17bb2c33c 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -435,8 +435,7 @@ static void __init chrp_find_openpic(void) if (len > 1) isu_size = iranges[3]; - chrp_mpic = mpic_alloc(np, opaddr, MPIC_PRIMARY, - isu_size, 0, " MPIC "); + chrp_mpic = mpic_alloc(np, opaddr, 0, isu_size, 0, " MPIC "); if (chrp_mpic == NULL) { printk(KERN_ERR "Failed to allocate MPIC structure\n"); goto bail; diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c index 2e9bcf6444c8..9cfcf20c0560 100644 --- a/arch/powerpc/platforms/embedded6xx/holly.c +++ b/arch/powerpc/platforms/embedded6xx/holly.c @@ -148,30 +148,14 @@ static void __init holly_setup_arch(void) static void __init holly_init_IRQ(void) { struct mpic *mpic; - phys_addr_t mpic_paddr = 0; - struct device_node *tsi_pic; #ifdef CONFIG_PCI unsigned int cascade_pci_irq; struct device_node *tsi_pci; struct device_node *cascade_node = NULL; #endif - tsi_pic = of_find_node_by_type(NULL, "open-pic"); - if (tsi_pic) { - unsigned int size; - const void *prop = of_get_property(tsi_pic, "reg", &size); - mpic_paddr = of_translate_address(tsi_pic, prop); - } - - if (mpic_paddr == 0) { - printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__); - return; - } - - pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr); - - mpic = mpic_alloc(tsi_pic, mpic_paddr, - MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | + mpic = mpic_alloc(NULL, 0, + MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, 24, NR_IRQS-4, /* num_sources used */ @@ -179,7 +163,7 @@ static void __init holly_init_IRQ(void) BUG_ON(mpic == NULL); - mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); + mpic_assign_isu(mpic, 0, mpic->paddr + 0x100); mpic_init(mpic); @@ -204,7 +188,6 @@ static void __init holly_init_IRQ(void) #endif /* Configure MPIC outputs to CPU0 */ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); - of_node_put(tsi_pic); } void holly_show_cpuinfo(struct seq_file *m) diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index 244f997de791..bcfad92c9cec 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -81,29 +81,19 @@ static void __init linkstation_setup_arch(void) static void __init linkstation_init_IRQ(void) { struct mpic *mpic; - struct device_node *dnp; - const u32 *prop; - int size; - phys_addr_t paddr; - dnp = of_find_node_by_type(NULL, "open-pic"); - if (dnp == NULL) - return; - - prop = of_get_property(dnp, "reg", &size); - paddr = (phys_addr_t)of_translate_address(dnp, prop); - - mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC "); + mpic = mpic_alloc(NULL, 0, MPIC_WANTS_RESET, + 4, 32, " EPIC "); BUG_ON(mpic == NULL); /* PCI IRQs */ - mpic_assign_isu(mpic, 0, paddr + 0x10200); + mpic_assign_isu(mpic, 0, mpic->paddr + 0x10200); /* I2C */ - mpic_assign_isu(mpic, 1, paddr + 0x11000); + mpic_assign_isu(mpic, 1, mpic->paddr + 0x11000); /* ttyS0, ttyS1 */ - mpic_assign_isu(mpic, 2, paddr + 0x11100); + mpic_assign_isu(mpic, 2, mpic->paddr + 0x11100); mpic_init(mpic); } diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index f8f33e16c6b6..f3350d786f5b 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -102,31 +102,14 @@ static void __init mpc7448_hpc2_setup_arch(void) static void __init mpc7448_hpc2_init_IRQ(void) { struct mpic *mpic; - phys_addr_t mpic_paddr = 0; - struct device_node *tsi_pic; #ifdef CONFIG_PCI unsigned int cascade_pci_irq; struct device_node *tsi_pci; struct device_node *cascade_node = NULL; #endif - tsi_pic = of_find_node_by_type(NULL, "open-pic"); - if (tsi_pic) { - unsigned int size; - const void *prop = of_get_property(tsi_pic, "reg", &size); - mpic_paddr = of_translate_address(tsi_pic, prop); - } - - if (mpic_paddr == 0) { - printk("%s: No tsi108 PIC found !\n", __func__); - return; - } - - DBG("%s: tsi108 pic phys_addr = 0x%x\n", __func__, - (u32) mpic_paddr); - - mpic = mpic_alloc(tsi_pic, mpic_paddr, - MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | + mpic = mpic_alloc(NULL, 0, + MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, 24, NR_IRQS-4, /* num_sources used */ @@ -134,7 +117,7 @@ static void __init mpc7448_hpc2_init_IRQ(void) BUG_ON(mpic == NULL); - mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); + mpic_assign_isu(mpic, 0, mpic->paddr + 0x100); mpic_init(mpic); @@ -159,7 +142,6 @@ static void __init mpc7448_hpc2_init_IRQ(void) #endif /* Configure MPIC outputs to CPU0 */ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); - of_node_put(tsi_pic); } void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index f1eebcae9bf0..afa638834965 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c @@ -83,35 +83,17 @@ static void __init storcenter_setup_arch(void) static void __init storcenter_init_IRQ(void) { struct mpic *mpic; - struct device_node *dnp; - const void *prop; - int size; - phys_addr_t paddr; - - dnp = of_find_node_by_type(NULL, "open-pic"); - if (dnp == NULL) - return; - - prop = of_get_property(dnp, "reg", &size); - if (prop == NULL) { - of_node_put(dnp); - return; - } - - paddr = (phys_addr_t)of_translate_address(dnp, prop); - mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, - 16, 32, " OpenPIC "); - - of_node_put(dnp); + mpic = mpic_alloc(NULL, 0, MPIC_WANTS_RESET, + 16, 32, " OpenPIC "); BUG_ON(mpic == NULL); /* * 16 Serial Interrupts followed by 16 Internal Interrupts. * I2C is the second internal, so it is at 17, 0x11020. */ - mpic_assign_isu(mpic, 0, paddr + 0x10200); - mpic_assign_isu(mpic, 1, paddr + 0x11000); + mpic_assign_isu(mpic, 0, mpic->paddr + 0x10200); + mpic_assign_isu(mpic, 1, mpic->paddr + 0x11000); mpic_init(mpic); } diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 4c372047c94e..0bcbfe7b2c55 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -221,7 +221,7 @@ static void __init maple_init_IRQ(void) unsigned long openpic_addr = 0; int naddr, n, i, opplen, has_isus = 0; struct mpic *mpic; - unsigned int flags = MPIC_PRIMARY; + unsigned int flags = 0; /* Locate MPIC in the device-tree. Note that there is a bug * in Maple device-tree where the type of the controller is diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 6f3558210554..98b7a7c13176 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -224,7 +224,7 @@ static __init void pas_init_IRQ(void) openpic_addr = of_read_number(opprop, naddr); printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); - mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS; + mpic_flags = MPIC_LARGE_VECTORS | MPIC_NO_BIAS; nmiprop = of_get_property(mpic_node, "nmi-source", NULL); if (nmiprop) @@ -234,7 +234,7 @@ static __init void pas_init_IRQ(void) mpic_flags, 0, 0, "PASEMI-OPIC"); BUG_ON(!mpic); - mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); + mpic_assign_isu(mpic, 0, mpic->paddr + 0x10000); mpic_init(mpic); /* The NMI/MCK source needs to be prio 15 */ if (nmiprop) { diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 901bfbddc3dd..7761aabfc293 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -52,13 +52,8 @@ struct device_node *of_irq_dflt_pic; /* Default addresses */ static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; -#define GC_LEVEL_MASK 0x3ff00000 -#define OHARE_LEVEL_MASK 0x1ff00000 -#define HEATHROW_LEVEL_MASK 0x1ff00000 - static int max_irqs; static int max_real_irqs; -static u32 level_mask[4]; static DEFINE_RAW_SPINLOCK(pmac_pic_lock); @@ -217,8 +212,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) { int i = irq >> 5; bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; - /* We must read level interrupts from the level register */ - bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); + bits |= in_le32(&pmac_irq_hw[i]->level); bits &= ppc_cached_irq_mask[i]; if (bits == 0) continue; @@ -248,8 +242,7 @@ static unsigned int pmac_pic_get_irq(void) for (irq = max_real_irqs; (irq -= 32) >= 0; ) { int i = irq >> 5; bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; - /* We must read level interrupts from the level register */ - bits |= (in_le32(&pmac_irq_hw[i]->level) & level_mask[i]); + bits |= in_le32(&pmac_irq_hw[i]->level); bits &= ppc_cached_irq_mask[i]; if (bits == 0) continue; @@ -284,19 +277,14 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node) static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { - int level; - if (hw >= max_irqs) return -EINVAL; /* Mark level interrupts, set delayed disable for edge ones and set * handlers */ - level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f))); - if (level) - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &pmac_pic, - level ? handle_level_irq : handle_edge_irq); + irq_set_status_flags(virq, IRQ_LEVEL); + irq_set_chip_and_handler(virq, &pmac_pic, handle_level_irq); return 0; } @@ -334,21 +322,14 @@ static void __init pmac_pic_probe_oldstyle(void) if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { max_irqs = max_real_irqs = 32; - level_mask[0] = GC_LEVEL_MASK; } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { max_irqs = max_real_irqs = 32; - level_mask[0] = OHARE_LEVEL_MASK; - /* We might have a second cascaded ohare */ slave = of_find_node_by_name(NULL, "pci106b,7"); - if (slave) { + if (slave) max_irqs = 64; - level_mask[1] = OHARE_LEVEL_MASK; - } } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { max_irqs = max_real_irqs = 64; - level_mask[0] = HEATHROW_LEVEL_MASK; - level_mask[1] = 0; /* We might have a second cascaded heathrow */ slave = of_find_node_by_name(master, "mac-io"); @@ -363,11 +344,8 @@ static void __init pmac_pic_probe_oldstyle(void) } /* We found a slave */ - if (slave) { + if (slave) max_irqs = 128; - level_mask[2] = HEATHROW_LEVEL_MASK; - level_mask[3] = 0; - } } BUG_ON(master == NULL); @@ -464,18 +442,6 @@ int of_irq_map_oldworld(struct device_node *device, int index, } #endif /* CONFIG_PPC32 */ -static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc) -{ - struct irq_chip *chip = irq_desc_get_chip(desc); - struct mpic *mpic = irq_desc_get_handler_data(desc); - unsigned int cascade_irq = mpic_get_one_irq(mpic); - - if (cascade_irq != NO_IRQ) - generic_handle_irq(cascade_irq); - - chip->irq_eoi(&desc->irq_data); -} - static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) { #if defined(CONFIG_XMON) && defined(CONFIG_PPC32) @@ -498,14 +464,8 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, int master) { const char *name = master ? " MPIC 1 " : " MPIC 2 "; - struct resource r; struct mpic *mpic; - unsigned int flags = master ? MPIC_PRIMARY : 0; - int rc; - - rc = of_address_to_resource(np, 0, &r); - if (rc) - return NULL; + unsigned int flags = master ? 0 : MPIC_SECONDARY; pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); @@ -519,7 +479,7 @@ static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, if (master && (flags & MPIC_BIG_ENDIAN)) flags |= MPIC_U3_HT_IRQS; - mpic = mpic_alloc(np, r.start, flags, 0, 0, name); + mpic = mpic_alloc(np, 0, flags, 0, 0, name); if (mpic == NULL) return NULL; @@ -532,7 +492,6 @@ static int __init pmac_pic_probe_mpic(void) { struct mpic *mpic1, *mpic2; struct device_node *np, *master = NULL, *slave = NULL; - unsigned int cascade; /* We can have up to 2 MPICs cascaded */ for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) @@ -568,27 +527,14 @@ static int __init pmac_pic_probe_mpic(void) of_node_put(master); - /* No slave, let's go out */ - if (slave == NULL) - return 0; - - /* Get/Map slave interrupt */ - cascade = irq_of_parse_and_map(slave, 0); - if (cascade == NO_IRQ) { - printk(KERN_ERR "Failed to map cascade IRQ\n"); - return 0; - } - - mpic2 = pmac_setup_one_mpic(slave, 0); - if (mpic2 == NULL) { - printk(KERN_ERR "Failed to setup slave MPIC\n"); + /* Set up a cascaded controller, if present */ + if (slave) { + mpic2 = pmac_setup_one_mpic(slave, 0); + if (mpic2 == NULL) + printk(KERN_ERR "Failed to setup slave MPIC\n"); of_node_put(slave); - return 0; } - irq_set_handler_data(cascade, mpic2); - irq_set_chained_handler(cascade, pmac_u3_cascade); - of_node_put(slave); return 0; } diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index e6f7378f4a49..44d769258ebf 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -414,7 +414,7 @@ static struct irqaction psurge_irqaction = { static void __init smp_psurge_setup_cpu(int cpu_nr) { - if (cpu_nr != 0) + if (cpu_nr != 0 || !psurge_start) return; /* reset the entry point so if we get another intr we won't diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 4a3f46d8533e..3bb07e5e43cd 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -99,3 +99,11 @@ OPAL_CALL(opal_write_oppanel, OPAL_WRITE_OPPANEL); OPAL_CALL(opal_pci_map_pe_dma_window, OPAL_PCI_MAP_PE_DMA_WINDOW); OPAL_CALL(opal_pci_map_pe_dma_window_real, OPAL_PCI_MAP_PE_DMA_WINDOW_REAL); OPAL_CALL(opal_pci_reset, OPAL_PCI_RESET); +OPAL_CALL(opal_pci_get_hub_diag_data, OPAL_PCI_GET_HUB_DIAG_DATA); +OPAL_CALL(opal_pci_get_phb_diag_data, OPAL_PCI_GET_PHB_DIAG_DATA); +OPAL_CALL(opal_pci_fence_phb, OPAL_PCI_FENCE_PHB); +OPAL_CALL(opal_pci_reinit, OPAL_PCI_REINIT); +OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); +OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); +OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); +OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index cf89f305c8b1..f31162cfdaa9 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -9,7 +9,7 @@ * 2 of the License, or (at your option) any later version. */ -#define DEBUG +#undef DEBUG #include <linux/kernel.h> #include <linux/pci.h> @@ -467,14 +467,13 @@ static void __devinit pnv_ioda_update_resources(struct pci_bus *bus) struct pci_bus *cbus; struct pci_dev *cdev; unsigned int i; - u16 cmd; - /* Clear all device enables */ - list_for_each_entry(cdev, &bus->devices, bus_list) { - pci_read_config_word(cdev, PCI_COMMAND, &cmd); - cmd &= ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER); - pci_write_config_word(cdev, PCI_COMMAND, cmd); - } + /* We used to clear all device enables here. However it looks like + * clearing MEM enable causes Obsidian (IPR SCS) to go bonkers, + * and shoot fatal errors to the PHB which in turns fences itself + * and we can't recover from that ... yet. So for now, let's leave + * the enables as-is and hope for the best. + */ /* Check if bus resources fit in our IO or M32 range */ for (i = 0; bus->self && (i < 2); i++) { @@ -618,7 +617,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, struct pci_dn *pdn = pnv_ioda_get_pdn(parent); if (pdn && pdn->pe_number != IODA_INVALID_PE) { rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, - pe->pe_number, 1); + pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); /* XXX What to do in case of error ? */ } parent = parent->bus->self; @@ -638,7 +637,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, pe->mve_number = -1; } else { rc = opal_pci_set_mve_enable(phb->opal_id, - pe->mve_number, 1); + pe->mve_number, OPAL_ENABLE_MVE); if (rc) { pe_err(pe, "OPAL error %ld enabling MVE %d\n", rc, pe->mve_number); @@ -1187,6 +1186,12 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) phb->opal_id = phb_id; phb->type = PNV_PHB_IODA1; + /* Detect specific models for error handling */ + if (of_device_is_compatible(np, "ibm,p7ioc-pciex")) + phb->model = PNV_PHB_MODEL_P7IOC; + else + phb->model = PNV_PHB_MODEL_UNKNOWN; + /* We parse "ranges" now since we need to deduce the register base * from the IO base */ @@ -1294,9 +1299,9 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) pci_add_flags(PCI_REASSIGN_ALL_RSRC); /* Reset IODA tables to a clean state */ - rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_RESET, OPAL_ASSERT_RESET); + rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); if (rc) - pr_warning(" OPAL Error %ld performing IODA reset !\n", rc); + pr_warning(" OPAL Error %ld performing IODA table reset !\n", rc); opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE); } diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 4c80f7c77d56..264967770c3a 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c @@ -137,6 +137,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, phb->hose->private_data = phb; phb->opal_id = phb_id; phb->type = PNV_PHB_P5IOC2; + phb->model = PNV_PHB_MODEL_P5IOC2; phb->regs = of_iomap(np, 0); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index c0ed379498a0..a70bc1e385eb 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -144,6 +144,112 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev) } #endif /* CONFIG_PCI_MSI */ +static void pnv_pci_dump_p7ioc_diag_data(struct pnv_phb *phb) +{ + struct OpalIoP7IOCPhbErrorData *data = &phb->diag.p7ioc; + int i; + + pr_info("PHB %d diagnostic data:\n", phb->hose->global_number); + + pr_info(" brdgCtl = 0x%08x\n", data->brdgCtl); + + pr_info(" portStatusReg = 0x%08x\n", data->portStatusReg); + pr_info(" rootCmplxStatus = 0x%08x\n", data->rootCmplxStatus); + pr_info(" busAgentStatus = 0x%08x\n", data->busAgentStatus); + + pr_info(" deviceStatus = 0x%08x\n", data->deviceStatus); + pr_info(" slotStatus = 0x%08x\n", data->slotStatus); + pr_info(" linkStatus = 0x%08x\n", data->linkStatus); + pr_info(" devCmdStatus = 0x%08x\n", data->devCmdStatus); + pr_info(" devSecStatus = 0x%08x\n", data->devSecStatus); + + pr_info(" rootErrorStatus = 0x%08x\n", data->rootErrorStatus); + pr_info(" uncorrErrorStatus = 0x%08x\n", data->uncorrErrorStatus); + pr_info(" corrErrorStatus = 0x%08x\n", data->corrErrorStatus); + pr_info(" tlpHdr1 = 0x%08x\n", data->tlpHdr1); + pr_info(" tlpHdr2 = 0x%08x\n", data->tlpHdr2); + pr_info(" tlpHdr3 = 0x%08x\n", data->tlpHdr3); + pr_info(" tlpHdr4 = 0x%08x\n", data->tlpHdr4); + pr_info(" sourceId = 0x%08x\n", data->sourceId); + + pr_info(" errorClass = 0x%016llx\n", data->errorClass); + pr_info(" correlator = 0x%016llx\n", data->correlator); + + pr_info(" p7iocPlssr = 0x%016llx\n", data->p7iocPlssr); + pr_info(" p7iocCsr = 0x%016llx\n", data->p7iocCsr); + pr_info(" lemFir = 0x%016llx\n", data->lemFir); + pr_info(" lemErrorMask = 0x%016llx\n", data->lemErrorMask); + pr_info(" lemWOF = 0x%016llx\n", data->lemWOF); + pr_info(" phbErrorStatus = 0x%016llx\n", data->phbErrorStatus); + pr_info(" phbFirstErrorStatus = 0x%016llx\n", data->phbFirstErrorStatus); + pr_info(" phbErrorLog0 = 0x%016llx\n", data->phbErrorLog0); + pr_info(" phbErrorLog1 = 0x%016llx\n", data->phbErrorLog1); + pr_info(" mmioErrorStatus = 0x%016llx\n", data->mmioErrorStatus); + pr_info(" mmioFirstErrorStatus = 0x%016llx\n", data->mmioFirstErrorStatus); + pr_info(" mmioErrorLog0 = 0x%016llx\n", data->mmioErrorLog0); + pr_info(" mmioErrorLog1 = 0x%016llx\n", data->mmioErrorLog1); + pr_info(" dma0ErrorStatus = 0x%016llx\n", data->dma0ErrorStatus); + pr_info(" dma0FirstErrorStatus = 0x%016llx\n", data->dma0FirstErrorStatus); + pr_info(" dma0ErrorLog0 = 0x%016llx\n", data->dma0ErrorLog0); + pr_info(" dma0ErrorLog1 = 0x%016llx\n", data->dma0ErrorLog1); + pr_info(" dma1ErrorStatus = 0x%016llx\n", data->dma1ErrorStatus); + pr_info(" dma1FirstErrorStatus = 0x%016llx\n", data->dma1FirstErrorStatus); + pr_info(" dma1ErrorLog0 = 0x%016llx\n", data->dma1ErrorLog0); + pr_info(" dma1ErrorLog1 = 0x%016llx\n", data->dma1ErrorLog1); + + for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { + if ((data->pestA[i] >> 63) == 0 && + (data->pestB[i] >> 63) == 0) + continue; + pr_info(" PE[%3d] PESTA = 0x%016llx\n", i, data->pestA[i]); + pr_info(" PESTB = 0x%016llx\n", data->pestB[i]); + } +} + +static void pnv_pci_dump_phb_diag_data(struct pnv_phb *phb) +{ + switch(phb->model) { + case PNV_PHB_MODEL_P7IOC: + pnv_pci_dump_p7ioc_diag_data(phb); + break; + default: + pr_warning("PCI %d: Can't decode this PHB diag data\n", + phb->hose->global_number); + } +} + +static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) +{ + unsigned long flags, rc; + int has_diag; + + spin_lock_irqsave(&phb->lock, flags); + + rc = opal_pci_get_phb_diag_data(phb->opal_id, phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE); + has_diag = (rc == OPAL_SUCCESS); + + rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + if (rc) { + pr_warning("PCI %d: Failed to clear EEH freeze state" + " for PE#%d, err %ld\n", + phb->hose->global_number, pe_no, rc); + + /* For now, let's only display the diag buffer when we fail to clear + * the EEH status. We'll do more sensible things later when we have + * proper EEH support. We need to make sure we don't pollute ourselves + * with the normal errors generated when probing empty slots + */ + if (has_diag) + pnv_pci_dump_phb_diag_data(phb); + else + pr_warning("PCI %d: No diag data available\n", + phb->hose->global_number); + } + + spin_unlock_irqrestore(&phb->lock, flags); +} + static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, u32 bdfn) { @@ -165,15 +271,8 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus, } cfg_dbg(" -> EEH check, bdfn=%04x PE%d fstate=%x\n", bdfn, pe_no, fstate); - if (fstate != 0) { - rc = opal_pci_eeh_freeze_clear(phb->opal_id, pe_no, - OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); - if (rc) { - pr_warning("PCI %d: Failed to clear EEH freeze state" - " for PE#%d, err %lld\n", - phb->hose->global_number, pe_no, rc); - } - } + if (fstate != 0) + pnv_pci_handle_eeh_config(phb, pe_no); } static int pnv_pci_read_config(struct pci_bus *bus, diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 28ae4ca512c4..8bc479634643 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -9,6 +9,15 @@ enum pnv_phb_type { PNV_PHB_IODA2, }; +/* Precise PHB model for error management */ +enum pnv_phb_model { + PNV_PHB_MODEL_UNKNOWN, + PNV_PHB_MODEL_P5IOC2, + PNV_PHB_MODEL_P7IOC, +}; + +#define PNV_PCI_DIAG_BUF_SIZE 4096 + /* Data associated with a PE, including IOMMU tracking etc.. */ struct pnv_ioda_pe { /* A PE can be associated with a single device or an @@ -56,6 +65,7 @@ struct pnv_ioda_pe { struct pnv_phb { struct pci_controller *hose; enum pnv_phb_type type; + enum pnv_phb_model model; u64 opal_id; void __iomem *regs; spinlock_t lock; @@ -118,6 +128,12 @@ struct pnv_phb { struct list_head pe_list; } ioda; }; + + /* PHB status structure */ + union { + unsigned char blob[PNV_PCI_DIAG_BUF_SIZE]; + struct OpalIoP7IOCPhbErrorData p7ioc; + } diag; }; extern struct pci_ops pnv_pci_ops; diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index e87736685243..17210c526c52 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -75,7 +75,7 @@ int __devinit pnv_smp_kick_cpu(int nr) /* On OPAL v2 the CPU are still spinning inside OPAL itself, * get them back now */ - if (firmware_has_feature(FW_FEATURE_OPALv2)) { + if (!paca[nr].cpu_start && firmware_has_feature(FW_FEATURE_OPALv2)) { pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); rc = opal_start_cpu(pcpu, start_here); if (rc != OPAL_SUCCESS) diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 1d6f4f478fe2..617efa12a3a5 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -31,18 +31,18 @@ #if defined(DEBUG) #define DBG udbg_printf +#define FAIL udbg_printf #else -#define DBG pr_debug +#define DBG pr_devel +#define FAIL pr_debug #endif /** * struct ps3_bmp - a per cpu irq status and mask bitmap structure * @status: 256 bit status bitmap indexed by plug - * @unused_1: + * @unused_1: Alignment * @mask: 256 bit mask bitmap indexed by plug - * @unused_2: - * @lock: - * @ipi_debug_brk_mask: + * @unused_2: Alignment * * The HV maintains per SMT thread mappings of HV outlet to HV plug on * behalf of the guest. These mappings are implemented as 256 bit guest @@ -73,21 +73,24 @@ struct ps3_bmp { unsigned long mask; u64 unused_2[3]; }; - u64 ipi_debug_brk_mask; - spinlock_t lock; }; /** * struct ps3_private - a per cpu data structure * @bmp: ps3_bmp structure + * @bmp_lock: Syncronize access to bmp. + * @ipi_debug_brk_mask: Mask for debug break IPIs * @ppe_id: HV logical_ppe_id * @thread_id: HV thread_id + * @ipi_mask: Mask of IPI virqs */ struct ps3_private { struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); + spinlock_t bmp_lock; u64 ppe_id; u64 thread_id; + unsigned long ipi_debug_brk_mask; unsigned long ipi_mask; }; @@ -105,7 +108,7 @@ static void ps3_chip_mask(struct irq_data *d) struct ps3_private *pd = irq_data_get_irq_chip_data(d); unsigned long flags; - pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, + DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, pd->thread_id, d->irq); local_irq_save(flags); @@ -126,7 +129,7 @@ static void ps3_chip_unmask(struct irq_data *d) struct ps3_private *pd = irq_data_get_irq_chip_data(d); unsigned long flags; - pr_debug("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, + DBG("%s:%d: thread_id %llu, virq %d\n", __func__, __LINE__, pd->thread_id, d->irq); local_irq_save(flags); @@ -190,19 +193,19 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, *virq = irq_create_mapping(NULL, outlet); if (*virq == NO_IRQ) { - pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n", + FAIL("%s:%d: irq_create_mapping failed: outlet %lu\n", __func__, __LINE__, outlet); result = -ENOMEM; goto fail_create; } - pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, + DBG("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, outlet, cpu, *virq); result = irq_set_chip_data(*virq, pd); if (result) { - pr_debug("%s:%d: irq_set_chip_data failed\n", + FAIL("%s:%d: irq_set_chip_data failed\n", __func__, __LINE__); goto fail_set; } @@ -228,13 +231,13 @@ static int ps3_virq_destroy(unsigned int virq) { const struct ps3_private *pd = irq_get_chip_data(virq); - pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, + DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, virq); irq_set_chip_data(virq, NULL); irq_dispose_mapping(virq); - pr_debug("%s:%d <-\n", __func__, __LINE__); + DBG("%s:%d <-\n", __func__, __LINE__); return 0; } @@ -257,7 +260,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, result = ps3_virq_setup(cpu, outlet, virq); if (result) { - pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); + FAIL("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); goto fail_setup; } @@ -269,7 +272,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, outlet, 0); if (result) { - pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", + FAIL("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", __func__, __LINE__, ps3_result(result)); result = -EPERM; goto fail_connect; @@ -298,7 +301,7 @@ int ps3_irq_plug_destroy(unsigned int virq) int result; const struct ps3_private *pd = irq_get_chip_data(virq); - pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, + DBG("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, virq); ps3_chip_mask(irq_get_irq_data(virq)); @@ -306,7 +309,7 @@ int ps3_irq_plug_destroy(unsigned int virq) result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq); if (result) - pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", + FAIL("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", __func__, __LINE__, ps3_result(result)); ps3_virq_destroy(virq); @@ -334,7 +337,7 @@ int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) result = lv1_construct_event_receive_port(&outlet); if (result) { - pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", + FAIL("%s:%d: lv1_construct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); *virq = NO_IRQ; return result; @@ -360,14 +363,14 @@ int ps3_event_receive_port_destroy(unsigned int virq) { int result; - pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq); + DBG(" -> %s:%d virq %u\n", __func__, __LINE__, virq); ps3_chip_mask(irq_get_irq_data(virq)); result = lv1_destruct_event_receive_port(virq_to_hw(virq)); if (result) - pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", + FAIL("%s:%d: lv1_destruct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); /* @@ -375,7 +378,7 @@ int ps3_event_receive_port_destroy(unsigned int virq) * calls from interrupt context (smp_call_function) when kexecing. */ - pr_debug(" <- %s:%d\n", __func__, __LINE__); + DBG(" <- %s:%d\n", __func__, __LINE__); return result; } @@ -411,7 +414,7 @@ int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, dev->dev_id, virq_to_hw(*virq), dev->interrupt_id); if (result) { - pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" + FAIL("%s:%d: lv1_connect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); ps3_event_receive_port_destroy(*virq); @@ -419,7 +422,7 @@ int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, return result; } - pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, + DBG("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, dev->interrupt_id, *virq); return 0; @@ -433,14 +436,14 @@ int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, int result; - pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, + DBG(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, dev->interrupt_id, virq); result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id, dev->dev_id, virq_to_hw(virq), dev->interrupt_id); if (result) - pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" + FAIL("%s:%d: lv1_disconnect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); @@ -455,7 +458,7 @@ int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, result = ps3_virq_destroy(virq); BUG_ON(result); - pr_debug(" <- %s:%d\n", __func__, __LINE__); + DBG(" <- %s:%d\n", __func__, __LINE__); return result; } EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); @@ -480,7 +483,7 @@ int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); if (result) { - pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", + FAIL("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } @@ -510,7 +513,7 @@ int ps3_io_irq_destroy(unsigned int virq) result = lv1_destruct_io_irq_outlet(outlet); if (result) - pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", + FAIL("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; @@ -542,7 +545,7 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); if (result) { - pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", + FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } @@ -562,7 +565,7 @@ int ps3_vuart_irq_destroy(unsigned int virq) result = lv1_deconfigure_virtual_uart_irq(); if (result) { - pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", + FAIL("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } @@ -595,7 +598,7 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); if (result) { - pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", + FAIL("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", __func__, __LINE__, ps3_result(result)); return result; } @@ -626,7 +629,7 @@ int ps3_spe_irq_destroy(unsigned int virq) static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, const char* func, int line) { - pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", + pr_debug("%s:%d: %s %u {%04llx_%04llx_%04llx_%04llx}\n", func, line, header, cpu, *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, *p & 0xffff); @@ -635,7 +638,7 @@ static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu, static void __maybe_unused _dump_256_bmp(const char *header, const u64 *p, unsigned cpu, const char* func, int line) { - pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", + pr_debug("%s:%d: %s %u {%016llx:%016llx:%016llx:%016llx}\n", func, line, header, cpu, p[0], p[1], p[2], p[3]); } @@ -644,10 +647,10 @@ static void _dump_bmp(struct ps3_private* pd, const char* func, int line) { unsigned long flags; - spin_lock_irqsave(&pd->bmp.lock, flags); + spin_lock_irqsave(&pd->bmp_lock, flags); _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line); - _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); - spin_unlock_irqrestore(&pd->bmp.lock, flags); + _dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line); + spin_unlock_irqrestore(&pd->bmp_lock, flags); } #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) @@ -656,9 +659,9 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd, { unsigned long flags; - spin_lock_irqsave(&pd->bmp.lock, flags); - _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line); - spin_unlock_irqrestore(&pd->bmp.lock, flags); + spin_lock_irqsave(&pd->bmp_lock, flags); + _dump_64_bmp("mask", (u64*)&pd->bmp.mask, pd->thread_id, func, line); + spin_unlock_irqrestore(&pd->bmp_lock, flags); } #else static void dump_bmp(struct ps3_private* pd) {}; @@ -667,7 +670,7 @@ static void dump_bmp(struct ps3_private* pd) {}; static int ps3_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hwirq) { - pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, + DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, virq); irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); @@ -690,10 +693,10 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) { struct ps3_private *pd = &per_cpu(ps3_private, cpu); - pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; + set_bit(63 - virq, &pd->ipi_debug_brk_mask); - pr_debug("%s:%d: cpu %u, virq %u, mask %llxh\n", __func__, __LINE__, - cpu, virq, pd->bmp.ipi_debug_brk_mask); + DBG("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__, + cpu, virq, pd->ipi_debug_brk_mask); } void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) @@ -714,14 +717,14 @@ static unsigned int ps3_get_irq(void) /* check for ipi break first to stop this cpu ASAP */ - if (x & pd->bmp.ipi_debug_brk_mask) - x &= pd->bmp.ipi_debug_brk_mask; + if (x & pd->ipi_debug_brk_mask) + x &= pd->ipi_debug_brk_mask; asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x)); plug &= 0x3f; if (unlikely(plug == NO_IRQ)) { - pr_debug("%s:%d: no plug found: thread_id %llu\n", __func__, + DBG("%s:%d: no plug found: thread_id %llu\n", __func__, __LINE__, pd->thread_id); dump_bmp(&per_cpu(ps3_private, 0)); dump_bmp(&per_cpu(ps3_private, 1)); @@ -760,9 +763,9 @@ void __init ps3_init_IRQ(void) lv1_get_logical_ppe_id(&pd->ppe_id); pd->thread_id = get_hard_smp_processor_id(cpu); - spin_lock_init(&pd->bmp.lock); + spin_lock_init(&pd->bmp_lock); - pr_debug("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", + DBG("%s:%d: ppe_id %llu, thread_id %llu, bmp %lxh\n", __func__, __LINE__, pd->ppe_id, pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); @@ -770,7 +773,7 @@ void __init ps3_init_IRQ(void) pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp))); if (result) - pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" + FAIL("%s:%d: lv1_configure_irq_state_bitmap failed:" " %s\n", __func__, __LINE__, ps3_result(result)); } diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index ca40f6afd35d..7bdfea336f5e 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -44,7 +44,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; s[i] = 0; - pr_debug("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); + pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s); #endif } @@ -53,7 +53,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line) static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, const char *func, int line) { - pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); + pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id); _dump_field("n1: ", n1, func, line); _dump_field("n2: ", n2, func, line); _dump_field("n3: ", n3, func, line); @@ -65,13 +65,13 @@ static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, u64 v1, u64 v2, const char *func, int line) { - pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); + pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id); _dump_field("n1: ", n1, func, line); _dump_field("n2: ", n2, func, line); _dump_field("n3: ", n3, func, line); _dump_field("n4: ", n4, func, line); - pr_debug("%s:%d: v1: %016llx\n", func, line, v1); - pr_debug("%s:%d: v2: %016llx\n", func, line, v2); + pr_devel("%s:%d: v1: %016llx\n", func, line, v1); + pr_devel("%s:%d: v2: %016llx\n", func, line, v2); } /** @@ -131,11 +131,11 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, lpar_id = id; } - result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1, + result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1, &v2); if (result) { - pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", + pr_warn("%s:%d: lv1_read_repository_node failed: %s\n", __func__, __LINE__, ps3_result(result)); dump_node_name(lpar_id, n1, n2, n3, n4); return -ENOENT; @@ -149,10 +149,10 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, *_v2 = v2; if (v1 && !_v1) - pr_debug("%s:%d: warning: discarding non-zero v1: %016llx\n", + pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n", __func__, __LINE__, v1); if (v2 && !_v2) - pr_debug("%s:%d: warning: discarding non-zero v2: %016llx\n", + pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n", __func__, __LINE__, v2); return 0; @@ -323,16 +323,16 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); if (result) { - pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); + pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__); return result; } - pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", + pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n", __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, num_dev); if (tmp.dev_index >= num_dev) { - pr_debug("%s:%d: no device found\n", __func__, __LINE__); + pr_devel("%s:%d: no device found\n", __func__, __LINE__); return -ENODEV; } @@ -340,7 +340,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) &tmp.dev_type); if (result) { - pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__); + pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__); return result; } @@ -348,12 +348,12 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) &tmp.dev_id); if (result) { - pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, + pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__, __LINE__); return result; } - pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", + pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n", __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); *repo = tmp; @@ -367,14 +367,14 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, struct ps3_repository_device tmp; unsigned int num_dev; - pr_debug(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, + pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__, bus_id, dev_id); for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { result = ps3_repository_read_bus_id(tmp.bus_index, &tmp.bus_id); if (result) { - pr_debug("%s:%u read_bus_id(%u) failed\n", __func__, + pr_devel("%s:%u read_bus_id(%u) failed\n", __func__, __LINE__, tmp.bus_index); return result; } @@ -382,23 +382,23 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, if (tmp.bus_id == bus_id) goto found_bus; - pr_debug("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, + pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__, tmp.bus_id); } - pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); + pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__); return result; found_bus: result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); if (result) { - pr_debug("%s:%u read_bus_type(%u) failed\n", __func__, + pr_devel("%s:%u read_bus_type(%u) failed\n", __func__, __LINE__, tmp.bus_index); return result; } result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); if (result) { - pr_debug("%s:%u read_bus_num_dev failed\n", __func__, + pr_devel("%s:%u read_bus_num_dev failed\n", __func__, __LINE__); return result; } @@ -408,7 +408,7 @@ found_bus: tmp.dev_index, &tmp.dev_id); if (result) { - pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__, + pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__, __LINE__, tmp.bus_index, tmp.dev_index); return result; } @@ -416,21 +416,21 @@ found_bus: if (tmp.dev_id == dev_id) goto found_dev; - pr_debug("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, + pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__, tmp.dev_id); } - pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__); + pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__); return result; found_dev: result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, &tmp.dev_type); if (result) { - pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__); + pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__); return result; } - pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", + pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n", __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, tmp.dev_index, tmp.bus_id, tmp.dev_id); *repo = tmp; @@ -443,18 +443,18 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, int result = 0; struct ps3_repository_device repo; - pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); + pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); repo.bus_type = bus_type; result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); if (result) { - pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); + pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__); return result; } result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); if (result) { - pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, + pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, repo.bus_index); return result; } @@ -469,13 +469,13 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type, result = callback(&repo); if (result) { - pr_debug("%s:%d: abort at callback\n", __func__, + pr_devel("%s:%d: abort at callback\n", __func__, __LINE__); break; } } - pr_debug(" <- %s:%d\n", __func__, __LINE__); + pr_devel(" <- %s:%d\n", __func__, __LINE__); return result; } @@ -489,7 +489,7 @@ int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, for (i = from; i < 10; i++) { error = ps3_repository_read_bus_type(i, &type); if (error) { - pr_debug("%s:%d read_bus_type failed\n", + pr_devel("%s:%d read_bus_type failed\n", __func__, __LINE__); *bus_index = UINT_MAX; return error; @@ -509,7 +509,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, int result = 0; unsigned int res_index; - pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); + pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); *interrupt_id = UINT_MAX; @@ -521,7 +521,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, repo->dev_index, res_index, &t, &id); if (result) { - pr_debug("%s:%d read_dev_intr failed\n", + pr_devel("%s:%d read_dev_intr failed\n", __func__, __LINE__); return result; } @@ -535,7 +535,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo, if (res_index == 10) return -ENODEV; - pr_debug("%s:%d: found intr_type %u at res_index %u\n", + pr_devel("%s:%d: found intr_type %u at res_index %u\n", __func__, __LINE__, intr_type, res_index); return result; @@ -547,7 +547,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, int result = 0; unsigned int res_index; - pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); + pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); *bus_addr = *len = 0; @@ -560,7 +560,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, repo->dev_index, res_index, &t, &a, &l); if (result) { - pr_debug("%s:%d read_dev_reg failed\n", + pr_devel("%s:%d read_dev_reg failed\n", __func__, __LINE__); return result; } @@ -575,7 +575,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo, if (res_index == 10) return -ENODEV; - pr_debug("%s:%d: found reg_type %u at res_index %u\n", + pr_devel("%s:%d: found reg_type %u at res_index %u\n", __func__, __LINE__, reg_type, res_index); return result; @@ -1009,7 +1009,7 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) int result = 0; unsigned int res_index; - pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, + pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, repo->bus_index, repo->dev_index); for (res_index = 0; res_index < 10; res_index++) { @@ -1021,13 +1021,13 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) if (result) { if (result != LV1_NO_ENTRY) - pr_debug("%s:%d ps3_repository_read_dev_intr" + pr_devel("%s:%d ps3_repository_read_dev_intr" " (%u:%u) failed\n", __func__, __LINE__, repo->bus_index, repo->dev_index); break; } - pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", + pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", __func__, __LINE__, repo->bus_index, repo->dev_index, intr_type, interrupt_id); } @@ -1042,18 +1042,18 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) if (result) { if (result != LV1_NO_ENTRY) - pr_debug("%s:%d ps3_repository_read_dev_reg" + pr_devel("%s:%d ps3_repository_read_dev_reg" " (%u:%u) failed\n", __func__, __LINE__, repo->bus_index, repo->dev_index); break; } - pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", + pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n", __func__, __LINE__, repo->bus_index, repo->dev_index, reg_type, bus_addr, len); } - pr_debug(" <- %s:%d\n", __func__, __LINE__); + pr_devel(" <- %s:%d\n", __func__, __LINE__); return result; } @@ -1063,22 +1063,22 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo) unsigned int num_regions, region_index; u64 port, blk_size, num_blocks; - pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, + pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, repo->bus_index, repo->dev_index); result = ps3_repository_read_stor_dev_info(repo->bus_index, repo->dev_index, &port, &blk_size, &num_blocks, &num_regions); if (result) { - pr_debug("%s:%d ps3_repository_read_stor_dev_info" + pr_devel("%s:%d ps3_repository_read_stor_dev_info" " (%u:%u) failed\n", __func__, __LINE__, repo->bus_index, repo->dev_index); goto out; } - pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks " - "%lu, num_regions %u\n", - __func__, __LINE__, repo->bus_index, repo->dev_index, port, - blk_size, num_blocks, num_regions); + pr_devel("%s:%d (%u:%u): port %llu, blk_size %llu, num_blocks " + "%llu, num_regions %u\n", + __func__, __LINE__, repo->bus_index, repo->dev_index, + port, blk_size, num_blocks, num_regions); for (region_index = 0; region_index < num_regions; region_index++) { unsigned int region_id; @@ -1088,19 +1088,20 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo) repo->dev_index, region_index, ®ion_id, ®ion_start, ®ion_size); if (result) { - pr_debug("%s:%d ps3_repository_read_stor_dev_region" + pr_devel("%s:%d ps3_repository_read_stor_dev_region" " (%u:%u) failed\n", __func__, __LINE__, repo->bus_index, repo->dev_index); break; } - pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", + pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n", __func__, __LINE__, repo->bus_index, repo->dev_index, - region_id, region_start, region_size); + region_id, (unsigned long)region_start, + (unsigned long)region_size); } out: - pr_debug(" <- %s:%d\n", __func__, __LINE__); + pr_devel(" <- %s:%d\n", __func__, __LINE__); return result; } @@ -1109,7 +1110,7 @@ static int dump_device_info(struct ps3_repository_device *repo, { int result = 0; - pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); + pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index); for (repo->dev_index = 0; repo->dev_index < num_dev; repo->dev_index++) { @@ -1118,7 +1119,7 @@ static int dump_device_info(struct ps3_repository_device *repo, repo->dev_index, &repo->dev_type); if (result) { - pr_debug("%s:%d ps3_repository_read_dev_type" + pr_devel("%s:%d ps3_repository_read_dev_type" " (%u:%u) failed\n", __func__, __LINE__, repo->bus_index, repo->dev_index); break; @@ -1128,15 +1129,15 @@ static int dump_device_info(struct ps3_repository_device *repo, repo->dev_index, &repo->dev_id); if (result) { - pr_debug("%s:%d ps3_repository_read_dev_id" + pr_devel("%s:%d ps3_repository_read_dev_id" " (%u:%u) failed\n", __func__, __LINE__, repo->bus_index, repo->dev_index); continue; } - pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, + pr_devel("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, __LINE__, repo->bus_index, repo->dev_index, - repo->dev_type, repo->dev_id); + repo->dev_type, (unsigned long)repo->dev_id); ps3_repository_dump_resource_info(repo); @@ -1144,7 +1145,7 @@ static int dump_device_info(struct ps3_repository_device *repo, dump_stor_dev_info(repo); } - pr_debug(" <- %s:%d\n", __func__, __LINE__); + pr_devel(" <- %s:%d\n", __func__, __LINE__); return result; } @@ -1153,7 +1154,7 @@ int ps3_repository_dump_bus_info(void) int result = 0; struct ps3_repository_device repo; - pr_debug(" -> %s:%d\n", __func__, __LINE__); + pr_devel(" -> %s:%d\n", __func__, __LINE__); memset(&repo, 0, sizeof(repo)); @@ -1164,7 +1165,7 @@ int ps3_repository_dump_bus_info(void) &repo.bus_type); if (result) { - pr_debug("%s:%d read_bus_type(%u) failed\n", + pr_devel("%s:%d read_bus_type(%u) failed\n", __func__, __LINE__, repo.bus_index); break; } @@ -1173,32 +1174,32 @@ int ps3_repository_dump_bus_info(void) &repo.bus_id); if (result) { - pr_debug("%s:%d read_bus_id(%u) failed\n", + pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, repo.bus_index); continue; } if (repo.bus_index != repo.bus_id) - pr_debug("%s:%d bus_index != bus_id\n", + pr_devel("%s:%d bus_index != bus_id\n", __func__, __LINE__); result = ps3_repository_read_bus_num_dev(repo.bus_index, &num_dev); if (result) { - pr_debug("%s:%d read_bus_num_dev(%u) failed\n", + pr_devel("%s:%d read_bus_num_dev(%u) failed\n", __func__, __LINE__, repo.bus_index); continue; } - pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", + pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", __func__, __LINE__, repo.bus_index, repo.bus_type, - repo.bus_id, num_dev); + (unsigned long)repo.bus_id, num_dev); dump_device_info(&repo, num_dev); } - pr_debug(" <- %s:%d\n", __func__, __LINE__); + pr_devel(" <- %s:%d\n", __func__, __LINE__); return result; } diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index e8ec1b2bfffd..2d664c5a83b0 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -193,10 +193,12 @@ static int ps3_set_dabr(unsigned long dabr) static void __init ps3_setup_arch(void) { + u64 tmp; DBG(" -> %s:%d\n", __func__, __LINE__); - lv1_get_version_info(&ps3_firmware_version.raw); + lv1_get_version_info(&ps3_firmware_version.raw, &tmp); + printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", ps3_firmware_version.major, ps3_firmware_version.minor, ps3_firmware_version.rev); diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index efc1cd8c034a..4b35166229fe 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -57,7 +57,7 @@ static void ps3_smp_message_pass(int cpu, int msg) " (%d)\n", __func__, __LINE__, cpu, msg, result); } -static int ps3_smp_probe(void) +static int __init ps3_smp_probe(void) { int cpu; diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 451fad1c92a8..e17fa1432d80 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -154,7 +154,7 @@ static unsigned long get_vas_id(void) u64 id; lv1_get_logical_ppe_id(&id); - lv1_get_virtual_address_space_id_of_ppe(id, &id); + lv1_get_virtual_address_space_id_of_ppe(&id); return id; } diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index c81f6bb9c10f..ae7b6d41fed3 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -120,3 +120,12 @@ config DTL which are accessible through a debugfs file. Say N if you are unsure. + +config PSERIES_IDLE + tristate "Cpuidle driver for pSeries platforms" + depends on CPU_IDLE + depends on PPC_PSERIES + default y + help + Select this option to enable processor idle state management + through cpuidle subsystem. diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 3556e402cbf5..236db46b4078 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_DTL) += dtl.o obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o +obj-$(CONFIG_PSERIES_IDLE) += processor_idle.o ifeq ($(CONFIG_PPC_PSERIES),y) obj-$(CONFIG_SUSPEND) += suspend.o diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index a76b22844d18..330a57b7c17c 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -625,6 +625,8 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, { static unsigned int oops_count = 0; static bool panicking = false; + static DEFINE_SPINLOCK(lock); + unsigned long flags; size_t text_len; unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ; int rc = -1; @@ -655,6 +657,9 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, if (clobbering_unread_rtas_event()) return; + if (!spin_trylock_irqsave(&lock, flags)) + return; + if (big_oops_buf) { text_len = capture_last_msgs(old_msgs, old_len, new_msgs, new_len, big_oops_buf, big_oops_buf_sz); @@ -670,4 +675,6 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, (void) nvram_write_os_partition(&oops_log_partition, oops_buf, (int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count); + + spin_unlock_irqrestore(&lock, flags); } diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c new file mode 100644 index 000000000000..085fd3f45ad2 --- /dev/null +++ b/arch/powerpc/platforms/pseries/processor_idle.c @@ -0,0 +1,329 @@ +/* + * processor_idle - idle state cpuidle driver. + * Adapted from drivers/idle/intel_idle.c and + * drivers/acpi/processor_idle.c + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/moduleparam.h> +#include <linux/cpuidle.h> +#include <linux/cpu.h> + +#include <asm/paca.h> +#include <asm/reg.h> +#include <asm/system.h> +#include <asm/machdep.h> +#include <asm/firmware.h> + +#include "plpar_wrappers.h" +#include "pseries.h" + +struct cpuidle_driver pseries_idle_driver = { + .name = "pseries_idle", + .owner = THIS_MODULE, +}; + +#define MAX_IDLE_STATE_COUNT 2 + +static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; +static struct cpuidle_device __percpu *pseries_cpuidle_devices; +static struct cpuidle_state *cpuidle_state_table; + +void update_smt_snooze_delay(int snooze) +{ + struct cpuidle_driver *drv = cpuidle_get_driver(); + if (drv) + drv->states[0].target_residency = snooze; +} + +static inline void idle_loop_prolog(unsigned long *in_purr, ktime_t *kt_before) +{ + + *kt_before = ktime_get_real(); + *in_purr = mfspr(SPRN_PURR); + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + get_lppaca()->idle = 1; +} + +static inline s64 idle_loop_epilog(unsigned long in_purr, ktime_t kt_before) +{ + get_lppaca()->wait_state_cycles += mfspr(SPRN_PURR) - in_purr; + get_lppaca()->idle = 0; + + return ktime_to_us(ktime_sub(ktime_get_real(), kt_before)); +} + +static int snooze_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + unsigned long in_purr; + ktime_t kt_before; + unsigned long start_snooze; + long snooze = drv->states[0].target_residency; + + idle_loop_prolog(&in_purr, &kt_before); + + if (snooze) { + start_snooze = get_tb() + snooze * tb_ticks_per_usec; + local_irq_enable(); + set_thread_flag(TIF_POLLING_NRFLAG); + + while ((snooze < 0) || (get_tb() < start_snooze)) { + if (need_resched() || cpu_is_offline(dev->cpu)) + goto out; + ppc64_runlatch_off(); + HMT_low(); + HMT_very_low(); + } + + HMT_medium(); + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb(); + local_irq_disable(); + } + +out: + HMT_medium(); + dev->last_residency = + (int)idle_loop_epilog(in_purr, kt_before); + return index; +} + +static int dedicated_cede_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + unsigned long in_purr; + ktime_t kt_before; + + idle_loop_prolog(&in_purr, &kt_before); + get_lppaca()->donate_dedicated_cpu = 1; + + ppc64_runlatch_off(); + HMT_medium(); + cede_processor(); + + get_lppaca()->donate_dedicated_cpu = 0; + dev->last_residency = + (int)idle_loop_epilog(in_purr, kt_before); + return index; +} + +static int shared_cede_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + unsigned long in_purr; + ktime_t kt_before; + + idle_loop_prolog(&in_purr, &kt_before); + + /* + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. + */ + cede_processor(); + + dev->last_residency = + (int)idle_loop_epilog(in_purr, kt_before); + return index; +} + +/* + * States for dedicated partition case. + */ +static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = { + { /* Snooze */ + .name = "snooze", + .desc = "snooze", + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 0, + .target_residency = 0, + .enter = &snooze_loop }, + { /* CEDE */ + .name = "CEDE", + .desc = "CEDE", + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 1, + .target_residency = 10, + .enter = &dedicated_cede_loop }, +}; + +/* + * States for shared partition case. + */ +static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { + { /* Shared Cede */ + .name = "Shared Cede", + .desc = "Shared Cede", + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 0, + .target_residency = 0, + .enter = &shared_cede_loop }, +}; + +int pseries_notify_cpuidle_add_cpu(int cpu) +{ + struct cpuidle_device *dev = + per_cpu_ptr(pseries_cpuidle_devices, cpu); + if (dev && cpuidle_get_driver()) { + cpuidle_disable_device(dev); + cpuidle_enable_device(dev); + } + return 0; +} + +/* + * pseries_cpuidle_driver_init() + */ +static int pseries_cpuidle_driver_init(void) +{ + int idle_state; + struct cpuidle_driver *drv = &pseries_idle_driver; + + drv->state_count = 0; + + for (idle_state = 0; idle_state < MAX_IDLE_STATE_COUNT; ++idle_state) { + + if (idle_state > max_idle_state) + break; + + /* is the state not enabled? */ + if (cpuidle_state_table[idle_state].enter == NULL) + continue; + + drv->states[drv->state_count] = /* structure copy */ + cpuidle_state_table[idle_state]; + + if (cpuidle_state_table == dedicated_states) + drv->states[drv->state_count].target_residency = + __get_cpu_var(smt_snooze_delay); + + drv->state_count += 1; + } + + return 0; +} + +/* pseries_idle_devices_uninit(void) + * unregister cpuidle devices and de-allocate memory + */ +static void pseries_idle_devices_uninit(void) +{ + int i; + struct cpuidle_device *dev; + + for_each_possible_cpu(i) { + dev = per_cpu_ptr(pseries_cpuidle_devices, i); + cpuidle_unregister_device(dev); + } + + free_percpu(pseries_cpuidle_devices); + return; +} + +/* pseries_idle_devices_init() + * allocate, initialize and register cpuidle device + */ +static int pseries_idle_devices_init(void) +{ + int i; + struct cpuidle_driver *drv = &pseries_idle_driver; + struct cpuidle_device *dev; + + pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device); + if (pseries_cpuidle_devices == NULL) + return -ENOMEM; + + for_each_possible_cpu(i) { + dev = per_cpu_ptr(pseries_cpuidle_devices, i); + dev->state_count = drv->state_count; + dev->cpu = i; + if (cpuidle_register_device(dev)) { + printk(KERN_DEBUG \ + "cpuidle_register_device %d failed!\n", i); + return -EIO; + } + } + + return 0; +} + +/* + * pseries_idle_probe() + * Choose state table for shared versus dedicated partition + */ +static int pseries_idle_probe(void) +{ + + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) + return -ENODEV; + + if (cpuidle_disable != IDLE_NO_OVERRIDE) + return -ENODEV; + + if (max_idle_state == 0) { + printk(KERN_DEBUG "pseries processor idle disabled.\n"); + return -EPERM; + } + + if (get_lppaca()->shared_proc) + cpuidle_state_table = shared_states; + else + cpuidle_state_table = dedicated_states; + + return 0; +} + +static int __init pseries_processor_idle_init(void) +{ + int retval; + + retval = pseries_idle_probe(); + if (retval) + return retval; + + pseries_cpuidle_driver_init(); + retval = cpuidle_register_driver(&pseries_idle_driver); + if (retval) { + printk(KERN_DEBUG "Registration of pseries driver failed.\n"); + return retval; + } + + retval = pseries_idle_devices_init(); + if (retval) { + pseries_idle_devices_uninit(); + cpuidle_unregister_driver(&pseries_idle_driver); + return retval; + } + + printk(KERN_DEBUG "pseries_idle_driver registered\n"); + + return 0; +} + +static void __exit pseries_processor_idle_exit(void) +{ + + pseries_idle_devices_uninit(); + cpuidle_unregister_driver(&pseries_idle_driver); + + return; +} + +module_init(pseries_processor_idle_init); +module_exit(pseries_processor_idle_exit); + +MODULE_AUTHOR("Deepthi Dharwar <deepthi@linux.vnet.ibm.com>"); +MODULE_DESCRIPTION("Cpuidle driver for POWER"); +MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 24c7162f11d9..9a3dda07566f 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -57,4 +57,7 @@ extern struct device_node *dlpar_configure_connector(u32); extern int dlpar_attach_node(struct device_node *); extern int dlpar_detach_node(struct device_node *); +/* Snooze Delay, pseries_idle */ +DECLARE_PER_CPU(long, smt_snooze_delay); + #endif /* _PSERIES_PSERIES_H */ diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index c3408ca8855e..f79f1278dfca 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -39,6 +39,7 @@ #include <linux/irq.h> #include <linux/seq_file.h> #include <linux/root_dev.h> +#include <linux/cpuidle.h> #include <asm/mmu.h> #include <asm/processor.h> @@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize); int fwnmi_active; /* TRUE if an FWNMI handler is present */ -static void pseries_shared_idle_sleep(void); -static void pseries_dedicated_idle_sleep(void); - static struct device_node *pSeries_mpic_node; static void pSeries_show_cpuinfo(struct seq_file *m) @@ -192,8 +190,7 @@ static void __init pseries_mpic_init_IRQ(void) BUG_ON(openpic_addr == 0); /* Setup the openpic driver */ - mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, - MPIC_PRIMARY, + mpic = mpic_alloc(pSeries_mpic_node, openpic_addr, 0, 16, 250, /* isu size, irq count */ " MPIC "); BUG_ON(mpic == NULL); @@ -352,8 +349,25 @@ static int alloc_dispatch_log_kmem_cache(void) } early_initcall(alloc_dispatch_log_kmem_cache); +static void pSeries_idle(void) +{ + /* This would call on the cpuidle framework, and the back-end pseries + * driver to go to idle states + */ + if (cpuidle_idle_call()) { + /* On error, execute default handler + * to go into low thread priority and possibly + * low power mode. + */ + HMT_low(); + HMT_very_low(); + } +} + static void __init pSeries_setup_arch(void) { + panic_timeout = 10; + /* Discover PIC type and setup ppc_md accordingly */ pseries_discover_pic(); @@ -374,18 +388,9 @@ static void __init pSeries_setup_arch(void) pSeries_nvram_init(); - /* Choose an idle loop */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { vpa_init(boot_cpuid); - if (get_lppaca()->shared_proc) { - printk(KERN_DEBUG "Using shared processor idle loop\n"); - ppc_md.power_save = pseries_shared_idle_sleep; - } else { - printk(KERN_DEBUG "Using dedicated idle loop\n"); - ppc_md.power_save = pseries_dedicated_idle_sleep; - } - } else { - printk(KERN_DEBUG "Using default idle loop\n"); + ppc_md.power_save = pSeries_idle; } if (firmware_has_feature(FW_FEATURE_LPAR)) @@ -586,80 +591,6 @@ static int __init pSeries_probe(void) return 1; } - -DECLARE_PER_CPU(long, smt_snooze_delay); - -static void pseries_dedicated_idle_sleep(void) -{ - unsigned int cpu = smp_processor_id(); - unsigned long start_snooze; - unsigned long in_purr, out_purr; - long snooze = __get_cpu_var(smt_snooze_delay); - - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; - get_lppaca()->donate_dedicated_cpu = 1; - in_purr = mfspr(SPRN_PURR); - - /* - * We come in with interrupts disabled, and need_resched() - * has been checked recently. If we should poll for a little - * while, do so. - */ - if (snooze) { - start_snooze = get_tb() + snooze * tb_ticks_per_usec; - local_irq_enable(); - set_thread_flag(TIF_POLLING_NRFLAG); - - while ((snooze < 0) || (get_tb() < start_snooze)) { - if (need_resched() || cpu_is_offline(cpu)) - goto out; - ppc64_runlatch_off(); - HMT_low(); - HMT_very_low(); - } - - HMT_medium(); - clear_thread_flag(TIF_POLLING_NRFLAG); - smp_mb(); - local_irq_disable(); - if (need_resched() || cpu_is_offline(cpu)) - goto out; - } - - cede_processor(); - -out: - HMT_medium(); - out_purr = mfspr(SPRN_PURR); - get_lppaca()->wait_state_cycles += out_purr - in_purr; - get_lppaca()->donate_dedicated_cpu = 0; - get_lppaca()->idle = 0; -} - -static void pseries_shared_idle_sleep(void) -{ - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; - - /* - * Yield the processor to the hypervisor. We return if - * an external interrupt occurs (which are driven prior - * to returning here) or if a prod occurs from another - * processor. When returning here, external interrupts - * are enabled. - */ - cede_processor(); - - get_lppaca()->idle = 0; -} - static int pSeries_pci_probe_mode(struct pci_bus *bus) { if (firmware_has_feature(FW_FEATURE_LPAR)) diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 26e93fd4c62b..bbc3c42f6730 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -148,6 +148,7 @@ static void __devinit smp_xics_setup_cpu(int cpu) set_cpu_current_state(cpu, CPU_STATE_ONLINE); set_default_offline_state(cpu); #endif + pseries_notify_cpuidle_add_cpu(cpu); } static int __devinit smp_pSeries_kick_cpu(int nr) |