diff options
author | Michal Marek <mmarek@suse.cz> | 2010-08-04 15:59:13 +0400 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2010-08-04 15:59:13 +0400 |
commit | 772320e84588dcbe1600ffb83e5f328f2209ac2a (patch) | |
tree | a7de21b79340aeaa17c58126f6b801b82c77b53a /arch/powerpc/platforms | |
parent | 1ce53adf13a54375d2a5c7cdbe341b2558389615 (diff) | |
parent | 9fe6206f400646a2322096b56c59891d530e8d51 (diff) | |
download | linux-772320e84588dcbe1600ffb83e5f328f2209ac2a.tar.xz |
Merge commit 'v2.6.35' into kbuild/kbuild
Conflicts:
arch/powerpc/Makefile
Diffstat (limited to 'arch/powerpc/platforms')
128 files changed, 1273 insertions, 601 deletions
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 7486bffd3ebb..69d668c072ae 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -1,3 +1,12 @@ +config PPC_47x + bool "Support for 47x variant" + depends on 44x + default n + select MPIC + help + This option enables support for the 47x family of processors and is + not currently compatible with other 44x or 46x varients + config BAMBOO bool "Bamboo" depends on 44x @@ -151,6 +160,28 @@ config YOSEMITE help This option enables support for the AMCC PPC440EP evaluation board. +config ISS4xx + bool "ISS 4xx Simulator" + depends on (44x || 40x) + default n + select 405GP if 40x + select 440GP if 44x && !PPC_47x + select PPC_FPU + select OF_RTC + help + This option enables support for the IBM ISS simulation environment + +config ICON + bool "Icon" + depends on 44x + default n + select PPC44x_SIMPLE + select 440SPe + select PCI + select PPC4xx_PCI_EXPRESS + help + This option enables support for the AMCC PPC440SPe evaluation board. + #config LUAN # bool "Luan" # depends on 44x diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index ee6185aeaa3b..82ff326e0795 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_SAM440EP) += sam440ep.o obj-$(CONFIG_WARP) += warp.o obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o +obj-$(CONFIG_ISS4xx) += iss4xx.o diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c new file mode 100644 index 000000000000..aa46e9d1e771 --- /dev/null +++ b/arch/powerpc/platforms/44x/iss4xx.c @@ -0,0 +1,167 @@ +/* + * PPC476 board specific routines + * + * Copyright 2010 Torez Smith, IBM Corporation. + * + * Based on earlier code: + * Matt Porter <mporter@kernel.crashing.org> + * Copyright 2002-2005 MontaVista Software Inc. + * + * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> + * Copyright (c) 2003-2005 Zultys Technologies + * + * Rewritten and ported to the merged powerpc tree: + * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/init.h> +#include <linux/of_platform.h> +#include <linux/rtc.h> + +#include <asm/machdep.h> +#include <asm/prom.h> +#include <asm/udbg.h> +#include <asm/time.h> +#include <asm/uic.h> +#include <asm/ppc4xx.h> +#include <asm/mpic.h> +#include <asm/mmu.h> + +static __initdata struct of_device_id iss4xx_of_bus[] = { + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,plb6", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init iss4xx_device_probe(void) +{ + of_platform_bus_probe(NULL, iss4xx_of_bus, NULL); + of_instantiate_rtc(); + + return 0; +} +machine_device_initcall(iss4xx, iss4xx_device_probe); + +/* We can have either UICs or MPICs */ +static void __init iss4xx_init_irq(void) +{ + struct device_node *np; + + /* Find top level interrupt controller */ + for_each_node_with_property(np, "interrupt-controller") { + if (of_get_property(np, "interrupts", NULL) == NULL) + break; + } + if (np == NULL) + panic("Can't find top level interrupt controller"); + + /* Check type and do appropriate initialization */ + if (of_device_is_compatible(np, "ibm,uic")) { + uic_init_tree(); + ppc_md.get_irq = uic_get_irq; +#ifdef CONFIG_MPIC + } else if (of_device_is_compatible(np, "chrp,open-pic")) { + /* 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, + " MPIC "); + BUG_ON(mpic == NULL); + mpic_init(mpic); + ppc_md.get_irq = mpic_get_irq; +#endif + } else + panic("Unrecognized top level interrupt controller"); +} + +#ifdef CONFIG_SMP +static void __cpuinit smp_iss4xx_setup_cpu(int cpu) +{ + mpic_setup_this_cpu(); +} + +static void __cpuinit smp_iss4xx_kick_cpu(int cpu) +{ + struct device_node *cpunode = of_get_cpu_node(cpu, NULL); + const u64 *spin_table_addr_prop; + u32 *spin_table; + extern void start_secondary_47x(void); + + BUG_ON(cpunode == NULL); + + /* Assume spin table. We could test for the enable-method in + * the device-tree but currently there's little point as it's + * our only supported method + */ + spin_table_addr_prop = of_get_property(cpunode, "cpu-release-addr", + NULL); + if (spin_table_addr_prop == NULL) { + pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu); + return; + } + + /* Assume it's mapped as part of the linear mapping. This is a bit + * fishy but will work fine for now + */ + spin_table = (u32 *)__va(*spin_table_addr_prop); + pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table); + + spin_table[3] = cpu; + smp_wmb(); + spin_table[1] = __pa(start_secondary_47x); + mb(); +} + +static struct smp_ops_t iss_smp_ops = { + .probe = smp_mpic_probe, + .message_pass = smp_mpic_message_pass, + .setup_cpu = smp_iss4xx_setup_cpu, + .kick_cpu = smp_iss4xx_kick_cpu, + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, +}; + +static void __init iss4xx_smp_init(void) +{ + if (mmu_has_feature(MMU_FTR_TYPE_47x)) + smp_ops = &iss_smp_ops; +} + +#else /* CONFIG_SMP */ +static void __init iss4xx_smp_init(void) { } +#endif /* CONFIG_SMP */ + +static void __init iss4xx_setup_arch(void) +{ + iss4xx_smp_init(); +} + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init iss4xx_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "ibm,iss-4xx")) + return 0; + + return 1; +} + +define_machine(iss4xx) { + .name = "ISS-4xx", + .probe = iss4xx_probe, + .progress = udbg_progress, + .init_IRQ = iss4xx_init_irq, + .setup_arch = iss4xx_setup_arch, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c index e8c23ccaa1fc..5f7a29d7f590 100644 --- a/arch/powerpc/platforms/44x/ppc44x_simple.c +++ b/arch/powerpc/platforms/44x/ppc44x_simple.c @@ -61,7 +61,8 @@ static char *board[] __initdata = { "amcc,redwood", "amcc,sequoia", "amcc,taishan", - "amcc,yosemite" + "amcc,yosemite", + "mosaixtech,icon" }; static int __init ppc44x_probe(void) diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index e5c1b096c3e1..8f771395f424 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c @@ -17,6 +17,7 @@ #include <linux/delay.h> #include <linux/of_gpio.h> #include <linux/of_i2c.h> +#include <linux/slab.h> #include <asm/machdep.h> #include <asm/prom.h> diff --git a/arch/powerpc/platforms/512x/clock.c b/arch/powerpc/platforms/512x/clock.c index 84544d072043..4c42246b86a7 100644 --- a/arch/powerpc/platforms/512x/clock.c +++ b/arch/powerpc/platforms/512x/clock.c @@ -698,8 +698,7 @@ static struct clk_interface mpc5121_clk_functions = { .clk_get_parent = NULL, }; -static int -mpc5121_clk_init(void) +int __init mpc5121_clk_init(void) { struct device_node *np; @@ -724,6 +723,3 @@ mpc5121_clk_init(void) clk_functions = mpc5121_clk_functions; return 0; } - - -arch_initcall(mpc5121_clk_init); diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c index 441abc488851..ee6ae129c25c 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads.c @@ -64,8 +64,9 @@ define_machine(mpc5121_ads) { .name = "MPC5121 ADS", .probe = mpc5121_ads_probe, .setup_arch = mpc5121_ads_setup_arch, - .init = mpc512x_declare_of_platform_devices, + .init = mpc512x_init, .init_IRQ = mpc5121_ads_init_IRQ, .get_irq = ipic_get_irq, .calibrate_decr = generic_calibrate_decr, + .restart = mpc512x_restart, }; diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c index da9b20a63769..4ecf4cf9a51b 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c @@ -79,7 +79,7 @@ cpld_unmask_irq(unsigned int irq) } static struct irq_chip cpld_pic = { - .name = " CPLD PIC ", + .name = "CPLD PIC", .mask = cpld_mask_irq, .ack = cpld_mask_irq, .unmask = cpld_unmask_irq, diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c index 2479de9e2d12..a6c0e3a2615d 100644 --- a/arch/powerpc/platforms/512x/mpc5121_generic.c +++ b/arch/powerpc/platforms/512x/mpc5121_generic.c @@ -51,8 +51,9 @@ static int __init mpc5121_generic_probe(void) define_machine(mpc5121_generic) { .name = "MPC5121 generic", .probe = mpc5121_generic_probe, - .init = mpc512x_declare_of_platform_devices, + .init = mpc512x_init, .init_IRQ = mpc512x_init_IRQ, .get_irq = ipic_get_irq, .calibrate_decr = generic_calibrate_decr, + .restart = mpc512x_restart, }; diff --git a/arch/powerpc/platforms/512x/mpc512x.h b/arch/powerpc/platforms/512x/mpc512x.h index 22a5352407e0..b2daca0d1488 100644 --- a/arch/powerpc/platforms/512x/mpc512x.h +++ b/arch/powerpc/platforms/512x/mpc512x.h @@ -12,5 +12,8 @@ #ifndef __MPC512X_H__ #define __MPC512X_H__ extern void __init mpc512x_init_IRQ(void); +extern void __init mpc512x_init(void); +extern int __init mpc5121_clk_init(void); void __init mpc512x_declare_of_platform_devices(void); +extern void mpc512x_restart(char *cmd); #endif /* __MPC512X_H__ */ diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 434d683df5a0..707e572b7c40 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -21,9 +21,39 @@ #include <asm/ipic.h> #include <asm/prom.h> #include <asm/time.h> +#include <asm/mpc5121.h> +#include <asm/mpc52xx_psc.h> #include "mpc512x.h" +static struct mpc512x_reset_module __iomem *reset_module_base; + +static void __init mpc512x_restart_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-reset"); + if (!np) + return; + + reset_module_base = of_iomap(np, 0); + of_node_put(np); +} + +void mpc512x_restart(char *cmd) +{ + if (reset_module_base) { + /* Enable software reset "RSTE" */ + out_be32(&reset_module_base->rpr, 0x52535445); + /* Set software hard reset */ + out_be32(&reset_module_base->rcr, 0x2); + } else { + pr_err("Restart module not mapped.\n"); + } + for (;;) + ; +} + void __init mpc512x_init_IRQ(void) { struct device_node *np; @@ -53,8 +83,99 @@ static struct of_device_id __initdata of_bus_ids[] = { void __init mpc512x_declare_of_platform_devices(void) { + struct device_node *np; + if (of_platform_bus_probe(NULL, of_bus_ids, NULL)) printk(KERN_ERR __FILE__ ": " "Error while probing of_platform bus\n"); + + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-nfc"); + if (np) { + of_platform_device_create(np, NULL, NULL); + of_node_put(np); + } } +#define DEFAULT_FIFO_SIZE 16 + +static unsigned int __init get_fifo_size(struct device_node *np, + char *prop_name) +{ + const unsigned int *fp; + + fp = of_get_property(np, prop_name, NULL); + if (fp) + return *fp; + + pr_warning("no %s property in %s node, defaulting to %d\n", + prop_name, np->full_name, DEFAULT_FIFO_SIZE); + + return DEFAULT_FIFO_SIZE; +} + +#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ + ((u32)(_base) + sizeof(struct mpc52xx_psc))) + +/* Init PSC FIFO space for TX and RX slices */ +void __init mpc512x_psc_fifo_init(void) +{ + struct device_node *np; + void __iomem *psc; + unsigned int tx_fifo_size; + unsigned int rx_fifo_size; + int fifobase = 0; /* current fifo address in 32 bit words */ + + for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { + tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); + rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); + + /* size in register is in 4 byte units */ + tx_fifo_size /= 4; + rx_fifo_size /= 4; + if (!tx_fifo_size) + tx_fifo_size = 1; + if (!rx_fifo_size) + rx_fifo_size = 1; + + psc = of_iomap(np, 0); + if (!psc) { + pr_err("%s: Can't map %s device\n", + __func__, np->full_name); + continue; + } + + /* FIFO space is 4KiB, check if requested size is available */ + if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { + pr_err("%s: no fifo space available for %s\n", + __func__, np->full_name); + iounmap(psc); + /* + * chances are that another device requests less + * fifo space, so we continue. + */ + continue; + } + + /* set tx and rx fifo size registers */ + out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); + fifobase += tx_fifo_size; + out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); + fifobase += rx_fifo_size; + + /* reset and enable the slices */ + out_be32(&FIFOC(psc)->txcmd, 0x80); + out_be32(&FIFOC(psc)->txcmd, 0x01); + out_be32(&FIFOC(psc)->rxcmd, 0x80); + out_be32(&FIFOC(psc)->rxcmd, 0x01); + + iounmap(psc); + } +} + +void __init mpc512x_init(void) +{ + mpc512x_declare_of_platform_devices(); + mpc5121_clk_init(); + mpc512x_restart_init(); + mpc512x_psc_fifo_init(); +} diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 2b8d8ef32e4e..ca5305a5bd61 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -19,6 +19,7 @@ #include <linux/of.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/of_gpio.h> #include <linux/io.h> #include <linux/of_platform.h> @@ -167,7 +168,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_wkup_gpio_get; ofchip->gc.set = mpc52xx_wkup_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; @@ -192,8 +193,11 @@ static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = { - .name = "gpio_wkup", - .match_table = mpc52xx_wkup_gpiochip_match, + .driver = { + .name = "gpio_wkup", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_wkup_gpiochip_match, + }, .probe = mpc52xx_wkup_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; @@ -328,7 +332,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, ofchip->gc.get = mpc52xx_simple_gpio_get; ofchip->gc.set = mpc52xx_simple_gpio_set; - ret = of_mm_gpiochip_add(ofdev->node, &chip->mmchip); + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); if (ret) return ret; @@ -348,8 +352,11 @@ static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { }; static struct of_platform_driver mpc52xx_simple_gpiochip_driver = { - .name = "gpio", - .match_table = mpc52xx_simple_gpiochip_match, + .driver = { + .name = "gpio", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_simple_gpiochip_match, + }, .probe = mpc52xx_simple_gpiochip_probe, .remove = mpc52xx_gpiochip_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 6f8ebe1085b3..46c93578cbf0 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -62,6 +62,7 @@ #include <linux/of_platform.h> #include <linux/of_gpio.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/watchdog.h> #include <linux/miscdevice.h> #include <linux/uaccess.h> @@ -553,7 +554,7 @@ static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data, return 0; } -static struct watchdog_info mpc5200_wdt_info = { +static const struct watchdog_info mpc5200_wdt_info = { .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .identity = WDT_IDENTITY, }; @@ -711,7 +712,11 @@ static int __devinit mpc52xx_gpt_wdt_init(void) return 0; } -#define mpc52xx_gpt_wdt_setup(x, y) (0) +static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt, + const u32 *period) +{ + return 0; +} #endif /* CONFIG_MPC5200_WDT */ @@ -729,8 +734,8 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, spin_lock_init(&gpt->lock); gpt->dev = &ofdev->dev; - gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->node); - gpt->regs = of_iomap(ofdev->node, 0); + gpt->ipb_freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node); + gpt->regs = of_iomap(ofdev->dev.of_node, 0); if (!gpt->regs) { kfree(gpt); return -ENOMEM; @@ -738,21 +743,21 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev, dev_set_drvdata(&ofdev->dev, gpt); - mpc52xx_gpt_gpio_setup(gpt, ofdev->node); - mpc52xx_gpt_irq_setup(gpt, ofdev->node); + mpc52xx_gpt_gpio_setup(gpt, ofdev->dev.of_node); + mpc52xx_gpt_irq_setup(gpt, ofdev->dev.of_node); mutex_lock(&mpc52xx_gpt_list_mutex); list_add(&gpt->list, &mpc52xx_gpt_list); mutex_unlock(&mpc52xx_gpt_list_mutex); /* check if this device could be a watchdog */ - if (of_get_property(ofdev->node, "fsl,has-wdt", NULL) || - of_get_property(ofdev->node, "has-wdt", NULL)) { + if (of_get_property(ofdev->dev.of_node, "fsl,has-wdt", NULL) || + of_get_property(ofdev->dev.of_node, "has-wdt", NULL)) { const u32 *on_boot_wdt; gpt->wdt_mode = MPC52xx_GPT_CAN_WDT; - on_boot_wdt = of_get_property(ofdev->node, "fsl,wdt-on-boot", - NULL); + on_boot_wdt = of_get_property(ofdev->dev.of_node, + "fsl,wdt-on-boot", NULL); if (on_boot_wdt) { dev_info(gpt->dev, "used as watchdog\n"); gpt->wdt_mode |= MPC52xx_GPT_IS_WDT; @@ -779,8 +784,11 @@ static const struct of_device_id mpc52xx_gpt_match[] = { }; static struct of_platform_driver mpc52xx_gpt_driver = { - .name = "mpc52xx-gpt", - .match_table = mpc52xx_gpt_match, + .driver = { + .name = "mpc52xx-gpt", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_gpt_match, + }, .probe = mpc52xx_gpt_probe, .remove = mpc52xx_gpt_remove, }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c index 929d017535a3..e86aec644501 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -445,14 +445,14 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) if (lpbfifo.dev != NULL) return -ENOSPC; - lpbfifo.irq = irq_of_parse_and_map(op->node, 0); + lpbfifo.irq = irq_of_parse_and_map(op->dev.of_node, 0); if (!lpbfifo.irq) return -ENODEV; - if (of_address_to_resource(op->node, 0, &res)) + if (of_address_to_resource(op->dev.of_node, 0, &res)) return -ENODEV; lpbfifo.regs_phys = res.start; - lpbfifo.regs = of_iomap(op->node, 0); + lpbfifo.regs = of_iomap(op->dev.of_node, 0); if (!lpbfifo.regs) return -ENOMEM; @@ -481,6 +481,8 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match) if (rc) goto err_bcom_rx_irq; + lpbfifo.dma_irqs_enabled = 1; + /* Request the Bestcomm transmit (memory --> fifo) task and IRQ */ lpbfifo.bcom_tx_task = bcom_gen_bd_tx_init(2, res.start + LPBFIFO_REG_FIFO_DATA, @@ -535,9 +537,11 @@ static struct of_device_id mpc52xx_lpbfifo_match[] __devinitconst = { }; static struct of_platform_driver mpc52xx_lpbfifo_driver = { - .owner = THIS_MODULE, - .name = "mpc52xx-lpbfifo", - .match_table = mpc52xx_lpbfifo_match, + .driver = { + .name = "mpc52xx-lpbfifo", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_lpbfifo_match, + }, .probe = mpc52xx_lpbfifo_probe, .remove = __devexit_p(mpc52xx_lpbfifo_remove), }; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index a55b0b6813ed..76722532bd95 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c @@ -64,10 +64,19 @@ int mpc52xx_pm_prepare(void) { .type = "builtin", .compatible = "mpc5200", }, /* efika */ {} }; + struct resource res; /* map the whole register space */ np = of_find_matching_node(NULL, immr_ids); - mbar = of_iomap(np, 0); + + if (of_address_to_resource(np, 0, &res)) { + pr_err("mpc52xx_pm_prepare(): could not get IMMR address\n"); + of_node_put(np); + return -ENOSYS; + } + + mbar = ioremap(res.start, 0xc000); /* we should map whole region including SRAM */ + of_node_put(np); if (!mbar) { pr_err("mpc52xx_pm_prepare(): could not map registers\n"); diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index f9aee182e6f7..9f2e52b36f91 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -15,6 +15,7 @@ #include <linux/fsl_devices.h> #include <linux/mdio-bitbang.h> #include <linux/of_mdio.h> +#include <linux/slab.h> #include <linux/of_platform.h> #include <asm/io.h> @@ -118,12 +119,12 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, struct device_node *node; int ret; - node = of_get_parent(ofdev->node); + node = of_get_parent(ofdev->dev.of_node); of_node_put(node); if (node != ep8248e_bcsr_node) return -ENODEV; - ret = of_address_to_resource(ofdev->node, 0, &res); + ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) return ret; @@ -141,7 +142,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); - ret = of_mdiobus_register(bus, ofdev->node); + ret = of_mdiobus_register(bus, ofdev->dev.of_node); if (ret) goto err_free_irq; @@ -169,8 +170,9 @@ static const struct of_device_id ep8248e_mdio_match[] = { static struct of_platform_driver ep8248e_mdio_driver = { .driver = { .name = "ep8248e-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = ep8248e_mdio_match, }, - .match_table = ep8248e_mdio_match, .probe = ep8248e_mdio_probe, .remove = ep8248e_mdio_remove, }; diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index 9d962d7c72c1..5a55d87d6bd6 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -17,6 +17,7 @@ #include <linux/irq.h> #include <linux/types.h> #include <linux/bootmem.h> +#include <linux/slab.h> #include <asm/io.h> #include <asm/prom.h> @@ -24,7 +25,7 @@ #include "pq2.h" -static DEFINE_SPINLOCK(pci_pic_lock); +static DEFINE_RAW_SPINLOCK(pci_pic_lock); struct pq2ads_pci_pic { struct device_node *node; @@ -45,12 +46,12 @@ static void pq2ads_pci_mask_irq(unsigned int virq) if (irq != -1) { unsigned long flags; - spin_lock_irqsave(&pci_pic_lock, flags); + raw_spin_lock_irqsave(&pci_pic_lock, flags); setbits32(&priv->regs->mask, 1 << irq); mb(); - spin_unlock_irqrestore(&pci_pic_lock, flags); + raw_spin_unlock_irqrestore(&pci_pic_lock, flags); } } @@ -62,9 +63,9 @@ static void pq2ads_pci_unmask_irq(unsigned int virq) if (irq != -1) { unsigned long flags; - spin_lock_irqsave(&pci_pic_lock, flags); + raw_spin_lock_irqsave(&pci_pic_lock, flags); clrbits32(&priv->regs->mask, 1 << irq); - spin_unlock_irqrestore(&pci_pic_lock, flags); + raw_spin_unlock_irqrestore(&pci_pic_lock, flags); } } diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 82a9bcb858b6..d119a7c1c17a 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -20,6 +20,7 @@ #include <linux/gpio.h> #include <linux/of.h> #include <linux/of_gpio.h> +#include <linux/slab.h> #include <asm/prom.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index 0b4f883b20eb..ae525e4745d2 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -74,6 +74,7 @@ static int __init mpc831x_rdb_probe(void) static struct of_device_id __initdata of_bus_ids[] = { { .compatible = "simple-bus" }, { .compatible = "gianfar" }, + { .compatible = "gpio-leds", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index a1908d261240..e00801c42540 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c @@ -72,6 +72,7 @@ static struct of_device_id mpc837x_ids[] = { { .compatible = "soc", }, { .compatible = "simple-bus", }, { .compatible = "gianfar", }, + { .compatible = "gpio-leds", }, {}, }; diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 43805348b81e..ebe6c3537209 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -321,7 +321,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = { static int pmc_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type = match->data; int ret = 0; @@ -423,8 +423,11 @@ static struct of_device_id pmc_match[] = { }; static struct of_platform_driver pmc_driver = { - .name = "mpc83xx-pmc", - .match_table = pmc_match, + .driver = { + .name = "mpc83xx-pmc", + .owner = THIS_MODULE, + .of_match_table = pmc_match, + }, .probe = pmc_probe, .remove = pmc_remove }; diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index d95121894eb7..3a2ade2e443f 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -51,7 +51,7 @@ config MPC85xx_DS bool "Freescale MPC85xx DS" select PPC_I8259 select DEFAULT_UIMAGE - select FSL_ULI1575 + select FSL_ULI1575 if PCI select SWIOTLB help This option enables support for the MPC85xx DS (MPC8544 DS) board @@ -60,7 +60,7 @@ config MPC85xx_RDB bool "Freescale MPC85xx RDB" select PPC_I8259 select DEFAULT_UIMAGE - select FSL_ULI1575 + select FSL_ULI1575 if PCI select SWIOTLB help This option enables support for the MPC85xx RDB (P2020 RDB) board diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c index 534c2ecc89d9..2ab338c9ac37 100644 --- a/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/arch/powerpc/platforms/85xx/corenet_ds.c @@ -16,7 +16,7 @@ #include <linux/kdev_t.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/system.h> #include <asm/time.h> @@ -100,7 +100,7 @@ void __init corenet_ds_setup_arch(void) #endif #ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() > max) { + if (memblock_end_of_DRAM() > max) { ppc_swiotlb_enable = 1; set_pci_dma_ops(&swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c index 004b7d36cdb7..f79f2f102141 100644 --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -17,7 +17,7 @@ #include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/of_platform.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/system.h> #include <asm/time.h> @@ -94,7 +94,7 @@ static void __init mpc8536_ds_setup_arch(void) #endif #ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() > max) { + if (memblock_end_of_DRAM() > max) { ppc_swiotlb_enable = 1; set_pci_dma_ops(&swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 544011a562fb..8190bc25bf27 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -20,7 +20,7 @@ #include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/of_platform.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/system.h> #include <asm/time.h> @@ -190,7 +190,7 @@ static void __init mpc85xx_ds_setup_arch(void) #endif #ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() > max) { + if (memblock_end_of_DRAM() > max) { ppc_swiotlb_enable = 1; set_pci_dma_ops(&swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 21f61b8c445b..494513682d70 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) Freescale Semicondutor, Inc. 2006-2007. All rights reserved. + * Copyright (C) Freescale Semicondutor, Inc. 2006-2010. All rights reserved. * * Author: Andy Fleming <afleming@freescale.com> * @@ -33,7 +33,7 @@ #include <linux/of_platform.h> #include <linux/of_device.h> #include <linux/phy.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/system.h> #include <asm/atomic.h> @@ -154,6 +154,10 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) * Setup the architecture * */ +#ifdef CONFIG_SMP +extern void __init mpc85xx_smp_init(void); +#endif + static void __init mpc85xx_mds_setup_arch(void) { struct device_node *np; @@ -194,6 +198,10 @@ static void __init mpc85xx_mds_setup_arch(void) } #endif +#ifdef CONFIG_SMP + mpc85xx_smp_init(); +#endif + #ifdef CONFIG_QUICC_ENGINE np = of_find_compatible_node(NULL, NULL, "fsl,qe"); if (!np) { @@ -237,6 +245,8 @@ static void __init mpc85xx_mds_setup_arch(void) } else if (machine_is(mpc8569_mds)) { #define BCSR7_UCC12_GETHnRST (0x1 << 2) #define BCSR8_UEM_MARVELL_RST (0x1 << 1) +#define BCSR_UCC_RGMII (0x1 << 6) +#define BCSR_UCC_RTBI (0x1 << 5) /* * U-Boot mangles interrupt polarity for Marvell PHYs, * so reset built-in and UEM Marvell PHYs, this puts @@ -247,13 +257,75 @@ static void __init mpc85xx_mds_setup_arch(void) setbits8(&bcsr_regs[7], BCSR7_UCC12_GETHnRST); clrbits8(&bcsr_regs[8], BCSR8_UEM_MARVELL_RST); + + for (np = NULL; (np = of_find_compatible_node(np, + "network", + "ucc_geth")) != NULL;) { + const unsigned int *prop; + int ucc_num; + + prop = of_get_property(np, "cell-index", NULL); + if (prop == NULL) + continue; + + ucc_num = *prop - 1; + + prop = of_get_property(np, "phy-connection-type", NULL); + if (prop == NULL) + continue; + + if (strcmp("rtbi", (const char *)prop) == 0) + clrsetbits_8(&bcsr_regs[7 + ucc_num], + BCSR_UCC_RGMII, BCSR_UCC_RTBI); + } + + } else if (machine_is(p1021_mds)) { +#define BCSR11_ENET_MICRST (0x1 << 5) + /* Reset Micrel PHY */ + clrbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); + setbits8(&bcsr_regs[11], BCSR11_ENET_MICRST); } + iounmap(bcsr_regs); } + + if (machine_is(p1021_mds)) { +#define MPC85xx_PMUXCR_OFFSET 0x60 +#define MPC85xx_PMUXCR_QE0 0x00008000 +#define MPC85xx_PMUXCR_QE3 0x00001000 +#define MPC85xx_PMUXCR_QE9 0x00000040 +#define MPC85xx_PMUXCR_QE12 0x00000008 + static __be32 __iomem *pmuxcr; + + np = of_find_node_by_name(NULL, "global-utilities"); + + if (np) { + pmuxcr = of_iomap(np, 0) + MPC85xx_PMUXCR_OFFSET; + + if (!pmuxcr) + printk(KERN_EMERG "Error: Alternate function" + " signal multiplex control register not" + " mapped!\n"); + else + /* P1021 has pins muxed for QE and other functions. To + * enable QE UEC mode, we need to set bit QE0 for UCC1 + * in Eth mode, QE0 and QE3 for UCC5 in Eth mode, QE9 + * and QE12 for QE MII management singals in PMUXCR + * register. + */ + setbits32(pmuxcr, MPC85xx_PMUXCR_QE0 | + MPC85xx_PMUXCR_QE3 | + MPC85xx_PMUXCR_QE9 | + MPC85xx_PMUXCR_QE12); + + of_node_put(np); + } + + } #endif /* CONFIG_QUICC_ENGINE */ #ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() > max) { + if (memblock_end_of_DRAM() > max) { ppc_swiotlb_enable = 1; set_pci_dma_ops(&swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; @@ -302,11 +374,24 @@ static struct of_device_id mpc85xx_ids[] = { { .compatible = "gianfar", }, { .compatible = "fsl,rapidio-delta", }, { .compatible = "fsl,mpc8548-guts", }, + { .compatible = "gpio-leds", }, + {}, +}; + +static struct of_device_id p1021_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .compatible = "simple-bus", }, + { .type = "qe", }, + { .compatible = "fsl,qe", }, + { .compatible = "gianfar", }, {}, }; static int __init mpc85xx_publish_devices(void) { + if (machine_is(mpc8568_mds)) + simple_gpiochip_init("fsl,mpc8568mds-bcsr-gpio"); if (machine_is(mpc8569_mds)) simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); @@ -315,11 +400,22 @@ static int __init mpc85xx_publish_devices(void) return 0; } + +static int __init p1021_publish_devices(void) +{ + /* Publish the QE devices */ + of_platform_bus_probe(NULL, p1021_ids, NULL); + + return 0; +} + machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); +machine_device_initcall(p1021_mds, p1021_publish_devices); machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); +machine_arch_initcall(p1021_mds, swiotlb_setup_bus_notifier); static void __init mpc85xx_mds_pic_init(void) { @@ -338,7 +434,8 @@ static void __init mpc85xx_mds_pic_init(void) } mpic = mpic_alloc(np, r.start, - MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, + MPIC_PRIMARY | 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); @@ -352,7 +449,11 @@ static void __init mpc85xx_mds_pic_init(void) if (!np) return; } - qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); + if (machine_is(p1021_mds)) + qe_ic_init(np, 0, qe_ic_cascade_low_mpic, + qe_ic_cascade_high_mpic); + else + qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL); of_node_put(np); #endif /* CONFIG_QUICC_ENGINE */ } @@ -398,3 +499,26 @@ define_machine(mpc8569_mds) { .pcibios_fixup_bus = fsl_pcibios_fixup_bus, #endif }; + +static int __init p1021_mds_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "fsl,P1021MDS"); + +} + +define_machine(p1021_mds) { + .name = "P1021 MDS", + .probe = p1021_mds_probe, + .setup_arch = mpc85xx_mds_setup_arch, + .init_IRQ = mpc85xx_mds_pic_init, + .get_irq = mpic_get_irq, + .restart = fsl_rstcr_restart, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif +}; + diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 04160a4cc699..a15f582300d8 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -46,6 +46,7 @@ smp_85xx_kick_cpu(int nr) __iomem u32 *bptr_vaddr; struct device_node *np; int n = 0; + int ioremappable; WARN_ON (nr < 0 || nr >= NR_CPUS); @@ -59,21 +60,37 @@ smp_85xx_kick_cpu(int nr) return; } + /* + * A secondary core could be in a spinloop in the bootpage + * (0xfffff000), somewhere in highmem, or somewhere in lowmem. + * The bootpage and highmem can be accessed via ioremap(), but + * we need to directly access the spinloop if its in lowmem. + */ + ioremappable = *cpu_rel_addr > virt_to_phys(high_memory); + /* Map the spin table */ - bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); + if (ioremappable) + bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); + else + bptr_vaddr = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); + if (!ioremappable) + flush_dcache_range((ulong)bptr_vaddr, + (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); + /* Wait a bit for the CPU to ack. */ while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) mdelay(1); local_irq_restore(flags); - iounmap(bptr_vaddr); + if (ioremappable) + iounmap(bptr_vaddr); pr_debug("waited %d msecs for CPU #%d.\n", n, nr); } diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c index e5da5f62b24a..d48527ffc425 100644 --- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c +++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c @@ -50,7 +50,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = { #define socrates_fpga_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) -static DEFINE_SPINLOCK(socrates_fpga_pic_lock); +static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock); static void __iomem *socrates_fpga_pic_iobase; static struct irq_host *socrates_fpga_pic_irq_host; @@ -80,9 +80,9 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq) if (i == 3) return NO_IRQ; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i)); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) { if (cause >> (i + 16)) break; @@ -116,12 +116,12 @@ static void socrates_fpga_pic_ack(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask |= (1 << (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_mask(unsigned int virq) @@ -134,12 +134,12 @@ static void socrates_fpga_pic_mask(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask &= ~(1 << hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_mask_ack(unsigned int virq) @@ -152,13 +152,13 @@ static void socrates_fpga_pic_mask_ack(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask &= ~(1 << hwirq); mask |= (1 << (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_unmask(unsigned int virq) @@ -171,12 +171,12 @@ static void socrates_fpga_pic_unmask(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask |= (1 << hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); } static void socrates_fpga_pic_eoi(unsigned int virq) @@ -189,12 +189,12 @@ static void socrates_fpga_pic_eoi(unsigned int virq) hwirq = socrates_fpga_irq_to_hw(virq); irq_line = fpga_irqs[hwirq].irq_line; - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line)) & SOCRATES_FPGA_IRQ_MASK; mask |= (1 << (hwirq + 16)); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); } static int socrates_fpga_pic_set_type(unsigned int virq, @@ -220,19 +220,19 @@ static int socrates_fpga_pic_set_type(unsigned int virq, default: return -EINVAL; } - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG); if (polarity) mask |= (1 << hwirq); else mask &= ~(1 << hwirq); socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); return 0; } static struct irq_chip socrates_fpga_pic_chip = { - .name = " FPGA-PIC ", + .name = "FPGA-PIC", .ack = socrates_fpga_pic_ack, .mask = socrates_fpga_pic_mask, .mask_ack = socrates_fpga_pic_mask_ack, @@ -314,14 +314,14 @@ void socrates_fpga_pic_init(struct device_node *pic) socrates_fpga_pic_iobase = of_iomap(pic, 0); - spin_lock_irqsave(&socrates_fpga_pic_lock, flags); + raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0), SOCRATES_FPGA_IRQ_MASK << 16); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1), SOCRATES_FPGA_IRQ_MASK << 16); socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2), SOCRATES_FPGA_IRQ_MASK << 16); - spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); + raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags); pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n"); } diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index f559918f3c6f..bc33d1859ae7 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c @@ -134,7 +134,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); - seq_printf(m, "Vendor\t\t: RPC Electronics STx \n"); + seq_printf(m, "Vendor\t\t: RPC Electronics STx\n"); seq_printf(m, "PVR\t\t: 0x%x\n", pvid); seq_printf(m, "SVR\t\t: 0x%x\n", svid); diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index 1b426050a2f9..0125604d096e 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -80,8 +80,8 @@ static void xes_mpc85xx_configure_l2(void __iomem *l2_base) printk(KERN_INFO "xes_mpc85xx: Enabling L2 as cache\n"); ctl = MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2I; - if (machine_is_compatible("MPC8540") || - machine_is_compatible("MPC8560")) + if (of_machine_is_compatible("MPC8540") || + of_machine_is_compatible("MPC8560")) /* * Assume L2 SRAM is used fully for cache, so set * L2BLKSZ (bits 4:5) to match L2SIZ (bits 2:3). diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 2bbfd530d6d8..a0b5638c5dc8 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -13,7 +13,7 @@ config MPC8641_HPCN bool "Freescale MPC8641 HPCN" select PPC_I8259 select DEFAULT_UIMAGE - select FSL_ULI1575 + select FSL_ULI1575 if PCI select HAS_RAPIDIO select SWIOTLB help @@ -28,37 +28,37 @@ config SBC8641D config MPC8610_HPCD bool "Freescale MPC8610 HPCD" select DEFAULT_UIMAGE - select FSL_ULI1575 + select FSL_ULI1575 if PCI help This option enables support for the MPC8610 HPCD board. config GEF_PPC9A - bool "GE Fanuc PPC9A" + bool "GE PPC9A" select DEFAULT_UIMAGE select MMIO_NVRAM select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help - This option enables support for GE Fanuc's PPC9A. + This option enables support for the GE PPC9A. config GEF_SBC310 - bool "GE Fanuc SBC310" + bool "GE SBC310" select DEFAULT_UIMAGE select MMIO_NVRAM select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help - This option enables support for GE Fanuc's SBC310. + This option enables support for the GE SBC310. config GEF_SBC610 - bool "GE Fanuc SBC610" + bool "GE SBC610" select DEFAULT_UIMAGE select MMIO_NVRAM select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select HAS_RAPIDIO help - This option enables support for GE Fanuc's SBC610. + This option enables support for the GE SBC610. endif diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c index b2ea8875adba..b8cb08dbd89c 100644 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/arch/powerpc/platforms/86xx/gef_gpio.c @@ -1,9 +1,9 @@ /* - * Driver for GE Fanuc's FPGA based GPIO pins + * Driver for GE FPGA based GPIO * - * Author: Martyn Welch <martyn.welch@gefanuc.com> + * Author: Martyn Welch <martyn.welch@ge.com> * - * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -26,6 +26,7 @@ #include <linux/of_platform.h> #include <linux/of_gpio.h> #include <linux/gpio.h> +#include <linux/slab.h> #define GEF_GPIO_DIRECT 0x00 #define GEF_GPIO_IN 0x04 @@ -164,6 +165,6 @@ static int __init gef_gpio_init(void) }; arch_initcall(gef_gpio_init); -MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver"); -MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com"); +MODULE_DESCRIPTION("GE I/O FPGA GPIO driver"); +MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com"); MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c index 0110a8736d33..6df9e2561c06 100644 --- a/arch/powerpc/platforms/86xx/gef_pic.c +++ b/arch/powerpc/platforms/86xx/gef_pic.c @@ -1,9 +1,9 @@ /* - * Interrupt handling for GE Fanuc's FPGA based PIC + * Interrupt handling for GE FPGA based PIC * - * Author: Martyn Welch <martyn.welch@gefanuc.com> + * Author: Martyn Welch <martyn.welch@ge.com> * - * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -49,7 +49,7 @@ #define gef_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) -static DEFINE_SPINLOCK(gef_pic_lock); +static DEFINE_RAW_SPINLOCK(gef_pic_lock); static void __iomem *gef_pic_irq_reg_base; static struct irq_host *gef_pic_irq_host; @@ -118,11 +118,11 @@ static void gef_pic_mask(unsigned int virq) hwirq = gef_irq_to_hw(virq); - spin_lock_irqsave(&gef_pic_lock, flags); + raw_spin_lock_irqsave(&gef_pic_lock, flags); mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); mask &= ~(1 << hwirq); out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - spin_unlock_irqrestore(&gef_pic_lock, flags); + raw_spin_unlock_irqrestore(&gef_pic_lock, flags); } static void gef_pic_mask_ack(unsigned int virq) @@ -141,11 +141,11 @@ static void gef_pic_unmask(unsigned int virq) hwirq = gef_irq_to_hw(virq); - spin_lock_irqsave(&gef_pic_lock, flags); + raw_spin_lock_irqsave(&gef_pic_lock, flags); mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0)); mask |= (1 << hwirq); out_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0), mask); - spin_unlock_irqrestore(&gef_pic_lock, flags); + raw_spin_unlock_irqrestore(&gef_pic_lock, flags); } static struct irq_chip gef_pic_chip = { @@ -199,7 +199,7 @@ void __init gef_pic_init(struct device_node *np) /* Map the devices registers into memory */ gef_pic_irq_reg_base = of_iomap(np, 0); - spin_lock_irqsave(&gef_pic_lock, flags); + raw_spin_lock_irqsave(&gef_pic_lock, flags); /* Initialise everything as masked. */ out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_INTR_MASK, 0); @@ -208,7 +208,7 @@ void __init gef_pic_init(struct device_node *np) out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU0_MCP_MASK, 0); out_be32(gef_pic_irq_reg_base + GEF_PIC_CPU1_MCP_MASK, 0); - spin_unlock_irqrestore(&gef_pic_lock, flags); + raw_spin_unlock_irqrestore(&gef_pic_lock, flags); /* Map controller */ gef_pic_cascade_irq = irq_of_parse_and_map(np, 0); diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index a792e5d85813..60ce07e39100 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c @@ -1,9 +1,9 @@ /* - * GE Fanuc PPC9A board support + * GE PPC9A board support * - * Author: Martyn Welch <martyn.welch@gefanuc.com> + * Author: Martyn Welch <martyn.welch@ge.com> * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -82,7 +82,7 @@ static void __init gef_ppc9a_setup_arch(void) } #endif - printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n"); + printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); @@ -151,7 +151,7 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m) { uint svid = mfspr(SPRN_SVR); - seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); + seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n"); seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(), ('A' + gef_ppc9a_get_board_rev())); @@ -235,7 +235,7 @@ static int __init declare_of_platform_devices(void) machine_device_initcall(gef_ppc9a, declare_of_platform_devices); define_machine(gef_ppc9a) { - .name = "GE Fanuc PPC9A", + .name = "GE PPC9A", .probe = gef_ppc9a_probe, .setup_arch = gef_ppc9a_setup_arch, .init_IRQ = gef_ppc9a_init_irq, diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 6a1a613836c2..3ecee25bf3ed 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -1,9 +1,9 @@ /* - * GE Fanuc SBC310 board support + * GE SBC310 board support * - * Author: Martyn Welch <martyn.welch@gefanuc.com> + * Author: Martyn Welch <martyn.welch@ge.com> * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -82,7 +82,7 @@ static void __init gef_sbc310_setup_arch(void) } #endif - printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n"); + printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); @@ -142,7 +142,7 @@ static void gef_sbc310_show_cpuinfo(struct seq_file *m) { uint svid = mfspr(SPRN_SVR); - seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); + seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n"); seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id()); seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(), @@ -223,7 +223,7 @@ static int __init declare_of_platform_devices(void) machine_device_initcall(gef_sbc310, declare_of_platform_devices); define_machine(gef_sbc310) { - .name = "GE Fanuc SBC310", + .name = "GE SBC310", .probe = gef_sbc310_probe, .setup_arch = gef_sbc310_setup_arch, .init_IRQ = gef_sbc310_init_irq, diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index e10688a0fc4e..5090d608d9ee 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -1,9 +1,9 @@ /* - * GE Fanuc SBC610 board support + * GE SBC610 board support * - * Author: Martyn Welch <martyn.welch@gefanuc.com> + * Author: Martyn Welch <martyn.welch@ge.com> * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -82,7 +82,7 @@ static void __init gef_sbc610_setup_arch(void) } #endif - printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC610 6U VPX SBC\n"); + printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); @@ -133,7 +133,7 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m) { uint svid = mfspr(SPRN_SVR); - seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); + seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n"); seq_printf(m, "Revision\t: %u%c\n", gef_sbc610_get_pcb_rev(), ('A' + gef_sbc610_get_board_rev() - 1)); @@ -212,7 +212,7 @@ static int __init declare_of_platform_devices(void) machine_device_initcall(gef_sbc610, declare_of_platform_devices); define_machine(gef_sbc610) { - .name = "GE Fanuc SBC610", + .name = "GE SBC610", .probe = gef_sbc610_probe, .setup_arch = gef_sbc610_setup_arch, .init_IRQ = gef_sbc610_init_irq, diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 5abe137f6309..018cc67be426 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -83,7 +83,8 @@ static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "fsl,mpc8610-immr", }, { .compatible = "fsl,mpc8610-guts", }, { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, + /* So that the DMA channel nodes can be probed individually: */ + { .compatible = "fsl,eloplus-dma", }, {} }; diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 2aa69a69bcc8..b11c3535f350 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -19,7 +19,7 @@ #include <linux/delay.h> #include <linux/seq_file.h> #include <linux/of_platform.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/system.h> #include <asm/time.h> @@ -103,7 +103,7 @@ mpc86xx_hpcn_setup_arch(void) #endif #ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() > max) { + if (memblock_end_of_DRAM() > max) { ppc_swiotlb_enable = 1; set_pci_dma_ops(&swiotlb_dma_ops); ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c index 242954c4293f..60168c1f98fe 100644 --- a/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -11,7 +11,6 @@ */ #include <linux/kernel.h> -#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/time.h> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index fa0f690d3867..d361f8119b1e 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -43,7 +43,7 @@ config 40x select PPC_PCI_CHOICE config 44x - bool "AMCC 44x" + bool "AMCC 44x, 46x or 47x" select PPC_DCR_NATIVE select PPC_UDBG_16550 select 4xx_SOC @@ -144,6 +144,16 @@ config FSL_EMB_PERFMON and some e300 cores (c3 and c4). Select this only if your core supports the Embedded Performance Monitor APU +config FSL_EMB_PERF_EVENT + bool + depends on FSL_EMB_PERFMON && PERF_EVENTS && !PPC_PERF_CTRS + default y + +config FSL_EMB_PERF_EVENT_E500 + bool + depends on FSL_EMB_PERF_EVENT && E500 + default y + config 4xx bool depends on 40x || 44x @@ -284,7 +294,7 @@ config PPC_PERF_CTRS This enables the powerpc-specific perf_event back-end. config SMP - depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE + depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE || PPC_47x bool "Symmetric multi-processing support" ---help--- This enables support for systems with more than one CPU. If you have @@ -312,6 +322,7 @@ config NR_CPUS config NOT_COHERENT_CACHE bool depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON + default n if PPC_47x default y config CHECK_CACHE_COHERENCY diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 96fe896f6df3..6257e5378615 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -15,6 +15,7 @@ #include <linux/msi.h> #include <linux/of_platform.h> #include <linux/debugfs.h> +#include <linux/slab.h> #include <asm/dcr.h> #include <asm/machdep.h> @@ -344,7 +345,7 @@ static int axon_msi_shutdown(struct of_device *device) static int axon_msi_probe(struct of_device *device, const struct of_device_id *device_id) { - struct device_node *dn = device->node; + struct device_node *dn = device->dev.of_node; struct axon_msic *msic; unsigned int virq; int dcr_base, dcr_len; @@ -446,11 +447,12 @@ static const struct of_device_id axon_msi_device_id[] = { }; static struct of_platform_driver axon_msi_driver = { - .match_table = axon_msi_device_id, .probe = axon_msi_probe, .shutdown = axon_msi_shutdown, - .driver = { - .name = "axon-msi" + .driver = { + .name = "axon-msi", + .owner = THIS_MODULE, + .of_match_table = axon_msi_device_id, }, }; diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c index 35b1ec492715..2516c1cf8467 100644 --- a/arch/powerpc/platforms/cell/beat_htab.c +++ b/arch/powerpc/platforms/cell/beat_htab.c @@ -40,7 +40,7 @@ #define DBG_LOW(fmt...) do { } while (0) #endif -static DEFINE_SPINLOCK(beat_htab_lock); +static DEFINE_RAW_SPINLOCK(beat_htab_lock); static inline unsigned int beat_read_mask(unsigned hpte_group) { @@ -114,18 +114,18 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, if (rflags & _PAGE_NO_CACHE) hpte_r &= ~_PAGE_COHERENT; - spin_lock(&beat_htab_lock); + raw_spin_lock(&beat_htab_lock); lpar_rc = beat_read_mask(hpte_group); if (lpar_rc == 0) { if (!(vflags & HPTE_V_BOLTED)) DBG_LOW(" full\n"); - spin_unlock(&beat_htab_lock); + raw_spin_unlock(&beat_htab_lock); return -1; } lpar_rc = beat_insert_htab_entry(0, hpte_group, lpar_rc << 48, hpte_v, hpte_r, &slot); - spin_unlock(&beat_htab_lock); + raw_spin_unlock(&beat_htab_lock); /* * Since we try and ioremap PHBs we don't own, the pte insert @@ -198,17 +198,17 @@ static long beat_lpar_hpte_updatepp(unsigned long slot, "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", want_v & HPTE_V_AVPN, slot, psize, newpp); - spin_lock(&beat_htab_lock); + raw_spin_lock(&beat_htab_lock); dummy0 = beat_lpar_hpte_getword0(slot); if ((dummy0 & ~0x7FUL) != (want_v & ~0x7FUL)) { DBG_LOW("not found !\n"); - spin_unlock(&beat_htab_lock); + raw_spin_unlock(&beat_htab_lock); return -1; } lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, &dummy0, &dummy1); - spin_unlock(&beat_htab_lock); + raw_spin_unlock(&beat_htab_lock); if (lpar_rc != 0 || dummy0 == 0) { DBG_LOW("not found !\n"); return -1; @@ -262,13 +262,13 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M); va = (vsid << 28) | (ea & 0x0fffffff); - spin_lock(&beat_htab_lock); + raw_spin_lock(&beat_htab_lock); slot = beat_lpar_hpte_find(va, psize); BUG_ON(slot == -1); lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, &dummy0, &dummy1); - spin_unlock(&beat_htab_lock); + raw_spin_unlock(&beat_htab_lock); BUG_ON(lpar_rc != 0); } @@ -285,18 +285,18 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, slot, va, psize, local); want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); - spin_lock_irqsave(&beat_htab_lock, flags); + raw_spin_lock_irqsave(&beat_htab_lock, flags); dummy1 = beat_lpar_hpte_getword0(slot); if ((dummy1 & ~0x7FUL) != (want_v & ~0x7FUL)) { DBG_LOW("not found !\n"); - spin_unlock_irqrestore(&beat_htab_lock, flags); + raw_spin_unlock_irqrestore(&beat_htab_lock, flags); return; } lpar_rc = beat_write_htab_entry(0, slot, 0, 0, HPTE_V_VALID, 0, &dummy1, &dummy2); - spin_unlock_irqrestore(&beat_htab_lock, flags); + raw_spin_unlock_irqrestore(&beat_htab_lock, flags); BUG_ON(lpar_rc != 0); } diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index 36052a9ebcda..682af97321a8 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c @@ -30,7 +30,7 @@ #include "beat_wrapper.h" #define MAX_IRQS NR_IRQS -static DEFINE_SPINLOCK(beatic_irq_mask_lock); +static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock); static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64]; static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64]; @@ -65,30 +65,30 @@ static void beatic_mask_irq(unsigned int irq_plug) { unsigned long flags; - spin_lock_irqsave(&beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64))); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); } static void beatic_unmask_irq(unsigned int irq_plug) { unsigned long flags; - spin_lock_irqsave(&beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); } static void beatic_ack_irq(unsigned int irq_plug) { unsigned long flags; - spin_lock_irqsave(&beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64))); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); } static void beatic_end_irq(unsigned int irq_plug) @@ -103,14 +103,14 @@ static void beatic_end_irq(unsigned int irq_plug) printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug); } - spin_lock_irqsave(&beatic_irq_mask_lock, flags); + raw_spin_lock_irqsave(&beatic_irq_mask_lock, flags); beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64)); beatic_update_irq_mask(irq_plug); - spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); + raw_spin_unlock_irqrestore(&beatic_irq_mask_lock, flags); } static struct irq_chip beatic_pic = { - .name = " CELL-BEAT ", + .name = "CELL-BEAT", .unmask = beatic_unmask_irq, .mask = beatic_mask_irq, .eoi = beatic_end_irq, diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index e6506cd0ff94..bfa2c0cb3d1e 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -118,7 +118,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cur = cbe_freqs[cur_pmode].frequency; #ifdef CONFIG_SMP - cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu)); + cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); #endif cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); diff --git a/arch/powerpc/platforms/cell/cbe_powerbutton.c b/arch/powerpc/platforms/cell/cbe_powerbutton.c index dcddaa5fcb66..f75a4daa4ca2 100644 --- a/arch/powerpc/platforms/cell/cbe_powerbutton.c +++ b/arch/powerpc/platforms/cell/cbe_powerbutton.c @@ -48,7 +48,7 @@ static int __init cbe_powerbutton_init(void) int ret = 0; struct input_dev *dev; - if (!machine_is_compatible("IBM,CBPLUS-1.0")) { + if (!of_machine_is_compatible("IBM,CBPLUS-1.0")) { printk(KERN_ERR "%s: Not a cell blade.\n", __func__); ret = -ENODEV; goto out; diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c index 00eaaa71630f..404d1fc04d59 100644 --- a/arch/powerpc/platforms/cell/celleb_pci.c +++ b/arch/powerpc/platforms/cell/celleb_pci.c @@ -33,6 +33,7 @@ #include <linux/pci_regs.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/slab.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 7fca09f990ba..a881bbee8de0 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -23,6 +23,7 @@ #include <linux/kernel.h> #include <linux/pci.h> #include <linux/string.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/bootmem.h> #include <linux/delay.h> diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 6829cf7e2bda..10eb1a443626 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -88,7 +88,7 @@ static void iic_eoi(unsigned int irq) } static struct irq_chip iic_chip = { - .name = " CELL-IIC ", + .name = "CELL-IIC", .mask = iic_mask, .unmask = iic_unmask, .eoi = iic_eoi, @@ -133,7 +133,7 @@ static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc) static struct irq_chip iic_ioexc_chip = { - .name = " CELL-IOEX", + .name = "CELL-IOEX", .mask = iic_mask, .unmask = iic_unmask, .eoi = iic_ioexc_eoi, diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index ca5bfdfe47f2..3712900471ba 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -28,7 +28,8 @@ #include <linux/notifier.h> #include <linux/of.h> #include <linux/of_platform.h> -#include <linux/lmb.h> +#include <linux/slab.h> +#include <linux/memblock.h> #include <asm/prom.h> #include <asm/iommu.h> @@ -544,7 +545,6 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) { struct iommu_window *window; struct cbe_iommu *iommu; - struct dev_archdata *archdata = &dev->archdata; /* Current implementation uses the first window available in that * node's iommu. We -might- do something smarter later though it may @@ -553,7 +553,7 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) iommu = cell_iommu_for_node(dev_to_node(dev)); if (iommu == NULL || list_empty(&iommu->windows)) { printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", - archdata->of_node ? archdata->of_node->full_name : "?", + dev->of_node ? dev->of_node->full_name : "?", dev_to_node(dev)); return NULL; } @@ -845,10 +845,10 @@ static int __init cell_iommu_init_disabled(void) /* If we found a DMA window, we check if it's big enough to enclose * all of physical memory. If not, we force enable IOMMU */ - if (np && size < lmb_end_of_DRAM()) { + if (np && size < memblock_end_of_DRAM()) { printk(KERN_WARNING "iommu: force-enabled, dma window" " (%ldMB) smaller than total memory (%lldMB)\n", - size >> 20, lmb_end_of_DRAM() >> 20); + size >> 20, memblock_end_of_DRAM() >> 20); return -ENODEV; } @@ -896,7 +896,7 @@ static u64 cell_iommu_get_fixed_address(struct device *dev) const u32 *ranges = NULL; int i, len, best, naddr, nsize, pna, range_size; - np = of_node_get(dev->archdata.of_node); + np = of_node_get(dev->of_node); while (1) { naddr = of_n_addr_cells(np); nsize = of_n_size_cells(np); @@ -1064,9 +1064,9 @@ static int __init cell_iommu_fixed_mapping_init(void) } fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT); - fsize = lmb_phys_mem_size(); + fsize = memblock_phys_mem_size(); - if ((fbase + fsize) <= 0x800000000) + if ((fbase + fsize) <= 0x800000000ul) hbase = 0; /* use the device tree window */ else { /* If we're over 32 GB we need to cheat. We can't map all of @@ -1169,7 +1169,7 @@ static int __init cell_iommu_init(void) * Note: should we make sure we have the IOMMU actually disabled ? */ if (iommu_is_off || - (!iommu_force_on && lmb_end_of_DRAM() <= 0x80000000ull)) + (!iommu_force_on && memblock_end_of_DRAM() <= 0x80000000ull)) if (cell_iommu_init_disabled() == 0) goto bail; diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 5e0a191764fc..1d3c4effea10 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -11,6 +11,7 @@ #include <linux/types.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/smp.h> #include <linux/reboot.h> #include <linux/kexec.h> @@ -255,7 +256,7 @@ static int __init cbe_sysreset_init(void) { struct cbe_pmd_regs __iomem *regs; - sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0"); + sysreset_hack = of_machine_is_compatible("IBM,CBPLUS-1.0"); if (!sysreset_hack) return 0; diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 59305369f6b2..50385db586bd 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -19,7 +19,6 @@ #include <linux/mm.h> #include <linux/stddef.h> #include <linux/unistd.h> -#include <linux/slab.h> #include <linux/user.h> #include <linux/reboot.h> #include <linux/init.h> diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index 5122ec145271..ca7731c0b595 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/of_platform.h> +#include <linux/slab.h> #include <linux/io.h> #include <asm/ppc-pci.h> diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 01244f254a11..5876e888e412 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -168,7 +168,7 @@ static int spider_set_irq_type(unsigned int virq, unsigned int type) } static struct irq_chip spider_pic = { - .name = " SPIDER ", + .name = "SPIDER", .unmask = spider_unmask_irq, .mask = spider_mask_irq, .ack = spider_ack_irq, diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 4c506c1463cd..f465d474ad9b 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -23,7 +23,6 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/ptrace.h> -#include <linux/slab.h> #include <linux/wait.h> #include <linux/mm.h> #include <linux/io.h> @@ -457,7 +456,7 @@ neighbour_spu(int cbe, struct device_node *target, struct device_node *avoid) continue; vic_handles = of_get_property(spu_dn, "vicinity", &lenp); for (i=0; i < (lenp / sizeof(phandle)); i++) { - if (vic_handles[i] == target->linux_phandle) + if (vic_handles[i] == target->phandle) return spu; } } @@ -499,7 +498,7 @@ static void init_affinity_node(int cbe) if (strcmp(name, "spe") == 0) { spu = devnode_spu(cbe, vic_dn); - avoid_ph = last_spu_dn->linux_phandle; + avoid_ph = last_spu_dn->phandle; } else { /* * "mic-tm" and "bif0" nodes do not have @@ -514,7 +513,7 @@ static void init_affinity_node(int cbe) last_spu->has_mem_affinity = 1; spu->has_mem_affinity = 1; } - avoid_ph = vic_dn->linux_phandle; + avoid_ph = vic_dn->phandle; } list_add_tail(&spu->aff_list, &last_spu->aff_list); diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 1410443731eb..121aec353f26 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -22,7 +22,6 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/ptrace.h> -#include <linux/slab.h> #include <linux/wait.h> #include <linux/mm.h> #include <linux/io.h> diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index eea120229cdb..6cf3ec628527 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -24,6 +24,7 @@ #include <linux/file.h> #include <linux/fdtable.h> #include <linux/fs.h> +#include <linux/gfp.h> #include <linux/list.h> #include <linux/module.h> #include <linux/syscalls.h> diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 64a4c2d85f7c..1a40da92154c 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -29,6 +29,7 @@ #include <linux/poll.h> #include <linux/ptrace.h> #include <linux/seq_file.h> +#include <linux/slab.h> #include <asm/io.h> #include <asm/time.h> @@ -1848,8 +1849,7 @@ out: return ret; } -static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, - int datasync) +static int spufs_mfc_fsync(struct file *file, int datasync) { return spufs_mfc_flush(file, NULL); } diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index fc1b1c42b1dc..e5e5f823d687 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -251,7 +251,7 @@ const struct file_operations spufs_context_fops = { .llseek = dcache_dir_lseek, .read = generic_read_dir, .readdir = dcache_readdir, - .fsync = simple_sync_file, + .fsync = noop_fsync, }; EXPORT_SYMBOL_GPL(spufs_context_fops); diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c index 0e9f325c9ff7..a101abf17504 100644 --- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c +++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <asm/spu.h> diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 4678078fede8..0b0466284932 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -27,6 +27,7 @@ #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/slab.h> #include <linux/completion.h> #include <linux/vmalloc.h> #include <linux/smp.h> diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index c23617c6baf3..187a7d32f86a 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -3,6 +3,7 @@ #include <linux/module.h> #include <linux/mount.h> #include <linux/namei.h> +#include <linux/slab.h> #include <asm/uaccess.h> diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c index 8efd4244701c..ba3588f2d8e0 100644 --- a/arch/powerpc/platforms/chrp/nvram.c +++ b/arch/powerpc/platforms/chrp/nvram.c @@ -12,7 +12,6 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/spinlock.h> #include <asm/uaccess.h> #include <asm/prom.h> diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 8f41685d8f42..8553cc49e0d6 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -15,7 +15,6 @@ #include <linux/stddef.h> #include <linux/unistd.h> #include <linux/ptrace.h> -#include <linux/slab.h> #include <linux/user.h> #include <linux/tty.h> #include <linux/major.h> diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c index 57e5b608fa1a..5cdcc7c8d973 100644 --- a/arch/powerpc/platforms/embedded6xx/wii.c +++ b/arch/powerpc/platforms/embedded6xx/wii.c @@ -20,7 +20,7 @@ #include <linux/seq_file.h> #include <linux/kexec.h> #include <linux/of_platform.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <mm/mmu_decl.h> #include <asm/io.h> @@ -65,19 +65,19 @@ static int __init page_aligned(unsigned long x) void __init wii_memory_fixups(void) { - struct lmb_property *p = lmb.memory.region; + struct memblock_property *p = memblock.memory.region; /* * This is part of a workaround to allow the use of two - * discontiguous RAM ranges on the Wii, even if this is + * discontinuous RAM ranges on the Wii, even if this is * currently unsupported on 32-bit PowerPC Linux. * - * We coealesce the two memory ranges of the Wii into a + * We coalesce the two memory ranges of the Wii into a * single range, then create a reservation for the "hole" * between both ranges. */ - BUG_ON(lmb.memory.cnt != 2); + BUG_ON(memblock.memory.cnt != 2); BUG_ON(!page_aligned(p[0].base) || !page_aligned(p[1].base)); p[0].size = _ALIGN_DOWN(p[0].size, PAGE_SIZE); @@ -92,11 +92,11 @@ void __init wii_memory_fixups(void) p[0].size += wii_hole_size + p[1].size; - lmb.memory.cnt = 1; - lmb_analyze(); + memblock.memory.cnt = 1; + memblock_analyze(); /* reserve the hole */ - lmb_reserve(wii_hole_start, wii_hole_size); + memblock_reserve(wii_hole_start, wii_hole_size); /* allow ioremapping the address space in the hole */ __allow_ioremap_reserved = 1; diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c index fd23a1d4b39d..8b0c2082a783 100644 --- a/arch/powerpc/platforms/fsl_uli1575.c +++ b/arch/powerpc/platforms/fsl_uli1575.c @@ -222,6 +222,7 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev) int i; u8 *dummy; struct pci_bus *bus = dev->bus; + struct resource *res; resource_size_t end = 0; for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCES+3; i++) { @@ -230,13 +231,12 @@ static void __devinit quirk_final_uli5249(struct pci_dev *dev) end = pci_resource_end(dev, i); } - for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { - if ((bus->resource[i]) && - (bus->resource[i]->flags & IORESOURCE_MEM)) { - if (bus->resource[i]->end == end) - dummy = ioremap(bus->resource[i]->start, 0x4); + pci_bus_for_each_resource(bus, res, i) { + if (res && res->flags & IORESOURCE_MEM) { + if (res->end == end) + dummy = ioremap(res->start, 0x4); else - dummy = ioremap(bus->resource[i]->end - 3, 0x4); + dummy = ioremap(res->end - 3, 0x4); if (dummy) { in_8(dummy); iounmap(dummy); diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S index 5369653dcf6a..32a56c6dfa72 100644 --- a/arch/powerpc/platforms/iseries/exception.S +++ b/arch/powerpc/platforms/iseries/exception.S @@ -43,17 +43,14 @@ system_reset_iSeries: LOAD_REG_ADDR(r23, alpaca) li r0,ALPACA_SIZE sub r23,r13,r23 - divdu r23,r23,r0 /* r23 has cpu number */ - LOAD_REG_ADDR(r13, paca) - mulli r0,r23,PACA_SIZE - add r13,r13,r0 - mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */ - mfmsr r24 - ori r24,r24,MSR_RI - mtmsrd r24 /* RI on */ - mr r24,r23 + divdu r24,r23,r0 /* r24 has cpu number */ cmpwi 0,r24,0 /* Are we processor 0? */ bne 1f + LOAD_REG_ADDR(r13, boot_paca) + mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */ + mfmsr r23 + ori r23,r23,MSR_RI + mtmsrd r23 /* RI on */ b .__start_initialization_iSeries /* Start up the first processor */ 1: mfspr r4,SPRN_CTRLF li r5,CTRL_RUNLATCH /* Turn off the run light */ @@ -86,6 +83,16 @@ system_reset_iSeries: #endif 2: + /* Load our paca now that it's been allocated */ + LOAD_REG_ADDR(r13, paca) + ld r13,0(r13) + mulli r0,r24,PACA_SIZE + add r13,r13,r0 + mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */ + mfmsr r23 + ori r23,r23,MSR_RI + mtmsrd r23 /* RI on */ + HMT_LOW #ifdef CONFIG_SMP lbz r23,PACAPROCSTART(r13) /* Test if this processor @@ -245,8 +252,8 @@ decrementer_iSeries_masked: li r11,1 ld r12,PACALPPACAPTR(r13) stb r11,LPPACADECRINT(r12) - LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy) - lwz r12,0(r12) + li r12,-1 + clrldi r12,r12,33 /* set DEC to 0x7fffffff */ mtspr SPRN_DEC,r12 /* fall through */ diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 9d53cb481a7c..ce61cea0afb5 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -29,6 +29,7 @@ #include <linux/list.h> #include <linux/pci.h> #include <linux/module.h> +#include <linux/slab.h> #include <asm/iommu.h> #include <asm/vio.h> diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index 86c4b29eea89..ba446bf355a9 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c @@ -273,7 +273,7 @@ static void iseries_end_IRQ(unsigned int irq) } static struct irq_chip iseries_pic = { - .name = "iSeries irq controller", + .name = "iSeries", .startup = iseries_startup_IRQ, .shutdown = iseries_shutdown_IRQ, .unmask = iseries_enable_IRQ, diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 6617915bcb1a..d2c1d497846e 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -33,6 +33,7 @@ #include <linux/dma-mapping.h> #include <linux/bcd.h> #include <linux/rtc.h> +#include <linux/slab.h> #include <asm/time.h> #include <asm/uaccess.h> diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 175aac8ca7e5..ab3962b0d246 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -27,10 +27,12 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/string.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/of.h> +#include <linux/ratelimit.h> #include <asm/types.h> #include <asm/io.h> @@ -443,7 +445,11 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev) } allocate_device_bars(pdev); - iseries_device_information(pdev, bus, *sub_bus); + if (likely(sub_bus)) + iseries_device_information(pdev, bus, *sub_bus); + else + printk(KERN_ERR "PCI: Device node %s has missing or invalid " + "linux,subbus property\n", node->full_name); } /* @@ -583,14 +589,9 @@ static inline struct device_node *xlate_iomm_address( orig_addr = (unsigned long __force)addr; if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) { - static unsigned long last_jiffies; - static int num_printed; + static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10); - if (time_after(jiffies, last_jiffies + 60 * HZ)) { - last_jiffies = jiffies; - num_printed = 0; - } - if (num_printed++ < 10) + if (__ratelimit(&ratelimit)) printk(KERN_ERR "iSeries_%s: invalid access at IO address %p\n", func, addr); diff --git a/arch/powerpc/platforms/iseries/proc.c b/arch/powerpc/platforms/iseries/proc.c index 91f4c6cd4b99..06763682db47 100644 --- a/arch/powerpc/platforms/iseries/proc.c +++ b/arch/powerpc/platforms/iseries/proc.c @@ -85,7 +85,7 @@ static int proc_titantod_show(struct seq_file *m, void *v) seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec); seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks); - seq_printf(m, " titan jiffies = %lu.%04lu \n", titan_jiffies, + seq_printf(m, " titan jiffies = %lu.%04lu\n", titan_jiffies, titan_jiff_rem_usec); seq_printf(m, " tb jiffies = %lu.%04lu\n", tb_jiffies, tb_jiff_rem_usec); diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index a6cd3394feaa..b0863410517f 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -256,7 +256,7 @@ static unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array, mem_blocks = iSeries_process_Condor_mainstore_vpd(mb_array, max_entries); - printk("Mainstore_VPD: numMemoryBlocks = %ld \n", mem_blocks); + printk("Mainstore_VPD: numMemoryBlocks = %ld\n", mem_blocks); for (i = 0; i < mem_blocks; ++i) { printk("Mainstore_VPD: block %3ld logical chunks %016lx - %016lx\n" " abs chunks %016lx - %016lx\n", diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c index 722335e32fd4..6590850045af 100644 --- a/arch/powerpc/platforms/iseries/smp.c +++ b/arch/powerpc/platforms/iseries/smp.c @@ -83,7 +83,7 @@ static void smp_iSeries_message_pass(int target, int msg) static int smp_iSeries_probe(void) { - return cpus_weight(cpu_possible_map); + return cpumask_weight(cpu_possible_mask); } static void smp_iSeries_kick_cpu(int nr) diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c index 2aa8b5631beb..00b6730bc48f 100644 --- a/arch/powerpc/platforms/iseries/vio.c +++ b/arch/powerpc/platforms/iseries/vio.c @@ -22,7 +22,7 @@ */ #include <linux/of.h> #include <linux/init.h> -#include <linux/gfp.h> +#include <linux/slab.h> #include <linux/completion.h> #include <linux/proc_fs.h> #include <linux/module.h> diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 5aea94f30836..b5f05d943a90 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -29,6 +29,7 @@ */ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/errno.h> #include <linux/vmalloc.h> #include <linux/string.h> diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 0636a3df6978..3fff8d979b41 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -21,7 +21,6 @@ #include <linux/stddef.h> #include <linux/unistd.h> #include <linux/ptrace.h> -#include <linux/slab.h> #include <linux/user.h> #include <linux/tty.h> #include <linux/string.h> @@ -42,7 +41,7 @@ #include <linux/smp.h> #include <linux/bitops.h> #include <linux/of_device.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/processor.h> #include <asm/sections.h> diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index be2527a516ea..c16537bc0c6e 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c @@ -213,7 +213,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("current astate is at %d\n",cur_astate); policy->cur = pas_freqs[cur_astate].frequency; - cpumask_copy(policy->cpus, &cpu_online_map); + cpumask_copy(policy->cpus, cpu_online_mask); ppc_proc_freq = policy->cur * 1000ul; @@ -304,8 +304,8 @@ static struct cpufreq_driver pas_cpufreq_driver = { static int __init pas_cpufreq_init(void) { - if (!machine_is_compatible("PA6T-1682M") && - !machine_is_compatible("pasemi,pwrficient")) + if (!of_machine_is_compatible("PA6T-1682M") && + !of_machine_is_compatible("pasemi,pwrficient")) return -ENODEV; return cpufreq_register_driver(&pas_cpufreq_driver); diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c index a6152d922243..09695ae50f91 100644 --- a/arch/powerpc/platforms/pasemi/dma_lib.c +++ b/arch/powerpc/platforms/pasemi/dma_lib.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/of.h> #include <asm/pasemi_dma.h> diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 3bf546797cbb..627ee089e75d 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -24,6 +24,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/errno.h> #include <linux/ioport.h> @@ -219,7 +220,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *np = ofdev->node; + struct device_node *np = ofdev->dev.of_node; struct mii_bus *new_bus; struct gpio_priv *priv; const unsigned int *prop; @@ -300,11 +301,12 @@ MODULE_DEVICE_TABLE(of, gpio_mdio_match); static struct of_platform_driver gpio_mdio_driver = { - .match_table = gpio_mdio_match, .probe = gpio_mdio_probe, .remove = gpio_mdio_remove, - .driver = { - .name = "gpio-mdio-bitbang", + .driver = { + .name = "gpio-mdio-bitbang", + .owner = THIS_MODULE, + .of_match_table = gpio_mdio_match, }, }; diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index 7b1d608ea3c8..1f9fb2c57761 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c @@ -204,7 +204,7 @@ int __init iob_init(struct device_node *dn) pr_debug(" -> %s\n", __func__); /* Allocate a spare page to map all invalid IOTLB pages. */ - tmp = lmb_alloc(IOBMAP_PAGE_SIZE, IOBMAP_PAGE_SIZE); + tmp = memblock_alloc(IOBMAP_PAGE_SIZE, IOBMAP_PAGE_SIZE); if (!tmp) panic("IOBMAP: Cannot allocate spare page!"); /* Empty l1 is marked invalid */ @@ -275,7 +275,7 @@ void __init alloc_iobmap_l2(void) return; #endif /* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */ - iob_l2_base = (u32 *)abs_to_virt(lmb_alloc_base(1UL<<21, 1UL<<21, 0x80000000)); + iob_l2_base = (u32 *)abs_to_virt(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000)); printk(KERN_INFO "IOBMAP L2 allocated at: %p\n", iob_l2_base); } diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 242f8095c2df..f372ec1691a3 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -28,6 +28,7 @@ #include <linux/console.h> #include <linux/pci.h> #include <linux/of_platform.h> +#include <linux/gfp.h> #include <asm/prom.h> #include <asm/system.h> @@ -359,10 +360,10 @@ static int pcmcia_notify(struct notifier_block *nb, unsigned long action, /* We know electra_cf devices will always have of_node set, since * electra_cf is an of_platform driver. */ - if (!parent->archdata.of_node) + if (!parent->of_node) return 0; - if (!of_device_is_compatible(parent->archdata.of_node, "electra-cf")) + if (!of_device_is_compatible(parent->of_node, "electra-cf")) return 0; /* We use the direct ops for localbus */ diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index 9dd789a7370d..84d7fd9bcc69 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c @@ -539,7 +539,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) if (model && (strcmp(model, "iMac,1") == 0 || strcmp(model, "PowerMac1,1") == 0)) { - bootx_printf("iMac,1 detected, shutting down USB \n"); + bootx_printf("iMac,1 detected, shutting down USB\n"); out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */ } } @@ -554,7 +554,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) } else space = bi->totalParamsSize; - bootx_printf("Total space used by parameters & ramdisk: 0x%x \n", space); + bootx_printf("Total space used by parameters & ramdisk: 0x%x\n", space); /* New BootX will have flushed all TLBs and enters kernel with * MMU switched OFF, so this should not be useful anymore. diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 08d94e4cedd3..1e9eba175ff0 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -21,7 +21,6 @@ #include <linux/sched.h> #include <linux/adb.h> #include <linux/pmu.h> -#include <linux/slab.h> #include <linux/cpufreq.h> #include <linux/init.h> #include <linux/sysdev.h> @@ -657,31 +656,31 @@ static int __init pmac_cpufreq_setup(void) cur_freq = (*value) / 1000; /* Check for 7447A based MacRISC3 */ - if (machine_is_compatible("MacRISC3") && + if (of_machine_is_compatible("MacRISC3") && of_get_property(cpunode, "dynamic-power-step", NULL) && PVR_VER(mfspr(SPRN_PVR)) == 0x8003) { pmac_cpufreq_init_7447A(cpunode); /* Check for other MacRISC3 machines */ - } else if (machine_is_compatible("PowerBook3,4") || - machine_is_compatible("PowerBook3,5") || - machine_is_compatible("MacRISC3")) { + } else if (of_machine_is_compatible("PowerBook3,4") || + of_machine_is_compatible("PowerBook3,5") || + of_machine_is_compatible("MacRISC3")) { pmac_cpufreq_init_MacRISC3(cpunode); /* Else check for iBook2 500/600 */ - } else if (machine_is_compatible("PowerBook4,1")) { + } else if (of_machine_is_compatible("PowerBook4,1")) { hi_freq = cur_freq; low_freq = 400000; set_speed_proc = pmu_set_cpu_speed; is_pmu_based = 1; } /* Else check for TiPb 550 */ - else if (machine_is_compatible("PowerBook3,3") && cur_freq == 550000) { + else if (of_machine_is_compatible("PowerBook3,3") && cur_freq == 550000) { hi_freq = cur_freq; low_freq = 500000; set_speed_proc = pmu_set_cpu_speed; is_pmu_based = 1; } /* Else check for TiPb 400 & 500 */ - else if (machine_is_compatible("PowerBook3,2")) { + else if (of_machine_is_compatible("PowerBook3,2")) { /* We only know about the 400 MHz and the 500Mhz model * they both have 300 MHz as low frequency */ diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index 708c75133377..9650c6029c82 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -18,7 +18,6 @@ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/sched.h> -#include <linux/slab.h> #include <linux/cpufreq.h> #include <linux/init.h> #include <linux/completion.h> @@ -363,7 +362,7 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) /* secondary CPUs are tied to the primary one by the * cpufreq core if in the secondary policy we tell it that * it actually must be one policy together with all others. */ - cpumask_copy(policy->cpus, &cpu_online_map); + cpumask_copy(policy->cpus, cpu_online_mask); cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu); return cpufreq_frequency_table_cpuinfo(policy, @@ -398,11 +397,11 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) int rc = -ENODEV; /* Check supported platforms */ - if (machine_is_compatible("PowerMac8,1") || - machine_is_compatible("PowerMac8,2") || - machine_is_compatible("PowerMac9,1")) + if (of_machine_is_compatible("PowerMac8,1") || + of_machine_is_compatible("PowerMac8,2") || + of_machine_is_compatible("PowerMac9,1")) use_volts_smu = 1; - else if (machine_is_compatible("PowerMac11,2")) + else if (of_machine_is_compatible("PowerMac11,2")) use_volts_vdnap = 1; else return -ENODEV; @@ -729,9 +728,9 @@ static int __init g5_cpufreq_init(void) return -ENODEV; } - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) + if (of_machine_is_compatible("PowerMac7,2") || + of_machine_is_compatible("PowerMac7,3") || + of_machine_is_compatible("RackMac3,1")) rc = g5_pm72_cpufreq_init(cpus); #ifdef CONFIG_PMAC_SMU else diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index fbc9bbd74dbd..9e1b9fd75206 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -59,10 +59,10 @@ extern struct device_node *k2_skiplist[2]; * We use a single global lock to protect accesses. Each driver has * to take care of its own locking */ -DEFINE_SPINLOCK(feature_lock); +DEFINE_RAW_SPINLOCK(feature_lock); -#define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); -#define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); +#define LOCK(flags) raw_spin_lock_irqsave(&feature_lock, flags); +#define UNLOCK(flags) raw_spin_unlock_irqrestore(&feature_lock, flags); /* @@ -2426,7 +2426,7 @@ static int __init probe_motherboard(void) } } for(i=0; i<ARRAY_SIZE(pmac_mb_defs); i++) { - if (machine_is_compatible(pmac_mb_defs[i].model_string)) { + if (of_machine_is_compatible(pmac_mb_defs[i].model_string)) { pmac_mb = pmac_mb_defs[i]; goto found; } diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 345e2da56767..06a137c5b8bb 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -43,6 +43,7 @@ #include <linux/timer.h> #include <linux/mutex.h> #include <linux/i2c.h> +#include <linux/slab.h> #include <asm/keylargo.h> #include <asm/uninorth.h> #include <asm/io.h> @@ -591,7 +592,7 @@ static void __init kw_i2c_probe(void) /* Probe keywest-i2c busses */ for_each_compatible_node(np, "i2c","keywest-i2c") { struct pmac_i2c_host_kw *host; - int multibus, chans, i; + int multibus; /* Found one, init a host structure */ host = kw_i2c_host_init(np); @@ -613,6 +614,8 @@ static void __init kw_i2c_probe(void) * parent type */ if (multibus) { + int chans, i; + parent = of_get_parent(np); if (parent == NULL) continue; @@ -1257,8 +1260,7 @@ static void pmac_i2c_do_end(struct pmf_function *func, void *instdata) if (inst == NULL) return; pmac_i2c_close(inst->bus); - if (inst) - kfree(inst); + kfree(inst); } static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len) diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c index c6f0f9e738e5..b1cdcf94aa8e 100644 --- a/arch/powerpc/platforms/powermac/nvram.c +++ b/arch/powerpc/platforms/powermac/nvram.c @@ -14,7 +14,6 @@ #include <linux/string.h> #include <linux/nvram.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/delay.h> #include <linux/errno.h> #include <linux/adb.h> @@ -80,7 +79,7 @@ static int is_core_99; static int core99_bank = 0; static int nvram_partitions[3]; // XXX Turn that into a sem -static DEFINE_SPINLOCK(nv_lock); +static DEFINE_RAW_SPINLOCK(nv_lock); static int (*core99_write_bank)(int bank, u8* datas); static int (*core99_erase_bank)(int bank); @@ -165,10 +164,10 @@ static unsigned char indirect_nvram_read_byte(int addr) unsigned char val; unsigned long flags; - spin_lock_irqsave(&nv_lock, flags); + raw_spin_lock_irqsave(&nv_lock, flags); out_8(nvram_addr, addr >> 5); val = in_8(&nvram_data[(addr & 0x1f) << 4]); - spin_unlock_irqrestore(&nv_lock, flags); + raw_spin_unlock_irqrestore(&nv_lock, flags); return val; } @@ -177,10 +176,10 @@ static void indirect_nvram_write_byte(int addr, unsigned char val) { unsigned long flags; - spin_lock_irqsave(&nv_lock, flags); + raw_spin_lock_irqsave(&nv_lock, flags); out_8(nvram_addr, addr >> 5); out_8(&nvram_data[(addr & 0x1f) << 4], val); - spin_unlock_irqrestore(&nv_lock, flags); + raw_spin_unlock_irqrestore(&nv_lock, flags); } @@ -481,7 +480,7 @@ static void core99_nvram_sync(void) if (!is_core_99 || !nvram_data || !nvram_image) return; - spin_lock_irqsave(&nv_lock, flags); + raw_spin_lock_irqsave(&nv_lock, flags); if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE, NVRAM_SIZE)) goto bail; @@ -503,7 +502,7 @@ static void core99_nvram_sync(void) if (core99_write_bank(core99_bank, nvram_image)) printk("nvram: Error writing bank %d\n", core99_bank); bail: - spin_unlock_irqrestore(&nv_lock, flags); + raw_spin_unlock_irqrestore(&nv_lock, flags); #ifdef DEBUG mdelay(2000); diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c index db20de512f3e..f5e3cda6660e 100644 --- a/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/arch/powerpc/platforms/powermac/pfunc_base.c @@ -50,13 +50,13 @@ static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask) value = ~value; /* Toggle the GPIO */ - spin_lock_irqsave(&feature_lock, flags); + raw_spin_lock_irqsave(&feature_lock, flags); tmp = readb(addr); tmp = (tmp & ~mask) | (value & mask); DBG("Do write 0x%02x to GPIO %s (%p)\n", tmp, func->node->full_name, addr); writeb(tmp, addr); - spin_unlock_irqrestore(&feature_lock, flags); + raw_spin_unlock_irqrestore(&feature_lock, flags); return 0; } @@ -145,9 +145,9 @@ static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask) struct macio_chip *macio = func->driver_data; unsigned long flags; - spin_lock_irqsave(&feature_lock, flags); + raw_spin_lock_irqsave(&feature_lock, flags); MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask)); - spin_unlock_irqrestore(&feature_lock, flags); + raw_spin_unlock_irqrestore(&feature_lock, flags); return 0; } @@ -168,9 +168,9 @@ static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask) struct macio_chip *macio = func->driver_data; unsigned long flags; - spin_lock_irqsave(&feature_lock, flags); + raw_spin_lock_irqsave(&feature_lock, flags); MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask)); - spin_unlock_irqrestore(&feature_lock, flags); + raw_spin_unlock_irqrestore(&feature_lock, flags); return 0; } @@ -223,12 +223,12 @@ static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift, if (args == NULL || args->count == 0) return -EINVAL; - spin_lock_irqsave(&feature_lock, flags); + raw_spin_lock_irqsave(&feature_lock, flags); tmp = MACIO_IN32(offset); val = args->u[0].v << shift; tmp = (tmp & ~mask) | (val & mask); MACIO_OUT32(offset, tmp); - spin_unlock_irqrestore(&feature_lock, flags); + raw_spin_unlock_irqrestore(&feature_lock, flags); return 0; } @@ -243,12 +243,12 @@ static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift, if (args == NULL || args->count == 0) return -EINVAL; - spin_lock_irqsave(&feature_lock, flags); + raw_spin_lock_irqsave(&feature_lock, flags); tmp = MACIO_IN8(offset); val = args->u[0].v << shift; tmp = (tmp & ~mask) | (val & mask); MACIO_OUT8(offset, tmp); - spin_unlock_irqrestore(&feature_lock, flags); + raw_spin_unlock_irqrestore(&feature_lock, flags); return 0; } @@ -278,12 +278,12 @@ static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask) { unsigned long flags; - spin_lock_irqsave(&feature_lock, flags); + raw_spin_lock_irqsave(&feature_lock, flags); /* This is fairly bogus in darwin, but it should work for our needs * implemeted that way: */ UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask)); - spin_unlock_irqrestore(&feature_lock, flags); + raw_spin_unlock_irqrestore(&feature_lock, flags); return 0; } diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 96d5ce50364e..cec635942657 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -9,6 +9,7 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/spinlock.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/mutex.h> @@ -842,7 +843,7 @@ struct pmf_function *__pmf_find_function(struct device_node *target, list_for_each_entry(func, &dev->functions, link) { if (name && strcmp(name, func->name)) continue; - if (func->phandle && target->node != func->phandle) + if (func->phandle && target->phandle != func->phandle) continue; if ((func->flags & flags) == 0) continue; diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 09e827296276..630a533d0e59 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -57,7 +57,7 @@ static int max_irqs; static int max_real_irqs; static u32 level_mask[4]; -static DEFINE_SPINLOCK(pmac_pic_lock); +static DEFINE_RAW_SPINLOCK(pmac_pic_lock); #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; @@ -85,7 +85,7 @@ static void pmac_mask_and_ack_irq(unsigned int virq) int i = src >> 5; unsigned long flags; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); __clear_bit(src, ppc_cached_irq_mask); if (__test_and_clear_bit(src, ppc_lost_interrupts)) atomic_dec(&ppc_n_lost_interrupts); @@ -97,7 +97,7 @@ static void pmac_mask_and_ack_irq(unsigned int virq) mb(); } while((in_le32(&pmac_irq_hw[i]->enable) & bit) != (ppc_cached_irq_mask[i] & bit)); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void pmac_ack_irq(unsigned int virq) @@ -107,12 +107,12 @@ static void pmac_ack_irq(unsigned int virq) int i = src >> 5; unsigned long flags; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); if (__test_and_clear_bit(src, ppc_lost_interrupts)) atomic_dec(&ppc_n_lost_interrupts); out_le32(&pmac_irq_hw[i]->ack, bit); (void)in_le32(&pmac_irq_hw[i]->ack); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost) @@ -152,12 +152,12 @@ static unsigned int pmac_startup_irq(unsigned int virq) unsigned long bit = 1UL << (src & 0x1f); int i = src >> 5; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); if ((irq_to_desc(virq)->status & IRQ_LEVEL) == 0) out_le32(&pmac_irq_hw[i]->ack, bit); __set_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 0); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); return 0; } @@ -167,10 +167,10 @@ static void pmac_mask_irq(unsigned int virq) unsigned long flags; unsigned int src = irq_map[virq].hwirq; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); __clear_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 1); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void pmac_unmask_irq(unsigned int virq) @@ -178,24 +178,24 @@ static void pmac_unmask_irq(unsigned int virq) unsigned long flags; unsigned int src = irq_map[virq].hwirq; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); __set_bit(src, ppc_cached_irq_mask); __pmac_set_irq_mask(src, 0); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); } static int pmac_retrigger(unsigned int virq) { unsigned long flags; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); __pmac_retrigger(irq_map[virq].hwirq); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); return 1; } static struct irq_chip pmac_pic = { - .name = " PMAC-PIC ", + .name = "PMAC-PIC", .startup = pmac_startup_irq, .mask = pmac_mask_irq, .ack = pmac_ack_irq, @@ -210,7 +210,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) int irq, bits; int rc = IRQ_NONE; - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); 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]; @@ -220,12 +220,12 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id) if (bits == 0) continue; irq += __ilog2(bits); - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); generic_handle_irq(irq); - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); rc = IRQ_HANDLED; } - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); return rc; } @@ -244,7 +244,7 @@ static unsigned int pmac_pic_get_irq(void) return NO_IRQ_IGNORE; /* ignore, already handled */ } #endif /* CONFIG_SMP */ - spin_lock_irqsave(&pmac_pic_lock, flags); + raw_spin_lock_irqsave(&pmac_pic_lock, flags); for (irq = max_real_irqs; (irq -= 32) >= 0; ) { int i = irq >> 5; bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i]; @@ -256,7 +256,7 @@ static unsigned int pmac_pic_get_irq(void) irq += __ilog2(bits); break; } - spin_unlock_irqrestore(&pmac_pic_lock, flags); + raw_spin_unlock_irqrestore(&pmac_pic_lock, flags); if (unlikely(irq < 0)) return NO_IRQ; return irq_linear_revmap(pmac_pic_host, irq); diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 3362e781b6a7..f0bc08f6c1f0 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -33,6 +33,8 @@ extern void pmac_setup_pci_dma(void); extern void pmac_check_ht_link(void); extern void pmac_setup_smp(void); +extern void pmac32_cpu_die(void); +extern void low_cpu_die(void) __attribute__((noreturn)); extern int pmac_nvram_init(void); extern void pmac_pic_init(void); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index c20522656367..9deb274841f1 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -31,7 +31,6 @@ #include <linux/stddef.h> #include <linux/unistd.h> #include <linux/ptrace.h> -#include <linux/slab.h> #include <linux/user.h> #include <linux/tty.h> #include <linux/string.h> @@ -52,7 +51,7 @@ #include <linux/suspend.h> #include <linux/of_device.h> #include <linux/of_platform.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/reg.h> #include <asm/sections.h> @@ -481,7 +480,7 @@ static void __init pmac_init_early(void) #endif /* SMP Init has to be done early as we need to patch up - * cpu_possible_map before interrupt stacks are allocated + * cpu_possible_mask before interrupt stacks are allocated * or kaboom... */ #ifdef CONFIG_SMP @@ -620,7 +619,7 @@ static int __init pmac_probe(void) * driver needs that. We have to allocate it now. We allocate 4k * (1 small page) for now. */ - smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL); + smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL); #endif /* CONFIG_PMAC_SMU */ return 1; @@ -647,7 +646,7 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) /* access per cpu vars from generic smp.c */ DECLARE_PER_CPU(int, cpu_state); -static void pmac_cpu_die(void) +static void pmac64_cpu_die(void) { /* * turn off as much as possible, we'll be @@ -718,8 +717,13 @@ define_machine(powermac) { .pcibios_after_init = pmac_pcibios_after_init, .phys_mem_access_prot = pci_phys_mem_access_prot, #endif -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) - .cpu_die = pmac_cpu_die, +#ifdef CONFIG_HOTPLUG_CPU +#ifdef CONFIG_PPC64 + .cpu_die = pmac64_cpu_die, +#endif +#ifdef CONFIG_PPC32 + .cpu_die = pmac32_cpu_die, +#endif #endif #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) .cpu_die = generic_mach_cpu_die, diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index b40c22d697f0..c95215f4f8b6 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -53,6 +53,8 @@ #include <asm/pmac_low_i2c.h> #include <asm/pmac_pfunc.h> +#include "pmac.h" + #undef DEBUG #ifdef DEBUG @@ -315,7 +317,7 @@ static int __init smp_psurge_probe(void) /* This is necessary because OF doesn't know about the * secondary cpu(s), and thus there aren't nodes in the * device tree for them, and smp_setup_cpu_maps hasn't - * set their bits in cpu_present_map. + * set their bits in cpu_present_mask. */ if (ncpus > NR_CPUS) ncpus = NR_CPUS; @@ -693,9 +695,9 @@ static void __init smp_core99_setup(int ncpus) #ifdef CONFIG_PPC64 /* i2c based HW sync on some G5s */ - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) + if (of_machine_is_compatible("PowerMac7,2") || + of_machine_is_compatible("PowerMac7,3") || + of_machine_is_compatible("RackMac3,1")) smp_core99_setup_i2c_hwsync(ncpus); /* pfunc based HW sync on recent G5s */ @@ -713,7 +715,7 @@ static void __init smp_core99_setup(int ncpus) #else /* CONFIG_PPC64 */ /* GPIO based HW sync on ppc32 Core99 */ - if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) { + if (pmac_tb_freeze == NULL && !of_machine_is_compatible("MacRISC4")) { struct device_node *cpu; const u32 *tbprop = NULL; @@ -750,7 +752,7 @@ static void __init smp_core99_setup(int ncpus) #endif /* 32 bits SMP can't NAP */ - if (!machine_is_compatible("MacRISC4")) + if (!of_machine_is_compatible("MacRISC4")) powersave_nap = 0; } @@ -852,7 +854,7 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr) /* If we didn't start the second CPU, we must take * it off the bus */ - if (machine_is_compatible("MacRISC4") && + if (of_machine_is_compatible("MacRISC4") && num_online_cpus() < 2) g5_phy_disable_cpu1(); #endif /* CONFIG_PPC64 */ @@ -878,10 +880,9 @@ int smp_core99_cpu_disable(void) return 0; } -extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */ static int cpu_dead[NR_CPUS]; -void cpu_die(void) +void pmac32_cpu_die(void) { local_irq_disable(); cpu_dead[smp_processor_id()] = 1; @@ -944,7 +945,7 @@ void __init pmac_setup_smp(void) } #ifdef CONFIG_PPC32 else { - /* We have to set bits in cpu_possible_map here since the + /* We have to set bits in cpu_possible_mask here since the * secondary CPU(s) aren't in the device tree. Various * things won't be initialized for CPUs not in the possible * map, so we really need to fix it up here. diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 1810e4226e56..48211ca134c3 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -317,9 +317,9 @@ void __init pmac_calibrate_decr(void) * calibration. That's better since the VIA itself seems * to be slightly off. --BenH */ - if (!machine_is_compatible("MacRISC2") && - !machine_is_compatible("MacRISC3") && - !machine_is_compatible("MacRISC4")) + if (!of_machine_is_compatible("MacRISC2") && + !of_machine_is_compatible("MacRISC3") && + !of_machine_is_compatible("MacRISC4")) if (via_calibrate_decr()) return; @@ -328,7 +328,7 @@ void __init pmac_calibrate_decr(void) * probably implement calibration based on the KL timer on these * machines anyway... -BenH */ - if (machine_is_compatible("PowerMac3,5")) + if (of_machine_is_compatible("PowerMac3,5")) if (via_calibrate_decr()) return; #endif diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c index 9490157da62e..d83135a9830e 100644 --- a/arch/powerpc/platforms/powermac/udbg_scc.c +++ b/arch/powerpc/platforms/powermac/udbg_scc.c @@ -132,9 +132,9 @@ void udbg_scc_init(int force_scc) scc_inittab[1] = in_8(sccc); out_8(sccc, 12); scc_inittab[3] = in_8(sccc); - } else if (machine_is_compatible("RackMac1,1") - || machine_is_compatible("RackMac1,2") - || machine_is_compatible("MacRISC4")) { + } else if (of_machine_is_compatible("RackMac1,1") + || of_machine_is_compatible("RackMac1,2") + || of_machine_is_compatible("MacRISC4")) { /* Xserves and G5s default to 57600 */ scc_inittab[1] = 0; scc_inittab[3] = 0; diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index bb028f165fb3..b341018326df 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -23,6 +23,7 @@ #include <linux/kernel.h> #include <linux/kthread.h> #include <linux/init.h> +#include <linux/slab.h> #include <linux/reboot.h> #include <asm/firmware.h> diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index 1e8a1e39dfe8..2c0ed87f2024 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c @@ -19,7 +19,7 @@ */ #include <linux/kernel.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <asm/machdep.h> #include <asm/prom.h> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index e81b028a2a48..c2045880e674 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -21,7 +21,8 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/memory_hotplug.h> -#include <linux/lmb.h> +#include <linux/memblock.h> +#include <linux/slab.h> #include <asm/cell-regs.h> #include <asm/firmware.h> @@ -317,8 +318,8 @@ static int __init ps3_mm_add_memory(void) return result; } - lmb_add(start_addr, map.r1.size); - lmb_analyze(); + memblock_add(start_addr, map.r1.size); + memblock_analyze(); result = online_pages(start_pfn, nr_pages); diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c index d6487a9c8019..5b759b669598 100644 --- a/arch/powerpc/platforms/ps3/os-area.c +++ b/arch/powerpc/platforms/ps3/os-area.c @@ -24,8 +24,9 @@ #include <linux/fs.h> #include <linux/syscalls.h> #include <linux/ctype.h> -#include <linux/lmb.h> +#include <linux/memblock.h> #include <linux/of.h> +#include <linux/slab.h> #include <asm/prom.h> @@ -722,7 +723,7 @@ static void os_area_queue_work(void) * flash to a high address in the boot memory region and then puts that RAM * address and the byte count into the repository for retrieval by the guest. * We copy the data we want into a static variable and allow the memory setup - * by the HV to be claimed by the lmb manager. + * by the HV to be claimed by the memblock manager. * * The os area mirror will not be available to a second stage kernel, and * the header verify will fail. In this case, the saved_params values will diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index b3c6a993f9f3..39a472e9e80f 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/slab.h> #include <linux/mmzone.h> #include <linux/io.h> #include <linux/mm.h> diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index e34b305a7a52..23083c397528 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/dma-mapping.h> #include <linux/err.h> +#include <linux/slab.h> #include <asm/udbg.h> #include <asm/lv1call.h> @@ -765,7 +766,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) BUG(); }; - dev->core.archdata.of_node = NULL; + dev->core.of_node = NULL; set_dev_node(&dev->core, 0); pr_debug("%s:%d add %s\n", __func__, __LINE__, dev_name(&dev->core)); diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 0ff5174ae4f5..3dbef309bc8d 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -7,7 +7,7 @@ EXTRA_CFLAGS += -DDEBUG endif obj-y := lpar.o hvCall.o nvram.o reconfig.o \ - setup.o iommu.o ras.o \ + setup.o iommu.o event_sources.o ras.o \ firmware.o power.o dlpar.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_XICS) += xics.o diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c index a277f2e28dbc..f4803868642c 100644 --- a/arch/powerpc/platforms/pseries/cmm.c +++ b/arch/powerpc/platforms/pseries/cmm.c @@ -24,6 +24,7 @@ #include <linux/delay.h> #include <linux/errno.h> #include <linux/fs.h> +#include <linux/gfp.h> #include <linux/init.h> #include <linux/kthread.h> #include <linux/module.h> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 37bce52526da..d71e58584086 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -16,6 +16,7 @@ #include <linux/proc_fs.h> #include <linux/spinlock.h> #include <linux/cpu.h> +#include <linux/slab.h> #include "offline_states.h" #include <asm/prom.h> @@ -78,13 +79,12 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) * prepend this to the full_name. */ name = (char *)ccwa + ccwa->name_offset; - dn->full_name = kmalloc(strlen(name) + 2, GFP_KERNEL); + dn->full_name = kasprintf(GFP_KERNEL, "/%s", name); if (!dn->full_name) { kfree(dn); return NULL; } - sprintf(dn->full_name, "/%s", name); return dn; } @@ -409,15 +409,13 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) * directory of the device tree. CPUs actually live in the * cpus directory so we need to fixup the full_name. */ - cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1, - GFP_KERNEL); + cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name); if (!cpu_name) { dlpar_free_cc_nodes(dn); rc = -ENOMEM; goto out; } - sprintf(cpu_name, "/cpus%s", dn->full_name); kfree(dn->full_name); dn->full_name = cpu_name; @@ -432,6 +430,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count) if (rc) { dlpar_release_drc(drc_index); dlpar_free_cc_nodes(dn); + goto out; } rc = dlpar_online_cpu(dn); diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index c5f3116b6ca5..a00addb55945 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -21,6 +21,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/debugfs.h> #include <asm/smp.h> #include <asm/system.h> diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index ccd8dd03b8c9..34b7dc12e731 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -100,7 +100,7 @@ int eeh_subsystem_enabled; EXPORT_SYMBOL(eeh_subsystem_enabled); /* Lock to avoid races due to multiple reports of an error */ -static DEFINE_SPINLOCK(confirm_error_lock); +static DEFINE_RAW_SPINLOCK(confirm_error_lock); /* Buffer for reporting slot-error-detail rtas calls. Its here * in BSS, and not dynamically alloced, so that it ends up in @@ -436,7 +436,7 @@ static void __eeh_clear_slot(struct device_node *parent, int mode_flag) void eeh_clear_slot (struct device_node *dn, int mode_flag) { unsigned long flags; - spin_lock_irqsave(&confirm_error_lock, flags); + raw_spin_lock_irqsave(&confirm_error_lock, flags); dn = find_device_pe (dn); @@ -447,7 +447,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag) PCI_DN(dn)->eeh_mode &= ~mode_flag; PCI_DN(dn)->eeh_check_count = 0; __eeh_clear_slot(dn, mode_flag); - spin_unlock_irqrestore(&confirm_error_lock, flags); + raw_spin_unlock_irqrestore(&confirm_error_lock, flags); } /** @@ -491,7 +491,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) pdn->eeh_mode & EEH_MODE_NOCHECK) { ignored_check++; pr_debug("EEH: Ignored check (%x) for %s %s\n", - pdn->eeh_mode, pci_name (dev), dn->full_name); + pdn->eeh_mode, eeh_pci_name(dev), dn->full_name); return 0; } @@ -506,7 +506,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) * in one slot might report errors simultaneously, and we * only want one error recovery routine running. */ - spin_lock_irqsave(&confirm_error_lock, flags); + raw_spin_lock_irqsave(&confirm_error_lock, flags); rc = 1; if (pdn->eeh_mode & EEH_MODE_ISOLATED) { pdn->eeh_check_count ++; @@ -515,7 +515,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) printk (KERN_ERR "EEH: %d reads ignored for recovering device at " "location=%s driver=%s pci addr=%s\n", pdn->eeh_check_count, location, - dev->driver->name, pci_name(dev)); + dev->driver->name, eeh_pci_name(dev)); printk (KERN_ERR "EEH: Might be infinite loop in %s driver\n", dev->driver->name); dump_stack(); @@ -575,7 +575,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) * with other functions on this device, and functions under * bridges. */ eeh_mark_slot (dn, EEH_MODE_ISOLATED); - spin_unlock_irqrestore(&confirm_error_lock, flags); + raw_spin_unlock_irqrestore(&confirm_error_lock, flags); eeh_send_failure_event (dn, dev); @@ -586,7 +586,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) return 1; dn_unlock: - spin_unlock_irqrestore(&confirm_error_lock, flags); + raw_spin_unlock_irqrestore(&confirm_error_lock, flags); return rc; } @@ -749,7 +749,7 @@ static void __rtas_set_slot_reset(struct pci_dn *pdn) /* Determine type of EEH reset required by device, * default hot reset or fundamental reset */ - if (dev->needs_freset) + if (dev && dev->needs_freset) rtas_pci_slot_reset(pdn, 3); else rtas_pci_slot_reset(pdn, 1); @@ -1064,7 +1064,7 @@ void __init eeh_init(void) struct device_node *phb, *np; struct eeh_early_enable_info info; - spin_lock_init(&confirm_error_lock); + raw_spin_lock_init(&confirm_error_lock); spin_lock_init(&slot_errbuf_lock); np = of_find_node_by_path("/rtas"); diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index ce37040af870..30b987b73c20 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c @@ -23,6 +23,7 @@ #include <linux/list.h> #include <linux/pci.h> #include <linux/rbtree.h> +#include <linux/slab.h> #include <linux/spinlock.h> #include <asm/atomic.h> #include <asm/pci-bridge.h> diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index ef8e45448480..b8d70f5d9aa9 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -337,7 +337,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) location = location ? location : "unknown"; printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " "for location=%s pci addr=%s\n", - location, pci_name(event->dev)); + location, eeh_pci_name(event->dev)); return NULL; } @@ -368,7 +368,7 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) pci_str = pci_name (frozen_pdn->pcidev); drv_str = pcid_name (frozen_pdn->pcidev); } else { - pci_str = pci_name (event->dev); + pci_str = eeh_pci_name(event->dev); drv_str = pcid_name (event->dev); } @@ -478,9 +478,9 @@ excess_failures: * due to actual, failed cards. */ printk(KERN_ERR - "EEH: PCI device at location=%s driver=%s pci addr=%s \n" + "EEH: PCI device at location=%s driver=%s pci addr=%s\n" "has failed %d times in the last hour " - "and has been permanently disabled. \n" + "and has been permanently disabled.\n" "Please try reseating this device or replacing it.\n", location, drv_str, pci_str, frozen_pdn->eeh_freeze_count); goto perm_error; @@ -488,7 +488,7 @@ excess_failures: hard_fail: printk(KERN_ERR "EEH: Unable to recover from failure of PCI device " - "at location=%s driver=%s pci addr=%s \n" + "at location=%s driver=%s pci addr=%s\n" "Please try reseating this device or replacing it.\n", location, drv_str, pci_str); diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index ddb80f5d850b..2ec500c130b5 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -22,6 +22,7 @@ #include <linux/list.h> #include <linux/mutex.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/workqueue.h> #include <asm/eeh_event.h> #include <asm/ppc-pci.h> @@ -80,7 +81,7 @@ static int eeh_event_handler(void * dummy) eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", - pci_name(event->dev)); + eeh_pci_name(event->dev)); pdn = handle_eeh_events(event); diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c new file mode 100644 index 000000000000..e889c9d9586a --- /dev/null +++ b/arch/powerpc/platforms/pseries/event_sources.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2001 Dave Engebretsen IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <asm/prom.h> + +#include "pseries.h" + +void request_event_sources_irqs(struct device_node *np, + irq_handler_t handler, + const char *name) +{ + int i, index, count = 0; + struct of_irq oirq; + const u32 *opicprop; + unsigned int opicplen; + unsigned int virqs[16]; + + /* Check for obsolete "open-pic-interrupt" property. If present, then + * map those interrupts using the default interrupt host and default + * trigger + */ + opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); + if (opicprop) { + opicplen /= sizeof(u32); + for (i = 0; i < opicplen; i++) { + if (count > 15) + break; + virqs[count] = irq_create_mapping(NULL, *(opicprop++)); + if (virqs[count] == NO_IRQ) + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", np->full_name); + else + count++; + + } + } + /* Else use normal interrupt tree parsing */ + else { + /* First try to do a proper OF tree parsing */ + for (index = 0; of_irq_map_one(np, index, &oirq) == 0; + index++) { + if (count > 15) + break; + virqs[count] = irq_create_of_mapping(oirq.controller, + oirq.specifier, + oirq.size); + if (virqs[count] == NO_IRQ) + printk(KERN_ERR "Unable to allocate interrupt " + "number for %s\n", np->full_name); + else + count++; + } + } + + /* Now request them */ + for (i = 0; i < count; i++) { + if (request_irq(virqs[i], handler, 0, name, NULL)) { + printk(KERN_ERR "Unable to request interrupt %d for " + "%s\n", virqs[i], np->full_name); + return; + } + } +} + diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6ea4698d9176..8f85f399ab9f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -122,74 +122,38 @@ static void pseries_mach_cpu_die(void) if (!get_lppaca()->shared_proc) get_lppaca()->donate_dedicated_cpu = 1; - printk(KERN_INFO - "cpu %u (hwid %u) ceding for offline with hint %d\n", - cpu, hwcpu, cede_latency_hint); while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { extended_cede_processor(cede_latency_hint); - printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n", - cpu, hwcpu); - printk(KERN_INFO - "Decrementer value = %x Timebase value = %llx\n", - get_dec(), get_tb()); } - printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n", - cpu, hwcpu); - if (!get_lppaca()->shared_proc) get_lppaca()->donate_dedicated_cpu = 0; get_lppaca()->idle = 0; - } - if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { - unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); + if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { + unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); - /* - * NOTE: Calling start_secondary() here for now to - * start new context. - * However, need to do it cleanly by resetting the - * stack pointer. - */ - start_secondary(); + /* + * Call to start_secondary_resume() will not return. + * Kernel stack will be reset and start_secondary() + * will be called to continue the online operation. + */ + start_secondary_resume(); + } + } - } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { + /* Requested state is CPU_STATE_OFFLINE at this point */ + WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE); - set_cpu_current_state(cpu, CPU_STATE_OFFLINE); - unregister_slb_shadow(hard_smp_processor_id(), - __pa(get_slb_shadow())); - rtas_stop_self(); - } + set_cpu_current_state(cpu, CPU_STATE_OFFLINE); + unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); + rtas_stop_self(); /* Should never get here... */ BUG(); for(;;); } -static int qcss_tok; /* query-cpu-stopped-state token */ - -/* Get state of physical CPU. - * Return codes: - * 0 - The processor is in the RTAS stopped state - * 1 - stop-self is in progress - * 2 - The processor is not in the RTAS stopped state - * -1 - Hardware Error - * -2 - Hardware Busy, Try again later. - */ -static int query_cpu_stopped(unsigned int pcpu) -{ - int cpu_status, status; - - status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); - if (status != 0) { - printk(KERN_ERR - "RTAS query-cpu-stopped-state failed: %i\n", status); - return status; - } - - return cpu_status; -} - static int pseries_cpu_disable(void) { int cpu = smp_processor_id(); @@ -199,7 +163,7 @@ static int pseries_cpu_disable(void) /*fix boot_cpuid here*/ if (cpu == boot_cpuid) - boot_cpuid = any_online_cpu(cpu_online_map); + boot_cpuid = cpumask_any(cpu_online_mask); /* FIXME: abstract this to not be platform specific later on */ xics_migrate_irqs_away(); @@ -236,8 +200,9 @@ static void pseries_cpu_die(unsigned int cpu) } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { for (tries = 0; tries < 25; tries++) { - cpu_status = query_cpu_stopped(pcpu); - if (cpu_status == 0 || cpu_status == -1) + cpu_status = smp_query_cpu_stopped(pcpu); + if (cpu_status == QCSS_STOPPED || + cpu_status == QCSS_HARDWARE_ERROR) break; cpu_relax(); } @@ -257,7 +222,7 @@ static void pseries_cpu_die(unsigned int cpu) } /* - * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle + * Update cpu_present_mask and paca(s) for a new cpu node. The wrinkle * here is that a cpu device node may represent up to two logical cpus * in the SMT case. We must honor the assumption in other code that * the logical ids for sibling SMT threads x and y are adjacent, such @@ -266,7 +231,7 @@ static void pseries_cpu_die(unsigned int cpu) static int pseries_add_processor(struct device_node *np) { unsigned int cpu; - cpumask_t candidate_map, tmp = CPU_MASK_NONE; + cpumask_var_t candidate_mask, tmp; int err = -ENOSPC, len, nthreads, i; const u32 *intserv; @@ -274,48 +239,53 @@ static int pseries_add_processor(struct device_node *np) if (!intserv) return 0; + zalloc_cpumask_var(&candidate_mask, GFP_KERNEL); + zalloc_cpumask_var(&tmp, GFP_KERNEL); + nthreads = len / sizeof(u32); for (i = 0; i < nthreads; i++) - cpu_set(i, tmp); + cpumask_set_cpu(i, tmp); cpu_maps_update_begin(); - BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); + BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask)); /* Get a bitmap of unoccupied slots. */ - cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); - if (cpus_empty(candidate_map)) { + cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask); + if (cpumask_empty(candidate_mask)) { /* If we get here, it most likely means that NR_CPUS is * less than the partition's max processors setting. */ printk(KERN_ERR "Cannot add cpu %s; this system configuration" " supports %d logical cpus.\n", np->full_name, - cpus_weight(cpu_possible_map)); + cpumask_weight(cpu_possible_mask)); goto out_unlock; } - while (!cpus_empty(tmp)) - if (cpus_subset(tmp, candidate_map)) + while (!cpumask_empty(tmp)) + if (cpumask_subset(tmp, candidate_mask)) /* Found a range where we can insert the new cpu(s) */ break; else - cpus_shift_left(tmp, tmp, nthreads); + cpumask_shift_left(tmp, tmp, nthreads); - if (cpus_empty(tmp)) { - printk(KERN_ERR "Unable to find space in cpu_present_map for" + if (cpumask_empty(tmp)) { + printk(KERN_ERR "Unable to find space in cpu_present_mask for" " processor %s with %d thread(s)\n", np->name, nthreads); goto out_unlock; } - for_each_cpu_mask(cpu, tmp) { - BUG_ON(cpu_isset(cpu, cpu_present_map)); + for_each_cpu(cpu, tmp) { + BUG_ON(cpumask_test_cpu(cpu, cpu_present_mask)); set_cpu_present(cpu, true); set_hard_smp_processor_id(cpu, *intserv++); } err = 0; out_unlock: cpu_maps_update_done(); + free_cpumask_var(candidate_mask); + free_cpumask_var(tmp); return err; } @@ -346,7 +316,7 @@ static void pseries_remove_processor(struct device_node *np) set_hard_smp_processor_id(cpu, -1); break; } - if (cpu == NR_CPUS) + if (cpu >= nr_cpu_ids) printk(KERN_WARNING "Could not find cpu to remove " "with physical id 0x%x\n", intserv[i]); } @@ -387,24 +357,12 @@ static char cede_parameters[CEDE_LATENCY_PARAM_MAX_LENGTH]; static int parse_cede_parameters(void) { - int call_status; - memset(cede_parameters, 0, CEDE_LATENCY_PARAM_MAX_LENGTH); - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, - NULL, - CEDE_LATENCY_TOKEN, - __pa(cede_parameters), - CEDE_LATENCY_PARAM_MAX_LENGTH); - - if (call_status != 0) - printk(KERN_INFO "CEDE_LATENCY: \ - %s %s Error calling get-system-parameter(0x%x)\n", - __FILE__, __func__, call_status); - else - printk(KERN_INFO "CEDE_LATENCY: \ - get-system-parameter successful.\n"); - - return call_status; + return rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, + NULL, + CEDE_LATENCY_TOKEN, + __pa(cede_parameters), + CEDE_LATENCY_PARAM_MAX_LENGTH); } static int __init pseries_cpu_hotplug_init(void) @@ -412,6 +370,7 @@ static int __init pseries_cpu_hotplug_init(void) struct device_node *np; const char *typep; int cpu; + int qcss_tok; for_each_node_by_name(np, "interrupt-controller") { typep = of_get_property(np, "compatible", NULL); diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 9b21ee68ea50..bc8803664140 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -10,13 +10,14 @@ */ #include <linux/of.h> -#include <linux/lmb.h> +#include <linux/memblock.h> +#include <linux/vmalloc.h> #include <asm/firmware.h> #include <asm/machdep.h> #include <asm/pSeries_reconfig.h> #include <asm/sparsemem.h> -static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) +static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long start, start_pfn; struct zone *zone; @@ -25,7 +26,7 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) start_pfn = base >> PAGE_SHIFT; if (!pfn_valid(start_pfn)) { - lmb_remove(base, lmb_size); + memblock_remove(base, memblock_size); return 0; } @@ -40,20 +41,26 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) * to sysfs "state" file and we can't remove sysfs entries * while writing to it. So we have to defer it to here. */ - ret = __remove_pages(zone, start_pfn, lmb_size >> PAGE_SHIFT); + ret = __remove_pages(zone, start_pfn, memblock_size >> PAGE_SHIFT); if (ret) return ret; /* * Update memory regions for memory remove */ - lmb_remove(base, lmb_size); + memblock_remove(base, memblock_size); /* * Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(base); - ret = remove_section_mapping(start, start + lmb_size); + ret = remove_section_mapping(start, start + memblock_size); + + /* Ensure all vmalloc mappings are flushed in case they also + * hit that section of memory + */ + vm_unmap_aliases(); + return ret; } @@ -73,7 +80,7 @@ static int pseries_remove_memory(struct device_node *np) return 0; /* - * Find the bae address and size of the lmb + * Find the bae address and size of the memblock */ regs = of_get_property(np, "reg", NULL); if (!regs) @@ -82,7 +89,7 @@ static int pseries_remove_memory(struct device_node *np) base = *(unsigned long *)regs; lmb_size = regs[3]; - ret = pseries_remove_lmb(base, lmb_size); + ret = pseries_remove_memblock(base, lmb_size); return ret; } @@ -102,7 +109,7 @@ static int pseries_add_memory(struct device_node *np) return 0; /* - * Find the base and size of the lmb + * Find the base and size of the memblock */ regs = of_get_property(np, "reg", NULL); if (!regs) @@ -114,7 +121,7 @@ static int pseries_add_memory(struct device_node *np) /* * Update memory region to represent the memory add */ - ret = lmb_add(base, lmb_size); + ret = memblock_add(base, lmb_size); return (ret < 0) ? -EINVAL : 0; } @@ -135,10 +142,10 @@ static int pseries_drconf_memory(unsigned long *base, unsigned int action) } if (action == PSERIES_DRCONF_MEM_ADD) { - rc = lmb_add(*base, *lmb_size); + rc = memblock_add(*base, *lmb_size); rc = (rc < 0) ? -EINVAL : 0; } else if (action == PSERIES_DRCONF_MEM_REMOVE) { - rc = pseries_remove_lmb(*base, *lmb_size); + rc = pseries_remove_memblock(*base, *lmb_size); } else { rc = -EINVAL; } diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 383a5d0e9818..48d20573e4de 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -228,3 +228,41 @@ _GLOBAL(plpar_hcall9) mtcrf 0xff,r0 blr /* return r3 = status */ + +/* See plpar_hcall_raw to see why this is needed */ +_GLOBAL(plpar_hcall9_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */ + ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */ + ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */ + + HVSC /* invoke the hypervisor */ + + mr r0,r12 + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + std r8, 32(r12) + std r9, 40(r12) + std r10,48(r12) + std r11,56(r12) + std r0, 64(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index 2f58c71b7259..e19ff021e711 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -102,7 +102,7 @@ static const struct file_operations hcall_inst_seq_fops = { #define CPU_NAME_BUF_SIZE 32 -static void probe_hcall_entry(unsigned long opcode, unsigned long *args) +static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long *args) { struct hcall_stats *h; @@ -114,7 +114,7 @@ static void probe_hcall_entry(unsigned long opcode, unsigned long *args) h->purr_start = mfspr(SPRN_PURR); } -static void probe_hcall_exit(unsigned long opcode, unsigned long retval, +static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long retval, unsigned long *retbuf) { struct hcall_stats *h; @@ -124,8 +124,8 @@ static void probe_hcall_exit(unsigned long opcode, unsigned long retval, h = &__get_cpu_var(hcall_stats)[opcode / 4]; h->num_calls++; - h->tb_total = mftb() - h->tb_start; - h->purr_total = mfspr(SPRN_PURR) - h->purr_start; + h->tb_total += mftb() - h->tb_start; + h->purr_total += mfspr(SPRN_PURR) - h->purr_start; put_cpu_var(hcall_stats); } @@ -140,11 +140,11 @@ static int __init hcall_inst_init(void) if (!firmware_has_feature(FW_FEATURE_LPAR)) return 0; - if (register_trace_hcall_entry(probe_hcall_entry)) + if (register_trace_hcall_entry(probe_hcall_entry, NULL)) return -EINVAL; - if (register_trace_hcall_exit(probe_hcall_exit)) { - unregister_trace_hcall_entry(probe_hcall_entry); + if (register_trace_hcall_exit(probe_hcall_exit, NULL)) { + unregister_trace_hcall_entry(probe_hcall_entry, NULL); return -EINVAL; } diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 1a0000a4b6d6..395848e30c52 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -66,7 +66,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, tcep = ((u64 *)tbl->it_base) + index; while (npages--) { - /* can't move this out since we might cross LMB boundary */ + /* can't move this out since we might cross MEMBLOCK boundary */ rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; @@ -468,7 +468,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) pr_debug("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev)); - dn = dev->dev.archdata.of_node; + dn = dev->dev.of_node; /* If we're the direct child of a root bus, then we need to allocate * an iommu table ourselves. The bus setup code should have setup diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 0707653612ba..cf79b46d8f88 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -367,21 +367,28 @@ static void pSeries_lpar_hptab_clear(void) { unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long hpte_count = size_bytes >> 4; - unsigned long dummy1, dummy2, dword0; + struct { + unsigned long pteh; + unsigned long ptel; + } ptes[4]; long lpar_rc; - int i; + int i, j; - /* TODO: Use bulk call */ - for (i = 0; i < hpte_count; i++) { - /* dont remove HPTEs with VRMA mappings */ - lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG, - &dummy1, &dummy2); - if (lpar_rc == H_NOT_FOUND) { - lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1); - if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK) - != HPTE_V_VRMA_MASK)) - /* Can be hpte for 1TB Seg. So remove it */ - plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); + /* Read in batches of 4, + * invalidate only valid entries not in the VRMA + * hpte_count will be a multiple of 4 + */ + for (i = 0; i < hpte_count; i += 4) { + lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes); + if (lpar_rc != H_SUCCESS) + continue; + for (j = 0; j < 4; j++){ + if ((ptes[j].pteh & HPTE_V_VRMA_MASK) == + HPTE_V_VRMA_MASK) + continue; + if (ptes[j].pteh & HPTE_V_VALID) + plpar_pte_remove_raw(0, i + j, 0, + &(ptes[j].pteh), &(ptes[j].ptel)); } } } diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 42f7e384e6c4..bc3c7f2abd79 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -15,7 +15,6 @@ #include <linux/types.h> #include <linux/errno.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/spinlock.h> #include <asm/uaccess.h> #include <asm/nvram.h> diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h index 22574e0d9d91..75a6f480d931 100644 --- a/arch/powerpc/platforms/pseries/offline_states.h +++ b/arch/powerpc/platforms/pseries/offline_states.h @@ -9,10 +9,31 @@ enum cpu_state_vals { CPU_MAX_OFFLINE_STATES }; +#ifdef CONFIG_HOTPLUG_CPU extern enum cpu_state_vals get_cpu_current_state(int cpu); extern void set_cpu_current_state(int cpu, enum cpu_state_vals state); -extern enum cpu_state_vals get_preferred_offline_state(int cpu); extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state); extern void set_default_offline_state(int cpu); +#else +static inline enum cpu_state_vals get_cpu_current_state(int cpu) +{ + return CPU_STATE_ONLINE; +} + +static inline void set_cpu_current_state(int cpu, enum cpu_state_vals state) +{ +} + +static inline void set_preferred_offline_state(int cpu, enum cpu_state_vals state) +{ +} + +static inline void set_default_offline_state(int cpu) +{ +} +#endif + +extern enum cpu_state_vals get_preferred_offline_state(int cpu); extern int start_secondary(void); +extern void start_secondary_resume(void); #endif diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index b6fa3e4b51b5..4b7a062dee15 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -165,7 +165,7 @@ int remove_phb_dynamic(struct pci_controller *phb) struct resource *res; int rc, i; - pr_debug("PCI: Removing PHB %04x:%02x... \n", + pr_debug("PCI: Removing PHB %04x:%02x...\n", pci_domain_nr(b), b->number); /* We cannot to remove a root bus that has children */ diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c index 15eb6107bcd2..6e7742da0072 100644 --- a/arch/powerpc/platforms/pseries/phyp_dump.c +++ b/arch/powerpc/platforms/pseries/phyp_dump.c @@ -11,6 +11,7 @@ * */ +#include <linux/gfp.h> #include <linux/init.h> #include <linux/kobject.h> #include <linux/mm.h> @@ -150,7 +151,7 @@ static void print_dump_header(const struct phyp_dump_header *ph) printk(KERN_INFO "Max auto time= %d\n", ph->maxtime_to_auto); /*set cpu state and hpte states as well scratch pad area */ - printk(KERN_INFO " CPU AREA \n"); + printk(KERN_INFO " CPU AREA\n"); printk(KERN_INFO "cpu dump_flags =%d\n", ph->cpu_data.dump_flags); printk(KERN_INFO "cpu source_type =%d\n", ph->cpu_data.source_type); printk(KERN_INFO "cpu error_flags =%d\n", ph->cpu_data.error_flags); @@ -161,7 +162,7 @@ static void print_dump_header(const struct phyp_dump_header *ph) printk(KERN_INFO "cpu length_copied =%llx\n", ph->cpu_data.length_copied); - printk(KERN_INFO " HPTE AREA \n"); + printk(KERN_INFO " HPTE AREA\n"); printk(KERN_INFO "HPTE dump_flags =%d\n", ph->hpte_data.dump_flags); printk(KERN_INFO "HPTE source_type =%d\n", ph->hpte_data.source_type); printk(KERN_INFO "HPTE error_flags =%d\n", ph->hpte_data.error_flags); @@ -172,7 +173,7 @@ static void print_dump_header(const struct phyp_dump_header *ph) printk(KERN_INFO "HPTE length_copied =%llx\n", ph->hpte_data.length_copied); - printk(KERN_INFO " SRSD AREA \n"); + printk(KERN_INFO " SRSD AREA\n"); printk(KERN_INFO "SRSD dump_flags =%d\n", ph->kernel_data.dump_flags); printk(KERN_INFO "SRSD source_type =%d\n", ph->kernel_data.source_type); printk(KERN_INFO "SRSD error_flags =%d\n", ph->kernel_data.error_flags); @@ -254,12 +255,12 @@ void invalidate_last_dump(struct phyp_dump_header *ph, unsigned long addr) /* ------------------------------------------------- */ /** - * release_memory_range -- release memory previously lmb_reserved + * release_memory_range -- release memory previously memblock_reserved * @start_pfn: starting physical frame number * @nr_pages: number of pages to free. * * This routine will release memory that had been previously - * lmb_reserved in early boot. The released memory becomes + * memblock_reserved in early boot. The released memory becomes * available for genreal use. */ static void release_memory_range(unsigned long start_pfn, diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 0603c91538ae..d9801117124b 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -4,6 +4,14 @@ #include <asm/hvcall.h> #include <asm/page.h> +/* Get state of physical CPU from query_cpu_stopped */ +int smp_query_cpu_stopped(unsigned int pcpu); +#define QCSS_STOPPED 0 +#define QCSS_STOPPING 1 +#define QCSS_NOT_STOPPED 2 +#define QCSS_HARDWARE_ERROR -1 +#define QCSS_HARDWARE_BUSY -2 + static inline long poll_pending(void) { return plpar_hcall_norets(H_POLL_PENDING); @@ -183,6 +191,24 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, return rc; } +/* + * plpar_pte_read_4_raw can be called in real mode. + * ptes must be 8*sizeof(unsigned long) + */ +static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex, + unsigned long *ptes) + +{ + long rc; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + + rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex); + + memcpy(ptes, retbuf, 8*sizeof(unsigned long)); + + return rc; +} + static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, unsigned long avpn) { @@ -259,12 +285,12 @@ static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr) return plpar_hcall_norets(H_IPI, servernum, mfrr); } -static inline long plpar_xirr(unsigned long *xirr_ret) +static inline long plpar_xirr(unsigned long *xirr_ret, unsigned char cppr) { long rc; unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; - rc = plpar_hcall(H_XIRR, retbuf); + rc = plpar_hcall(H_XIRR, retbuf, cppr); *xirr_ret = retbuf[0]; diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 9e17c0d2a0c8..40c93cad91d2 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -10,6 +10,13 @@ #ifndef _PSERIES_PSERIES_H #define _PSERIES_PSERIES_H +#include <linux/interrupt.h> + +struct device_node; + +extern void request_event_sources_irqs(struct device_node *np, + irq_handler_t handler, const char *name); + extern void __init fw_feature_init(const char *hypertas, unsigned long len); struct pt_regs; diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index d20b96e22c2e..41a3e9a039ed 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -30,7 +30,6 @@ #include <linux/interrupt.h> #include <linux/timex.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/delay.h> #include <linux/irq.h> #include <linux/random.h> @@ -68,63 +67,6 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id); static irqreturn_t ras_error_interrupt(int irq, void *dev_id); -static void request_ras_irqs(struct device_node *np, - irq_handler_t handler, - const char *name) -{ - int i, index, count = 0; - struct of_irq oirq; - const u32 *opicprop; - unsigned int opicplen; - unsigned int virqs[16]; - - /* Check for obsolete "open-pic-interrupt" property. If present, then - * map those interrupts using the default interrupt host and default - * trigger - */ - opicprop = of_get_property(np, "open-pic-interrupt", &opicplen); - if (opicprop) { - opicplen /= sizeof(u32); - for (i = 0; i < opicplen; i++) { - if (count > 15) - break; - virqs[count] = irq_create_mapping(NULL, *(opicprop++)); - if (virqs[count] == NO_IRQ) - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", np->full_name); - else - count++; - - } - } - /* Else use normal interrupt tree parsing */ - else { - /* First try to do a proper OF tree parsing */ - for (index = 0; of_irq_map_one(np, index, &oirq) == 0; - index++) { - if (count > 15) - break; - virqs[count] = irq_create_of_mapping(oirq.controller, - oirq.specifier, - oirq.size); - if (virqs[count] == NO_IRQ) - printk(KERN_ERR "Unable to allocate interrupt " - "number for %s\n", np->full_name); - else - count++; - } - } - - /* Now request them */ - for (i = 0; i < count; i++) { - if (request_irq(virqs[i], handler, 0, name, NULL)) { - printk(KERN_ERR "Unable to request interrupt %d for " - "%s\n", virqs[i], np->full_name); - return; - } - } -} - /* * Initialize handlers for the set of interrupts caused by hardware errors * and power system events. @@ -139,14 +81,15 @@ static int __init init_ras_IRQ(void) /* Internal Errors */ np = of_find_node_by_path("/event-sources/internal-errors"); if (np != NULL) { - request_ras_irqs(np, ras_error_interrupt, "RAS_ERROR"); + request_event_sources_irqs(np, ras_error_interrupt, + "RAS_ERROR"); of_node_put(np); } /* EPOW Events */ np = of_find_node_by_path("/event-sources/epow-events"); if (np != NULL) { - request_ras_irqs(np, ras_epow_interrupt, "RAS_EPOW"); + request_event_sources_irqs(np, ras_epow_interrupt, "RAS_EPOW"); of_node_put(np); } diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index a2305d29bbbd..1a58637bcea5 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -15,6 +15,7 @@ #include <linux/kref.h> #include <linux/notifier.h> #include <linux/proc_fs.h> +#include <linux/slab.h> #include <asm/prom.h> #include <asm/machdep.h> diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 1b45c458f952..80e9e7652a4d 100644 --- a/arch/powerpc/platforms/pseries/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c @@ -26,6 +26,7 @@ #include <linux/proc_fs.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/slab.h> #include <asm/uaccess.h> #include <asm/rtas.h> #include <asm/prom.h> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index ca5f2e10972c..a6d19e3a505e 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -23,7 +23,6 @@ #include <linux/mm.h> #include <linux/stddef.h> #include <linux/unistd.h> -#include <linux/slab.h> #include <linux/user.h> #include <linux/tty.h> #include <linux/major.h> @@ -497,13 +496,14 @@ static int __init pSeries_probe(void) } -DECLARE_PER_CPU(unsigned long, smt_snooze_delay); +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 @@ -518,13 +518,12 @@ static void pseries_dedicated_idle_sleep(void) * has been checked recently. If we should poll for a little * while, do so. */ - if (__get_cpu_var(smt_snooze_delay)) { - start_snooze = get_tb() + - __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec; + if (snooze) { + start_snooze = get_tb() + snooze * tb_ticks_per_usec; local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); - while (get_tb() < start_snooze) { + while ((snooze < 0) || (get_tb() < start_snooze)) { if (need_resched() || cpu_is_offline(cpu)) goto out; ppc64_runlatch_off(); diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index b4886635972c..3b1bf61c45be 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -55,7 +55,29 @@ * The Primary thread of each non-boot processor was started from the OF client * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop. */ -static cpumask_t of_spin_map; +static cpumask_var_t of_spin_mask; + +/* Query where a cpu is now. Return codes #defined in plpar_wrappers.h */ +int smp_query_cpu_stopped(unsigned int pcpu) +{ + int cpu_status, status; + int qcss_tok = rtas_token("query-cpu-stopped-state"); + + if (qcss_tok == RTAS_UNKNOWN_SERVICE) { + printk(KERN_INFO "Firmware doesn't support " + "query-cpu-stopped-state\n"); + return QCSS_HARDWARE_ERROR; + } + + status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); + if (status != 0) { + printk(KERN_ERR + "RTAS query-cpu-stopped-state failed: %i\n", status); + return status; + } + + return cpu_status; +} /** * smp_startup_cpu() - start the given cpu @@ -76,12 +98,18 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) unsigned int pcpu; int start_cpu; - if (cpu_isset(lcpu, of_spin_map)) + if (cpumask_test_cpu(lcpu, of_spin_mask)) /* Already started by OF and sitting in spin loop */ return 1; pcpu = get_hard_smp_processor_id(lcpu); + /* Check to see if the CPU out of FW already for kexec */ + if (smp_query_cpu_stopped(pcpu) == QCSS_NOT_STOPPED){ + cpumask_set_cpu(lcpu, of_spin_mask); + return 1; + } + /* Fixup atomic count: it exited inside IRQ handler. */ task_thread_info(paca[lcpu].__current)->preempt_count = 0; @@ -115,7 +143,7 @@ static void __devinit smp_xics_setup_cpu(int cpu) if (firmware_has_feature(FW_FEATURE_SPLPAR)) vpa_init(cpu); - cpu_clear(cpu, of_spin_map); + cpumask_clear_cpu(cpu, of_spin_mask); set_cpu_current_state(cpu, CPU_STATE_ONLINE); set_default_offline_state(cpu); @@ -144,8 +172,8 @@ static void __devinit smp_pSeries_kick_cpu(int nr) hcpuid = get_hard_smp_processor_id(nr); rc = plpar_hcall_norets(H_PROD, hcpuid); if (rc != H_SUCCESS) - printk(KERN_ERR "Error: Prod to wake up processor %d\ - Ret= %ld\n", nr, rc); + printk(KERN_ERR "Error: Prod to wake up processor %d " + "Ret= %ld\n", nr, rc); } } @@ -186,17 +214,19 @@ static void __init smp_init_pseries(void) pr_debug(" -> smp_init_pSeries()\n"); + alloc_bootmem_cpumask_var(&of_spin_mask); + /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { if (cpu_thread_in_core(i) == 0) - cpu_set(i, of_spin_map); + cpumask_set_cpu(i, of_spin_mask); } } else { - of_spin_map = cpu_present_map; + cpumask_copy(of_spin_mask, cpu_present_mask); } - cpu_clear(boot_cpuid, of_spin_map); + cpumask_clear_cpu(boot_cpuid, of_spin_mask); /* Non-lpar has additional take/give timebase */ if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index d80f193cd871..f19d19468393 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -120,14 +120,14 @@ static inline void direct_qirr_info(int n_cpu, u8 value) /* LPAR low level accessors */ -static inline unsigned int lpar_xirr_info_get(void) +static inline unsigned int lpar_xirr_info_get(unsigned char cppr) { unsigned long lpar_rc; unsigned long return_value; - lpar_rc = plpar_xirr(&return_value); + lpar_rc = plpar_xirr(&return_value, cppr); if (lpar_rc != H_SUCCESS) - panic(" bad return code xirr - rc = %lx \n", lpar_rc); + panic(" bad return code xirr - rc = %lx\n", lpar_rc); return (unsigned int)return_value; } @@ -163,39 +163,43 @@ static inline void lpar_qirr_info(int n_cpu , u8 value) /* Interface to generic irq subsystem */ #ifdef CONFIG_SMP -static int get_irq_server(unsigned int virq, cpumask_t cpumask, +/* + * For the moment we only implement delivery to all cpus or one cpu. + * + * If the requested affinity is cpu_all_mask, we set global affinity. + * If not we set it to the first cpu in the mask, even if multiple cpus + * are set. This is so things like irqbalance (which set core and package + * wide affinities) do the right thing. + */ +static int get_irq_server(unsigned int virq, const struct cpumask *cpumask, unsigned int strict_check) { - int server; - /* For the moment only implement delivery to all cpus or one cpu */ - cpumask_t tmp = CPU_MASK_NONE; if (!distribute_irqs) return default_server; - if (!cpus_equal(cpumask, CPU_MASK_ALL)) { - cpus_and(tmp, cpu_online_map, cpumask); - - server = first_cpu(tmp); + if (!cpumask_equal(cpumask, cpu_all_mask)) { + int server = cpumask_first_and(cpu_online_mask, cpumask); - if (server < NR_CPUS) + if (server < nr_cpu_ids) return get_hard_smp_processor_id(server); if (strict_check) return -1; } - if (cpus_equal(cpu_online_map, cpu_present_map)) + /* + * Workaround issue with some versions of JS20 firmware that + * deliver interrupts to cpus which haven't been started. This + * happens when using the maxcpus= boot option. + */ + if (cpumask_equal(cpu_online_mask, cpu_present_mask)) return default_distrib_server; return default_server; } #else -static int get_irq_server(unsigned int virq, cpumask_t cpumask, - unsigned int strict_check) -{ - return default_server; -} +#define get_irq_server(virq, cpumask, strict_check) (default_server) #endif static void xics_unmask_irq(unsigned int virq) @@ -211,7 +215,7 @@ static void xics_unmask_irq(unsigned int virq) if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) return; - server = get_irq_server(virq, *(irq_to_desc(virq)->affinity), 0); + server = get_irq_server(virq, irq_to_desc(virq)->affinity, 0); call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, DEFAULT_PRIORITY); @@ -335,7 +339,8 @@ static unsigned int xics_get_irq_direct(void) static unsigned int xics_get_irq_lpar(void) { - unsigned int xirr = lpar_xirr_info_get(); + struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); + unsigned int xirr = lpar_xirr_info_get(os_cppr->stack[os_cppr->index]); unsigned int vec = xics_xirr_vector(xirr); unsigned int irq; @@ -401,11 +406,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask) return -1; } - /* - * For the moment only implement delivery to all cpus or one cpu. - * Get current irq_server for the given irq - */ - irq_server = get_irq_server(virq, *cpumask, 1); + irq_server = get_irq_server(virq, cpumask, 1); if (irq_server == -1) { char cpulist[128]; cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); @@ -428,7 +429,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask) } static struct irq_chip xics_pic_direct = { - .name = " XICS ", + .name = "XICS", .startup = xics_startup, .mask = xics_mask_irq, .unmask = xics_unmask_irq, @@ -437,7 +438,7 @@ static struct irq_chip xics_pic_direct = { }; static struct irq_chip xics_pic_lpar = { - .name = " XICS ", + .name = "XICS", .startup = xics_startup, .mask = xics_mask_irq, .unmask = xics_unmask_irq, @@ -514,15 +515,13 @@ static void __init xics_init_host(void) /* * XICS only has a single IPI, so encode the messages per CPU */ -struct xics_ipi_struct { - unsigned long value; - } ____cacheline_aligned; - -static struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; +static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message); static inline void smp_xics_do_message(int cpu, int msg) { - set_bit(msg, &xics_ipi_message[cpu].value); + unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); + + set_bit(msg, tgt); mb(); if (firmware_has_feature(FW_FEATURE_LPAR)) lpar_qirr_info(cpu, IPI_PRIORITY); @@ -548,25 +547,23 @@ void smp_xics_message_pass(int target, int msg) static irqreturn_t xics_ipi_dispatch(int cpu) { + unsigned long *tgt = &per_cpu(xics_ipi_message, cpu); + WARN_ON(cpu_is_offline(cpu)); mb(); /* order mmio clearing qirr */ - while (xics_ipi_message[cpu].value) { - if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, - &xics_ipi_message[cpu].value)) { + while (*tgt) { + if (test_and_clear_bit(PPC_MSG_CALL_FUNCTION, tgt)) { smp_message_recv(PPC_MSG_CALL_FUNCTION); } - if (test_and_clear_bit(PPC_MSG_RESCHEDULE, - &xics_ipi_message[cpu].value)) { + if (test_and_clear_bit(PPC_MSG_RESCHEDULE, tgt)) { smp_message_recv(PPC_MSG_RESCHEDULE); } - if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, - &xics_ipi_message[cpu].value)) { + if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, tgt)) { smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); } #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) - if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, - &xics_ipi_message[cpu].value)) { + if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, tgt)) { smp_message_recv(PPC_MSG_DEBUGGER_BREAK); } #endif @@ -618,7 +615,7 @@ int __init smp_xics_probe(void) { xics_request_ipi(); - return cpus_weight(cpu_possible_map); + return cpumask_weight(cpu_possible_mask); } #endif /* CONFIG_SMP */ @@ -788,9 +785,13 @@ static void xics_set_cpu_priority(unsigned char cppr) { struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); - BUG_ON(os_cppr->index != 0); + /* + * we only really want to set the priority when there's + * just one cppr value on the stack + */ + WARN_ON(os_cppr->index != 0); - os_cppr->stack[os_cppr->index] = cppr; + os_cppr->stack[0] = cppr; if (firmware_has_feature(FW_FEATURE_LPAR)) lpar_cppr_info(cppr); @@ -825,8 +826,14 @@ void xics_setup_cpu(void) void xics_teardown_cpu(void) { + struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); int cpu = smp_processor_id(); + /* + * we have to reset the cppr index to 0 because we're + * not going to return from the IPI + */ + os_cppr->index = 0; xics_set_cpu_priority(0); /* Clear any pending IPI request */ |