aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-09-27 14:57:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-09-27 14:57:54 -0400
commit2dc94310bd94d0906febea7d0f7c188da620c952 (patch)
tree6de4096f1887e2c00966177354b1c378e59bd632 /arch
parentc06015148fa9a3cc452ec7121b8c3f59f4a7d6ac (diff)
parentfb60cf4ab52f3520c2119aa42f7d4ed8e7594eb6 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/tmlind/linux-omap-upstream into devel
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap1/clock.c107
-rw-r--r--arch/arm/mach-omap1/clock.h14
-rw-r--r--arch/arm/mach-omap1/mux.c11
-rw-r--r--arch/arm/mach-omap2/board-apollon.c7
-rw-r--r--arch/arm/mach-omap2/clock.c146
-rw-r--r--arch/arm/mach-omap2/clock.h20
-rw-r--r--arch/arm/mach-omap2/gpmc.c180
-rw-r--r--arch/arm/mach-omap2/irq.c12
-rw-r--r--arch/arm/mach-omap2/mux.c14
-rw-r--r--arch/arm/mach-omap2/prcm.c10
-rw-r--r--arch/arm/plat-omap/clock.c26
-rw-r--r--arch/arm/plat-omap/devices.c20
-rw-r--r--arch/arm/plat-omap/dma.c95
-rw-r--r--arch/arm/plat-omap/dmtimer.c76
-rw-r--r--arch/arm/plat-omap/gpio.c45
-rw-r--r--arch/arm/plat-omap/mcbsp.c9
-rw-r--r--arch/arm/plat-omap/pm.c670
-rw-r--r--arch/arm/plat-omap/sram.c5
-rw-r--r--arch/arm/plat-omap/timer32k.c38
-rw-r--r--arch/frv/Makefile5
-rw-r--r--arch/frv/boot/Makefile3
-rw-r--r--arch/i386/crypto/Makefile3
-rw-r--r--arch/i386/crypto/aes.c3
-rw-r--r--arch/i386/crypto/twofish-i586-asm.S335
-rw-r--r--arch/i386/crypto/twofish.c97
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c39
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c186
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.h48
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c42
-rw-r--r--arch/powerpc/Kconfig14
-rw-r--r--arch/powerpc/Kconfig.debug16
-rw-r--r--arch/powerpc/boot/Makefile7
-rw-r--r--arch/powerpc/boot/dts/mpc8349emds.dts16
-rw-r--r--arch/powerpc/boot/flatdevtree.h46
-rw-r--r--arch/powerpc/boot/main.c250
-rw-r--r--arch/powerpc/boot/of.c (renamed from arch/powerpc/boot/prom.c)144
-rw-r--r--arch/powerpc/boot/ops.h100
-rw-r--r--arch/powerpc/boot/prom.h41
-rw-r--r--arch/powerpc/boot/stdio.c4
-rw-r--r--arch/powerpc/boot/stdio.h8
-rw-r--r--arch/powerpc/boot/types.h23
-rw-r--r--arch/powerpc/configs/maple_defconfig2
-rw-r--r--arch/powerpc/kernel/Makefile4
-rw-r--r--arch/powerpc/kernel/asm-offsets.c17
-rw-r--r--arch/powerpc/kernel/btext.c24
-rw-r--r--arch/powerpc/kernel/cpu_setup_ppc970.S (renamed from arch/powerpc/kernel/cpu_setup_power4.S)103
-rw-r--r--arch/powerpc/kernel/cputable.c21
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/dma_64.c65
-rw-r--r--arch/powerpc/kernel/entry_64.S8
-rw-r--r--arch/powerpc/kernel/head_64.S54
-rw-r--r--arch/powerpc/kernel/ibmebus.c6
-rw-r--r--arch/powerpc/kernel/io.c131
-rw-r--r--arch/powerpc/kernel/irq.c5
-rw-r--r--arch/powerpc/kernel/legacy_serial.c35
-rw-r--r--arch/powerpc/kernel/lparcfg.c30
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c10
-rw-r--r--arch/powerpc/kernel/misc.S159
-rw-r--r--arch/powerpc/kernel/of_device.c24
-rw-r--r--arch/powerpc/kernel/paca.c15
-rw-r--r--arch/powerpc/kernel/pci_32.c39
-rw-r--r--arch/powerpc/kernel/pci_64.c67
-rw-r--r--arch/powerpc/kernel/pci_dn.c13
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c19
-rw-r--r--arch/powerpc/kernel/prom.c44
-rw-r--r--arch/powerpc/kernel/prom_init.c10
-rw-r--r--arch/powerpc/kernel/prom_parse.c90
-rw-r--r--arch/powerpc/kernel/rtas-proc.c25
-rw-r--r--arch/powerpc/kernel/rtas.c47
-rw-r--r--arch/powerpc/kernel/rtas_pci.c28
-rw-r--r--arch/powerpc/kernel/setup-common.c32
-rw-r--r--arch/powerpc/kernel/setup_64.c23
-rw-r--r--arch/powerpc/kernel/sysfs.c9
-rw-r--r--arch/powerpc/kernel/time.c8
-rw-r--r--arch/powerpc/kernel/traps.c25
-rw-r--r--arch/powerpc/kernel/vio.c16
-rw-r--r--arch/powerpc/lib/Makefile1
-rw-r--r--arch/powerpc/lib/e2a.c116
-rw-r--r--arch/powerpc/lib/locks.c27
-rw-r--r--arch/powerpc/mm/numa.c31
-rw-r--r--arch/powerpc/mm/slb.c37
-rw-r--r--arch/powerpc/mm/tlb_64.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c4
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c4
-rw-r--r--arch/powerpc/platforms/83xx/pci.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c4
-rw-r--r--arch/powerpc/platforms/85xx/pci.c4
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c4
-rw-r--r--arch/powerpc/platforms/86xx/pci.c4
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c8
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c25
-rw-r--r--arch/powerpc/platforms/cell/iommu.c22
-rw-r--r--arch/powerpc/platforms/cell/setup.c4
-rw-r--r--arch/powerpc/platforms/cell/smp.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c10
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c18
-rw-r--r--arch/powerpc/platforms/chrp/nvram.c5
-rw-r--r--arch/powerpc/platforms/chrp/pci.c53
-rw-r--r--arch/powerpc/platforms/chrp/setup.c48
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c8
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig8
-rw-r--r--arch/powerpc/platforms/iseries/dt.c45
-rw-r--r--arch/powerpc/platforms/iseries/hvlpconfig.c13
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c19
-rw-r--r--arch/powerpc/platforms/iseries/it_exp_vpd_panel.h51
-rw-r--r--arch/powerpc/platforms/iseries/it_lp_naca.h80
-rw-r--r--arch/powerpc/platforms/iseries/lpardata.c6
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c2
-rw-r--r--arch/powerpc/platforms/iseries/main_store.h126
-rw-r--r--arch/powerpc/platforms/iseries/pci.c289
-rw-r--r--arch/powerpc/platforms/iseries/setup.c1
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c28
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c22
-rw-r--r--arch/powerpc/platforms/maple/pci.c70
-rw-r--r--arch/powerpc/platforms/maple/setup.c27
-rw-r--r--arch/powerpc/platforms/pasemi/Makefile1
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h8
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c198
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c188
-rw-r--r--arch/powerpc/platforms/pasemi/time.c29
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c3
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c23
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c27
-rw-r--r--arch/powerpc/platforms/powermac/feature.c30
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c24
-rw-r--r--arch/powerpc/platforms/powermac/pci.c37
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c2
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_core.c5
-rw-r--r--arch/powerpc/platforms/powermac/setup.c18
-rw-r--r--arch/powerpc/platforms/powermac/smp.c9
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c10
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c96
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c17
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c112
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c4
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c2
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S273
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c129
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c5
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c13
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c46
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c5
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h107
-rw-r--r--arch/powerpc/platforms/pseries/ras.c4
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c42
-rw-r--r--arch/powerpc/platforms/pseries/smp.c12
-rw-r--r--arch/powerpc/platforms/pseries/xics.c44
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c28
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h2
-rw-r--r--arch/powerpc/sysdev/i8259.c2
-rw-r--r--arch/powerpc/sysdev/ipic.c42
-rw-r--r--arch/powerpc/sysdev/mmio_nvram.c4
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c4
-rw-r--r--arch/powerpc/xmon/xmon.c10
-rw-r--r--arch/ppc/Kconfig6
-rw-r--r--arch/ppc/kernel/misc.S88
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c9
-rw-r--r--arch/ppc/kernel/setup.c17
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.h1
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.h18
-rw-r--r--arch/ppc/syslib/m8260_pci_erratum9.c16
-rw-r--r--arch/ppc/xmon/start.c28
-rw-r--r--arch/ppc/xmon/xmon.c28
-rw-r--r--arch/s390/Kconfig17
-rw-r--r--arch/s390/appldata/appldata.h16
-rw-r--r--arch/s390/appldata/appldata_base.c81
-rw-r--r--arch/s390/appldata/appldata_os.c1
-rw-r--r--arch/s390/crypto/aes_s390.c285
-rw-r--r--arch/s390/crypto/crypt_s390.h3
-rw-r--r--arch/s390/crypto/des_s390.c559
-rw-r--r--arch/s390/crypto/sha1_s390.c2
-rw-r--r--arch/s390/crypto/sha256_s390.c2
-rw-r--r--arch/s390/defconfig1
-rw-r--r--arch/s390/hypfs/hypfs.h2
-rw-r--r--arch/s390/hypfs/hypfs_diag.c16
-rw-r--r--arch/s390/hypfs/hypfs_diag.h2
-rw-r--r--arch/s390/hypfs/inode.c12
-rw-r--r--arch/s390/kernel/Makefile3
-rw-r--r--arch/s390/kernel/entry.S12
-rw-r--r--arch/s390/kernel/entry64.S16
-rw-r--r--arch/s390/kernel/head.S69
-rw-r--r--arch/s390/kernel/head31.S48
-rw-r--r--arch/s390/kernel/head64.S59
-rw-r--r--arch/s390/kernel/ipl.c942
-rw-r--r--arch/s390/kernel/kprobes.c657
-rw-r--r--arch/s390/kernel/reipl.S33
-rw-r--r--arch/s390/kernel/reipl64.S34
-rw-r--r--arch/s390/kernel/reipl_diag.c39
-rw-r--r--arch/s390/kernel/s390_ksyms.c6
-rw-r--r--arch/s390/kernel/setup.c272
-rw-r--r--arch/s390/kernel/signal.c40
-rw-r--r--arch/s390/kernel/smp.c10
-rw-r--r--arch/s390/kernel/traps.c31
-rw-r--r--arch/s390/kernel/vmlinux.lds.S3
-rw-r--r--arch/s390/lib/Makefile4
-rw-r--r--arch/s390/lib/uaccess.S211
-rw-r--r--arch/s390/lib/uaccess64.S207
-rw-r--r--arch/s390/lib/uaccess_mvcos.c156
-rw-r--r--arch/s390/lib/uaccess_std.c340
-rw-r--r--arch/s390/mm/cmm.c30
-rw-r--r--arch/s390/mm/fault.c40
-rw-r--r--arch/s390/mm/init.c36
-rw-r--r--arch/sh/kernel/process.c1
-rw-r--r--arch/sparc/kernel/ebus.c7
-rw-r--r--arch/sparc/kernel/ioport.c2
-rw-r--r--arch/sparc64/defconfig25
-rw-r--r--arch/sparc64/kernel/time.c2
-rw-r--r--arch/x86_64/crypto/Makefile3
-rw-r--r--arch/x86_64/crypto/aes.c5
-rw-r--r--arch/x86_64/crypto/twofish-x86_64-asm.S324
-rw-r--r--arch/x86_64/crypto/twofish.c97
216 files changed, 7903 insertions, 4076 deletions
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index f1958e882e86..638490e62d5f 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -20,6 +20,7 @@
20#include <linux/clk.h> 20#include <linux/clk.h>
21 21
22#include <asm/io.h> 22#include <asm/io.h>
23#include <asm/mach-types.h>
23 24
24#include <asm/arch/cpu.h> 25#include <asm/arch/cpu.h>
25#include <asm/arch/usb.h> 26#include <asm/arch/usb.h>
@@ -586,77 +587,53 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
586 *-------------------------------------------------------------------------*/ 587 *-------------------------------------------------------------------------*/
587 588
588#ifdef CONFIG_OMAP_RESET_CLOCKS 589#ifdef CONFIG_OMAP_RESET_CLOCKS
589/*
590 * Resets some clocks that may be left on from bootloader,
591 * but leaves serial clocks on. See also omap_late_clk_reset().
592 */
593static inline void omap1_early_clk_reset(void)
594{
595 //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
596}
597 590
598static int __init omap1_late_clk_reset(void) 591static void __init omap1_clk_disable_unused(struct clk *clk)
599{ 592{
600 /* Turn off all unused clocks */
601 struct clk *p;
602 __u32 regval32; 593 __u32 regval32;
603 594
604 /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ 595 /* Clocks in the DSP domain need api_ck. Just assume bootloader
605 regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); 596 * has not enabled any DSP clocks */
606 omap_writew(regval32, SOFT_REQ_REG); 597 if ((u32)clk->enable_reg == DSP_IDLECT2) {
607 omap_writew(0, SOFT_REQ_REG2); 598 printk(KERN_INFO "Skipping reset check for DSP domain "
608 599 "clock \"%s\"\n", clk->name);
609 list_for_each_entry(p, &clocks, node) { 600 return;
610 if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || 601 }
611 p->enable_reg == 0)
612 continue;
613
614 /* Clocks in the DSP domain need api_ck. Just assume bootloader
615 * has not enabled any DSP clocks */
616 if ((u32)p->enable_reg == DSP_IDLECT2) {
617 printk(KERN_INFO "Skipping reset check for DSP domain "
618 "clock \"%s\"\n", p->name);
619 continue;
620 }
621 602
622 /* Is the clock already disabled? */ 603 /* Is the clock already disabled? */
623 if (p->flags & ENABLE_REG_32BIT) { 604 if (clk->flags & ENABLE_REG_32BIT) {
624 if (p->flags & VIRTUAL_IO_ADDRESS) 605 if (clk->flags & VIRTUAL_IO_ADDRESS)
625 regval32 = __raw_readl(p->enable_reg); 606 regval32 = __raw_readl(clk->enable_reg);
626 else
627 regval32 = omap_readl(p->enable_reg);
628 } else {
629 if (p->flags & VIRTUAL_IO_ADDRESS)
630 regval32 = __raw_readw(p->enable_reg);
631 else 607 else
632 regval32 = omap_readw(p->enable_reg); 608 regval32 = omap_readl(clk->enable_reg);
633 } 609 } else {
634 610 if (clk->flags & VIRTUAL_IO_ADDRESS)
635 if ((regval32 & (1 << p->enable_bit)) == 0) 611 regval32 = __raw_readw(clk->enable_reg);
636 continue; 612 else
613 regval32 = omap_readw(clk->enable_reg);
614 }
637 615
638 /* FIXME: This clock seems to be necessary but no-one 616 if ((regval32 & (1 << clk->enable_bit)) == 0)
639 * has asked for its activation. */ 617 return;
640 if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
641 || p == &ck_dpll1out.clk // FIX: SoSSI, SSR
642 || p == &arm_gpio_ck // FIX: GPIO code for 1510
643 ) {
644 printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
645 p->name);
646 continue;
647 }
648 618
649 printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); 619 /* FIXME: This clock seems to be necessary but no-one
650 p->disable(p); 620 * has asked for its activation. */
651 printk(" done\n"); 621 if (clk == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
622 || clk == &ck_dpll1out.clk // FIX: SoSSI, SSR
623 || clk == &arm_gpio_ck // FIX: GPIO code for 1510
624 ) {
625 printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
626 clk->name);
627 return;
652 } 628 }
653 629
654 return 0; 630 printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
631 clk->disable(clk);
632 printk(" done\n");
655} 633}
656late_initcall(omap1_late_clk_reset);
657 634
658#else 635#else
659#define omap1_early_clk_reset() {} 636#define omap1_clk_disable_unused NULL
660#endif 637#endif
661 638
662static struct clk_functions omap1_clk_functions = { 639static struct clk_functions omap1_clk_functions = {
@@ -664,6 +641,7 @@ static struct clk_functions omap1_clk_functions = {
664 .clk_disable = omap1_clk_disable, 641 .clk_disable = omap1_clk_disable,
665 .clk_round_rate = omap1_clk_round_rate, 642 .clk_round_rate = omap1_clk_round_rate,
666 .clk_set_rate = omap1_clk_set_rate, 643 .clk_set_rate = omap1_clk_set_rate,
644 .clk_disable_unused = omap1_clk_disable_unused,
667}; 645};
668 646
669int __init omap1_clk_init(void) 647int __init omap1_clk_init(void)
@@ -671,8 +649,13 @@ int __init omap1_clk_init(void)
671 struct clk ** clkp; 649 struct clk ** clkp;
672 const struct omap_clock_config *info; 650 const struct omap_clock_config *info;
673 int crystal_type = 0; /* Default 12 MHz */ 651 int crystal_type = 0; /* Default 12 MHz */
652 u32 reg;
653
654 /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
655 reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
656 omap_writew(reg, SOFT_REQ_REG);
657 omap_writew(0, SOFT_REQ_REG2);
674 658
675 omap1_early_clk_reset();
676 clk_init(&omap1_clk_functions); 659 clk_init(&omap1_clk_functions);
677 660
678 /* By default all idlect1 clocks are allowed to idle */ 661 /* By default all idlect1 clocks are allowed to idle */
@@ -772,6 +755,12 @@ int __init omap1_clk_init(void)
772 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); 755 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
773#endif 756#endif
774 757
758 /* Amstrad Delta wants BCLK high when inactive */
759 if (machine_is_ams_delta())
760 omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
761 (1 << SDW_MCLK_INV_BIT),
762 ULPD_CLOCK_CTRL);
763
775 /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ 764 /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
776 /* (on 730, bit 13 must not be cleared) */ 765 /* (on 730, bit 13 must not be cleared) */
777 if (cpu_is_omap730()) 766 if (cpu_is_omap730())
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index b7c68819c4e7..f7df00205c4a 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -89,6 +89,7 @@ struct arm_idlect1_clk {
89#define EN_DSPTIMCK 5 89#define EN_DSPTIMCK 5
90 90
91/* Various register defines for clock controls scattered around OMAP chip */ 91/* Various register defines for clock controls scattered around OMAP chip */
92#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */
92#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ 93#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
93#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ 94#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
94#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ 95#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
@@ -741,6 +742,18 @@ static struct clk i2c_fck = {
741 .disable = &omap1_clk_disable_generic, 742 .disable = &omap1_clk_disable_generic,
742}; 743};
743 744
745static struct clk i2c_ick = {
746 .name = "i2c_ick",
747 .id = 1,
748 .flags = CLOCK_IN_OMAP16XX |
749 VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
750 ALWAYS_ENABLED,
751 .parent = &armper_ck.clk,
752 .recalc = &followparent_recalc,
753 .enable = &omap1_clk_enable_generic,
754 .disable = &omap1_clk_disable_generic,
755};
756
744static struct clk * onchip_clks[] = { 757static struct clk * onchip_clks[] = {
745 /* non-ULPD clocks */ 758 /* non-ULPD clocks */
746 &ck_ref, 759 &ck_ref,
@@ -790,6 +803,7 @@ static struct clk * onchip_clks[] = {
790 /* Virtual clocks */ 803 /* Virtual clocks */
791 &virtual_ck_mpu, 804 &virtual_ck_mpu,
792 &i2c_fck, 805 &i2c_fck,
806 &i2c_ick,
793}; 807};
794 808
795#endif 809#endif
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index fa74ef7af15f..5432335bc493 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -199,6 +199,17 @@ MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
199MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) 199MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
200MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) 200MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
201 201
202/* OMAP-1610 SPI */
203MUX_CFG("U19_1610_SPIF_SCK", 7, 21, 6, 1, 15, 0, 1, 1, 1)
204MUX_CFG("U18_1610_SPIF_DIN", 8, 0, 6, 1, 18, 1, 1, 0, 1)
205MUX_CFG("P20_1610_SPIF_DIN", 6, 27, 4, 1, 7, 1, 1, 0, 1)
206MUX_CFG("W21_1610_SPIF_DOUT", 8, 3, 6, 1, 19, 0, 1, 0, 1)
207MUX_CFG("R18_1610_SPIF_DOUT", 7, 9, 3, 1, 11, 0, 1, 0, 1)
208MUX_CFG("N14_1610_SPIF_CS0", 8, 9, 6, 1, 21, 0, 1, 1, 1)
209MUX_CFG("N15_1610_SPIF_CS1", 7, 18, 6, 1, 14, 0, 1, 1, 1)
210MUX_CFG("T19_1610_SPIF_CS2", 7, 15, 4, 1, 13, 0, 1, 1, 1)
211MUX_CFG("P15_1610_SPIF_CS3", 8, 12, 3, 1, 22, 0, 1, 1, 1)
212
202/* OMAP-1610 Flash */ 213/* OMAP-1610 Flash */
203MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) 214MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
204MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) 215MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 7993b7bae2bd..2db6b732b084 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -166,8 +166,8 @@ static struct omap_uart_config apollon_uart_config __initdata = {
166 166
167static struct omap_mmc_config apollon_mmc_config __initdata = { 167static struct omap_mmc_config apollon_mmc_config __initdata = {
168 .mmc [0] = { 168 .mmc [0] = {
169 .enabled = 0, 169 .enabled = 1,
170 .wire4 = 0, 170 .wire4 = 1,
171 .wp_pin = -1, 171 .wp_pin = -1,
172 .power_pin = -1, 172 .power_pin = -1,
173 .switch_pin = -1, 173 .switch_pin = -1,
@@ -257,6 +257,9 @@ static void __init omap_apollon_init(void)
257 /* REVISIT: where's the correct place */ 257 /* REVISIT: where's the correct place */
258 omap_cfg_reg(W19_24XX_SYS_NIRQ); 258 omap_cfg_reg(W19_24XX_SYS_NIRQ);
259 259
260 /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
261 CONTROL_DEVCONF |= (1 << 24);
262
260 /* 263 /*
261 * Make sure the serial ports are muxed on at this point. 264 * Make sure the serial ports are muxed on at this point.
262 * You have to mux them off in device drivers later on 265 * You have to mux them off in device drivers later on
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d1b648a4efbf..0de201c3d50b 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -32,10 +32,14 @@
32#include "memory.h" 32#include "memory.h"
33#include "clock.h" 33#include "clock.h"
34 34
35#undef DEBUG
36
35//#define DOWN_VARIABLE_DPLL 1 /* Experimental */ 37//#define DOWN_VARIABLE_DPLL 1 /* Experimental */
36 38
37static struct prcm_config *curr_prcm_set; 39static struct prcm_config *curr_prcm_set;
38static u32 curr_perf_level = PRCM_FULL_SPEED; 40static u32 curr_perf_level = PRCM_FULL_SPEED;
41static struct clk *vclk;
42static struct clk *sclk;
39 43
40/*------------------------------------------------------------------------- 44/*-------------------------------------------------------------------------
41 * Omap2 specific clock functions 45 * Omap2 specific clock functions
@@ -79,6 +83,14 @@ static void omap2_propagate_rate(struct clk * clk)
79 propagate_rate(clk); 83 propagate_rate(clk);
80} 84}
81 85
86static void omap2_set_osc_ck(int enable)
87{
88 if (enable)
89 PRCM_CLKSRC_CTRL &= ~(0x3 << 3);
90 else
91 PRCM_CLKSRC_CTRL |= 0x3 << 3;
92}
93
82/* Enable an APLL if off */ 94/* Enable an APLL if off */
83static void omap2_clk_fixed_enable(struct clk *clk) 95static void omap2_clk_fixed_enable(struct clk *clk)
84{ 96{
@@ -101,12 +113,54 @@ static void omap2_clk_fixed_enable(struct clk *clk)
101 else if (clk == &apll54_ck) 113 else if (clk == &apll54_ck)
102 cval = (1 << 6); 114 cval = (1 << 6);
103 115
104 while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */ 116 while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */
105 ++i; 117 ++i;
106 udelay(1); 118 udelay(1);
107 if (i == 100000) 119 if (i == 100000) {
120 printk(KERN_ERR "Clock %s didn't lock\n", clk->name);
121 break;
122 }
123 }
124}
125
126static void omap2_clk_wait_ready(struct clk *clk)
127{
128 unsigned long reg, other_reg, st_reg;
129 u32 bit;
130 int i;
131
132 reg = (unsigned long) clk->enable_reg;
133 if (reg == (unsigned long) &CM_FCLKEN1_CORE ||
134 reg == (unsigned long) &CM_FCLKEN2_CORE)
135 other_reg = (reg & ~0xf0) | 0x10;
136 else if (reg == (unsigned long) &CM_ICLKEN1_CORE ||
137 reg == (unsigned long) &CM_ICLKEN2_CORE)
138 other_reg = (reg & ~0xf0) | 0x00;
139 else
140 return;
141
142 /* No check for DSS or cam clocks */
143 if ((reg & 0x0f) == 0) {
144 if (clk->enable_bit <= 1 || clk->enable_bit == 31)
145 return;
146 }
147
148 /* Check if both functional and interface clocks
149 * are running. */
150 bit = 1 << clk->enable_bit;
151 if (!(__raw_readl(other_reg) & bit))
152 return;
153 st_reg = (other_reg & ~0xf0) | 0x20;
154 i = 0;
155 while (!(__raw_readl(st_reg) & bit)) {
156 i++;
157 if (i == 100000) {
158 printk(KERN_ERR "Timeout enabling clock %s\n", clk->name);
108 break; 159 break;
160 }
109 } 161 }
162 if (i)
163 pr_debug("Clock %s stable after %d loops\n", clk->name, i);
110} 164}
111 165
112/* Enables clock without considering parent dependencies or use count 166/* Enables clock without considering parent dependencies or use count
@@ -119,6 +173,11 @@ static int _omap2_clk_enable(struct clk * clk)
119 if (clk->flags & ALWAYS_ENABLED) 173 if (clk->flags & ALWAYS_ENABLED)
120 return 0; 174 return 0;
121 175
176 if (unlikely(clk == &osc_ck)) {
177 omap2_set_osc_ck(1);
178 return 0;
179 }
180
122 if (unlikely(clk->enable_reg == 0)) { 181 if (unlikely(clk->enable_reg == 0)) {
123 printk(KERN_ERR "clock.c: Enable for %s without enable code\n", 182 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
124 clk->name); 183 clk->name);
@@ -133,6 +192,9 @@ static int _omap2_clk_enable(struct clk * clk)
133 regval32 = __raw_readl(clk->enable_reg); 192 regval32 = __raw_readl(clk->enable_reg);
134 regval32 |= (1 << clk->enable_bit); 193 regval32 |= (1 << clk->enable_bit);
135 __raw_writel(regval32, clk->enable_reg); 194 __raw_writel(regval32, clk->enable_reg);
195 wmb();
196
197 omap2_clk_wait_ready(clk);
136 198
137 return 0; 199 return 0;
138} 200}
@@ -155,6 +217,11 @@ static void _omap2_clk_disable(struct clk *clk)
155{ 217{
156 u32 regval32; 218 u32 regval32;
157 219
220 if (unlikely(clk == &osc_ck)) {
221 omap2_set_osc_ck(0);
222 return;
223 }
224
158 if (clk->enable_reg == 0) 225 if (clk->enable_reg == 0)
159 return; 226 return;
160 227
@@ -166,6 +233,7 @@ static void _omap2_clk_disable(struct clk *clk)
166 regval32 = __raw_readl(clk->enable_reg); 233 regval32 = __raw_readl(clk->enable_reg);
167 regval32 &= ~(1 << clk->enable_bit); 234 regval32 &= ~(1 << clk->enable_bit);
168 __raw_writel(regval32, clk->enable_reg); 235 __raw_writel(regval32, clk->enable_reg);
236 wmb();
169} 237}
170 238
171static int omap2_clk_enable(struct clk *clk) 239static int omap2_clk_enable(struct clk *clk)
@@ -695,12 +763,14 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
695 reg_val = __raw_readl(reg); 763 reg_val = __raw_readl(reg);
696 reg_val &= ~(field_mask << div_off); 764 reg_val &= ~(field_mask << div_off);
697 reg_val |= (field_val << div_off); 765 reg_val |= (field_val << div_off);
698
699 __raw_writel(reg_val, reg); 766 __raw_writel(reg_val, reg);
767 wmb();
700 clk->rate = clk->parent->rate / field_val; 768 clk->rate = clk->parent->rate / field_val;
701 769
702 if (clk->flags & DELAYED_APP) 770 if (clk->flags & DELAYED_APP) {
703 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 771 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
772 wmb();
773 }
704 ret = 0; 774 ret = 0;
705 } else if (clk->set_rate != 0) 775 } else if (clk->set_rate != 0)
706 ret = clk->set_rate(clk, rate); 776 ret = clk->set_rate(clk, rate);
@@ -836,10 +906,12 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
836 reg_val = __raw_readl(reg) & ~(field_mask << src_off); 906 reg_val = __raw_readl(reg) & ~(field_mask << src_off);
837 reg_val |= (field_val << src_off); 907 reg_val |= (field_val << src_off);
838 __raw_writel(reg_val, reg); 908 __raw_writel(reg_val, reg);
909 wmb();
839 910
840 if (clk->flags & DELAYED_APP) 911 if (clk->flags & DELAYED_APP) {
841 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); 912 __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
842 913 wmb();
914 }
843 if (clk->usecount > 0) 915 if (clk->usecount > 0)
844 _omap2_clk_enable(clk); 916 _omap2_clk_enable(clk);
845 917
@@ -953,12 +1025,29 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
953 * Omap2 clock reset and init functions 1025 * Omap2 clock reset and init functions
954 *-------------------------------------------------------------------------*/ 1026 *-------------------------------------------------------------------------*/
955 1027
1028#ifdef CONFIG_OMAP_RESET_CLOCKS
1029static void __init omap2_clk_disable_unused(struct clk *clk)
1030{
1031 u32 regval32;
1032
1033 regval32 = __raw_readl(clk->enable_reg);
1034 if ((regval32 & (1 << clk->enable_bit)) == 0)
1035 return;
1036
1037 printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
1038 _omap2_clk_disable(clk);
1039}
1040#else
1041#define omap2_clk_disable_unused NULL
1042#endif
1043
956static struct clk_functions omap2_clk_functions = { 1044static struct clk_functions omap2_clk_functions = {
957 .clk_enable = omap2_clk_enable, 1045 .clk_enable = omap2_clk_enable,
958 .clk_disable = omap2_clk_disable, 1046 .clk_disable = omap2_clk_disable,
959 .clk_round_rate = omap2_clk_round_rate, 1047 .clk_round_rate = omap2_clk_round_rate,
960 .clk_set_rate = omap2_clk_set_rate, 1048 .clk_set_rate = omap2_clk_set_rate,
961 .clk_set_parent = omap2_clk_set_parent, 1049 .clk_set_parent = omap2_clk_set_parent,
1050 .clk_disable_unused = omap2_clk_disable_unused,
962}; 1051};
963 1052
964static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) 1053static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
@@ -984,27 +1073,19 @@ static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
984 sys->rate = sclk; 1073 sys->rate = sclk;
985} 1074}
986 1075
987#ifdef CONFIG_OMAP_RESET_CLOCKS 1076/*
988static void __init omap2_disable_unused_clocks(void) 1077 * Set clocks for bypass mode for reboot to work.
1078 */
1079void omap2_clk_prepare_for_reboot(void)
989{ 1080{
990 struct clk *ck; 1081 u32 rate;
991 u32 regval32;
992 1082
993 list_for_each_entry(ck, &clocks, node) { 1083 if (vclk == NULL || sclk == NULL)
994 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || 1084 return;
995 ck->enable_reg == 0)
996 continue;
997
998 regval32 = __raw_readl(ck->enable_reg);
999 if ((regval32 & (1 << ck->enable_bit)) == 0)
1000 continue;
1001 1085
1002 printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); 1086 rate = clk_get_rate(sclk);
1003 _omap2_clk_disable(ck); 1087 clk_set_rate(vclk, rate);
1004 }
1005} 1088}
1006late_initcall(omap2_disable_unused_clocks);
1007#endif
1008 1089
1009/* 1090/*
1010 * Switch the MPU rate if specified on cmdline. 1091 * Switch the MPU rate if specified on cmdline.
@@ -1077,8 +1158,27 @@ int __init omap2_clk_init(void)
1077 */ 1158 */
1078 clk_enable(&sync_32k_ick); 1159 clk_enable(&sync_32k_ick);
1079 clk_enable(&omapctrl_ick); 1160 clk_enable(&omapctrl_ick);
1161
1162 /* Force the APLLs active during bootup to avoid disabling and
1163 * enabling them unnecessarily. */
1164 clk_enable(&apll96_ck);
1165 clk_enable(&apll54_ck);
1166
1080 if (cpu_is_omap2430()) 1167 if (cpu_is_omap2430())
1081 clk_enable(&sdrc_ick); 1168 clk_enable(&sdrc_ick);
1082 1169
1170 /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
1171 vclk = clk_get(NULL, "virt_prcm_set");
1172 sclk = clk_get(NULL, "sys_ck");
1173
1174 return 0;
1175}
1176
1177static int __init omap2_disable_aplls(void)
1178{
1179 clk_disable(&apll96_ck);
1180 clk_disable(&apll54_ck);
1181
1083 return 0; 1182 return 0;
1084} 1183}
1184late_initcall(omap2_disable_aplls);
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 2781dfbc5164..8816f5a33a28 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -560,7 +560,7 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
560 .name = "osc_ck", 560 .name = "osc_ck",
561 .rate = 26000000, /* fixed up in clock init */ 561 .rate = 26000000, /* fixed up in clock init */
562 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | 562 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
563 RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, 563 RATE_FIXED | RATE_PROPAGATES,
564}; 564};
565 565
566/* With out modem likely 12MHz, with modem likely 13MHz */ 566/* With out modem likely 12MHz, with modem likely 13MHz */
@@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = {
1368}; 1368};
1369 1369
1370static struct clk mcspi1_ick = { 1370static struct clk mcspi1_ick = {
1371 .name = "mcspi1_ick", 1371 .name = "mcspi_ick",
1372 .id = 1,
1372 .parent = &l4_ck, 1373 .parent = &l4_ck,
1373 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1374 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1374 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, 1375 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = {
1377}; 1378};
1378 1379
1379static struct clk mcspi1_fck = { 1380static struct clk mcspi1_fck = {
1380 .name = "mcspi1_fck", 1381 .name = "mcspi_fck",
1382 .id = 1,
1381 .parent = &func_48m_ck, 1383 .parent = &func_48m_ck,
1382 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1384 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1383 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, 1385 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = {
1386}; 1388};
1387 1389
1388static struct clk mcspi2_ick = { 1390static struct clk mcspi2_ick = {
1389 .name = "mcspi2_ick", 1391 .name = "mcspi_ick",
1392 .id = 2,
1390 .parent = &l4_ck, 1393 .parent = &l4_ck,
1391 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1394 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1392 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, 1395 .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE,
@@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = {
1395}; 1398};
1396 1399
1397static struct clk mcspi2_fck = { 1400static struct clk mcspi2_fck = {
1398 .name = "mcspi2_fck", 1401 .name = "mcspi_fck",
1402 .id = 2,
1399 .parent = &func_48m_ck, 1403 .parent = &func_48m_ck,
1400 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, 1404 .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
1401 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, 1405 .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE,
@@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = {
1404}; 1408};
1405 1409
1406static struct clk mcspi3_ick = { 1410static struct clk mcspi3_ick = {
1407 .name = "mcspi3_ick", 1411 .name = "mcspi_ick",
1412 .id = 3,
1408 .parent = &l4_ck, 1413 .parent = &l4_ck,
1409 .flags = CLOCK_IN_OMAP243X, 1414 .flags = CLOCK_IN_OMAP243X,
1410 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, 1415 .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE,
@@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = {
1413}; 1418};
1414 1419
1415static struct clk mcspi3_fck = { 1420static struct clk mcspi3_fck = {
1416 .name = "mcspi3_fck", 1421 .name = "mcspi_fck",
1422 .id = 3,
1417 .parent = &func_48m_ck, 1423 .parent = &func_48m_ck,
1418 .flags = CLOCK_IN_OMAP243X, 1424 .flags = CLOCK_IN_OMAP243X,
1419 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, 1425 .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE,
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c7a48f921fef..f4f04d87df32 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -13,6 +13,8 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/ioport.h>
17#include <linux/spinlock.h>
16 18
17#include <asm/io.h> 19#include <asm/io.h>
18#include <asm/arch/gpmc.h> 20#include <asm/arch/gpmc.h>
@@ -41,6 +43,19 @@
41#define GPMC_CS0 0x60 43#define GPMC_CS0 0x60
42#define GPMC_CS_SIZE 0x30 44#define GPMC_CS_SIZE 0x30
43 45
46#define GPMC_CS_NUM 8
47#define GPMC_MEM_START 0x00000000
48#define GPMC_MEM_END 0x3FFFFFFF
49#define BOOT_ROM_SPACE 0x100000 /* 1MB */
50
51#define GPMC_CHUNK_SHIFT 24 /* 16 MB */
52#define GPMC_SECTION_SHIFT 28 /* 128 MB */
53
54static struct resource gpmc_mem_root;
55static struct resource gpmc_cs_mem[GPMC_CS_NUM];
56static spinlock_t gpmc_mem_lock = SPIN_LOCK_UNLOCKED;
57static unsigned gpmc_cs_map;
58
44static void __iomem *gpmc_base = 59static void __iomem *gpmc_base =
45 (void __iomem *) IO_ADDRESS(GPMC_BASE); 60 (void __iomem *) IO_ADDRESS(GPMC_BASE);
46static void __iomem *gpmc_cs_base = 61static void __iomem *gpmc_cs_base =
@@ -187,9 +202,168 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
187 return 0; 202 return 0;
188} 203}
189 204
190unsigned long gpmc_cs_get_base_addr(int cs) 205static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
206{
207 u32 l;
208 u32 mask;
209
210 mask = (1 << GPMC_SECTION_SHIFT) - size;
211 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
212 l &= ~0x3f;
213 l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
214 l &= ~(0x0f << 8);
215 l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
216 l |= 1 << 6; /* CSVALID */
217 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
218}
219
220static void gpmc_cs_disable_mem(int cs)
221{
222 u32 l;
223
224 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
225 l &= ~(1 << 6); /* CSVALID */
226 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
227}
228
229static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size)
230{
231 u32 l;
232 u32 mask;
233
234 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
235 *base = (l & 0x3f) << GPMC_CHUNK_SHIFT;
236 mask = (l >> 8) & 0x0f;
237 *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT);
238}
239
240static int gpmc_cs_mem_enabled(int cs)
241{
242 u32 l;
243
244 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
245 return l & (1 << 6);
246}
247
248static void gpmc_cs_set_reserved(int cs, int reserved)
191{ 249{
192 return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24; 250 gpmc_cs_map &= ~(1 << cs);
251 gpmc_cs_map |= (reserved ? 1 : 0) << cs;
252}
253
254static int gpmc_cs_reserved(int cs)
255{
256 return gpmc_cs_map & (1 << cs);
257}
258
259static unsigned long gpmc_mem_align(unsigned long size)
260{
261 int order;
262
263 size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1);
264 order = GPMC_CHUNK_SHIFT - 1;
265 do {
266 size >>= 1;
267 order++;
268 } while (size);
269 size = 1 << order;
270 return size;
271}
272
273static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
274{
275 struct resource *res = &gpmc_cs_mem[cs];
276 int r;
277
278 size = gpmc_mem_align(size);
279 spin_lock(&gpmc_mem_lock);
280 res->start = base;
281 res->end = base + size - 1;
282 r = request_resource(&gpmc_mem_root, res);
283 spin_unlock(&gpmc_mem_lock);
284
285 return r;
286}
287
288int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
289{
290 struct resource *res = &gpmc_cs_mem[cs];
291 int r = -1;
292
293 if (cs > GPMC_CS_NUM)
294 return -ENODEV;
295
296 size = gpmc_mem_align(size);
297 if (size > (1 << GPMC_SECTION_SHIFT))
298 return -ENOMEM;
299
300 spin_lock(&gpmc_mem_lock);
301 if (gpmc_cs_reserved(cs)) {
302 r = -EBUSY;
303 goto out;
304 }
305 if (gpmc_cs_mem_enabled(cs))
306 r = adjust_resource(res, res->start & ~(size - 1), size);
307 if (r < 0)
308 r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0,
309 size, NULL, NULL);
310 if (r < 0)
311 goto out;
312
313 gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1);
314 *base = res->start;
315 gpmc_cs_set_reserved(cs, 1);
316out:
317 spin_unlock(&gpmc_mem_lock);
318 return r;
319}
320
321void gpmc_cs_free(int cs)
322{
323 spin_lock(&gpmc_mem_lock);
324 if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) {
325 printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
326 BUG();
327 spin_unlock(&gpmc_mem_lock);
328 return;
329 }
330 gpmc_cs_disable_mem(cs);
331 release_resource(&gpmc_cs_mem[cs]);
332 gpmc_cs_set_reserved(cs, 0);
333 spin_unlock(&gpmc_mem_lock);
334}
335
336void __init gpmc_mem_init(void)
337{
338 int cs;
339 unsigned long boot_rom_space = 0;
340
341 if (cpu_is_omap242x()) {
342 u32 l;
343 l = omap_readl(OMAP242X_CONTROL_STATUS);
344 /* In case of internal boot the 1st MB is redirected to the
345 * boot ROM memory space.
346 */
347 if (l & (1 << 3))
348 boot_rom_space = BOOT_ROM_SPACE;
349 } else
350 /* We assume internal boot if the mode can't be
351 * determined.
352 */
353 boot_rom_space = BOOT_ROM_SPACE;
354 gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
355 gpmc_mem_root.end = GPMC_MEM_END;
356
357 /* Reserve all regions that has been set up by bootloader */
358 for (cs = 0; cs < GPMC_CS_NUM; cs++) {
359 u32 base, size;
360
361 if (!gpmc_cs_mem_enabled(cs))
362 continue;
363 gpmc_cs_get_memconf(cs, &base, &size);
364 if (gpmc_cs_insert_mem(cs, base, size) < 0)
365 BUG();
366 }
193} 367}
194 368
195void __init gpmc_init(void) 369void __init gpmc_init(void)
@@ -206,4 +380,6 @@ void __init gpmc_init(void)
206 l &= 0x03 << 3; 380 l &= 0x03 << 3;
207 l |= (0x02 << 3) | (1 << 0); 381 l |= (0x02 << 3) | (1 << 0);
208 gpmc_write_reg(GPMC_SYSCONFIG, l); 382 gpmc_write_reg(GPMC_SYSCONFIG, l);
383
384 gpmc_mem_init();
209} 385}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index dfc3b35cc1ff..1ed2fff4691a 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -41,18 +41,6 @@ static struct omap_irq_bank {
41 .nr_irqs = 96, 41 .nr_irqs = 96,
42 }, { 42 }, {
43 /* XXX: DSP INTC */ 43 /* XXX: DSP INTC */
44
45#if 0
46 /*
47 * Commented out for now until we fix the IVA clocking
48 */
49#ifdef CONFIG_ARCH_OMAP2420
50 }, {
51 /* IVA INTC (2420 only) */
52 .base_reg = OMAP24XX_IVA_INTC_BASE,
53 .nr_irqs = 16, /* Actually 32, but only 16 are used */
54#endif
55#endif
56 } 44 }
57}; 45};
58 46
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 60ef084faffd..f538d0fdb13c 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -104,6 +104,20 @@ MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1)
104MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) 104MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
105MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) 105MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
106 106
107/* MMC/SDIO */
108MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1)
109MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1)
110MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1)
111MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1)
112MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1)
113MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1)
114MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1)
115MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1)
116MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1)
117MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1)
118MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1)
119MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1)
120
107/* Keypad GPIO*/ 121/* Keypad GPIO*/
108MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) 122MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
109MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) 123MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1)
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
index c2bf57ef6825..90f530540c65 100644
--- a/arch/arm/mach-omap2/prcm.c
+++ b/arch/arm/mach-omap2/prcm.c
@@ -19,6 +19,8 @@
19 19
20#include "prcm-regs.h" 20#include "prcm-regs.h"
21 21
22extern void omap2_clk_prepare_for_reboot(void);
23
22u32 omap_prcm_get_reset_sources(void) 24u32 omap_prcm_get_reset_sources(void)
23{ 25{
24 return RM_RSTST_WKUP & 0x7f; 26 return RM_RSTST_WKUP & 0x7f;
@@ -28,12 +30,6 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources);
28/* Resets clock rates and reboots the system. Only called from system.h */ 30/* Resets clock rates and reboots the system. Only called from system.h */
29void omap_prcm_arch_reset(char mode) 31void omap_prcm_arch_reset(char mode)
30{ 32{
31 u32 rate; 33 omap2_clk_prepare_for_reboot();
32 struct clk *vclk, *sclk;
33
34 vclk = clk_get(NULL, "virt_prcm_set");
35 sclk = clk_get(NULL, "sys_ck");
36 rate = clk_get_rate(sclk);
37 clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */
38 RM_RSTCTRL_WKUP |= 2; 34 RM_RSTCTRL_WKUP |= 2;
39} 35}
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 7f45c7c3e673..f1179ad4be1b 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -100,6 +100,7 @@ void clk_disable(struct clk *clk)
100 return; 100 return;
101 101
102 spin_lock_irqsave(&clockfw_lock, flags); 102 spin_lock_irqsave(&clockfw_lock, flags);
103 BUG_ON(clk->usecount == 0);
103 if (arch_clock->clk_disable) 104 if (arch_clock->clk_disable)
104 arch_clock->clk_disable(clk); 105 arch_clock->clk_disable(clk);
105 spin_unlock_irqrestore(&clockfw_lock, flags); 106 spin_unlock_irqrestore(&clockfw_lock, flags);
@@ -322,6 +323,31 @@ EXPORT_SYMBOL(clk_allow_idle);
322 323
323/*-------------------------------------------------------------------------*/ 324/*-------------------------------------------------------------------------*/
324 325
326#ifdef CONFIG_OMAP_RESET_CLOCKS
327/*
328 * Disable any unused clocks left on by the bootloader
329 */
330static int __init clk_disable_unused(void)
331{
332 struct clk *ck;
333 unsigned long flags;
334
335 list_for_each_entry(ck, &clocks, node) {
336 if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
337 ck->enable_reg == 0)
338 continue;
339
340 spin_lock_irqsave(&clockfw_lock, flags);
341 if (arch_clock->clk_disable_unused)
342 arch_clock->clk_disable_unused(ck);
343 spin_unlock_irqrestore(&clockfw_lock, flags);
344 }
345
346 return 0;
347}
348late_initcall(clk_disable_unused);
349#endif
350
325int __init clk_init(struct clk_functions * custom_clocks) 351int __init clk_init(struct clk_functions * custom_clocks)
326{ 352{
327 if (!custom_clocks) { 353 if (!custom_clocks) {
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 1812f237d12f..dbc3f44e07a6 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -148,7 +148,7 @@ static inline void omap_init_kp(void) {}
148 148
149#ifdef CONFIG_ARCH_OMAP24XX 149#ifdef CONFIG_ARCH_OMAP24XX
150#define OMAP_MMC1_BASE 0x4809c000 150#define OMAP_MMC1_BASE 0x4809c000
151#define OMAP_MMC1_INT 83 151#define OMAP_MMC1_INT INT_24XX_MMC_IRQ
152#else 152#else
153#define OMAP_MMC1_BASE 0xfffb7800 153#define OMAP_MMC1_BASE 0xfffb7800
154#define OMAP_MMC1_INT INT_MMC 154#define OMAP_MMC1_INT INT_MMC
@@ -225,7 +225,14 @@ static void __init omap_init_mmc(void)
225 /* block 1 is always available and has just one pinout option */ 225 /* block 1 is always available and has just one pinout option */
226 mmc = &mmc_conf->mmc[0]; 226 mmc = &mmc_conf->mmc[0];
227 if (mmc->enabled) { 227 if (mmc->enabled) {
228 if (!cpu_is_omap24xx()) { 228 if (cpu_is_omap24xx()) {
229 omap_cfg_reg(H18_24XX_MMC_CMD);
230 omap_cfg_reg(H15_24XX_MMC_CLKI);
231 omap_cfg_reg(G19_24XX_MMC_CLKO);
232 omap_cfg_reg(F20_24XX_MMC_DAT0);
233 omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
234 omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
235 } else {
229 omap_cfg_reg(MMC_CMD); 236 omap_cfg_reg(MMC_CMD);
230 omap_cfg_reg(MMC_CLK); 237 omap_cfg_reg(MMC_CLK);
231 omap_cfg_reg(MMC_DAT0); 238 omap_cfg_reg(MMC_DAT0);
@@ -236,7 +243,14 @@ static void __init omap_init_mmc(void)
236 } 243 }
237 } 244 }
238 if (mmc->wire4) { 245 if (mmc->wire4) {
239 if (!cpu_is_omap24xx()) { 246 if (cpu_is_omap24xx()) {
247 omap_cfg_reg(H14_24XX_MMC_DAT1);
248 omap_cfg_reg(E19_24XX_MMC_DAT2);
249 omap_cfg_reg(D19_24XX_MMC_DAT3);
250 omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
251 omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
252 omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
253 } else {
240 omap_cfg_reg(MMC_DAT1); 254 omap_cfg_reg(MMC_DAT1);
241 /* NOTE: DAT2 can be on W10 (here) or M15 */ 255 /* NOTE: DAT2 can be on W10 (here) or M15 */
242 if (!mmc->nomux) 256 if (!mmc->nomux)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 9eddc9507147..1bbb431843ce 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -119,32 +119,41 @@ static void clear_lch_regs(int lch)
119 omap_writew(0, lch_base + i); 119 omap_writew(0, lch_base + i);
120} 120}
121 121
122void omap_set_dma_priority(int dst_port, int priority) 122void omap_set_dma_priority(int lch, int dst_port, int priority)
123{ 123{
124 unsigned long reg; 124 unsigned long reg;
125 u32 l; 125 u32 l;
126 126
127 switch (dst_port) { 127 if (cpu_class_is_omap1()) {
128 case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ 128 switch (dst_port) {
129 reg = OMAP_TC_OCPT1_PRIOR; 129 case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */
130 break; 130 reg = OMAP_TC_OCPT1_PRIOR;
131 case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ 131 break;
132 reg = OMAP_TC_OCPT2_PRIOR; 132 case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */
133 break; 133 reg = OMAP_TC_OCPT2_PRIOR;
134 case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ 134 break;
135 reg = OMAP_TC_EMIFF_PRIOR; 135 case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */
136 break; 136 reg = OMAP_TC_EMIFF_PRIOR;
137 case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ 137 break;
138 reg = OMAP_TC_EMIFS_PRIOR; 138 case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */
139 break; 139 reg = OMAP_TC_EMIFS_PRIOR;
140 default: 140 break;
141 BUG(); 141 default:
142 return; 142 BUG();
143 return;
144 }
145 l = omap_readl(reg);
146 l &= ~(0xf << 8);
147 l |= (priority & 0xf) << 8;
148 omap_writel(l, reg);
149 }
150
151 if (cpu_is_omap24xx()) {
152 if (priority)
153 OMAP_DMA_CCR_REG(lch) |= (1 << 6);
154 else
155 OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
143 } 156 }
144 l = omap_readl(reg);
145 l &= ~(0xf << 8);
146 l |= (priority & 0xf) << 8;
147 omap_writel(l, reg);
148} 157}
149 158
150void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, 159void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
@@ -234,6 +243,14 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
234 OMAP1_DMA_LCH_CTRL_REG(lch) = w; 243 OMAP1_DMA_LCH_CTRL_REG(lch) = w;
235} 244}
236 245
246void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
247{
248 if (cpu_is_omap24xx()) {
249 OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
250 OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
251 }
252}
253
237/* Note that src_port is only for omap1 */ 254/* Note that src_port is only for omap1 */
238void omap_set_dma_src_params(int lch, int src_port, int src_amode, 255void omap_set_dma_src_params(int lch, int src_port, int src_amode,
239 unsigned long src_start, 256 unsigned long src_start,
@@ -698,6 +715,32 @@ void omap_stop_dma(int lch)
698} 715}
699 716
700/* 717/*
718 * Allows changing the DMA callback function or data. This may be needed if
719 * the driver shares a single DMA channel for multiple dma triggers.
720 */
721int omap_set_dma_callback(int lch,
722 void (* callback)(int lch, u16 ch_status, void *data),
723 void *data)
724{
725 unsigned long flags;
726
727 if (lch < 0)
728 return -ENODEV;
729
730 spin_lock_irqsave(&dma_chan_lock, flags);
731 if (dma_chan[lch].dev_id == -1) {
732 printk(KERN_ERR "DMA callback for not set for free channel\n");
733 spin_unlock_irqrestore(&dma_chan_lock, flags);
734 return -EINVAL;
735 }
736 dma_chan[lch].callback = callback;
737 dma_chan[lch].data = data;
738 spin_unlock_irqrestore(&dma_chan_lock, flags);
739
740 return 0;
741}
742
743/*
701 * Returns current physical source address for the given DMA channel. 744 * Returns current physical source address for the given DMA channel.
702 * If the channel is running the caller must disable interrupts prior calling 745 * If the channel is running the caller must disable interrupts prior calling
703 * this function and process the returned value before re-enabling interrupt to 746 * this function and process the returned value before re-enabling interrupt to
@@ -1339,6 +1382,14 @@ static int __init omap_init_dma(void)
1339 dma_chan_count = 16; 1382 dma_chan_count = 16;
1340 } else 1383 } else
1341 dma_chan_count = 9; 1384 dma_chan_count = 9;
1385 if (cpu_is_omap16xx()) {
1386 u16 w;
1387
1388 /* this would prevent OMAP sleep */
1389 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
1390 w &= ~(1 << 8);
1391 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
1392 }
1342 } else if (cpu_is_omap24xx()) { 1393 } else if (cpu_is_omap24xx()) {
1343 u8 revision = omap_readb(OMAP_DMA4_REVISION); 1394 u8 revision = omap_readb(OMAP_DMA4_REVISION);
1344 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", 1395 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
@@ -1414,11 +1465,13 @@ EXPORT_SYMBOL(omap_request_dma);
1414EXPORT_SYMBOL(omap_free_dma); 1465EXPORT_SYMBOL(omap_free_dma);
1415EXPORT_SYMBOL(omap_start_dma); 1466EXPORT_SYMBOL(omap_start_dma);
1416EXPORT_SYMBOL(omap_stop_dma); 1467EXPORT_SYMBOL(omap_stop_dma);
1468EXPORT_SYMBOL(omap_set_dma_callback);
1417EXPORT_SYMBOL(omap_enable_dma_irq); 1469EXPORT_SYMBOL(omap_enable_dma_irq);
1418EXPORT_SYMBOL(omap_disable_dma_irq); 1470EXPORT_SYMBOL(omap_disable_dma_irq);
1419 1471
1420EXPORT_SYMBOL(omap_set_dma_transfer_params); 1472EXPORT_SYMBOL(omap_set_dma_transfer_params);
1421EXPORT_SYMBOL(omap_set_dma_color_mode); 1473EXPORT_SYMBOL(omap_set_dma_color_mode);
1474EXPORT_SYMBOL(omap_set_dma_write_mode);
1422 1475
1423EXPORT_SYMBOL(omap_set_dma_src_params); 1476EXPORT_SYMBOL(omap_set_dma_src_params);
1424EXPORT_SYMBOL(omap_set_dma_src_index); 1477EXPORT_SYMBOL(omap_set_dma_src_index);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 50524436de63..bcbb8d7392be 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -75,10 +75,14 @@ struct omap_dm_timer {
75#endif 75#endif
76 void __iomem *io_base; 76 void __iomem *io_base;
77 unsigned reserved:1; 77 unsigned reserved:1;
78 unsigned enabled:1;
78}; 79};
79 80
80#ifdef CONFIG_ARCH_OMAP1 81#ifdef CONFIG_ARCH_OMAP1
81 82
83#define omap_dm_clk_enable(x)
84#define omap_dm_clk_disable(x)
85
82static struct omap_dm_timer dm_timers[] = { 86static struct omap_dm_timer dm_timers[] = {
83 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, 87 { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
84 { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, 88 { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
@@ -92,6 +96,9 @@ static struct omap_dm_timer dm_timers[] = {
92 96
93#elif defined(CONFIG_ARCH_OMAP2) 97#elif defined(CONFIG_ARCH_OMAP2)
94 98
99#define omap_dm_clk_enable(x) clk_enable(x)
100#define omap_dm_clk_disable(x) clk_disable(x)
101
95static struct omap_dm_timer dm_timers[] = { 102static struct omap_dm_timer dm_timers[] = {
96 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, 103 { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
97 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, 104 { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
@@ -154,24 +161,28 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
154{ 161{
155 u32 l; 162 u32 l;
156 163
157 if (timer != &dm_timers[0]) { 164 if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
158 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); 165 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
159 omap_dm_timer_wait_for_reset(timer); 166 omap_dm_timer_wait_for_reset(timer);
160 } 167 }
161 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK); 168 omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
162 169
163 /* Set to smart-idle mode */ 170 /* Set to smart-idle mode */
164 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); 171 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
165 l |= 0x02 << 3; 172 l |= 0x02 << 3;
173
174 if (cpu_class_is_omap2() && timer == &dm_timers[0]) {
175 /* Enable wake-up only for GPT1 on OMAP2 CPUs*/
176 l |= 1 << 2;
177 /* Non-posted mode */
178 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0);
179 }
166 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); 180 omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
167} 181}
168 182
169static void omap_dm_timer_prepare(struct omap_dm_timer *timer) 183static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
170{ 184{
171#ifdef CONFIG_ARCH_OMAP2 185 omap_dm_timer_enable(timer);
172 clk_enable(timer->iclk);
173 clk_enable(timer->fclk);
174#endif
175 omap_dm_timer_reset(timer); 186 omap_dm_timer_reset(timer);
176} 187}
177 188
@@ -223,15 +234,36 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
223 234
224void omap_dm_timer_free(struct omap_dm_timer *timer) 235void omap_dm_timer_free(struct omap_dm_timer *timer)
225{ 236{
237 omap_dm_timer_enable(timer);
226 omap_dm_timer_reset(timer); 238 omap_dm_timer_reset(timer);
227#ifdef CONFIG_ARCH_OMAP2 239 omap_dm_timer_disable(timer);
228 clk_disable(timer->iclk); 240
229 clk_disable(timer->fclk);
230#endif
231 WARN_ON(!timer->reserved); 241 WARN_ON(!timer->reserved);
232 timer->reserved = 0; 242 timer->reserved = 0;
233} 243}
234 244
245void omap_dm_timer_enable(struct omap_dm_timer *timer)
246{
247 if (timer->enabled)
248 return;
249
250 omap_dm_clk_enable(timer->fclk);
251 omap_dm_clk_enable(timer->iclk);
252
253 timer->enabled = 1;
254}
255
256void omap_dm_timer_disable(struct omap_dm_timer *timer)
257{
258 if (!timer->enabled)
259 return;
260
261 omap_dm_clk_disable(timer->iclk);
262 omap_dm_clk_disable(timer->fclk);
263
264 timer->enabled = 0;
265}
266
235int omap_dm_timer_get_irq(struct omap_dm_timer *timer) 267int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
236{ 268{
237 return timer->irq; 269 return timer->irq;
@@ -276,7 +308,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
276 308
277struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 309struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
278{ 310{
279 return timer->fclk; 311 return timer->fclk;
280} 312}
281 313
282__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 314__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
@@ -406,11 +438,16 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
406 unsigned int value) 438 unsigned int value)
407{ 439{
408 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); 440 omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
441 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
409} 442}
410 443
411unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 444unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
412{ 445{
413 return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); 446 unsigned int l;
447
448 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
449
450 return l;
414} 451}
415 452
416void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 453void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
@@ -420,12 +457,16 @@ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
420 457
421unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 458unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
422{ 459{
423 return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); 460 unsigned int l;
461
462 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
463
464 return l;
424} 465}
425 466
426void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 467void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
427{ 468{
428 return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); 469 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
429} 470}
430 471
431int omap_dm_timers_active(void) 472int omap_dm_timers_active(void)
@@ -436,9 +477,14 @@ int omap_dm_timers_active(void)
436 struct omap_dm_timer *timer; 477 struct omap_dm_timer *timer;
437 478
438 timer = &dm_timers[i]; 479 timer = &dm_timers[i];
480
481 if (!timer->enabled)
482 continue;
483
439 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & 484 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
440 OMAP_TIMER_CTRL_ST) 485 OMAP_TIMER_CTRL_ST) {
441 return 1; 486 return 1;
487 }
442 } 488 }
443 return 0; 489 return 0;
444} 490}
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index cd7f973fb286..f55f99ae58ae 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -94,6 +94,8 @@
94#define OMAP24XX_GPIO_SYSCONFIG 0x0010 94#define OMAP24XX_GPIO_SYSCONFIG 0x0010
95#define OMAP24XX_GPIO_SYSSTATUS 0x0014 95#define OMAP24XX_GPIO_SYSSTATUS 0x0014
96#define OMAP24XX_GPIO_IRQSTATUS1 0x0018 96#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
97#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
98#define OMAP24XX_GPIO_IRQENABLE2 0x002c
97#define OMAP24XX_GPIO_IRQENABLE1 0x001c 99#define OMAP24XX_GPIO_IRQENABLE1 0x001c
98#define OMAP24XX_GPIO_CTRL 0x0030 100#define OMAP24XX_GPIO_CTRL 0x0030
99#define OMAP24XX_GPIO_OE 0x0034 101#define OMAP24XX_GPIO_OE 0x0034
@@ -110,8 +112,6 @@
110#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 112#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
111#define OMAP24XX_GPIO_SETDATAOUT 0x0094 113#define OMAP24XX_GPIO_SETDATAOUT 0x0094
112 114
113#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff)
114
115struct gpio_bank { 115struct gpio_bank {
116 void __iomem *base; 116 void __iomem *base;
117 u16 irq; 117 u16 irq;
@@ -216,11 +216,13 @@ static inline int gpio_valid(int gpio)
216{ 216{
217 if (gpio < 0) 217 if (gpio < 0)
218 return -1; 218 return -1;
219#ifndef CONFIG_ARCH_OMAP24XX
219 if (OMAP_GPIO_IS_MPUIO(gpio)) { 220 if (OMAP_GPIO_IS_MPUIO(gpio)) {
220 if ((gpio & OMAP_MPUIO_MASK) > 16) 221 if (gpio >= OMAP_MAX_GPIO_LINES + 16)
221 return -1; 222 return -1;
222 return 0; 223 return 0;
223 } 224 }
225#endif
224#ifdef CONFIG_ARCH_OMAP15XX 226#ifdef CONFIG_ARCH_OMAP15XX
225 if (cpu_is_omap15xx() && gpio < 16) 227 if (cpu_is_omap15xx() && gpio < 16)
226 return 0; 228 return 0;
@@ -529,6 +531,10 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
529 return; 531 return;
530 } 532 }
531 __raw_writel(gpio_mask, reg); 533 __raw_writel(gpio_mask, reg);
534
535 /* Workaround for clearing DSP GPIO interrupts to allow retention */
536 if (cpu_is_omap2420())
537 __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2);
532} 538}
533 539
534static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) 540static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
@@ -662,6 +668,14 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
662 } 668 }
663} 669}
664 670
671static void _reset_gpio(struct gpio_bank *bank, int gpio)
672{
673 _set_gpio_direction(bank, get_gpio_index(gpio), 1);
674 _set_gpio_irqenable(bank, gpio, 0);
675 _clear_gpio_irqstatus(bank, gpio);
676 _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
677}
678
665/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ 679/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
666static int gpio_wake_enable(unsigned int irq, unsigned int enable) 680static int gpio_wake_enable(unsigned int irq, unsigned int enable)
667{ 681{
@@ -672,9 +686,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable)
672 if (check_gpio(gpio) < 0) 686 if (check_gpio(gpio) < 0)
673 return -ENODEV; 687 return -ENODEV;
674 bank = get_gpio_bank(gpio); 688 bank = get_gpio_bank(gpio);
675 spin_lock(&bank->lock);
676 retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); 689 retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
677 spin_unlock(&bank->lock);
678 690
679 return retval; 691 return retval;
680} 692}
@@ -696,7 +708,9 @@ int omap_request_gpio(int gpio)
696 } 708 }
697 bank->reserved_map |= (1 << get_gpio_index(gpio)); 709 bank->reserved_map |= (1 << get_gpio_index(gpio));
698 710
699 /* Set trigger to none. You need to enable the trigger after request_irq */ 711 /* Set trigger to none. You need to enable the desired trigger with
712 * request_irq() or set_irq_type().
713 */
700 _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); 714 _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
701 715
702#ifdef CONFIG_ARCH_OMAP15XX 716#ifdef CONFIG_ARCH_OMAP15XX
@@ -756,9 +770,7 @@ void omap_free_gpio(int gpio)
756 } 770 }
757#endif 771#endif
758 bank->reserved_map &= ~(1 << get_gpio_index(gpio)); 772 bank->reserved_map &= ~(1 << get_gpio_index(gpio));
759 _set_gpio_direction(bank, get_gpio_index(gpio), 1); 773 _reset_gpio(bank, gpio);
760 _set_gpio_irqenable(bank, gpio, 0);
761 _clear_gpio_irqstatus(bank, gpio);
762 spin_unlock(&bank->lock); 774 spin_unlock(&bank->lock);
763} 775}
764 776
@@ -898,6 +910,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
898 910
899} 911}
900 912
913static void gpio_irq_shutdown(unsigned int irq)
914{
915 unsigned int gpio = irq - IH_GPIO_BASE;
916 struct gpio_bank *bank = get_gpio_bank(gpio);
917
918 _reset_gpio(bank, gpio);
919}
920
901static void gpio_ack_irq(unsigned int irq) 921static void gpio_ack_irq(unsigned int irq)
902{ 922{
903 unsigned int gpio = irq - IH_GPIO_BASE; 923 unsigned int gpio = irq - IH_GPIO_BASE;
@@ -946,6 +966,7 @@ static void mpuio_unmask_irq(unsigned int irq)
946 966
947static struct irq_chip gpio_irq_chip = { 967static struct irq_chip gpio_irq_chip = {
948 .name = "GPIO", 968 .name = "GPIO",
969 .shutdown = gpio_irq_shutdown,
949 .ack = gpio_ack_irq, 970 .ack = gpio_ack_irq,
950 .mask = gpio_mask_irq, 971 .mask = gpio_mask_irq,
951 .unmask = gpio_unmask_irq, 972 .unmask = gpio_unmask_irq,
@@ -985,7 +1006,7 @@ static int __init _omap_gpio_init(void)
985 else 1006 else
986 clk_enable(gpio_ick); 1007 clk_enable(gpio_ick);
987 gpio_fck = clk_get(NULL, "gpios_fck"); 1008 gpio_fck = clk_get(NULL, "gpios_fck");
988 if (IS_ERR(gpio_ick)) 1009 if (IS_ERR(gpio_fck))
989 printk("Could not get gpios_fck\n"); 1010 printk("Could not get gpios_fck\n");
990 else 1011 else
991 clk_enable(gpio_fck); 1012 clk_enable(gpio_fck);
@@ -1144,8 +1165,8 @@ static int omap_gpio_resume(struct sys_device *dev)
1144 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; 1165 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
1145 break; 1166 break;
1146 case METHOD_GPIO_24XX: 1167 case METHOD_GPIO_24XX:
1147 wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; 1168 wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
1148 wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; 1169 wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
1149 break; 1170 break;
1150 default: 1171 default:
1151 continue; 1172 continue;
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 196aac3ac329..ade9a0fa6ef6 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -75,8 +75,6 @@ static struct clk *mcbsp1_ick = 0;
75static struct clk *mcbsp1_fck = 0; 75static struct clk *mcbsp1_fck = 0;
76static struct clk *mcbsp2_ick = 0; 76static struct clk *mcbsp2_ick = 0;
77static struct clk *mcbsp2_fck = 0; 77static struct clk *mcbsp2_fck = 0;
78static struct clk *sys_ck = 0;
79static struct clk *sys_clkout = 0;
80#endif 78#endif
81 79
82static void omap_mcbsp_dump_reg(u8 id) 80static void omap_mcbsp_dump_reg(u8 id)
@@ -232,7 +230,6 @@ static void omap2_mcbsp2_mux_setup(void)
232 omap_cfg_reg(W15_24XX_MCBSP2_DR); 230 omap_cfg_reg(W15_24XX_MCBSP2_DR);
233 omap_cfg_reg(V15_24XX_MCBSP2_DX); 231 omap_cfg_reg(V15_24XX_MCBSP2_DX);
234 omap_cfg_reg(V14_24XX_GPIO117); 232 omap_cfg_reg(V14_24XX_GPIO117);
235 omap_cfg_reg(W14_24XX_SYS_CLKOUT);
236} 233}
237#endif 234#endif
238 235
@@ -984,13 +981,7 @@ static int __init omap_mcbsp_init(void)
984 if (cpu_is_omap24xx()) { 981 if (cpu_is_omap24xx()) {
985 mcbsp_info = mcbsp_24xx; 982 mcbsp_info = mcbsp_24xx;
986 mcbsp_count = ARRAY_SIZE(mcbsp_24xx); 983 mcbsp_count = ARRAY_SIZE(mcbsp_24xx);
987
988 /* REVISIT: where's the right place? */
989 omap2_mcbsp2_mux_setup(); 984 omap2_mcbsp2_mux_setup();
990 sys_ck = clk_get(0, "sys_ck");
991 sys_clkout = clk_get(0, "sys_clkout");
992 clk_set_parent(sys_clkout, sys_ck);
993 clk_enable(sys_clkout);
994 } 985 }
995#endif 986#endif
996 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { 987 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
deleted file mode 100644
index 04b4102727a8..000000000000
--- a/arch/arm/plat-omap/pm.c
+++ /dev/null
@@ -1,670 +0,0 @@
1/*
2 * linux/arch/arm/plat-omap/pm.c
3 *
4 * OMAP Power Management Routines
5 *
6 * Original code for the SA11x0:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8 *
9 * Modified for the PXA250 by Nicolas Pitre:
10 * Copyright (c) 2002 Monta Vista Software, Inc.
11 *
12 * Modified for the OMAP1510 by David Singleton:
13 * Copyright (c) 2002 Monta Vista Software, Inc.
14 *
15 * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version.
21 *
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * You should have received a copy of the GNU General Public License along
34 * with this program; if not, write to the Free Software Foundation, Inc.,
35 * 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38#include <linux/pm.h>
39#include <linux/sched.h>
40#include <linux/proc_fs.h>
41#include <linux/pm.h>
42#include <linux/interrupt.h>
43
44#include <asm/io.h>
45#include <asm/irq.h>
46#include <asm/mach/time.h>
47#include <asm/mach/irq.h>
48
49#include <asm/mach-types.h>
50#include <asm/arch/irqs.h>
51#include <asm/arch/tc.h>
52#include <asm/arch/pm.h>
53#include <asm/arch/mux.h>
54#include <asm/arch/tps65010.h>
55#include <asm/arch/dsp_common.h>
56
57#include <asm/arch/clock.h>
58#include <asm/arch/sram.h>
59
60static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
61static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
62static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
63static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
64static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
65
66static void (*omap_sram_idle)(void) = NULL;
67static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
68
69/*
70 * Let's power down on idle, but only if we are really
71 * idle, because once we start down the path of
72 * going idle we continue to do idle even if we get
73 * a clock tick interrupt . .
74 */
75void omap_pm_idle(void)
76{
77 unsigned int mask32 = 0;
78
79 /*
80 * If the DSP is being used let's just idle the CPU, the overhead
81 * to wake up from Big Sleep is big, milliseconds versus micro
82 * seconds for wait for interrupt.
83 */
84
85 local_irq_disable();
86 local_fiq_disable();
87 if (need_resched()) {
88 local_fiq_enable();
89 local_irq_enable();
90 return;
91 }
92 mask32 = omap_readl(ARM_SYSST);
93
94 /*
95 * Prevent the ULPD from entering low power state by setting
96 * POWER_CTRL_REG:4 = 0
97 */
98 omap_writew(omap_readw(ULPD_POWER_CTRL) &
99 ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL);
100
101 /*
102 * Since an interrupt may set up a timer, we don't want to
103 * reprogram the hardware timer with interrupts enabled.
104 * Re-enable interrupts only after returning from idle.
105 */
106 timer_dyn_reprogram();
107
108 if ((mask32 & DSP_IDLE) == 0) {
109 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
110 } else
111 omap_sram_idle();
112
113 local_fiq_enable();
114 local_irq_enable();
115}
116
117/*
118 * Configuration of the wakeup event is board specific. For the
119 * moment we put it into this helper function. Later it may move
120 * to board specific files.
121 */
122static void omap_pm_wakeup_setup(void)
123{
124 u32 level1_wake = 0;
125 u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
126
127 /*
128 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
129 * and the L2 wakeup interrupts: keypad and UART2. Note that the
130 * drivers must still separately call omap_set_gpio_wakeup() to
131 * wake up to a GPIO interrupt.
132 */
133 if (cpu_is_omap730())
134 level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
135 OMAP_IRQ_BIT(INT_730_IH2_IRQ);
136 else if (cpu_is_omap1510())
137 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
138 OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
139 else if (cpu_is_omap16xx())
140 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
141 OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
142
143 omap_writel(~level1_wake, OMAP_IH1_MIR);
144
145 if (cpu_is_omap730()) {
146 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
147 omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR);
148 } else if (cpu_is_omap1510()) {
149 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
150 omap_writel(~level2_wake, OMAP_IH2_MIR);
151 } else if (cpu_is_omap16xx()) {
152 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
153 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
154
155 /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
156 omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
157 omap_writel(~0x0, OMAP_IH2_2_MIR);
158 omap_writel(~0x0, OMAP_IH2_3_MIR);
159 }
160
161 /* New IRQ agreement, recalculate in cascade order */
162 omap_writel(1, OMAP_IH2_CONTROL);
163 omap_writel(1, OMAP_IH1_CONTROL);
164}
165
166void omap_pm_suspend(void)
167{
168 unsigned long arg0 = 0, arg1 = 0;
169
170 printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
171
172 omap_serial_wake_trigger(1);
173
174 if (machine_is_omap_osk()) {
175 /* Stop LED1 (D9) blink */
176 tps65010_set_led(LED1, OFF);
177 }
178
179 omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
180
181 /*
182 * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
183 */
184
185 local_irq_disable();
186 local_fiq_disable();
187
188 /*
189 * Step 2: save registers
190 *
191 * The omap is a strange/beautiful device. The caches, memory
192 * and register state are preserved across power saves.
193 * We have to save and restore very little register state to
194 * idle the omap.
195 *
196 * Save interrupt, MPUI, ARM and UPLD control registers.
197 */
198
199 if (cpu_is_omap730()) {
200 MPUI730_SAVE(OMAP_IH1_MIR);
201 MPUI730_SAVE(OMAP_IH2_0_MIR);
202 MPUI730_SAVE(OMAP_IH2_1_MIR);
203 MPUI730_SAVE(MPUI_CTRL);
204 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
205 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
206 MPUI730_SAVE(EMIFS_CONFIG);
207 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
208
209 } else if (cpu_is_omap1510()) {
210 MPUI1510_SAVE(OMAP_IH1_MIR);
211 MPUI1510_SAVE(OMAP_IH2_MIR);
212 MPUI1510_SAVE(MPUI_CTRL);
213 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
214 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
215 MPUI1510_SAVE(EMIFS_CONFIG);
216 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
217 } else if (cpu_is_omap16xx()) {
218 MPUI1610_SAVE(OMAP_IH1_MIR);
219 MPUI1610_SAVE(OMAP_IH2_0_MIR);
220 MPUI1610_SAVE(OMAP_IH2_1_MIR);
221 MPUI1610_SAVE(OMAP_IH2_2_MIR);
222 MPUI1610_SAVE(OMAP_IH2_3_MIR);
223 MPUI1610_SAVE(MPUI_CTRL);
224 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
225 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
226 MPUI1610_SAVE(EMIFS_CONFIG);
227 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
228 }
229
230 ARM_SAVE(ARM_CKCTL);
231 ARM_SAVE(ARM_IDLECT1);
232 ARM_SAVE(ARM_IDLECT2);
233 if (!(cpu_is_omap1510()))
234 ARM_SAVE(ARM_IDLECT3);
235 ARM_SAVE(ARM_EWUPCT);
236 ARM_SAVE(ARM_RSTCT1);
237 ARM_SAVE(ARM_RSTCT2);
238 ARM_SAVE(ARM_SYSST);
239 ULPD_SAVE(ULPD_CLOCK_CTRL);
240 ULPD_SAVE(ULPD_STATUS_REQ);
241
242 /* (Step 3 removed - we now allow deep sleep by default) */
243
244 /*
245 * Step 4: OMAP DSP Shutdown
246 */
247
248
249 /*
250 * Step 5: Wakeup Event Setup
251 */
252
253 omap_pm_wakeup_setup();
254
255 /*
256 * Step 6: ARM and Traffic controller shutdown
257 */
258
259 /* disable ARM watchdog */
260 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
261 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
262
263 /*
264 * Step 6b: ARM and Traffic controller shutdown
265 *
266 * Step 6 continues here. Prepare jump to power management
267 * assembly code in internal SRAM.
268 *
269 * Since the omap_cpu_suspend routine has been copied to
270 * SRAM, we'll do an indirect procedure call to it and pass the
271 * contents of arm_idlect1 and arm_idlect2 so it can restore
272 * them when it wakes up and it will return.
273 */
274
275 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
276 arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
277
278 /*
279 * Step 6c: ARM and Traffic controller shutdown
280 *
281 * Jump to assembly code. The processor will stay there
282 * until wake up.
283 */
284 omap_sram_suspend(arg0, arg1);
285
286 /*
287 * If we are here, processor is woken up!
288 */
289
290 /*
291 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
292 */
293
294 if (!(cpu_is_omap1510()))
295 ARM_RESTORE(ARM_IDLECT3);
296 ARM_RESTORE(ARM_CKCTL);
297 ARM_RESTORE(ARM_EWUPCT);
298 ARM_RESTORE(ARM_RSTCT1);
299 ARM_RESTORE(ARM_RSTCT2);
300 ARM_RESTORE(ARM_SYSST);
301 ULPD_RESTORE(ULPD_CLOCK_CTRL);
302 ULPD_RESTORE(ULPD_STATUS_REQ);
303
304 if (cpu_is_omap730()) {
305 MPUI730_RESTORE(EMIFS_CONFIG);
306 MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
307 MPUI730_RESTORE(OMAP_IH1_MIR);
308 MPUI730_RESTORE(OMAP_IH2_0_MIR);
309 MPUI730_RESTORE(OMAP_IH2_1_MIR);
310 } else if (cpu_is_omap1510()) {
311 MPUI1510_RESTORE(MPUI_CTRL);
312 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
313 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
314 MPUI1510_RESTORE(EMIFS_CONFIG);
315 MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
316 MPUI1510_RESTORE(OMAP_IH1_MIR);
317 MPUI1510_RESTORE(OMAP_IH2_MIR);
318 } else if (cpu_is_omap16xx()) {
319 MPUI1610_RESTORE(MPUI_CTRL);
320 MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
321 MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
322 MPUI1610_RESTORE(EMIFS_CONFIG);
323 MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
324
325 MPUI1610_RESTORE(OMAP_IH1_MIR);
326 MPUI1610_RESTORE(OMAP_IH2_0_MIR);
327 MPUI1610_RESTORE(OMAP_IH2_1_MIR);
328 MPUI1610_RESTORE(OMAP_IH2_2_MIR);
329 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
330 }
331
332 omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
333
334 /*
335 * Reenable interrupts
336 */
337
338 local_irq_enable();
339 local_fiq_enable();
340
341 omap_serial_wake_trigger(0);
342
343 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
344
345 if (machine_is_omap_osk()) {
346 /* Let LED1 (D9) blink again */
347 tps65010_set_led(LED1, BLINK);
348 }
349}
350
351#if defined(DEBUG) && defined(CONFIG_PROC_FS)
352static int g_read_completed;
353
354/*
355 * Read system PM registers for debugging
356 */
357static int omap_pm_read_proc(
358 char *page_buffer,
359 char **my_first_byte,
360 off_t virtual_start,
361 int length,
362 int *eof,
363 void *data)
364{
365 int my_buffer_offset = 0;
366 char * const my_base = page_buffer;
367
368 ARM_SAVE(ARM_CKCTL);
369 ARM_SAVE(ARM_IDLECT1);
370 ARM_SAVE(ARM_IDLECT2);
371 if (!(cpu_is_omap1510()))
372 ARM_SAVE(ARM_IDLECT3);
373 ARM_SAVE(ARM_EWUPCT);
374 ARM_SAVE(ARM_RSTCT1);
375 ARM_SAVE(ARM_RSTCT2);
376 ARM_SAVE(ARM_SYSST);
377
378 ULPD_SAVE(ULPD_IT_STATUS);
379 ULPD_SAVE(ULPD_CLOCK_CTRL);
380 ULPD_SAVE(ULPD_SOFT_REQ);
381 ULPD_SAVE(ULPD_STATUS_REQ);
382 ULPD_SAVE(ULPD_DPLL_CTRL);
383 ULPD_SAVE(ULPD_POWER_CTRL);
384
385 if (cpu_is_omap730()) {
386 MPUI730_SAVE(MPUI_CTRL);
387 MPUI730_SAVE(MPUI_DSP_STATUS);
388 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
389 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
390 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
391 MPUI730_SAVE(EMIFS_CONFIG);
392 } else if (cpu_is_omap1510()) {
393 MPUI1510_SAVE(MPUI_CTRL);
394 MPUI1510_SAVE(MPUI_DSP_STATUS);
395 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
396 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
397 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
398 MPUI1510_SAVE(EMIFS_CONFIG);
399 } else if (cpu_is_omap16xx()) {
400 MPUI1610_SAVE(MPUI_CTRL);
401 MPUI1610_SAVE(MPUI_DSP_STATUS);
402 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
403 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
404 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
405 MPUI1610_SAVE(EMIFS_CONFIG);
406 }
407
408 if (virtual_start == 0) {
409 g_read_completed = 0;
410
411 my_buffer_offset += sprintf(my_base + my_buffer_offset,
412 "ARM_CKCTL_REG: 0x%-8x \n"
413 "ARM_IDLECT1_REG: 0x%-8x \n"
414 "ARM_IDLECT2_REG: 0x%-8x \n"
415 "ARM_IDLECT3_REG: 0x%-8x \n"
416 "ARM_EWUPCT_REG: 0x%-8x \n"
417 "ARM_RSTCT1_REG: 0x%-8x \n"
418 "ARM_RSTCT2_REG: 0x%-8x \n"
419 "ARM_SYSST_REG: 0x%-8x \n"
420 "ULPD_IT_STATUS_REG: 0x%-4x \n"
421 "ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
422 "ULPD_SOFT_REQ_REG: 0x%-4x \n"
423 "ULPD_DPLL_CTRL_REG: 0x%-4x \n"
424 "ULPD_STATUS_REQ_REG: 0x%-4x \n"
425 "ULPD_POWER_CTRL_REG: 0x%-4x \n",
426 ARM_SHOW(ARM_CKCTL),
427 ARM_SHOW(ARM_IDLECT1),
428 ARM_SHOW(ARM_IDLECT2),
429 ARM_SHOW(ARM_IDLECT3),
430 ARM_SHOW(ARM_EWUPCT),
431 ARM_SHOW(ARM_RSTCT1),
432 ARM_SHOW(ARM_RSTCT2),
433 ARM_SHOW(ARM_SYSST),
434 ULPD_SHOW(ULPD_IT_STATUS),
435 ULPD_SHOW(ULPD_CLOCK_CTRL),
436 ULPD_SHOW(ULPD_SOFT_REQ),
437 ULPD_SHOW(ULPD_DPLL_CTRL),
438 ULPD_SHOW(ULPD_STATUS_REQ),
439 ULPD_SHOW(ULPD_POWER_CTRL));
440
441 if (cpu_is_omap730()) {
442 my_buffer_offset += sprintf(my_base + my_buffer_offset,
443 "MPUI730_CTRL_REG 0x%-8x \n"
444 "MPUI730_DSP_STATUS_REG: 0x%-8x \n"
445 "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
446 "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
447 "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
448 "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
449 MPUI730_SHOW(MPUI_CTRL),
450 MPUI730_SHOW(MPUI_DSP_STATUS),
451 MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
452 MPUI730_SHOW(MPUI_DSP_API_CONFIG),
453 MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
454 MPUI730_SHOW(EMIFS_CONFIG));
455 } else if (cpu_is_omap1510()) {
456 my_buffer_offset += sprintf(my_base + my_buffer_offset,
457 "MPUI1510_CTRL_REG 0x%-8x \n"
458 "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
459 "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
460 "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
461 "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
462 "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
463 MPUI1510_SHOW(MPUI_CTRL),
464 MPUI1510_SHOW(MPUI_DSP_STATUS),
465 MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
466 MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
467 MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
468 MPUI1510_SHOW(EMIFS_CONFIG));
469 } else if (cpu_is_omap16xx()) {
470 my_buffer_offset += sprintf(my_base + my_buffer_offset,
471 "MPUI1610_CTRL_REG 0x%-8x \n"
472 "MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
473 "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
474 "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
475 "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
476 "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
477 MPUI1610_SHOW(MPUI_CTRL),
478 MPUI1610_SHOW(MPUI_DSP_STATUS),
479 MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
480 MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
481 MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
482 MPUI1610_SHOW(EMIFS_CONFIG));
483 }
484
485 g_read_completed++;
486 } else if (g_read_completed >= 1) {
487 *eof = 1;
488 return 0;
489 }
490 g_read_completed++;
491
492 *my_first_byte = page_buffer;
493 return my_buffer_offset;
494}
495
496static void omap_pm_init_proc(void)
497{
498 struct proc_dir_entry *entry;
499
500 entry = create_proc_read_entry("driver/omap_pm",
501 S_IWUSR | S_IRUGO, NULL,
502 omap_pm_read_proc, NULL);
503}
504
505#endif /* DEBUG && CONFIG_PROC_FS */
506
507/*
508 * omap_pm_prepare - Do preliminary suspend work.
509 * @state: suspend state we're entering.
510 *
511 */
512//#include <asm/hardware.h>
513
514static int omap_pm_prepare(suspend_state_t state)
515{
516 int error = 0;
517
518 switch (state)
519 {
520 case PM_SUSPEND_STANDBY:
521 case PM_SUSPEND_MEM:
522 break;
523
524 case PM_SUSPEND_DISK:
525 return -ENOTSUPP;
526
527 default:
528 return -EINVAL;
529 }
530
531 return error;
532}
533
534
535/*
536 * omap_pm_enter - Actually enter a sleep state.
537 * @state: State we're entering.
538 *
539 */
540
541static int omap_pm_enter(suspend_state_t state)
542{
543 switch (state)
544 {
545 case PM_SUSPEND_STANDBY:
546 case PM_SUSPEND_MEM:
547 omap_pm_suspend();
548 break;
549
550 case PM_SUSPEND_DISK:
551 return -ENOTSUPP;
552
553 default:
554 return -EINVAL;
555 }
556
557 return 0;
558}
559
560
561/**
562 * omap_pm_finish - Finish up suspend sequence.
563 * @state: State we're coming out of.
564 *
565 * This is called after we wake back up (or if entering the sleep state
566 * failed).
567 */
568
569static int omap_pm_finish(suspend_state_t state)
570{
571 return 0;
572}
573
574
575static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
576 struct pt_regs * regs)
577{
578 return IRQ_HANDLED;
579}
580
581static struct irqaction omap_wakeup_irq = {
582 .name = "peripheral wakeup",
583 .flags = IRQF_DISABLED,
584 .handler = omap_wakeup_interrupt
585};
586
587
588
589static struct pm_ops omap_pm_ops ={
590 .pm_disk_mode = 0,
591 .prepare = omap_pm_prepare,
592 .enter = omap_pm_enter,
593 .finish = omap_pm_finish,
594};
595
596static int __init omap_pm_init(void)
597{
598 printk("Power Management for TI OMAP.\n");
599 /*
600 * We copy the assembler sleep/wakeup routines to SRAM.
601 * These routines need to be in SRAM as that's the only
602 * memory the MPU can see when it wakes up.
603 */
604 if (cpu_is_omap730()) {
605 omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
606 omap730_idle_loop_suspend_sz);
607 omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
608 omap730_cpu_suspend_sz);
609 } else if (cpu_is_omap1510()) {
610 omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
611 omap1510_idle_loop_suspend_sz);
612 omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
613 omap1510_cpu_suspend_sz);
614 } else if (cpu_is_omap16xx()) {
615 omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
616 omap1610_idle_loop_suspend_sz);
617 omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
618 omap1610_cpu_suspend_sz);
619 }
620
621 if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
622 printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
623 return -ENODEV;
624 }
625
626 pm_idle = omap_pm_idle;
627
628 if (cpu_is_omap730())
629 setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
630 else if (cpu_is_omap16xx())
631 setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
632
633#if 0
634 /* --- BEGIN BOARD-DEPENDENT CODE --- */
635 /* Sleepx mask direction */
636 omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
637 /* Unmask sleepx signal */
638 omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
639 /* --- END BOARD-DEPENDENT CODE --- */
640#endif
641
642 /* Program new power ramp-up time
643 * (0 for most boards since we don't lower voltage when in deep sleep)
644 */
645 omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
646
647 /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
648 omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
649
650 /* Configure IDLECT3 */
651 if (cpu_is_omap730())
652 omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
653 else if (cpu_is_omap16xx())
654 omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
655
656 pm_set_ops(&omap_pm_ops);
657
658#if defined(DEBUG) && defined(CONFIG_PROC_FS)
659 omap_pm_init_proc();
660#endif
661
662 if (cpu_is_omap16xx()) {
663 /* configure LOW_PWR pin */
664 omap_cfg_reg(T20_1610_LOW_PWR);
665 }
666
667 return 0;
668}
669__initcall(omap_pm_init);
670
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e75718301b0f..19014b2ff4c6 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -174,10 +174,7 @@ void __init omap_map_sram(void)
174 if (cpu_is_omap24xx()) { 174 if (cpu_is_omap24xx()) {
175 omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; 175 omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
176 176
177 if (is_sram_locked()) 177 base = OMAP2_SRAM_PA;
178 base = OMAP2_SRAM_PUB_PA;
179 else
180 base = OMAP2_SRAM_PA;
181 base = ROUND_DOWN(base, PAGE_SIZE); 178 base = ROUND_DOWN(base, PAGE_SIZE);
182 omap_sram_io_desc[0].pfn = __phys_to_pfn(base); 179 omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
183 } 180 }
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c
index 281ecc7fcdfc..cf6df3378d37 100644
--- a/arch/arm/plat-omap/timer32k.c
+++ b/arch/arm/plat-omap/timer32k.c
@@ -105,6 +105,8 @@ static inline unsigned long omap_32k_timer_read(int reg)
105 105
106static inline void omap_32k_timer_start(unsigned long load_val) 106static inline void omap_32k_timer_start(unsigned long load_val)
107{ 107{
108 if (!load_val)
109 load_val = 1;
108 omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); 110 omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
109 omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); 111 omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
110} 112}
@@ -192,14 +194,11 @@ unsigned long long sched_clock(void)
192 * issues with dynamic tick. In the dynamic tick case, we need to lock 194 * issues with dynamic tick. In the dynamic tick case, we need to lock
193 * with irqsave. 195 * with irqsave.
194 */ 196 */
195static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, 197static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id,
196 struct pt_regs *regs) 198 struct pt_regs *regs)
197{ 199{
198 unsigned long flags;
199 unsigned long now; 200 unsigned long now;
200 201
201 write_seqlock_irqsave(&xtime_lock, flags);
202
203 omap_32k_timer_ack_irq(); 202 omap_32k_timer_ack_irq();
204 now = omap_32k_sync_timer_read(); 203 now = omap_32k_sync_timer_read();
205 204
@@ -215,6 +214,23 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
215 * continuous timer can be overridden from pm_idle to be longer. 214 * continuous timer can be overridden from pm_idle to be longer.
216 */ 215 */
217 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); 216 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
217
218 return IRQ_HANDLED;
219}
220
221static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id,
222 struct pt_regs *regs)
223{
224 return _omap_32k_timer_interrupt(irq, dev_id, regs);
225}
226
227static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
228 struct pt_regs *regs)
229{
230 unsigned long flags;
231
232 write_seqlock_irqsave(&xtime_lock, flags);
233 _omap_32k_timer_interrupt(irq, dev_id, regs);
218 write_sequnlock_irqrestore(&xtime_lock, flags); 234 write_sequnlock_irqrestore(&xtime_lock, flags);
219 235
220 return IRQ_HANDLED; 236 return IRQ_HANDLED;
@@ -230,7 +246,15 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
230 */ 246 */
231void omap_32k_timer_reprogram(unsigned long next_tick) 247void omap_32k_timer_reprogram(unsigned long next_tick)
232{ 248{
233 omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); 249 unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1;
250 unsigned long now = omap_32k_sync_timer_read();
251 unsigned long idled = now - omap_32k_last_tick;
252
253 if (idled + 1 < ticks)
254 ticks -= idled;
255 else
256 ticks = 1;
257 omap_32k_timer_start(ticks);
234} 258}
235 259
236static struct irqaction omap_32k_timer_irq; 260static struct irqaction omap_32k_timer_irq;
@@ -252,7 +276,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = {
252 .enable = omap_32k_timer_enable_dyn_tick, 276 .enable = omap_32k_timer_enable_dyn_tick,
253 .disable = omap_32k_timer_disable_dyn_tick, 277 .disable = omap_32k_timer_disable_dyn_tick,
254 .reprogram = omap_32k_timer_reprogram, 278 .reprogram = omap_32k_timer_reprogram,
255 .handler = omap_32k_timer_interrupt, 279 .handler = omap_32k_timer_handler,
256}; 280};
257#endif /* CONFIG_NO_IDLE_HZ */ 281#endif /* CONFIG_NO_IDLE_HZ */
258 282
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index d163747d17c0..038e3a8457e0 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -108,11 +108,8 @@ Image: vmlinux
108bootstrap: 108bootstrap:
109 $(Q)$(MAKEBOOT) bootstrap 109 $(Q)$(MAKEBOOT) bootstrap
110 110
111archmrproper:
112 $(Q)$(MAKE) $(build)=arch/frv/boot mrproper
113
114archclean: 111archclean:
115 $(Q)$(MAKE) $(build)=arch/frv/boot clean 112 $(Q)$(MAKE) $(clean)=arch/frv/boot
116 113
117archdep: scripts/mkdep symlinks 114archdep: scripts/mkdep symlinks
118 $(Q)$(MAKE) $(build)=arch/frv/boot dep 115 $(Q)$(MAKE) $(build)=arch/frv/boot dep
diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
index 5dfc93fd945a..dc6f03824423 100644
--- a/arch/frv/boot/Makefile
+++ b/arch/frv/boot/Makefile
@@ -8,6 +8,8 @@
8# Copyright (C) 1995-2000 Russell King 8# Copyright (C) 1995-2000 Russell King
9# 9#
10 10
11targets := Image zImage bootpImage
12
11SYSTEM =$(TOPDIR)/$(LINUX) 13SYSTEM =$(TOPDIR)/$(LINUX)
12 14
13ZTEXTADDR = 0x02080000 15ZTEXTADDR = 0x02080000
@@ -66,7 +68,6 @@ zinstall: $(CONFIGURE) zImage
66# miscellany 68# miscellany
67# 69#
68mrproper clean: 70mrproper clean:
69 $(RM) Image zImage bootpImage
70# @$(MAKE) -C compressed clean 71# @$(MAKE) -C compressed clean
71# @$(MAKE) -C bootp clean 72# @$(MAKE) -C bootp clean
72 73
diff --git a/arch/i386/crypto/Makefile b/arch/i386/crypto/Makefile
index 103c353d0a63..3fd19af18e34 100644
--- a/arch/i386/crypto/Makefile
+++ b/arch/i386/crypto/Makefile
@@ -5,5 +5,8 @@
5# 5#
6 6
7obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o 7obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
8obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
8 9
9aes-i586-y := aes-i586-asm.o aes.o 10aes-i586-y := aes-i586-asm.o aes.o
11twofish-i586-y := twofish-i586-asm.o twofish.o
12
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c
index d3806daa3de3..49aad9397f10 100644
--- a/arch/i386/crypto/aes.c
+++ b/arch/i386/crypto/aes.c
@@ -379,12 +379,13 @@ static void gen_tabs(void)
379} 379}
380 380
381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 381static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
382 unsigned int key_len, u32 *flags) 382 unsigned int key_len)
383{ 383{
384 int i; 384 int i;
385 u32 ss[8]; 385 u32 ss[8];
386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 386 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
387 const __le32 *key = (const __le32 *)in_key; 387 const __le32 *key = (const __le32 *)in_key;
388 u32 *flags = &tfm->crt_flags;
388 389
389 /* encryption schedule */ 390 /* encryption schedule */
390 391
diff --git a/arch/i386/crypto/twofish-i586-asm.S b/arch/i386/crypto/twofish-i586-asm.S
new file mode 100644
index 000000000000..39b98ed2c1b9
--- /dev/null
+++ b/arch/i386/crypto/twofish-i586-asm.S
@@ -0,0 +1,335 @@
1/***************************************************************************
2* Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
3* *
4* This program is free software; you can redistribute it and/or modify *
5* it under the terms of the GNU General Public License as published by *
6* the Free Software Foundation; either version 2 of the License, or *
7* (at your option) any later version. *
8* *
9* This program is distributed in the hope that it will be useful, *
10* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12* GNU General Public License for more details. *
13* *
14* You should have received a copy of the GNU General Public License *
15* along with this program; if not, write to the *
16* Free Software Foundation, Inc., *
17* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18***************************************************************************/
19
20.file "twofish-i586-asm.S"
21.text
22
23#include <asm/asm-offsets.h>
24
25/* return adress at 0 */
26
27#define in_blk 12 /* input byte array address parameter*/
28#define out_blk 8 /* output byte array address parameter*/
29#define tfm 4 /* Twofish context structure */
30
31#define a_offset 0
32#define b_offset 4
33#define c_offset 8
34#define d_offset 12
35
36/* Structure of the crypto context struct*/
37
38#define s0 0 /* S0 Array 256 Words each */
39#define s1 1024 /* S1 Array */
40#define s2 2048 /* S2 Array */
41#define s3 3072 /* S3 Array */
42#define w 4096 /* 8 whitening keys (word) */
43#define k 4128 /* key 1-32 ( word ) */
44
45/* define a few register aliases to allow macro substitution */
46
47#define R0D %eax
48#define R0B %al
49#define R0H %ah
50
51#define R1D %ebx
52#define R1B %bl
53#define R1H %bh
54
55#define R2D %ecx
56#define R2B %cl
57#define R2H %ch
58
59#define R3D %edx
60#define R3B %dl
61#define R3H %dh
62
63
64/* performs input whitening */
65#define input_whitening(src,context,offset)\
66 xor w+offset(context), src;
67
68/* performs input whitening */
69#define output_whitening(src,context,offset)\
70 xor w+16+offset(context), src;
71
72/*
73 * a input register containing a (rotated 16)
74 * b input register containing b
75 * c input register containing c
76 * d input register containing d (already rol $1)
77 * operations on a and b are interleaved to increase performance
78 */
79#define encrypt_round(a,b,c,d,round)\
80 push d ## D;\
81 movzx b ## B, %edi;\
82 mov s1(%ebp,%edi,4),d ## D;\
83 movzx a ## B, %edi;\
84 mov s2(%ebp,%edi,4),%esi;\
85 movzx b ## H, %edi;\
86 ror $16, b ## D;\
87 xor s2(%ebp,%edi,4),d ## D;\
88 movzx a ## H, %edi;\
89 ror $16, a ## D;\
90 xor s3(%ebp,%edi,4),%esi;\
91 movzx b ## B, %edi;\
92 xor s3(%ebp,%edi,4),d ## D;\
93 movzx a ## B, %edi;\
94 xor (%ebp,%edi,4), %esi;\
95 movzx b ## H, %edi;\
96 ror $15, b ## D;\
97 xor (%ebp,%edi,4), d ## D;\
98 movzx a ## H, %edi;\
99 xor s1(%ebp,%edi,4),%esi;\
100 pop %edi;\
101 add d ## D, %esi;\
102 add %esi, d ## D;\
103 add k+round(%ebp), %esi;\
104 xor %esi, c ## D;\
105 rol $15, c ## D;\
106 add k+4+round(%ebp),d ## D;\
107 xor %edi, d ## D;
108
109/*
110 * a input register containing a (rotated 16)
111 * b input register containing b
112 * c input register containing c
113 * d input register containing d (already rol $1)
114 * operations on a and b are interleaved to increase performance
115 * last round has different rotations for the output preparation
116 */
117#define encrypt_last_round(a,b,c,d,round)\
118 push d ## D;\
119 movzx b ## B, %edi;\
120 mov s1(%ebp,%edi,4),d ## D;\
121 movzx a ## B, %edi;\
122 mov s2(%ebp,%edi,4),%esi;\
123 movzx b ## H, %edi;\
124 ror $16, b ## D;\
125 xor s2(%ebp,%edi,4),d ## D;\
126 movzx a ## H, %edi;\
127 ror $16, a ## D;\
128 xor s3(%ebp,%edi,4),%esi;\
129 movzx b ## B, %edi;\
130 xor s3(%ebp,%edi,4),d ## D;\
131 movzx a ## B, %edi;\
132 xor (%ebp,%edi,4), %esi;\
133 movzx b ## H, %edi;\
134 ror $16, b ## D;\
135 xor (%ebp,%edi,4), d ## D;\
136 movzx a ## H, %edi;\
137 xor s1(%ebp,%edi,4),%esi;\
138 pop %edi;\
139 add d ## D, %esi;\
140 add %esi, d ## D;\
141 add k+round(%ebp), %esi;\
142 xor %esi, c ## D;\
143 ror $1, c ## D;\
144 add k+4+round(%ebp),d ## D;\
145 xor %edi, d ## D;
146
147/*
148 * a input register containing a
149 * b input register containing b (rotated 16)
150 * c input register containing c
151 * d input register containing d (already rol $1)
152 * operations on a and b are interleaved to increase performance
153 */
154#define decrypt_round(a,b,c,d,round)\
155 push c ## D;\
156 movzx a ## B, %edi;\
157 mov (%ebp,%edi,4), c ## D;\
158 movzx b ## B, %edi;\
159 mov s3(%ebp,%edi,4),%esi;\
160 movzx a ## H, %edi;\
161 ror $16, a ## D;\
162 xor s1(%ebp,%edi,4),c ## D;\
163 movzx b ## H, %edi;\
164 ror $16, b ## D;\
165 xor (%ebp,%edi,4), %esi;\
166 movzx a ## B, %edi;\
167 xor s2(%ebp,%edi,4),c ## D;\
168 movzx b ## B, %edi;\
169 xor s1(%ebp,%edi,4),%esi;\
170 movzx a ## H, %edi;\
171 ror $15, a ## D;\
172 xor s3(%ebp,%edi,4),c ## D;\
173 movzx b ## H, %edi;\
174 xor s2(%ebp,%edi,4),%esi;\
175 pop %edi;\
176 add %esi, c ## D;\
177 add c ## D, %esi;\
178 add k+round(%ebp), c ## D;\
179 xor %edi, c ## D;\
180 add k+4+round(%ebp),%esi;\
181 xor %esi, d ## D;\
182 rol $15, d ## D;
183
184/*
185 * a input register containing a
186 * b input register containing b (rotated 16)
187 * c input register containing c
188 * d input register containing d (already rol $1)
189 * operations on a and b are interleaved to increase performance
190 * last round has different rotations for the output preparation
191 */
192#define decrypt_last_round(a,b,c,d,round)\
193 push c ## D;\
194 movzx a ## B, %edi;\
195 mov (%ebp,%edi,4), c ## D;\
196 movzx b ## B, %edi;\
197 mov s3(%ebp,%edi,4),%esi;\
198 movzx a ## H, %edi;\
199 ror $16, a ## D;\
200 xor s1(%ebp,%edi,4),c ## D;\
201 movzx b ## H, %edi;\
202 ror $16, b ## D;\
203 xor (%ebp,%edi,4), %esi;\
204 movzx a ## B, %edi;\
205 xor s2(%ebp,%edi,4),c ## D;\
206 movzx b ## B, %edi;\
207 xor s1(%ebp,%edi,4),%esi;\
208 movzx a ## H, %edi;\
209 ror $16, a ## D;\
210 xor s3(%ebp,%edi,4),c ## D;\
211 movzx b ## H, %edi;\
212 xor s2(%ebp,%edi,4),%esi;\
213 pop %edi;\
214 add %esi, c ## D;\
215 add c ## D, %esi;\
216 add k+round(%ebp), c ## D;\
217 xor %edi, c ## D;\
218 add k+4+round(%ebp),%esi;\
219 xor %esi, d ## D;\
220 ror $1, d ## D;
221
222.align 4
223.global twofish_enc_blk
224.global twofish_dec_blk
225
226twofish_enc_blk:
227 push %ebp /* save registers according to calling convention*/
228 push %ebx
229 push %esi
230 push %edi
231
232 mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
233 add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
234 mov in_blk+16(%esp),%edi /* input adress in edi */
235
236 mov (%edi), %eax
237 mov b_offset(%edi), %ebx
238 mov c_offset(%edi), %ecx
239 mov d_offset(%edi), %edx
240 input_whitening(%eax,%ebp,a_offset)
241 ror $16, %eax
242 input_whitening(%ebx,%ebp,b_offset)
243 input_whitening(%ecx,%ebp,c_offset)
244 input_whitening(%edx,%ebp,d_offset)
245 rol $1, %edx
246
247 encrypt_round(R0,R1,R2,R3,0);
248 encrypt_round(R2,R3,R0,R1,8);
249 encrypt_round(R0,R1,R2,R3,2*8);
250 encrypt_round(R2,R3,R0,R1,3*8);
251 encrypt_round(R0,R1,R2,R3,4*8);
252 encrypt_round(R2,R3,R0,R1,5*8);
253 encrypt_round(R0,R1,R2,R3,6*8);
254 encrypt_round(R2,R3,R0,R1,7*8);
255 encrypt_round(R0,R1,R2,R3,8*8);
256 encrypt_round(R2,R3,R0,R1,9*8);
257 encrypt_round(R0,R1,R2,R3,10*8);
258 encrypt_round(R2,R3,R0,R1,11*8);
259 encrypt_round(R0,R1,R2,R3,12*8);
260 encrypt_round(R2,R3,R0,R1,13*8);
261 encrypt_round(R0,R1,R2,R3,14*8);
262 encrypt_last_round(R2,R3,R0,R1,15*8);
263
264 output_whitening(%eax,%ebp,c_offset)
265 output_whitening(%ebx,%ebp,d_offset)
266 output_whitening(%ecx,%ebp,a_offset)
267 output_whitening(%edx,%ebp,b_offset)
268 mov out_blk+16(%esp),%edi;
269 mov %eax, c_offset(%edi)
270 mov %ebx, d_offset(%edi)
271 mov %ecx, (%edi)
272 mov %edx, b_offset(%edi)
273
274 pop %edi
275 pop %esi
276 pop %ebx
277 pop %ebp
278 mov $1, %eax
279 ret
280
281twofish_dec_blk:
282 push %ebp /* save registers according to calling convention*/
283 push %ebx
284 push %esi
285 push %edi
286
287
288 mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
289 add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
290 mov in_blk+16(%esp),%edi /* input adress in edi */
291
292 mov (%edi), %eax
293 mov b_offset(%edi), %ebx
294 mov c_offset(%edi), %ecx
295 mov d_offset(%edi), %edx
296 output_whitening(%eax,%ebp,a_offset)
297 output_whitening(%ebx,%ebp,b_offset)
298 ror $16, %ebx
299 output_whitening(%ecx,%ebp,c_offset)
300 output_whitening(%edx,%ebp,d_offset)
301 rol $1, %ecx
302
303 decrypt_round(R0,R1,R2,R3,15*8);
304 decrypt_round(R2,R3,R0,R1,14*8);
305 decrypt_round(R0,R1,R2,R3,13*8);
306 decrypt_round(R2,R3,R0,R1,12*8);
307 decrypt_round(R0,R1,R2,R3,11*8);
308 decrypt_round(R2,R3,R0,R1,10*8);
309 decrypt_round(R0,R1,R2,R3,9*8);
310 decrypt_round(R2,R3,R0,R1,8*8);
311 decrypt_round(R0,R1,R2,R3,7*8);
312 decrypt_round(R2,R3,R0,R1,6*8);
313 decrypt_round(R0,R1,R2,R3,5*8);
314 decrypt_round(R2,R3,R0,R1,4*8);
315 decrypt_round(R0,R1,R2,R3,3*8);
316 decrypt_round(R2,R3,R0,R1,2*8);
317 decrypt_round(R0,R1,R2,R3,1*8);
318 decrypt_last_round(R2,R3,R0,R1,0);
319
320 input_whitening(%eax,%ebp,c_offset)
321 input_whitening(%ebx,%ebp,d_offset)
322 input_whitening(%ecx,%ebp,a_offset)
323 input_whitening(%edx,%ebp,b_offset)
324 mov out_blk+16(%esp),%edi;
325 mov %eax, c_offset(%edi)
326 mov %ebx, d_offset(%edi)
327 mov %ecx, (%edi)
328 mov %edx, b_offset(%edi)
329
330 pop %edi
331 pop %esi
332 pop %ebx
333 pop %ebp
334 mov $1, %eax
335 ret
diff --git a/arch/i386/crypto/twofish.c b/arch/i386/crypto/twofish.c
new file mode 100644
index 000000000000..e3004dfe9c7a
--- /dev/null
+++ b/arch/i386/crypto/twofish.c
@@ -0,0 +1,97 @@
1/*
2 * Glue Code for optimized 586 assembler version of TWOFISH
3 *
4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
6 * 256-bit key length added March 20, 1999
7 * Some modifications to reduce the text size by Werner Koch, April, 1998
8 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
9 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
10 *
11 * The original author has disclaimed all copyright interest in this
12 * code and thus put it in the public domain. The subsequent authors
13 * have put this under the GNU General Public License.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 *
30 * This code is a "clean room" implementation, written from the paper
31 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
32 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
33 * through http://www.counterpane.com/twofish.html
34 *
35 * For background information on multiplication in finite fields, used for
36 * the matrix operations in the key schedule, see the book _Contemporary
37 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
38 * Third Edition.
39 */
40
41#include <crypto/twofish.h>
42#include <linux/crypto.h>
43#include <linux/init.h>
44#include <linux/module.h>
45#include <linux/types.h>
46
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
52{
53 twofish_enc_blk(tfm, dst, src);
54}
55
56static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
57{
58 twofish_dec_blk(tfm, dst, src);
59}
60
61static struct crypto_alg alg = {
62 .cra_name = "twofish",
63 .cra_driver_name = "twofish-i586",
64 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE,
67 .cra_ctxsize = sizeof(struct twofish_ctx),
68 .cra_alignmask = 3,
69 .cra_module = THIS_MODULE,
70 .cra_list = LIST_HEAD_INIT(alg.cra_list),
71 .cra_u = {
72 .cipher = {
73 .cia_min_keysize = TF_MIN_KEY_SIZE,
74 .cia_max_keysize = TF_MAX_KEY_SIZE,
75 .cia_setkey = twofish_setkey,
76 .cia_encrypt = twofish_encrypt,
77 .cia_decrypt = twofish_decrypt
78 }
79 }
80};
81
82static int __init init(void)
83{
84 return crypto_register_alg(&alg);
85}
86
87static void __exit fini(void)
88{
89 crypto_unregister_alg(&alg);
90}
91
92module_init(init);
93module_exit(fini);
94
95MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized");
97MODULE_ALIAS("twofish");
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index e6ea00edcb54..ea19d091fd41 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -32,6 +32,7 @@
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/compiler.h> 33#include <linux/compiler.h>
34#include <linux/sched.h> /* current */ 34#include <linux/sched.h> /* current */
35#include <linux/dmi.h>
35#include <asm/io.h> 36#include <asm/io.h>
36#include <asm/delay.h> 37#include <asm/delay.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
@@ -387,6 +388,33 @@ static int acpi_cpufreq_early_init_acpi(void)
387 return acpi_processor_preregister_performance(acpi_perf_data); 388 return acpi_processor_preregister_performance(acpi_perf_data);
388} 389}
389 390
391/*
392 * Some BIOSes do SW_ANY coordination internally, either set it up in hw
393 * or do it in BIOS firmware and won't inform about it to OS. If not
394 * detected, this has a side effect of making CPU run at a different speed
395 * than OS intended it to run at. Detect it and handle it cleanly.
396 */
397static int bios_with_sw_any_bug;
398
399static int __init sw_any_bug_found(struct dmi_system_id *d)
400{
401 bios_with_sw_any_bug = 1;
402 return 0;
403}
404
405static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = {
406 {
407 .callback = sw_any_bug_found,
408 .ident = "Supermicro Server X6DLP",
409 .matches = {
410 DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
411 DMI_MATCH(DMI_BIOS_VERSION, "080010"),
412 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
413 },
414 },
415 { }
416};
417
390static int 418static int
391acpi_cpufreq_cpu_init ( 419acpi_cpufreq_cpu_init (
392 struct cpufreq_policy *policy) 420 struct cpufreq_policy *policy)
@@ -422,8 +450,17 @@ acpi_cpufreq_cpu_init (
422 * coordination is required. 450 * coordination is required.
423 */ 451 */
424 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || 452 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
425 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) 453 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
426 policy->cpus = perf->shared_cpu_map; 454 policy->cpus = perf->shared_cpu_map;
455 }
456
457#ifdef CONFIG_SMP
458 dmi_check_system(sw_any_bug_dmi_table);
459 if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
460 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
461 policy->cpus = cpu_core_map[cpu];
462 }
463#endif
427 464
428 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { 465 if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
429 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; 466 acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index 4f2c3aeef724..f5cc9f5c9bab 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -27,6 +27,7 @@
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/cpufreq.h> 29#include <linux/cpufreq.h>
30#include <linux/pci.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/string.h> 32#include <linux/string.h>
32 33
@@ -52,18 +53,26 @@
52#define CPU_NEHEMIAH 5 53#define CPU_NEHEMIAH 5
53 54
54static int cpu_model; 55static int cpu_model;
55static unsigned int numscales=16, numvscales; 56static unsigned int numscales=16;
56static unsigned int fsb; 57static unsigned int fsb;
57static int minvid, maxvid; 58
59static struct mV_pos *vrm_mV_table;
60static unsigned char *mV_vrm_table;
61struct f_msr {
62 unsigned char vrm;
63};
64static struct f_msr f_msr_table[32];
65
66static unsigned int highest_speed, lowest_speed; /* kHz */
58static unsigned int minmult, maxmult; 67static unsigned int minmult, maxmult;
59static int can_scale_voltage; 68static int can_scale_voltage;
60static int vrmrev;
61static struct acpi_processor *pr = NULL; 69static struct acpi_processor *pr = NULL;
62static struct acpi_processor_cx *cx = NULL; 70static struct acpi_processor_cx *cx = NULL;
71static int port22_en;
63 72
64/* Module parameters */ 73/* Module parameters */
65static int dont_scale_voltage; 74static int scale_voltage;
66 75static int ignore_latency;
67 76
68#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg) 77#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
69 78
@@ -71,7 +80,6 @@ static int dont_scale_voltage;
71/* Clock ratios multiplied by 10 */ 80/* Clock ratios multiplied by 10 */
72static int clock_ratio[32]; 81static int clock_ratio[32];
73static int eblcr_table[32]; 82static int eblcr_table[32];
74static int voltage_table[32];
75static unsigned int highest_speed, lowest_speed; /* kHz */ 83static unsigned int highest_speed, lowest_speed; /* kHz */
76static int longhaul_version; 84static int longhaul_version;
77static struct cpufreq_frequency_table *longhaul_table; 85static struct cpufreq_frequency_table *longhaul_table;
@@ -124,10 +132,9 @@ static int longhaul_get_cpu_mult(void)
124 132
125/* For processor with BCR2 MSR */ 133/* For processor with BCR2 MSR */
126 134
127static void do_longhaul1(int cx_address, unsigned int clock_ratio_index) 135static void do_longhaul1(unsigned int clock_ratio_index)
128{ 136{
129 union msr_bcr2 bcr2; 137 union msr_bcr2 bcr2;
130 u32 t;
131 138
132 rdmsrl(MSR_VIA_BCR2, bcr2.val); 139 rdmsrl(MSR_VIA_BCR2, bcr2.val);
133 /* Enable software clock multiplier */ 140 /* Enable software clock multiplier */
@@ -136,13 +143,11 @@ static void do_longhaul1(int cx_address, unsigned int clock_ratio_index)
136 143
137 /* Sync to timer tick */ 144 /* Sync to timer tick */
138 safe_halt(); 145 safe_halt();
139 ACPI_FLUSH_CPU_CACHE();
140 /* Change frequency on next halt or sleep */ 146 /* Change frequency on next halt or sleep */
141 wrmsrl(MSR_VIA_BCR2, bcr2.val); 147 wrmsrl(MSR_VIA_BCR2, bcr2.val);
142 /* Invoke C3 */ 148 /* Invoke transition */
143 inb(cx_address); 149 ACPI_FLUSH_CPU_CACHE();
144 /* Dummy op - must do something useless after P_LVL3 read */ 150 halt();
145 t = inl(acpi_fadt.xpm_tmr_blk.address);
146 151
147 /* Disable software clock multiplier */ 152 /* Disable software clock multiplier */
148 local_irq_disable(); 153 local_irq_disable();
@@ -164,11 +169,16 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index)
164 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; 169 longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
165 longhaul.bits.EnableSoftBusRatio = 1; 170 longhaul.bits.EnableSoftBusRatio = 1;
166 171
172 if (can_scale_voltage) {
173 longhaul.bits.SoftVID = f_msr_table[clock_ratio_index].vrm;
174 longhaul.bits.EnableSoftVID = 1;
175 }
176
167 /* Sync to timer tick */ 177 /* Sync to timer tick */
168 safe_halt(); 178 safe_halt();
169 ACPI_FLUSH_CPU_CACHE();
170 /* Change frequency on next halt or sleep */ 179 /* Change frequency on next halt or sleep */
171 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); 180 wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
181 ACPI_FLUSH_CPU_CACHE();
172 /* Invoke C3 */ 182 /* Invoke C3 */
173 inb(cx_address); 183 inb(cx_address);
174 /* Dummy op - must do something useless after P_LVL3 read */ 184 /* Dummy op - must do something useless after P_LVL3 read */
@@ -227,10 +237,13 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
227 outb(0xFF,0xA1); /* Overkill */ 237 outb(0xFF,0xA1); /* Overkill */
228 outb(0xFE,0x21); /* TMR0 only */ 238 outb(0xFE,0x21); /* TMR0 only */
229 239
230 /* Disable bus master arbitration */ 240 if (pr->flags.bm_control) {
231 if (pr->flags.bm_check) { 241 /* Disable bus master arbitration */
232 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, 242 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
233 ACPI_MTX_DO_NOT_LOCK); 243 ACPI_MTX_DO_NOT_LOCK);
244 } else if (port22_en) {
245 /* Disable AGP and PCI arbiters */
246 outb(3, 0x22);
234 } 247 }
235 248
236 switch (longhaul_version) { 249 switch (longhaul_version) {
@@ -244,7 +257,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
244 */ 257 */
245 case TYPE_LONGHAUL_V1: 258 case TYPE_LONGHAUL_V1:
246 case TYPE_LONGHAUL_V2: 259 case TYPE_LONGHAUL_V2:
247 do_longhaul1(cx->address, clock_ratio_index); 260 do_longhaul1(clock_ratio_index);
248 break; 261 break;
249 262
250 /* 263 /*
@@ -259,14 +272,20 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
259 * to work in practice. 272 * to work in practice.
260 */ 273 */
261 case TYPE_POWERSAVER: 274 case TYPE_POWERSAVER:
275 /* Don't allow wakeup */
276 acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0,
277 ACPI_MTX_DO_NOT_LOCK);
262 do_powersaver(cx->address, clock_ratio_index); 278 do_powersaver(cx->address, clock_ratio_index);
263 break; 279 break;
264 } 280 }
265 281
266 /* Enable bus master arbitration */ 282 if (pr->flags.bm_control) {
267 if (pr->flags.bm_check) { 283 /* Enable bus master arbitration */
268 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, 284 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,
269 ACPI_MTX_DO_NOT_LOCK); 285 ACPI_MTX_DO_NOT_LOCK);
286 } else if (port22_en) {
287 /* Enable arbiters */
288 outb(0, 0x22);
270 } 289 }
271 290
272 outb(pic2_mask,0xA1); /* restore mask */ 291 outb(pic2_mask,0xA1); /* restore mask */
@@ -446,53 +465,57 @@ static int __init longhaul_get_ranges(void)
446static void __init longhaul_setup_voltagescaling(void) 465static void __init longhaul_setup_voltagescaling(void)
447{ 466{
448 union msr_longhaul longhaul; 467 union msr_longhaul longhaul;
468 struct mV_pos minvid, maxvid;
469 unsigned int j, speed, pos, kHz_step, numvscales;
449 470
450 rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); 471 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
451 472 if (!(longhaul.bits.RevisionID & 1)) {
452 if (!(longhaul.bits.RevisionID & 1)) 473 printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
453 return; 474 return;
475 }
476
477 if (!longhaul.bits.VRMRev) {
478 printk (KERN_INFO PFX "VRM 8.5\n");
479 vrm_mV_table = &vrm85_mV[0];
480 mV_vrm_table = &mV_vrm85[0];
481 } else {
482 printk (KERN_INFO PFX "Mobile VRM\n");
483 vrm_mV_table = &mobilevrm_mV[0];
484 mV_vrm_table = &mV_mobilevrm[0];
485 }
454 486
455 minvid = longhaul.bits.MinimumVID; 487 minvid = vrm_mV_table[longhaul.bits.MinimumVID];
456 maxvid = longhaul.bits.MaximumVID; 488 maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
457 vrmrev = longhaul.bits.VRMRev; 489 numvscales = maxvid.pos - minvid.pos + 1;
490 kHz_step = (highest_speed - lowest_speed) / numvscales;
458 491
459 if (minvid == 0 || maxvid == 0) { 492 if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
460 printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " 493 printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
461 "Voltage scaling disabled.\n", 494 "Voltage scaling disabled.\n",
462 minvid/1000, minvid%1000, maxvid/1000, maxvid%1000); 495 minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
463 return; 496 return;
464 } 497 }
465 498
466 if (minvid == maxvid) { 499 if (minvid.mV == maxvid.mV) {
467 printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are " 500 printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
468 "both %d.%03d. Voltage scaling disabled\n", 501 "both %d.%03d. Voltage scaling disabled\n",
469 maxvid/1000, maxvid%1000); 502 maxvid.mV/1000, maxvid.mV%1000);
470 return; 503 return;
471 } 504 }
472 505
473 if (vrmrev==0) { 506 printk(KERN_INFO PFX "Max VID=%d.%03d Min VID=%d.%03d, %d possible voltage scales\n",
474 dprintk ("VRM 8.5\n"); 507 maxvid.mV/1000, maxvid.mV%1000,
475 memcpy (voltage_table, vrm85scales, sizeof(voltage_table)); 508 minvid.mV/1000, minvid.mV%1000,
476 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25; 509 numvscales);
477 } else { 510
478 dprintk ("Mobile VRM\n"); 511 j = 0;
479 memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table)); 512 while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
480 numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5; 513 speed = longhaul_table[j].frequency;
514 pos = (speed - lowest_speed) / kHz_step + minvid.pos;
515 f_msr_table[longhaul_table[j].index].vrm = mV_vrm_table[pos];
516 j++;
481 } 517 }
482 518
483 /* Current voltage isn't readable at first, so we need to
484 set it to a known value. The spec says to use maxvid */
485 longhaul.bits.RevisionKey = longhaul.bits.RevisionID; /* FIXME: This is bad. */
486 longhaul.bits.EnableSoftVID = 1;
487 longhaul.bits.SoftVID = maxvid;
488 wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
489
490 minvid = voltage_table[minvid];
491 maxvid = voltage_table[maxvid];
492
493 dprintk ("Min VID=%d.%03d Max VID=%d.%03d, %d possible voltage scales\n",
494 maxvid/1000, maxvid%1000, minvid/1000, minvid%1000, numvscales);
495
496 can_scale_voltage = 1; 519 can_scale_voltage = 1;
497} 520}
498 521
@@ -540,21 +563,33 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
540 return 1; 563 return 1;
541} 564}
542 565
566/* VIA don't support PM2 reg, but have something similar */
567static int enable_arbiter_disable(void)
568{
569 struct pci_dev *dev;
570 u8 pci_cmd;
571
572 /* Find PLE133 host bridge */
573 dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL);
574 if (dev != NULL) {
575 /* Enable access to port 0x22 */
576 pci_read_config_byte(dev, 0x78, &pci_cmd);
577 if ( !(pci_cmd & 1<<7) ) {
578 pci_cmd |= 1<<7;
579 pci_write_config_byte(dev, 0x78, pci_cmd);
580 }
581 return 1;
582 }
583 return 0;
584}
585
543static int __init longhaul_cpu_init(struct cpufreq_policy *policy) 586static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
544{ 587{
545 struct cpuinfo_x86 *c = cpu_data; 588 struct cpuinfo_x86 *c = cpu_data;
546 char *cpuname=NULL; 589 char *cpuname=NULL;
547 int ret; 590 int ret;
548 591
549 /* Check ACPI support for C3 state */ 592 /* Check what we have on this motherboard */
550 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
551 &longhaul_walk_callback, NULL, (void *)&pr);
552 if (pr == NULL) goto err_acpi;
553
554 cx = &pr->power.states[ACPI_STATE_C3];
555 if (cx->address == 0 || cx->latency > 1000) goto err_acpi;
556
557 /* Now check what we have on this motherboard */
558 switch (c->x86_model) { 593 switch (c->x86_model) {
559 case 6: 594 case 6:
560 cpu_model = CPU_SAMUEL; 595 cpu_model = CPU_SAMUEL;
@@ -636,12 +671,36 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
636 break; 671 break;
637 }; 672 };
638 673
674 /* Find ACPI data for processor */
675 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
676 &longhaul_walk_callback, NULL, (void *)&pr);
677 if (pr == NULL)
678 goto err_acpi;
679
680 if (longhaul_version == TYPE_POWERSAVER) {
681 /* Check ACPI support for C3 state */
682 cx = &pr->power.states[ACPI_STATE_C3];
683 if (cx->address == 0 ||
684 (cx->latency > 1000 && ignore_latency == 0) )
685 goto err_acpi;
686
687 } else {
688 /* Check ACPI support for bus master arbiter disable */
689 if (!pr->flags.bm_control) {
690 if (!enable_arbiter_disable()) {
691 printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n");
692 return -ENODEV;
693 } else
694 port22_en = 1;
695 }
696 }
697
639 ret = longhaul_get_ranges(); 698 ret = longhaul_get_ranges();
640 if (ret != 0) 699 if (ret != 0)
641 return ret; 700 return ret;
642 701
643 if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) && 702 if ((longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) &&
644 (dont_scale_voltage==0)) 703 (scale_voltage != 0))
645 longhaul_setup_voltagescaling(); 704 longhaul_setup_voltagescaling();
646 705
647 policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 706 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
@@ -729,8 +788,10 @@ static void __exit longhaul_exit(void)
729 kfree(longhaul_table); 788 kfree(longhaul_table);
730} 789}
731 790
732module_param (dont_scale_voltage, int, 0644); 791module_param (scale_voltage, int, 0644);
733MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor"); 792MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
793module_param(ignore_latency, int, 0644);
794MODULE_PARM_DESC(ignore_latency, "Skip ACPI C3 latency test");
734 795
735MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>"); 796MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
736MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); 797MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
@@ -738,4 +799,3 @@ MODULE_LICENSE ("GPL");
738 799
739late_initcall(longhaul_init); 800late_initcall(longhaul_init);
740module_exit(longhaul_exit); 801module_exit(longhaul_exit);
741
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.h b/arch/i386/kernel/cpu/cpufreq/longhaul.h
index d3a95d77ee85..bc4682aad69b 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.h
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.h
@@ -450,17 +450,45 @@ static int __initdata nehemiah_c_eblcr[32] = {
450 * Voltage scales. Div/Mod by 1000 to get actual voltage. 450 * Voltage scales. Div/Mod by 1000 to get actual voltage.
451 * Which scale to use depends on the VRM type in use. 451 * Which scale to use depends on the VRM type in use.
452 */ 452 */
453static int __initdata vrm85scales[32] = { 453
454 1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700, 454struct mV_pos {
455 1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300, 455 unsigned short mV;
456 1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725, 456 unsigned short pos;
457 1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325, 457};
458
459static struct mV_pos __initdata vrm85_mV[32] = {
460 {1250, 8}, {1200, 6}, {1150, 4}, {1100, 2},
461 {1050, 0}, {1800, 30}, {1750, 28}, {1700, 26},
462 {1650, 24}, {1600, 22}, {1550, 20}, {1500, 18},
463 {1450, 16}, {1400, 14}, {1350, 12}, {1300, 10},
464 {1275, 9}, {1225, 7}, {1175, 5}, {1125, 3},
465 {1075, 1}, {1825, 31}, {1775, 29}, {1725, 27},
466 {1675, 25}, {1625, 23}, {1575, 21}, {1525, 19},
467 {1475, 17}, {1425, 15}, {1375, 13}, {1325, 11}
468};
469
470static unsigned char __initdata mV_vrm85[32] = {
471 0x04, 0x14, 0x03, 0x13, 0x02, 0x12, 0x01, 0x11,
472 0x00, 0x10, 0x0f, 0x1f, 0x0e, 0x1e, 0x0d, 0x1d,
473 0x0c, 0x1c, 0x0b, 0x1b, 0x0a, 0x1a, 0x09, 0x19,
474 0x08, 0x18, 0x07, 0x17, 0x06, 0x16, 0x05, 0x15
475};
476
477static struct mV_pos __initdata mobilevrm_mV[32] = {
478 {1750, 31}, {1700, 30}, {1650, 29}, {1600, 28},
479 {1550, 27}, {1500, 26}, {1450, 25}, {1400, 24},
480 {1350, 23}, {1300, 22}, {1250, 21}, {1200, 20},
481 {1150, 19}, {1100, 18}, {1050, 17}, {1000, 16},
482 {975, 15}, {950, 14}, {925, 13}, {900, 12},
483 {875, 11}, {850, 10}, {825, 9}, {800, 8},
484 {775, 7}, {750, 6}, {725, 5}, {700, 4},
485 {675, 3}, {650, 2}, {625, 1}, {600, 0}
458}; 486};
459 487
460static int __initdata mobilevrmscales[32] = { 488static unsigned char __initdata mV_mobilevrm[32] = {
461 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, 489 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
462 1600, 1550, 1500, 1450, 1500, 1350, 1300, -1, 490 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
463 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, 491 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
464 1075, 1050, 1025, 1000, 975, 950, 925, -1, 492 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
465}; 493};
466 494
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index b77f1358bd79..7a9325349e94 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -23,6 +23,7 @@
23 23
24#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI 24#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
25#include <linux/acpi.h> 25#include <linux/acpi.h>
26#include <linux/dmi.h>
26#include <acpi/processor.h> 27#include <acpi/processor.h>
27#endif 28#endif
28 29
@@ -377,6 +378,35 @@ static int centrino_cpu_early_init_acpi(void)
377 return 0; 378 return 0;
378} 379}
379 380
381
382/*
383 * Some BIOSes do SW_ANY coordination internally, either set it up in hw
384 * or do it in BIOS firmware and won't inform about it to OS. If not
385 * detected, this has a side effect of making CPU run at a different speed
386 * than OS intended it to run at. Detect it and handle it cleanly.
387 */
388static int bios_with_sw_any_bug;
389static int __init sw_any_bug_found(struct dmi_system_id *d)
390{
391 bios_with_sw_any_bug = 1;
392 return 0;
393}
394
395
396static struct dmi_system_id sw_any_bug_dmi_table[] = {
397 {
398 .callback = sw_any_bug_found,
399 .ident = "Supermicro Server X6DLP",
400 .matches = {
401 DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
402 DMI_MATCH(DMI_BIOS_VERSION, "080010"),
403 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
404 },
405 },
406 { }
407};
408
409
380/* 410/*
381 * centrino_cpu_init_acpi - register with ACPI P-States library 411 * centrino_cpu_init_acpi - register with ACPI P-States library
382 * 412 *
@@ -398,14 +428,24 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
398 dprintk(PFX "obtaining ACPI data failed\n"); 428 dprintk(PFX "obtaining ACPI data failed\n");
399 return -EIO; 429 return -EIO;
400 } 430 }
431
401 policy->shared_type = p->shared_type; 432 policy->shared_type = p->shared_type;
402 /* 433 /*
403 * Will let policy->cpus know about dependency only when software 434 * Will let policy->cpus know about dependency only when software
404 * coordination is required. 435 * coordination is required.
405 */ 436 */
406 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || 437 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
407 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) 438 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
408 policy->cpus = p->shared_cpu_map; 439 policy->cpus = p->shared_cpu_map;
440 }
441
442#ifdef CONFIG_SMP
443 dmi_check_system(sw_any_bug_dmi_table);
444 if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
445 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
446 policy->cpus = cpu_core_map[cpu];
447 }
448#endif
409 449
410 /* verify the acpi_data */ 450 /* verify the acpi_data */
411 if (p->state_count <= 1) { 451 if (p->state_count <= 1) {
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 694b0c63ee50..de1ef2fa1a20 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -417,6 +417,17 @@ config PPC_MAPLE
417 This option enables support for the Maple 970FX Evaluation Board. 417 This option enables support for the Maple 970FX Evaluation Board.
418 For more informations, refer to <http://www.970eval.com> 418 For more informations, refer to <http://www.970eval.com>
419 419
420config PPC_PASEMI
421 depends on PPC_MULTIPLATFORM && PPC64
422 bool "PA Semi SoC-based platforms"
423 default n
424 select MPIC
425 select PPC_UDBG_16550
426 select GENERIC_TBSYNC
427 help
428 This option enables support for PA Semi's PWRficient line
429 of SoC processors, including PA6T-1682M
430
420config PPC_CELL 431config PPC_CELL
421 bool 432 bool
422 default n 433 default n
@@ -436,7 +447,8 @@ config PPC_IBM_CELL_BLADE
436 select UDBG_RTAS_CONSOLE 447 select UDBG_RTAS_CONSOLE
437 448
438config UDBG_RTAS_CONSOLE 449config UDBG_RTAS_CONSOLE
439 bool 450 bool "RTAS based debug console"
451 depends on PPC_RTAS
440 default n 452 default n
441 453
442config XICS 454config XICS
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index e29ef77d3b00..5ad149b47e34 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE
18 18
19 This option will slow down process creation somewhat. 19 This option will slow down process creation somewhat.
20 20
21config HCALL_STATS
22 bool "Hypervisor call instrumentation"
23 depends on PPC_PSERIES && DEBUG_FS
24 help
25 Adds code to keep track of the number of hypervisor calls made and
26 the amount of time spent in hypervisor callsr. Wall time spent in
27 each call is always calculated, and if available CPU cycles spent
28 are also calculated. A directory named hcall_inst is added at the
29 root of the debugfs filesystem. Within the hcall_inst directory
30 are files that contain CPU specific call statistics.
31
32 This option will add a small amount of overhead to all hypervisor
33 calls.
34
21config DEBUGGER 35config DEBUGGER
22 bool "Enable debugger hooks" 36 bool "Enable debugger hooks"
23 depends on DEBUG_KERNEL 37 depends on DEBUG_KERNEL
@@ -74,6 +88,8 @@ config XMON
74 very early during boot. 'xmon=on' will just enable the xmon 88 very early during boot. 'xmon=on' will just enable the xmon
75 debugger hooks. 'xmon=off' will disable the debugger hooks 89 debugger hooks. 'xmon=off' will disable the debugger hooks
76 if CONFIG_XMON_DEFAULT is set. 90 if CONFIG_XMON_DEFAULT is set.
91 xmon will print a backtrace on the very first invocation.
92 'xmon=nobt' will disable this autobacktrace.
77 93
78config XMON_DEFAULT 94config XMON_DEFAULT
79 bool "Enable xmon by default" 95 bool "Enable xmon by default"
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index d961bfeed05f..e73774136b55 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -36,11 +36,16 @@ zliblinuxheader := zlib.h zconf.h zutil.h
36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) 36$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
37#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) 37#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
38 38
39src-boot := crt0.S string.S prom.c stdio.c main.c div64.S 39src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
40src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
40src-boot += $(zlib) 41src-boot += $(zlib)
41src-boot := $(addprefix $(obj)/, $(src-boot)) 42src-boot := $(addprefix $(obj)/, $(src-boot))
42obj-boot := $(addsuffix .o, $(basename $(src-boot))) 43obj-boot := $(addsuffix .o, $(basename $(src-boot)))
43 44
45ifeq ($(call cc-option-yn, -fstack-protector),y)
46BOOTCFLAGS += -fno-stack-protector
47endif
48
44BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) 49BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
45 50
46quiet_cmd_copy_zlib = COPY $@ 51quiet_cmd_copy_zlib = COPY $@
diff --git a/arch/powerpc/boot/dts/mpc8349emds.dts b/arch/powerpc/boot/dts/mpc8349emds.dts
index 12f5dbf3055f..efceb3432653 100644
--- a/arch/powerpc/boot/dts/mpc8349emds.dts
+++ b/arch/powerpc/boot/dts/mpc8349emds.dts
@@ -214,10 +214,10 @@
214 b800 0 0 4 700 15 8 214 b800 0 0 4 700 15 8
215 215
216 /* IDSEL 0x18 */ 216 /* IDSEL 0x18 */
217 b000 0 0 1 700 15 8 217 c000 0 0 1 700 15 8
218 b000 0 0 2 700 16 8 218 c000 0 0 2 700 16 8
219 b000 0 0 3 700 17 8 219 c000 0 0 3 700 17 8
220 b000 0 0 4 700 14 8>; 220 c000 0 0 4 700 14 8>;
221 interrupt-parent = <700>; 221 interrupt-parent = <700>;
222 interrupts = <42 8>; 222 interrupts = <42 8>;
223 bus-range = <0 0>; 223 bus-range = <0 0>;
@@ -274,10 +274,10 @@
274 b800 0 0 4 700 15 8 274 b800 0 0 4 700 15 8
275 275
276 /* IDSEL 0x18 */ 276 /* IDSEL 0x18 */
277 b000 0 0 1 700 15 8 277 c000 0 0 1 700 15 8
278 b000 0 0 2 700 16 8 278 c000 0 0 2 700 16 8
279 b000 0 0 3 700 17 8 279 c000 0 0 3 700 17 8
280 b000 0 0 4 700 14 8>; 280 c000 0 0 4 700 14 8>;
281 interrupt-parent = <700>; 281 interrupt-parent = <700>;
282 interrupts = <42 8>; 282 interrupts = <42 8>;
283 bus-range = <0 0>; 283 bus-range = <0 0>;
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
new file mode 100644
index 000000000000..761c8dc84008
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree.h
@@ -0,0 +1,46 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17#ifndef FLATDEVTREE_H
18#define FLATDEVTREE_H
19
20#include "types.h"
21
22/* Definitions used by the flattened device tree */
23#define OF_DT_HEADER 0xd00dfeed /* marker */
24#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
25#define OF_DT_END_NODE 0x2 /* End node */
26#define OF_DT_PROP 0x3 /* Property: name off, size, content */
27#define OF_DT_NOP 0x4 /* nop */
28#define OF_DT_END 0x9
29
30#define OF_DT_VERSION 0x10
31
32struct boot_param_header {
33 u32 magic; /* magic word OF_DT_HEADER */
34 u32 totalsize; /* total size of DT block */
35 u32 off_dt_struct; /* offset to structure */
36 u32 off_dt_strings; /* offset to strings */
37 u32 off_mem_rsvmap; /* offset to memory reserve map */
38 u32 version; /* format version */
39 u32 last_comp_version; /* last compatible version */
40 /* version 2 fields below */
41 u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
42 /* version 3 fields below */
43 u32 dt_strings_size; /* size of the DT strings block */
44};
45
46#endif /* FLATDEVTREE_H */
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index b66634c9ea34..d719bb9333d1 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -14,17 +14,12 @@
14#include "page.h" 14#include "page.h"
15#include "string.h" 15#include "string.h"
16#include "stdio.h" 16#include "stdio.h"
17#include "prom.h"
18#include "zlib.h" 17#include "zlib.h"
18#include "ops.h"
19#include "flatdevtree.h"
19 20
20extern void flush_cache(void *, unsigned long); 21extern void flush_cache(void *, unsigned long);
21 22
22
23/* Value picked to match that used by yaboot */
24#define PROG_START 0x01400000 /* only used on 64-bit systems */
25#define RAM_END (512<<20) /* Fixme: use OF */
26#define ONE_MB 0x100000
27
28extern char _start[]; 23extern char _start[];
29extern char __bss_start[]; 24extern char __bss_start[];
30extern char _end[]; 25extern char _end[];
@@ -33,14 +28,6 @@ extern char _vmlinux_end[];
33extern char _initrd_start[]; 28extern char _initrd_start[];
34extern char _initrd_end[]; 29extern char _initrd_end[];
35 30
36/* A buffer that may be edited by tools operating on a zImage binary so as to
37 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
38 * The buffer is put in it's own section so that tools may locate it easier.
39 */
40static char builtin_cmdline[512]
41 __attribute__((section("__builtin_cmdline")));
42
43
44struct addr_range { 31struct addr_range {
45 unsigned long addr; 32 unsigned long addr;
46 unsigned long size; 33 unsigned long size;
@@ -51,21 +38,16 @@ static struct addr_range vmlinuz;
51static struct addr_range initrd; 38static struct addr_range initrd;
52 39
53static unsigned long elfoffset; 40static unsigned long elfoffset;
41static int is_64bit;
54 42
55static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */ 43/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */
44static char scratch[46912];
56static char elfheader[256]; 45static char elfheader[256];
57 46
58 47typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
59typedef void (*kernel_entry_t)( unsigned long,
60 unsigned long,
61 void *,
62 void *);
63
64 48
65#undef DEBUG 49#undef DEBUG
66 50
67static unsigned long claim_base;
68
69#define HEAD_CRC 2 51#define HEAD_CRC 2
70#define EXTRA_FIELD 4 52#define EXTRA_FIELD 4
71#define ORIG_NAME 8 53#define ORIG_NAME 8
@@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
123 zlib_inflateEnd(&s); 105 zlib_inflateEnd(&s);
124} 106}
125 107
126static unsigned long try_claim(unsigned long size)
127{
128 unsigned long addr = 0;
129
130 for(; claim_base < RAM_END; claim_base += ONE_MB) {
131#ifdef DEBUG
132 printf(" trying: 0x%08lx\n\r", claim_base);
133#endif
134 addr = (unsigned long)claim(claim_base, size, 0);
135 if ((void *)addr != (void *)-1)
136 break;
137 }
138 if (addr == 0)
139 return 0;
140 claim_base = PAGE_ALIGN(claim_base + size);
141 return addr;
142}
143
144static int is_elf64(void *hdr) 108static int is_elf64(void *hdr)
145{ 109{
146 Elf64_Ehdr *elf64 = hdr; 110 Elf64_Ehdr *elf64 = hdr;
@@ -169,16 +133,7 @@ static int is_elf64(void *hdr)
169 vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; 133 vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
170 vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; 134 vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
171 135
172#if defined(PROG_START) 136 is_64bit = 1;
173 /*
174 * Maintain a "magic" minimum address. This keeps some older
175 * firmware platforms running.
176 */
177
178 if (claim_base < PROG_START)
179 claim_base = PROG_START;
180#endif
181
182 return 1; 137 return 1;
183} 138}
184 139
@@ -212,47 +167,9 @@ static int is_elf32(void *hdr)
212 return 1; 167 return 1;
213} 168}
214 169
215void export_cmdline(void* chosen_handle) 170static void prep_kernel(unsigned long *a1, unsigned long *a2)
216{
217 int len;
218 char cmdline[2] = { 0, 0 };
219
220 if (builtin_cmdline[0] == 0)
221 return;
222
223 len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
224 if (len > 0 && cmdline[0] != 0)
225 return;
226
227 setprop(chosen_handle, "bootargs", builtin_cmdline,
228 strlen(builtin_cmdline) + 1);
229}
230
231
232void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
233{ 171{
234 int len; 172 int len;
235 kernel_entry_t kernel_entry;
236
237 memset(__bss_start, 0, _end - __bss_start);
238
239 prom = (int (*)(void *)) promptr;
240 chosen_handle = finddevice("/chosen");
241 if (chosen_handle == (void *) -1)
242 exit();
243 if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
244 exit();
245
246 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
247
248 /*
249 * The first available claim_base must be above the end of the
250 * the loaded kernel wrapper file (_start to _end includes the
251 * initrd image if it is present) and rounded up to a nice
252 * 1 MB boundary for good measure.
253 */
254
255 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
256 173
257 vmlinuz.addr = (unsigned long)_vmlinux_start; 174 vmlinuz.addr = (unsigned long)_vmlinux_start;
258 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); 175 vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
263 gunzip(elfheader, sizeof(elfheader), 180 gunzip(elfheader, sizeof(elfheader),
264 (unsigned char *)vmlinuz.addr, &len); 181 (unsigned char *)vmlinuz.addr, &len);
265 } else 182 } else
266 memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader)); 183 memcpy(elfheader, (const void *)vmlinuz.addr,
184 sizeof(elfheader));
267 185
268 if (!is_elf64(elfheader) && !is_elf32(elfheader)) { 186 if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
269 printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r"); 187 printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
270 exit(); 188 exit();
271 } 189 }
190 if (platform_ops.image_hdr)
191 platform_ops.image_hdr(elfheader);
272 192
273 /* We need to claim the memsize plus the file offset since gzip 193 /* We need to alloc the memsize plus the file offset since gzip
274 * will expand the header (file offset), then the kernel, then 194 * will expand the header (file offset), then the kernel, then
275 * possible rubbish we don't care about. But the kernel bss must 195 * possible rubbish we don't care about. But the kernel bss must
276 * be claimed (it will be zero'd by the kernel itself) 196 * be claimed (it will be zero'd by the kernel itself)
277 */ 197 */
278 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize); 198 printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
279 vmlinux.addr = try_claim(vmlinux.memsize); 199 vmlinux.addr = (unsigned long)malloc(vmlinux.memsize);
280 if (vmlinux.addr == 0) { 200 if (vmlinux.addr == 0) {
281 printf("Can't allocate memory for kernel image !\n\r"); 201 printf("Can't allocate memory for kernel image !\n\r");
282 exit(); 202 exit();
283 } 203 }
284 204
285 /* 205 /*
286 * Now we try to claim memory for the initrd (and copy it there) 206 * Now we try to alloc memory for the initrd (and copy it there)
287 */ 207 */
288 initrd.size = (unsigned long)(_initrd_end - _initrd_start); 208 initrd.size = (unsigned long)(_initrd_end - _initrd_start);
289 initrd.memsize = initrd.size; 209 initrd.memsize = initrd.size;
290 if ( initrd.size > 0 ) { 210 if ( initrd.size > 0 ) {
291 printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size); 211 printf("Allocating 0x%lx bytes for initrd ...\n\r",
292 initrd.addr = try_claim(initrd.size); 212 initrd.size);
213 initrd.addr = (unsigned long)malloc((u32)initrd.size);
293 if (initrd.addr == 0) { 214 if (initrd.addr == 0) {
294 printf("Can't allocate memory for initial ramdisk !\n\r"); 215 printf("Can't allocate memory for initial "
216 "ramdisk !\n\r");
295 exit(); 217 exit();
296 } 218 }
297 a1 = initrd.addr; 219 *a1 = initrd.addr;
298 a2 = initrd.size; 220 *a2 = initrd.size;
299 printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", 221 printf("initial ramdisk moving 0x%lx <- 0x%lx "
300 initrd.addr, (unsigned long)_initrd_start, initrd.size); 222 "(0x%lx bytes)\n\r", initrd.addr,
301 memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); 223 (unsigned long)_initrd_start, initrd.size);
302 printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); 224 memmove((void *)initrd.addr, (void *)_initrd_start,
225 initrd.size);
226 printf("initrd head: 0x%lx\n\r",
227 *((unsigned long *)initrd.addr));
303 } 228 }
304 229
305 /* Eventually gunzip the kernel */ 230 /* Eventually gunzip the kernel */
@@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
311 (unsigned char *)vmlinuz.addr, &len); 236 (unsigned char *)vmlinuz.addr, &len);
312 printf("done 0x%lx bytes\n\r", len); 237 printf("done 0x%lx bytes\n\r", len);
313 } else { 238 } else {
314 memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); 239 memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
240 vmlinuz.size);
315 } 241 }
316 242
317 export_cmdline(chosen_handle);
318
319 /* Skip over the ELF header */ 243 /* Skip over the ELF header */
320#ifdef DEBUG 244#ifdef DEBUG
321 printf("... skipping 0x%lx bytes of ELF header\n\r", 245 printf("... skipping 0x%lx bytes of ELF header\n\r",
@@ -324,23 +248,107 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
324 vmlinux.addr += elfoffset; 248 vmlinux.addr += elfoffset;
325 249
326 flush_cache((void *)vmlinux.addr, vmlinux.size); 250 flush_cache((void *)vmlinux.addr, vmlinux.size);
251}
327 252
328 kernel_entry = (kernel_entry_t)vmlinux.addr; 253void __attribute__ ((weak)) ft_init(void *dt_blob)
329#ifdef DEBUG 254{
330 printf( "kernel:\n\r" 255}
331 " entry addr = 0x%lx\n\r"
332 " a1 = 0x%lx,\n\r"
333 " a2 = 0x%lx,\n\r"
334 " prom = 0x%lx,\n\r"
335 " bi_recs = 0x%lx,\n\r",
336 (unsigned long)kernel_entry, a1, a2,
337 (unsigned long)prom, NULL);
338#endif
339 256
340 kernel_entry(a1, a2, prom, NULL); 257/* A buffer that may be edited by tools operating on a zImage binary so as to
258 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
259 * The buffer is put in it's own section so that tools may locate it easier.
260 */
261static char builtin_cmdline[COMMAND_LINE_SIZE]
262 __attribute__((__section__("__builtin_cmdline")));
341 263
342 printf("Error: Linux kernel returned to zImage bootloader!\n\r"); 264static void get_cmdline(char *buf, int size)
265{
266 void *devp;
267 int len = strlen(builtin_cmdline);
343 268
344 exit(); 269 buf[0] = '\0';
270
271 if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */
272 len = min(len, size-1);
273 strncpy(buf, builtin_cmdline, len);
274 buf[len] = '\0';
275 }
276 else if ((devp = finddevice("/chosen")))
277 getprop(devp, "bootargs", buf, size);
278}
279
280static void set_cmdline(char *buf)
281{
282 void *devp;
283
284 if ((devp = finddevice("/chosen")))
285 setprop(devp, "bootargs", buf, strlen(buf) + 1);
345} 286}
346 287
288/* Section where ft can be tacked on after zImage is built */
289union blobspace {
290 struct boot_param_header hdr;
291 char space[8*1024];
292} dt_blob __attribute__((__section__("__builtin_ft")));
293
294struct platform_ops platform_ops;
295struct dt_ops dt_ops;
296struct console_ops console_ops;
297
298void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
299{
300 int have_dt = 0;
301 kernel_entry_t kentry;
302 char cmdline[COMMAND_LINE_SIZE];
303
304 memset(__bss_start, 0, _end - __bss_start);
305 memset(&platform_ops, 0, sizeof(platform_ops));
306 memset(&dt_ops, 0, sizeof(dt_ops));
307 memset(&console_ops, 0, sizeof(console_ops));
308
309 /* Override the dt_ops and device tree if there was an flat dev
310 * tree attached to the zImage.
311 */
312 if (dt_blob.hdr.magic == OF_DT_HEADER) {
313 have_dt = 1;
314 ft_init(&dt_blob);
315 }
316
317 if (platform_init(promptr))
318 exit();
319 if (console_ops.open && (console_ops.open() < 0))
320 exit();
321 if (platform_ops.fixups)
322 platform_ops.fixups();
323
324 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
325 _start, sp);
326
327 prep_kernel(&a1, &a2);
328
329 /* If cmdline came from zimage wrapper or if we can edit the one
330 * in the dt, print it out and edit it, if possible.
331 */
332 if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
333 get_cmdline(cmdline, COMMAND_LINE_SIZE);
334 printf("\n\rLinux/PowerPC load: %s", cmdline);
335 if (console_ops.edit_cmdline)
336 console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
337 printf("\n\r");
338 set_cmdline(cmdline);
339 }
340
341 if (console_ops.close)
342 console_ops.close();
343
344 kentry = (kernel_entry_t) vmlinux.addr;
345 if (have_dt)
346 kentry(dt_ops.ft_addr(), 0, NULL);
347 else
348 /* XXX initrd addr/size should be passed in properties */
349 kentry(a1, a2, promptr);
350
351 /* console closed so printf below may not work */
352 printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
353 exit();
354}
diff --git a/arch/powerpc/boot/prom.c b/arch/powerpc/boot/of.c
index fa0057736f6b..fd99f789a37b 100644
--- a/arch/powerpc/boot/prom.c
+++ b/arch/powerpc/boot/of.c
@@ -8,15 +8,29 @@
8 */ 8 */
9#include <stdarg.h> 9#include <stdarg.h>
10#include <stddef.h> 10#include <stddef.h>
11#include "types.h"
12#include "elf.h"
11#include "string.h" 13#include "string.h"
12#include "stdio.h" 14#include "stdio.h"
13#include "prom.h" 15#include "page.h"
16#include "ops.h"
14 17
15int (*prom)(void *); 18typedef void *ihandle;
16phandle chosen_handle; 19typedef void *phandle;
17ihandle stdout;
18 20
19int call_prom(const char *service, int nargs, int nret, ...) 21extern char _end[];
22
23/* Value picked to match that used by yaboot */
24#define PROG_START 0x01400000 /* only used on 64-bit systems */
25#define RAM_END (512<<20) /* Fixme: use OF */
26#define ONE_MB 0x100000
27
28int (*prom) (void *);
29
30
31static unsigned long claim_base;
32
33static int call_prom(const char *service, int nargs, int nret, ...)
20{ 34{
21 int i; 35 int i;
22 struct prom_args { 36 struct prom_args {
@@ -45,7 +59,7 @@ int call_prom(const char *service, int nargs, int nret, ...)
45 return (nret > 0)? args.args[nargs]: 0; 59 return (nret > 0)? args.args[nargs]: 0;
46} 60}
47 61
48int call_prom_ret(const char *service, int nargs, int nret, 62static int call_prom_ret(const char *service, int nargs, int nret,
49 unsigned int *rets, ...) 63 unsigned int *rets, ...)
50{ 64{
51 int i; 65 int i;
@@ -79,11 +93,6 @@ int call_prom_ret(const char *service, int nargs, int nret,
79 return (nret > 0)? args.args[nargs]: 0; 93 return (nret > 0)? args.args[nargs]: 0;
80} 94}
81 95
82int write(void *handle, void *ptr, int nb)
83{
84 return call_prom("write", 3, 1, handle, ptr, nb);
85}
86
87/* 96/*
88 * Older OF's require that when claiming a specific range of addresses, 97 * Older OF's require that when claiming a specific range of addresses,
89 * we claim the physical space in the /memory node and the virtual 98 * we claim the physical space in the /memory node and the virtual
@@ -142,7 +151,7 @@ static int check_of_version(void)
142 return 1; 151 return 1;
143} 152}
144 153
145void *claim(unsigned long virt, unsigned long size, unsigned long align) 154static void *claim(unsigned long virt, unsigned long size, unsigned long align)
146{ 155{
147 int ret; 156 int ret;
148 unsigned int result; 157 unsigned int result;
@@ -151,7 +160,7 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
151 need_map = check_of_version(); 160 need_map = check_of_version();
152 if (align || !need_map) 161 if (align || !need_map)
153 return (void *) call_prom("claim", 3, 1, virt, size, align); 162 return (void *) call_prom("claim", 3, 1, virt, size, align);
154 163
155 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, 164 ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
156 align, size, virt); 165 align, size, virt);
157 if (ret != 0 || result == -1) 166 if (ret != 0 || result == -1)
@@ -163,3 +172,112 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
163 0x12, size, virt, virt); 172 0x12, size, virt, virt);
164 return (void *) virt; 173 return (void *) virt;
165} 174}
175
176static void *of_try_claim(u32 size)
177{
178 unsigned long addr = 0;
179 static u8 first_time = 1;
180
181 if (first_time) {
182 claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
183 first_time = 0;
184 }
185
186 for(; claim_base < RAM_END; claim_base += ONE_MB) {
187#ifdef DEBUG
188 printf(" trying: 0x%08lx\n\r", claim_base);
189#endif
190 addr = (unsigned long)claim(claim_base, size, 0);
191 if ((void *)addr != (void *)-1)
192 break;
193 }
194 if (addr == 0)
195 return NULL;
196 claim_base = PAGE_ALIGN(claim_base + size);
197 return (void *)addr;
198}
199
200static void of_image_hdr(const void *hdr)
201{
202 const Elf64_Ehdr *elf64 = hdr;
203
204 if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
205 /*
206 * Maintain a "magic" minimum address. This keeps some older
207 * firmware platforms running.
208 */
209 if (claim_base < PROG_START)
210 claim_base = PROG_START;
211 }
212}
213
214static void of_exit(void)
215{
216 call_prom("exit", 0, 0);
217}
218
219/*
220 * OF device tree routines
221 */
222static void *of_finddevice(const char *name)
223{
224 return (phandle) call_prom("finddevice", 1, 1, name);
225}
226
227static int of_getprop(const void *phandle, const char *name, void *buf,
228 const int buflen)
229{
230 return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
231}
232
233static int of_setprop(const void *phandle, const char *name, const void *buf,
234 const int buflen)
235{
236 return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
237}
238
239/*
240 * OF console routines
241 */
242static void *of_stdout_handle;
243
244static int of_console_open(void)
245{
246 void *devp;
247
248 if (((devp = finddevice("/chosen")) != NULL)
249 && (getprop(devp, "stdout", &of_stdout_handle,
250 sizeof(of_stdout_handle))
251 == sizeof(of_stdout_handle)))
252 return 0;
253
254 return -1;
255}
256
257static void of_console_write(char *buf, int len)
258{
259 call_prom("write", 3, 1, of_stdout_handle, buf, len);
260}
261
262int platform_init(void *promptr)
263{
264 platform_ops.fixups = NULL;
265 platform_ops.image_hdr = of_image_hdr;
266 platform_ops.malloc = of_try_claim;
267 platform_ops.free = NULL;
268 platform_ops.exit = of_exit;
269
270 dt_ops.finddevice = of_finddevice;
271 dt_ops.getprop = of_getprop;
272 dt_ops.setprop = of_setprop;
273 dt_ops.translate_addr = NULL;
274
275 console_ops.open = of_console_open;
276 console_ops.write = of_console_write;
277 console_ops.edit_cmdline = NULL;
278 console_ops.close = NULL;
279 console_ops.data = NULL;
280
281 prom = (int (*)(void *))promptr;
282 return 0;
283}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
new file mode 100644
index 000000000000..135eb4bb03b4
--- /dev/null
+++ b/arch/powerpc/boot/ops.h
@@ -0,0 +1,100 @@
1/*
2 * Global definition of all the bootwrapper operations.
3 *
4 * Author: Mark A. Greer <mgreer@mvista.com>
5 *
6 * 2006 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11#ifndef _PPC_BOOT_OPS_H_
12#define _PPC_BOOT_OPS_H_
13
14#include "types.h"
15
16#define COMMAND_LINE_SIZE 512
17#define MAX_PATH_LEN 256
18#define MAX_PROP_LEN 256 /* What should this be? */
19
20/* Platform specific operations */
21struct platform_ops {
22 void (*fixups)(void);
23 void (*image_hdr)(const void *);
24 void * (*malloc)(u32 size);
25 void (*free)(void *ptr, u32 size);
26 void (*exit)(void);
27};
28extern struct platform_ops platform_ops;
29
30/* Device Tree operations */
31struct dt_ops {
32 void * (*finddevice)(const char *name);
33 int (*getprop)(const void *node, const char *name, void *buf,
34 const int buflen);
35 int (*setprop)(const void *node, const char *name,
36 const void *buf, const int buflen);
37 u64 (*translate_addr)(const char *path, const u32 *in_addr,
38 const u32 addr_len);
39 unsigned long (*ft_addr)(void);
40};
41extern struct dt_ops dt_ops;
42
43/* Console operations */
44struct console_ops {
45 int (*open)(void);
46 void (*write)(char *buf, int len);
47 void (*edit_cmdline)(char *buf, int len);
48 void (*close)(void);
49 void *data;
50};
51extern struct console_ops console_ops;
52
53/* Serial console operations */
54struct serial_console_data {
55 int (*open)(void);
56 void (*putc)(unsigned char c);
57 unsigned char (*getc)(void);
58 u8 (*tstc)(void);
59 void (*close)(void);
60};
61
62extern int platform_init(void *promptr);
63extern void simple_alloc_init(void);
64extern void ft_init(void *dt_blob);
65extern int serial_console_init(void);
66
67static inline void *finddevice(const char *name)
68{
69 return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
70}
71
72static inline int getprop(void *devp, const char *name, void *buf, int buflen)
73{
74 return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
75}
76
77static inline int setprop(void *devp, const char *name, void *buf, int buflen)
78{
79 return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
80}
81
82static inline void *malloc(u32 size)
83{
84 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
85}
86
87static inline void free(void *ptr, u32 size)
88{
89 if (platform_ops.free)
90 platform_ops.free(ptr, size);
91}
92
93static inline void exit(void)
94{
95 if (platform_ops.exit)
96 platform_ops.exit();
97 for(;;);
98}
99
100#endif /* _PPC_BOOT_OPS_H_ */
diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h
deleted file mode 100644
index a57b184c564f..000000000000
--- a/arch/powerpc/boot/prom.h
+++ /dev/null
@@ -1,41 +0,0 @@
1#ifndef _PPC_BOOT_PROM_H_
2#define _PPC_BOOT_PROM_H_
3
4typedef void *phandle;
5typedef void *ihandle;
6
7extern int (*prom) (void *);
8extern phandle chosen_handle;
9extern ihandle stdout;
10
11int call_prom(const char *service, int nargs, int nret, ...);
12int call_prom_ret(const char *service, int nargs, int nret,
13 unsigned int *rets, ...);
14
15extern int write(void *handle, void *ptr, int nb);
16extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
17
18static inline void exit(void)
19{
20 call_prom("exit", 0, 0);
21}
22
23static inline phandle finddevice(const char *name)
24{
25 return (phandle) call_prom("finddevice", 1, 1, name);
26}
27
28static inline int getprop(void *phandle, const char *name,
29 void *buf, int buflen)
30{
31 return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
32}
33
34
35static inline int setprop(void *phandle, const char *name,
36 void *buf, int buflen)
37{
38 return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
39}
40
41#endif /* _PPC_BOOT_PROM_H_ */
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index b5aa522f8b77..6d5f6382e1ce 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -10,7 +10,7 @@
10#include <stddef.h> 10#include <stddef.h>
11#include "string.h" 11#include "string.h"
12#include "stdio.h" 12#include "stdio.h"
13#include "prom.h" 13#include "ops.h"
14 14
15size_t strnlen(const char * s, size_t count) 15size_t strnlen(const char * s, size_t count)
16{ 16{
@@ -320,6 +320,6 @@ printf(const char *fmt, ...)
320 va_start(args, fmt); 320 va_start(args, fmt);
321 n = vsprintf(sprint_buf, fmt, args); 321 n = vsprintf(sprint_buf, fmt, args);
322 va_end(args); 322 va_end(args);
323 write(stdout, sprint_buf, n); 323 console_ops.write(sprint_buf, n);
324 return n; 324 return n;
325} 325}
diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h
index eb9e16c87aef..73b8a91bfb34 100644
--- a/arch/powerpc/boot/stdio.h
+++ b/arch/powerpc/boot/stdio.h
@@ -1,8 +1,16 @@
1#ifndef _PPC_BOOT_STDIO_H_ 1#ifndef _PPC_BOOT_STDIO_H_
2#define _PPC_BOOT_STDIO_H_ 2#define _PPC_BOOT_STDIO_H_
3 3
4#include <stdarg.h>
5
6#define ENOMEM 12 /* Out of Memory */
7#define EINVAL 22 /* Invalid argument */
8#define ENOSPC 28 /* No space left on device */
9
4extern int printf(const char *fmt, ...); 10extern int printf(const char *fmt, ...);
5 11
12#define fprintf(fmt, args...) printf(args)
13
6extern int sprintf(char *buf, const char *fmt, ...); 14extern int sprintf(char *buf, const char *fmt, ...);
7 15
8extern int vsprintf(char *buf, const char *fmt, va_list args); 16extern int vsprintf(char *buf, const char *fmt, va_list args);
diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
new file mode 100644
index 000000000000..79d26e708677
--- /dev/null
+++ b/arch/powerpc/boot/types.h
@@ -0,0 +1,23 @@
1#ifndef _TYPES_H_
2#define _TYPES_H_
3
4#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5
6typedef unsigned char u8;
7typedef unsigned short u16;
8typedef unsigned int u32;
9typedef unsigned long long u64;
10
11#define min(x,y) ({ \
12 typeof(x) _x = (x); \
13 typeof(y) _y = (y); \
14 (void) (&_x == &_y); \
15 _x < _y ? _x : _y; })
16
17#define max(x,y) ({ \
18 typeof(x) _x = (x); \
19 typeof(y) _y = (y); \
20 (void) (&_x == &_y); \
21 _x > _y ? _x : _y; })
22
23#endif /* _TYPES_H_ */
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 2860be106f4f..62ba66091a13 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -496,7 +496,7 @@ CONFIG_E1000=y
496# CONFIG_SKY2 is not set 496# CONFIG_SKY2 is not set
497# CONFIG_SK98LIN is not set 497# CONFIG_SK98LIN is not set
498# CONFIG_VIA_VELOCITY is not set 498# CONFIG_VIA_VELOCITY is not set
499# CONFIG_TIGON3 is not set 499CONFIG_TIGON3=y
500# CONFIG_BNX2 is not set 500# CONFIG_BNX2 is not set
501# CONFIG_MV643XX_ETH is not set 501# CONFIG_MV643XX_ETH is not set
502 502
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 7d32ad0194a4..8b133afbdc20 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
16obj-y += vdso32/ 16obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 18 signal_64.o ptrace32.o \
19 paca.o cpu_setup_power4.o \ 19 paca.o cpu_setup_ppc970.o \
20 firmware.o sysfs.o 20 firmware.o sysfs.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
@@ -51,7 +51,7 @@ extra-$(CONFIG_8xx) := head_8xx.o
51extra-y += vmlinux.lds 51extra-y += vmlinux.lds
52 52
53obj-y += time.o prom.o traps.o setup-common.o \ 53obj-y += time.o prom.o traps.o setup-common.o \
54 udbg.o misc.o 54 udbg.o misc.o io.o
55obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o 55obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
56obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o 56obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
57obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 57obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 7ee84968087b..d06f378597bb 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -40,9 +40,10 @@
40#ifdef CONFIG_PPC64 40#ifdef CONFIG_PPC64
41#include <asm/paca.h> 41#include <asm/paca.h>
42#include <asm/lppaca.h> 42#include <asm/lppaca.h>
43#include <asm/iseries/hv_lp_event.h>
44#include <asm/cache.h> 43#include <asm/cache.h>
45#include <asm/compat.h> 44#include <asm/compat.h>
45#include <asm/mmu.h>
46#include <asm/hvcall.h>
46#endif 47#endif
47 48
48#define DEFINE(sym, val) \ 49#define DEFINE(sym, val) \
@@ -136,11 +137,18 @@ int main(void)
136 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); 137 DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
137 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); 138 DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
138 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); 139 DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
140 DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
141 DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
139 142
143 DEFINE(SLBSHADOW_STACKVSID,
144 offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
145 DEFINE(SLBSHADOW_STACKESID,
146 offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid));
140 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); 147 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
141 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1)); 148 DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
142 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int)); 149 DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
143 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int)); 150 DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
151 DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
144#endif /* CONFIG_PPC64 */ 152#endif /* CONFIG_PPC64 */
145 153
146 /* RTAS */ 154 /* RTAS */
@@ -159,6 +167,12 @@ int main(void)
159 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */ 167 /* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
160 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); 168 DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
161 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16); 169 DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
170
171 /* hcall statistics */
172 DEFINE(HCALL_STAT_SIZE, sizeof(struct hcall_stats));
173 DEFINE(HCALL_STAT_CALLS, offsetof(struct hcall_stats, num_calls));
174 DEFINE(HCALL_STAT_TB, offsetof(struct hcall_stats, tb_total));
175 DEFINE(HCALL_STAT_PURR, offsetof(struct hcall_stats, purr_total));
162#endif /* CONFIG_PPC64 */ 176#endif /* CONFIG_PPC64 */
163 DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0])); 177 DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
164 DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1])); 178 DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
@@ -240,6 +254,7 @@ int main(void)
240 DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); 254 DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
241 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); 255 DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
242 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); 256 DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
257 DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
243 258
244#ifndef CONFIG_PPC64 259#ifndef CONFIG_PPC64
245 DEFINE(pbe_address, offsetof(struct pbe, address)); 260 DEFINE(pbe_address, offsetof(struct pbe, address));
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index f4e5e14ee2b6..995fcef156fd 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -158,35 +158,35 @@ int btext_initialize(struct device_node *np)
158{ 158{
159 unsigned int width, height, depth, pitch; 159 unsigned int width, height, depth, pitch;
160 unsigned long address = 0; 160 unsigned long address = 0;
161 u32 *prop; 161 const u32 *prop;
162 162
163 prop = (u32 *)get_property(np, "linux,bootx-width", NULL); 163 prop = get_property(np, "linux,bootx-width", NULL);
164 if (prop == NULL) 164 if (prop == NULL)
165 prop = (u32 *)get_property(np, "width", NULL); 165 prop = get_property(np, "width", NULL);
166 if (prop == NULL) 166 if (prop == NULL)
167 return -EINVAL; 167 return -EINVAL;
168 width = *prop; 168 width = *prop;
169 prop = (u32 *)get_property(np, "linux,bootx-height", NULL); 169 prop = get_property(np, "linux,bootx-height", NULL);
170 if (prop == NULL) 170 if (prop == NULL)
171 prop = (u32 *)get_property(np, "height", NULL); 171 prop = get_property(np, "height", NULL);
172 if (prop == NULL) 172 if (prop == NULL)
173 return -EINVAL; 173 return -EINVAL;
174 height = *prop; 174 height = *prop;
175 prop = (u32 *)get_property(np, "linux,bootx-depth", NULL); 175 prop = get_property(np, "linux,bootx-depth", NULL);
176 if (prop == NULL) 176 if (prop == NULL)
177 prop = (u32 *)get_property(np, "depth", NULL); 177 prop = get_property(np, "depth", NULL);
178 if (prop == NULL) 178 if (prop == NULL)
179 return -EINVAL; 179 return -EINVAL;
180 depth = *prop; 180 depth = *prop;
181 pitch = width * ((depth + 7) / 8); 181 pitch = width * ((depth + 7) / 8);
182 prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL); 182 prop = get_property(np, "linux,bootx-linebytes", NULL);
183 if (prop == NULL) 183 if (prop == NULL)
184 prop = (u32 *)get_property(np, "linebytes", NULL); 184 prop = get_property(np, "linebytes", NULL);
185 if (prop) 185 if (prop)
186 pitch = *prop; 186 pitch = *prop;
187 if (pitch == 1) 187 if (pitch == 1)
188 pitch = 0x1000; 188 pitch = 0x1000;
189 prop = (u32 *)get_property(np, "address", NULL); 189 prop = get_property(np, "address", NULL);
190 if (prop) 190 if (prop)
191 address = *prop; 191 address = *prop;
192 192
@@ -214,11 +214,11 @@ int btext_initialize(struct device_node *np)
214 214
215int __init btext_find_display(int allow_nonstdout) 215int __init btext_find_display(int allow_nonstdout)
216{ 216{
217 char *name; 217 const char *name;
218 struct device_node *np = NULL; 218 struct device_node *np = NULL;
219 int rc = -ENODEV; 219 int rc = -ENODEV;
220 220
221 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 221 name = get_property(of_chosen, "linux,stdout-path", NULL);
222 if (name != NULL) { 222 if (name != NULL) {
223 np = of_find_node_by_path(name); 223 np = of_find_node_by_path(name);
224 if (np != NULL) { 224 if (np != NULL) {
diff --git a/arch/powerpc/kernel/cpu_setup_power4.S b/arch/powerpc/kernel/cpu_setup_ppc970.S
index 76e97aa71c45..652594891d58 100644
--- a/arch/powerpc/kernel/cpu_setup_power4.S
+++ b/arch/powerpc/kernel/cpu_setup_ppc970.S
@@ -16,27 +16,12 @@
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/cache.h> 17#include <asm/cache.h>
18 18
19_GLOBAL(__970_cpu_preinit) 19_GLOBAL(__cpu_preinit_ppc970)
20 /* 20 /* Do nothing if not running in HV mode */
21 * Do nothing if not running in HV mode
22 */
23 mfmsr r0 21 mfmsr r0
24 rldicl. r0,r0,4,63 22 rldicl. r0,r0,4,63
25 beqlr 23 beqlr
26 24
27 /*
28 * Deal only with PPC970 and PPC970FX.
29 */
30 mfspr r0,SPRN_PVR
31 srwi r0,r0,16
32 cmpwi r0,0x39
33 beq 1f
34 cmpwi r0,0x3c
35 beq 1f
36 cmpwi r0,0x44
37 bnelr
381:
39
40 /* Make sure HID4:rm_ci is off before MMU is turned off, that large 25 /* Make sure HID4:rm_ci is off before MMU is turned off, that large
41 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and 26 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
42 * HID5:DCBZ32_ill 27 * HID5:DCBZ32_ill
@@ -72,23 +57,6 @@ _GLOBAL(__970_cpu_preinit)
72 isync 57 isync
73 blr 58 blr
74 59
75_GLOBAL(__setup_cpu_ppc970)
76 mfspr r0,SPRN_HID0
77 li r11,5 /* clear DOZE and SLEEP */
78 rldimi r0,r11,52,8 /* set NAP and DPM */
79 li r11,0
80 rldimi r0,r11,32,31 /* clear EN_ATTN */
81 mtspr SPRN_HID0,r0
82 mfspr r0,SPRN_HID0
83 mfspr r0,SPRN_HID0
84 mfspr r0,SPRN_HID0
85 mfspr r0,SPRN_HID0
86 mfspr r0,SPRN_HID0
87 mfspr r0,SPRN_HID0
88 sync
89 isync
90 blr
91
92/* Definitions for the table use to save CPU states */ 60/* Definitions for the table use to save CPU states */
93#define CS_HID0 0 61#define CS_HID0 0
94#define CS_HID1 8 62#define CS_HID1 8
@@ -103,33 +71,30 @@ cpu_state_storage:
103 .balign L1_CACHE_BYTES,0 71 .balign L1_CACHE_BYTES,0
104 .text 72 .text
105 73
106/* Called in normal context to backup CPU 0 state. This
107 * does not include cache settings. This function is also
108 * called for machine sleep. This does not include the MMU
109 * setup, BATs, etc... but rather the "special" registers
110 * like HID0, HID1, HID4, etc...
111 */
112_GLOBAL(__save_cpu_setup)
113 /* Some CR fields are volatile, we back it up all */
114 mfcr r7
115
116 /* Get storage ptr */
117 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
118 74
119 /* We only deal with 970 for now */ 75_GLOBAL(__setup_cpu_ppc970)
120 mfspr r0,SPRN_PVR 76 /* Do nothing if not running in HV mode */
121 srwi r0,r0,16
122 cmpwi r0,0x39
123 beq 1f
124 cmpwi r0,0x3c
125 beq 1f
126 cmpwi r0,0x44
127 bne 2f
128
1291: /* skip if not running in HV mode */
130 mfmsr r0 77 mfmsr r0
131 rldicl. r0,r0,4,63 78 rldicl. r0,r0,4,63
132 beq 2f 79 beqlr
80
81 mfspr r0,SPRN_HID0
82 li r11,5 /* clear DOZE and SLEEP */
83 rldimi r0,r11,52,8 /* set NAP and DPM */
84 li r11,0
85 rldimi r0,r11,32,31 /* clear EN_ATTN */
86 mtspr SPRN_HID0,r0
87 mfspr r0,SPRN_HID0
88 mfspr r0,SPRN_HID0
89 mfspr r0,SPRN_HID0
90 mfspr r0,SPRN_HID0
91 mfspr r0,SPRN_HID0
92 mfspr r0,SPRN_HID0
93 sync
94 isync
95
96 /* Save away cpu state */
97 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
133 98
134 /* Save HID0,1,4 and 5 */ 99 /* Save HID0,1,4 and 5 */
135 mfspr r3,SPRN_HID0 100 mfspr r3,SPRN_HID0
@@ -141,35 +106,19 @@ _GLOBAL(__save_cpu_setup)
141 mfspr r3,SPRN_HID5 106 mfspr r3,SPRN_HID5
142 std r3,CS_HID5(r5) 107 std r3,CS_HID5(r5)
143 108
1442:
145 mtcr r7
146 blr 109 blr
147 110
148/* Called with no MMU context (typically MSR:IR/DR off) to 111/* Called with no MMU context (typically MSR:IR/DR off) to
149 * restore CPU state as backed up by the previous 112 * restore CPU state as backed up by the previous
150 * function. This does not include cache setting 113 * function. This does not include cache setting
151 */ 114 */
152_GLOBAL(__restore_cpu_setup) 115_GLOBAL(__restore_cpu_ppc970)
153 /* Get storage ptr (FIXME when using anton reloc as we 116 /* Do nothing if not running in HV mode */
154 * are running with translation disabled here
155 */
156 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
157
158 /* We only deal with 970 for now */
159 mfspr r0,SPRN_PVR
160 srwi r0,r0,16
161 cmpwi r0,0x39
162 beq 1f
163 cmpwi r0,0x3c
164 beq 1f
165 cmpwi r0,0x44
166 bnelr
167
1681: /* skip if not running in HV mode */
169 mfmsr r0 117 mfmsr r0
170 rldicl. r0,r0,4,63 118 rldicl. r0,r0,4,63
171 beqlr 119 beqlr
172 120
121 LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
173 /* Before accessing memory, we make sure rm_ci is clear */ 122 /* Before accessing memory, we make sure rm_ci is clear */
174 li r0,0 123 li r0,0
175 mfspr r3,SPRN_HID4 124 mfspr r3,SPRN_HID4
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 272e43622fd6..190a57e20765 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -39,7 +39,10 @@ extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
39extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); 39extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
40extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); 40extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
41#endif /* CONFIG_PPC32 */ 41#endif /* CONFIG_PPC32 */
42#ifdef CONFIG_PPC64
42extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 43extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
44extern void __restore_cpu_ppc970(void);
45#endif /* CONFIG_PPC64 */
43 46
44/* This table only contains "desktop" CPUs, it need to be filled with embedded 47/* This table only contains "desktop" CPUs, it need to be filled with embedded
45 * ones as well... 48 * ones as well...
@@ -55,6 +58,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
55#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\ 58#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
56 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \ 59 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
57 PPC_FEATURE_TRUE_LE) 60 PPC_FEATURE_TRUE_LE)
61#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
62 PPC_FEATURE_TRUE_LE | \
63 PPC_FEATURE_HAS_ALTIVEC_COMP)
58#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ 64#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
59 PPC_FEATURE_BOOKE) 65 PPC_FEATURE_BOOKE)
60 66
@@ -184,6 +190,7 @@ struct cpu_spec cpu_specs[] = {
184 .dcache_bsize = 128, 190 .dcache_bsize = 128,
185 .num_pmcs = 8, 191 .num_pmcs = 8,
186 .cpu_setup = __setup_cpu_ppc970, 192 .cpu_setup = __setup_cpu_ppc970,
193 .cpu_restore = __restore_cpu_ppc970,
187 .oprofile_cpu_type = "ppc64/970", 194 .oprofile_cpu_type = "ppc64/970",
188 .oprofile_type = PPC_OPROFILE_POWER4, 195 .oprofile_type = PPC_OPROFILE_POWER4,
189 .platform = "ppc970", 196 .platform = "ppc970",
@@ -199,6 +206,7 @@ struct cpu_spec cpu_specs[] = {
199 .dcache_bsize = 128, 206 .dcache_bsize = 128,
200 .num_pmcs = 8, 207 .num_pmcs = 8,
201 .cpu_setup = __setup_cpu_ppc970, 208 .cpu_setup = __setup_cpu_ppc970,
209 .cpu_restore = __restore_cpu_ppc970,
202 .oprofile_cpu_type = "ppc64/970", 210 .oprofile_cpu_type = "ppc64/970",
203 .oprofile_type = PPC_OPROFILE_POWER4, 211 .oprofile_type = PPC_OPROFILE_POWER4,
204 .platform = "ppc970", 212 .platform = "ppc970",
@@ -214,6 +222,7 @@ struct cpu_spec cpu_specs[] = {
214 .dcache_bsize = 128, 222 .dcache_bsize = 128,
215 .num_pmcs = 8, 223 .num_pmcs = 8,
216 .cpu_setup = __setup_cpu_ppc970, 224 .cpu_setup = __setup_cpu_ppc970,
225 .cpu_restore = __restore_cpu_ppc970,
217 .oprofile_cpu_type = "ppc64/970", 226 .oprofile_cpu_type = "ppc64/970",
218 .oprofile_type = PPC_OPROFILE_POWER4, 227 .oprofile_type = PPC_OPROFILE_POWER4,
219 .platform = "ppc970", 228 .platform = "ppc970",
@@ -280,6 +289,17 @@ struct cpu_spec cpu_specs[] = {
280 .dcache_bsize = 128, 289 .dcache_bsize = 128,
281 .platform = "ppc-cell-be", 290 .platform = "ppc-cell-be",
282 }, 291 },
292 { /* PA Semi PA6T */
293 .pvr_mask = 0x7fff0000,
294 .pvr_value = 0x00900000,
295 .cpu_name = "PA6T",
296 .cpu_features = CPU_FTRS_PA6T,
297 .cpu_user_features = COMMON_USER_PA6T,
298 .icache_bsize = 64,
299 .dcache_bsize = 64,
300 .num_pmcs = 6,
301 .platform = "pa6t",
302 },
283 { /* default match */ 303 { /* default match */
284 .pvr_mask = 0x00000000, 304 .pvr_mask = 0x00000000,
285 .pvr_value = 0x00000000, 305 .pvr_value = 0x00000000,
@@ -929,6 +949,7 @@ struct cpu_spec cpu_specs[] = {
929 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, 949 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
930 .icache_bsize = 32, 950 .icache_bsize = 32,
931 .dcache_bsize = 32, 951 .dcache_bsize = 32,
952 .platform = "ppc405",
932 }, 953 },
933 { /* 405EP */ 954 { /* 405EP */
934 .pvr_mask = 0xffff0000, 955 .pvr_mask = 0xffff0000,
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 371973be8d71..2f6f5a7bc69e 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -80,7 +80,7 @@ static int __init parse_savemaxmem(char *p)
80} 80}
81__setup("savemaxmem=", parse_savemaxmem); 81__setup("savemaxmem=", parse_savemaxmem);
82 82
83/* 83/**
84 * copy_oldmem_page - copy one page from "oldmem" 84 * copy_oldmem_page - copy one page from "oldmem"
85 * @pfn: page frame number to be copied 85 * @pfn: page frame number to be copied
86 * @buf: target memory address for the copy; this can be in kernel address 86 * @buf: target memory address for the copy; this can be in kernel address
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 36aaa7663f02..6c168f6ea142 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -35,10 +35,9 @@ int dma_supported(struct device *dev, u64 mask)
35{ 35{
36 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 36 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
37 37
38 if (dma_ops) 38 BUG_ON(!dma_ops);
39 return dma_ops->dma_supported(dev, mask); 39
40 BUG(); 40 return dma_ops->dma_supported(dev, mask);
41 return 0;
42} 41}
43EXPORT_SYMBOL(dma_supported); 42EXPORT_SYMBOL(dma_supported);
44 43
@@ -66,10 +65,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
66{ 65{
67 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 66 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
68 67
69 if (dma_ops) 68 BUG_ON(!dma_ops);
70 return dma_ops->alloc_coherent(dev, size, dma_handle, flag); 69
71 BUG(); 70 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
72 return NULL;
73} 71}
74EXPORT_SYMBOL(dma_alloc_coherent); 72EXPORT_SYMBOL(dma_alloc_coherent);
75 73
@@ -78,10 +76,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
78{ 76{
79 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 77 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
80 78
81 if (dma_ops) 79 BUG_ON(!dma_ops);
82 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); 80
83 else 81 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
84 BUG();
85} 82}
86EXPORT_SYMBOL(dma_free_coherent); 83EXPORT_SYMBOL(dma_free_coherent);
87 84
@@ -90,10 +87,9 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
90{ 87{
91 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 88 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
92 89
93 if (dma_ops) 90 BUG_ON(!dma_ops);
94 return dma_ops->map_single(dev, cpu_addr, size, direction); 91
95 BUG(); 92 return dma_ops->map_single(dev, cpu_addr, size, direction);
96 return (dma_addr_t)0;
97} 93}
98EXPORT_SYMBOL(dma_map_single); 94EXPORT_SYMBOL(dma_map_single);
99 95
@@ -102,10 +98,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
102{ 98{
103 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 99 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
104 100
105 if (dma_ops) 101 BUG_ON(!dma_ops);
106 dma_ops->unmap_single(dev, dma_addr, size, direction); 102
107 else 103 dma_ops->unmap_single(dev, dma_addr, size, direction);
108 BUG();
109} 104}
110EXPORT_SYMBOL(dma_unmap_single); 105EXPORT_SYMBOL(dma_unmap_single);
111 106
@@ -115,11 +110,10 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
115{ 110{
116 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 111 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
117 112
118 if (dma_ops) 113 BUG_ON(!dma_ops);
119 return dma_ops->map_single(dev, 114
120 (page_address(page) + offset), size, direction); 115 return dma_ops->map_single(dev, page_address(page) + offset, size,
121 BUG(); 116 direction);
122 return (dma_addr_t)0;
123} 117}
124EXPORT_SYMBOL(dma_map_page); 118EXPORT_SYMBOL(dma_map_page);
125 119
@@ -128,10 +122,9 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
128{ 122{
129 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 123 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
130 124
131 if (dma_ops) 125 BUG_ON(!dma_ops);
132 dma_ops->unmap_single(dev, dma_address, size, direction); 126
133 else 127 dma_ops->unmap_single(dev, dma_address, size, direction);
134 BUG();
135} 128}
136EXPORT_SYMBOL(dma_unmap_page); 129EXPORT_SYMBOL(dma_unmap_page);
137 130
@@ -140,10 +133,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
140{ 133{
141 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 134 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
142 135
143 if (dma_ops) 136 BUG_ON(!dma_ops);
144 return dma_ops->map_sg(dev, sg, nents, direction); 137
145 BUG(); 138 return dma_ops->map_sg(dev, sg, nents, direction);
146 return 0;
147} 139}
148EXPORT_SYMBOL(dma_map_sg); 140EXPORT_SYMBOL(dma_map_sg);
149 141
@@ -152,9 +144,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
152{ 144{
153 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 145 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
154 146
155 if (dma_ops) 147 BUG_ON(!dma_ops);
156 dma_ops->unmap_sg(dev, sg, nhwentries, direction); 148
157 else 149 dma_ops->unmap_sg(dev, sg, nhwentries, direction);
158 BUG();
159} 150}
160EXPORT_SYMBOL(dma_unmap_sg); 151EXPORT_SYMBOL(dma_unmap_sg);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 54d9f5cdaab4..2cd872b5283b 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -375,6 +375,14 @@ BEGIN_FTR_SECTION
375 ld r7,KSP_VSID(r4) /* Get new stack's VSID */ 375 ld r7,KSP_VSID(r4) /* Get new stack's VSID */
376 oris r0,r6,(SLB_ESID_V)@h 376 oris r0,r6,(SLB_ESID_V)@h
377 ori r0,r0,(SLB_NUM_BOLTED-1)@l 377 ori r0,r0,(SLB_NUM_BOLTED-1)@l
378
379 /* Update the last bolted SLB */
380 ld r9,PACA_SLBSHADOWPTR(r13)
381 li r12,0
382 std r12,SLBSHADOW_STACKESID(r9) /* Clear ESID */
383 std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
384 std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
385
378 slbie r6 386 slbie r6
379 slbie r6 /* Workaround POWER5 < DD2.1 issue */ 387 slbie r6 /* Workaround POWER5 < DD2.1 issue */
380 slbmte r7,r0 388 slbmte r7,r0
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 6ff3cf506088..3065b472b95d 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -132,7 +132,7 @@ _GLOBAL(__secondary_hold)
132 bne 100b 132 bne 100b
133 133
134#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) 134#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
135 LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) 135 LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init)
136 mtctr r4 136 mtctr r4
137 mr r3,r24 137 mr r3,r24
138 bctr 138 bctr
@@ -1484,19 +1484,17 @@ fwnmi_data_area:
1484 . = 0x8000 1484 . = 0x8000
1485 1485
1486/* 1486/*
1487 * On pSeries, secondary processors spin in the following code. 1487 * On pSeries and most other platforms, secondary processors spin
1488 * in the following code.
1488 * At entry, r3 = this processor's number (physical cpu id) 1489 * At entry, r3 = this processor's number (physical cpu id)
1489 */ 1490 */
1490_GLOBAL(pSeries_secondary_smp_init) 1491_GLOBAL(generic_secondary_smp_init)
1491 mr r24,r3 1492 mr r24,r3
1492 1493
1493 /* turn on 64-bit mode */ 1494 /* turn on 64-bit mode */
1494 bl .enable_64b_mode 1495 bl .enable_64b_mode
1495 isync 1496 isync
1496 1497
1497 /* Copy some CPU settings from CPU 0 */
1498 bl .__restore_cpu_setup
1499
1500 /* Set up a paca value for this processor. Since we have the 1498 /* Set up a paca value for this processor. Since we have the
1501 * physical cpu id in r24, we need to search the pacas to find 1499 * physical cpu id in r24, we need to search the pacas to find
1502 * which logical id maps to our physical one. 1500 * which logical id maps to our physical one.
@@ -1522,15 +1520,28 @@ _GLOBAL(pSeries_secondary_smp_init)
1522 /* start. */ 1520 /* start. */
1523 sync 1521 sync
1524 1522
1525 /* Create a temp kernel stack for use before relocation is on. */ 1523#ifndef CONFIG_SMP
1524 b 3b /* Never go on non-SMP */
1525#else
1526 cmpwi 0,r23,0
1527 beq 3b /* Loop until told to go */
1528
1529 /* See if we need to call a cpu state restore handler */
1530 LOAD_REG_IMMEDIATE(r23, cur_cpu_spec)
1531 ld r23,0(r23)
1532 ld r23,CPU_SPEC_RESTORE(r23)
1533 cmpdi 0,r23,0
1534 beq 4f
1535 ld r23,0(r23)
1536 mtctr r23
1537 bctrl
1538
15394: /* Create a temp kernel stack for use before relocation is on. */
1526 ld r1,PACAEMERGSP(r13) 1540 ld r1,PACAEMERGSP(r13)
1527 subi r1,r1,STACK_FRAME_OVERHEAD 1541 subi r1,r1,STACK_FRAME_OVERHEAD
1528 1542
1529 cmpwi 0,r23,0 1543 b .__secondary_start
1530#ifdef CONFIG_SMP
1531 bne .__secondary_start
1532#endif 1544#endif
1533 b 3b /* Loop until told to go */
1534 1545
1535#ifdef CONFIG_PPC_ISERIES 1546#ifdef CONFIG_PPC_ISERIES
1536_STATIC(__start_initialization_iSeries) 1547_STATIC(__start_initialization_iSeries)
@@ -1611,7 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform)
1611 bl .enable_64b_mode 1622 bl .enable_64b_mode
1612 1623
1613 /* Setup some critical 970 SPRs before switching MMU off */ 1624 /* Setup some critical 970 SPRs before switching MMU off */
1614 bl .__970_cpu_preinit 1625 mfspr r0,SPRN_PVR
1626 srwi r0,r0,16
1627 cmpwi r0,0x39 /* 970 */
1628 beq 1f
1629 cmpwi r0,0x3c /* 970FX */
1630 beq 1f
1631 cmpwi r0,0x44 /* 970MP */
1632 bne 2f
16331: bl .__cpu_preinit_ppc970
16342:
1615 1635
1616 /* Switch off MMU if not already */ 1636 /* Switch off MMU if not already */
1617 LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) 1637 LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
@@ -1728,7 +1748,7 @@ _STATIC(__after_prom_start)
1728_GLOBAL(copy_and_flush) 1748_GLOBAL(copy_and_flush)
1729 addi r5,r5,-8 1749 addi r5,r5,-8
1730 addi r6,r6,-8 1750 addi r6,r6,-8
17314: li r0,16 /* Use the least common */ 17514: li r0,8 /* Use the smallest common */
1732 /* denominator cache line */ 1752 /* denominator cache line */
1733 /* size. This results in */ 1753 /* size. This results in */
1734 /* extra cache line flushes */ 1754 /* extra cache line flushes */
@@ -1782,7 +1802,7 @@ _GLOBAL(pmac_secondary_start)
1782 isync 1802 isync
1783 1803
1784 /* Copy some CPU settings from CPU 0 */ 1804 /* Copy some CPU settings from CPU 0 */
1785 bl .__restore_cpu_setup 1805 bl .__restore_cpu_ppc970
1786 1806
1787 /* pSeries do that early though I don't think we really need it */ 1807 /* pSeries do that early though I don't think we really need it */
1788 mfmsr r3 1808 mfmsr r3
@@ -1932,12 +1952,6 @@ _STATIC(start_here_multiplatform)
1932 mr r5,r26 1952 mr r5,r26
1933 bl .identify_cpu 1953 bl .identify_cpu
1934 1954
1935 /* Save some low level config HIDs of CPU0 to be copied to
1936 * other CPUs later on, or used for suspend/resume
1937 */
1938 bl .__save_cpu_setup
1939 sync
1940
1941 /* Do very early kernel initializations, including initial hash table, 1955 /* Do very early kernel initializations, including initial hash table,
1942 * stab and slb setup before we turn on relocation. */ 1956 * stab and slb setup before we turn on relocation. */
1943 1957
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 68e5ab0443d2..124dbcba94a8 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -167,7 +167,7 @@ static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name,
167 NULL); 167 NULL);
168 168
169static struct ibmebus_dev* __devinit ibmebus_register_device_common( 169static struct ibmebus_dev* __devinit ibmebus_register_device_common(
170 struct ibmebus_dev *dev, char *name) 170 struct ibmebus_dev *dev, const char *name)
171{ 171{
172 int err = 0; 172 int err = 0;
173 173
@@ -194,10 +194,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
194 struct device_node *dn) 194 struct device_node *dn)
195{ 195{
196 struct ibmebus_dev *dev; 196 struct ibmebus_dev *dev;
197 char *loc_code; 197 const char *loc_code;
198 int length; 198 int length;
199 199
200 loc_code = (char *)get_property(dn, "ibm,loc-code", NULL); 200 loc_code = get_property(dn, "ibm,loc-code", NULL);
201 if (!loc_code) { 201 if (!loc_code) {
202 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", 202 printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
203 __FUNCTION__, dn->name ? dn->name : "<unknown>"); 203 __FUNCTION__, dn->name ? dn->name : "<unknown>");
diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c
new file mode 100644
index 000000000000..e98180686b35
--- /dev/null
+++ b/arch/powerpc/kernel/io.c
@@ -0,0 +1,131 @@
1/*
2 * I/O string operations
3 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
4 * Copyright (C) 2006 IBM Corporation
5 *
6 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
7 * and Paul Mackerras.
8 *
9 * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
10 * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
11 *
12 * Rewritten in C by Stephen Rothwell.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 */
19#include <linux/kernel.h>
20#include <linux/types.h>
21#include <linux/compiler.h>
22#include <linux/module.h>
23
24#include <asm/io.h>
25#include <asm/firmware.h>
26#include <asm/bug.h>
27
28void _insb(volatile u8 __iomem *port, void *buf, long count)
29{
30 u8 *tbuf = buf;
31 u8 tmp;
32
33 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
34
35 if (unlikely(count <= 0))
36 return;
37 asm volatile("sync");
38 do {
39 tmp = *port;
40 asm volatile("eieio");
41 *tbuf++ = tmp;
42 } while (--count != 0);
43 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
44}
45EXPORT_SYMBOL(_insb);
46
47void _outsb(volatile u8 __iomem *port, const void *buf, long count)
48{
49 const u8 *tbuf = buf;
50
51 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
52
53 if (unlikely(count <= 0))
54 return;
55 asm volatile("sync");
56 do {
57 *port = *tbuf++;
58 } while (--count != 0);
59 asm volatile("sync");
60}
61EXPORT_SYMBOL(_outsb);
62
63void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
64{
65 u16 *tbuf = buf;
66 u16 tmp;
67
68 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
69
70 if (unlikely(count <= 0))
71 return;
72 asm volatile("sync");
73 do {
74 tmp = *port;
75 asm volatile("eieio");
76 *tbuf++ = tmp;
77 } while (--count != 0);
78 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
79}
80EXPORT_SYMBOL(_insw_ns);
81
82void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
83{
84 const u16 *tbuf = buf;
85
86 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
87
88 if (unlikely(count <= 0))
89 return;
90 asm volatile("sync");
91 do {
92 *port = *tbuf++;
93 } while (--count != 0);
94 asm volatile("sync");
95}
96EXPORT_SYMBOL(_outsw_ns);
97
98void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
99{
100 u32 *tbuf = buf;
101 u32 tmp;
102
103 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
104
105 if (unlikely(count <= 0))
106 return;
107 asm volatile("sync");
108 do {
109 tmp = *port;
110 asm volatile("eieio");
111 *tbuf++ = tmp;
112 } while (--count != 0);
113 asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
114}
115EXPORT_SYMBOL(_insl_ns);
116
117void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
118{
119 const u32 *tbuf = buf;
120
121 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
122
123 if (unlikely(count <= 0))
124 return;
125 asm volatile("sync");
126 do {
127 *port = *tbuf++;
128 } while (--count != 0);
129 asm volatile("sync");
130}
131EXPORT_SYMBOL(_outsl_ns);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 12c5971d6565..b4432332341f 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -52,6 +52,7 @@
52#include <linux/radix-tree.h> 52#include <linux/radix-tree.h>
53#include <linux/mutex.h> 53#include <linux/mutex.h>
54#include <linux/bootmem.h> 54#include <linux/bootmem.h>
55#include <linux/pci.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
57#include <asm/system.h> 58#include <asm/system.h>
@@ -875,12 +876,14 @@ int pci_enable_msi(struct pci_dev * pdev)
875 else 876 else
876 return -1; 877 return -1;
877} 878}
879EXPORT_SYMBOL(pci_enable_msi);
878 880
879void pci_disable_msi(struct pci_dev * pdev) 881void pci_disable_msi(struct pci_dev * pdev)
880{ 882{
881 if (ppc_md.disable_msi) 883 if (ppc_md.disable_msi)
882 ppc_md.disable_msi(pdev); 884 ppc_md.disable_msi(pdev);
883} 885}
886EXPORT_SYMBOL(pci_disable_msi);
884 887
885void pci_scan_msi_device(struct pci_dev *dev) {} 888void pci_scan_msi_device(struct pci_dev *dev) {}
886int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;} 889int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
@@ -888,6 +891,8 @@ void pci_disable_msix(struct pci_dev *dev) {}
888void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} 891void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
889void disable_msi_mode(struct pci_dev *dev, int pos, int type) {} 892void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
890void pci_no_msi(void) {} 893void pci_no_msi(void) {}
894EXPORT_SYMBOL(pci_enable_msix);
895EXPORT_SYMBOL(pci_disable_msix);
891 896
892#endif 897#endif
893 898
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 40a39291861f..5e6ddfa474c0 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -39,16 +39,17 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
39 phys_addr_t taddr, unsigned long irq, 39 phys_addr_t taddr, unsigned long irq,
40 upf_t flags, int irq_check_parent) 40 upf_t flags, int irq_check_parent)
41{ 41{
42 u32 *clk, *spd, clock = BASE_BAUD * 16; 42 const u32 *clk, *spd;
43 u32 clock = BASE_BAUD * 16;
43 int index; 44 int index;
44 45
45 /* get clock freq. if present */ 46 /* get clock freq. if present */
46 clk = (u32 *)get_property(np, "clock-frequency", NULL); 47 clk = get_property(np, "clock-frequency", NULL);
47 if (clk && *clk) 48 if (clk && *clk)
48 clock = *clk; 49 clock = *clk;
49 50
50 /* get default speed if present */ 51 /* get default speed if present */
51 spd = (u32 *)get_property(np, "current-speed", NULL); 52 spd = get_property(np, "current-speed", NULL);
52 53
53 /* If we have a location index, then try to use it */ 54 /* If we have a location index, then try to use it */
54 if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) 55 if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
@@ -113,7 +114,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
113 struct device_node *soc_dev) 114 struct device_node *soc_dev)
114{ 115{
115 u64 addr; 116 u64 addr;
116 u32 *addrp; 117 const u32 *addrp;
117 upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; 118 upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
118 struct device_node *tsi = of_get_parent(np); 119 struct device_node *tsi = of_get_parent(np);
119 120
@@ -144,15 +145,15 @@ static int __init add_legacy_soc_port(struct device_node *np,
144static int __init add_legacy_isa_port(struct device_node *np, 145static int __init add_legacy_isa_port(struct device_node *np,
145 struct device_node *isa_brg) 146 struct device_node *isa_brg)
146{ 147{
147 u32 *reg; 148 const u32 *reg;
148 char *typep; 149 const char *typep;
149 int index = -1; 150 int index = -1;
150 u64 taddr; 151 u64 taddr;
151 152
152 DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); 153 DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
153 154
154 /* Get the ISA port number */ 155 /* Get the ISA port number */
155 reg = (u32 *)get_property(np, "reg", NULL); 156 reg = get_property(np, "reg", NULL);
156 if (reg == NULL) 157 if (reg == NULL)
157 return -1; 158 return -1;
158 159
@@ -163,7 +164,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
163 /* Now look for an "ibm,aix-loc" property that gives us ordering 164 /* Now look for an "ibm,aix-loc" property that gives us ordering
164 * if any... 165 * if any...
165 */ 166 */
166 typep = (char *)get_property(np, "ibm,aix-loc", NULL); 167 typep = get_property(np, "ibm,aix-loc", NULL);
167 168
168 /* If we have a location index, then use it */ 169 /* If we have a location index, then use it */
169 if (typep && *typep == 'S') 170 if (typep && *typep == 'S')
@@ -188,7 +189,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
188 struct device_node *pci_dev) 189 struct device_node *pci_dev)
189{ 190{
190 u64 addr, base; 191 u64 addr, base;
191 u32 *addrp; 192 const u32 *addrp;
192 unsigned int flags; 193 unsigned int flags;
193 int iotype, index = -1, lindex = 0; 194 int iotype, index = -1, lindex = 0;
194 195
@@ -227,7 +228,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
227 * we get to their "reg" property 228 * we get to their "reg" property
228 */ 229 */
229 if (np != pci_dev) { 230 if (np != pci_dev) {
230 u32 *reg = (u32 *)get_property(np, "reg", NULL); 231 const u32 *reg = get_property(np, "reg", NULL);
231 if (reg && (*reg < 4)) 232 if (reg && (*reg < 4))
232 index = lindex = *reg; 233 index = lindex = *reg;
233 } 234 }
@@ -285,13 +286,13 @@ static void __init setup_legacy_serial_console(int console)
285void __init find_legacy_serial_ports(void) 286void __init find_legacy_serial_ports(void)
286{ 287{
287 struct device_node *np, *stdout = NULL; 288 struct device_node *np, *stdout = NULL;
288 char *path; 289 const char *path;
289 int index; 290 int index;
290 291
291 DBG(" -> find_legacy_serial_port()\n"); 292 DBG(" -> find_legacy_serial_port()\n");
292 293
293 /* Now find out if one of these is out firmware console */ 294 /* Now find out if one of these is out firmware console */
294 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 295 path = get_property(of_chosen, "linux,stdout-path", NULL);
295 if (path != NULL) { 296 if (path != NULL) {
296 stdout = of_find_node_by_path(path); 297 stdout = of_find_node_by_path(path);
297 if (stdout) 298 if (stdout)
@@ -491,8 +492,8 @@ static int __init check_legacy_serial_console(void)
491{ 492{
492 struct device_node *prom_stdout = NULL; 493 struct device_node *prom_stdout = NULL;
493 int speed = 0, offset = 0; 494 int speed = 0, offset = 0;
494 char *name; 495 const char *name;
495 u32 *spd; 496 const u32 *spd;
496 497
497 DBG(" -> check_legacy_serial_console()\n"); 498 DBG(" -> check_legacy_serial_console()\n");
498 499
@@ -513,7 +514,7 @@ static int __init check_legacy_serial_console(void)
513 } 514 }
514 /* We are getting a weird phandle from OF ... */ 515 /* We are getting a weird phandle from OF ... */
515 /* ... So use the full path instead */ 516 /* ... So use the full path instead */
516 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 517 name = get_property(of_chosen, "linux,stdout-path", NULL);
517 if (name == NULL) { 518 if (name == NULL) {
518 DBG(" no linux,stdout-path !\n"); 519 DBG(" no linux,stdout-path !\n");
519 return -ENODEV; 520 return -ENODEV;
@@ -525,12 +526,12 @@ static int __init check_legacy_serial_console(void)
525 } 526 }
526 DBG("stdout is %s\n", prom_stdout->full_name); 527 DBG("stdout is %s\n", prom_stdout->full_name);
527 528
528 name = (char *)get_property(prom_stdout, "name", NULL); 529 name = get_property(prom_stdout, "name", NULL);
529 if (!name) { 530 if (!name) {
530 DBG(" stdout package has no name !\n"); 531 DBG(" stdout package has no name !\n");
531 goto not_found; 532 goto not_found;
532 } 533 }
533 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); 534 spd = get_property(prom_stdout, "current-speed", NULL);
534 if (spd) 535 if (spd)
535 speed = *spd; 536 speed = *spd;
536 537
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 23f34daa044a..41c05dcd68f4 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -32,7 +32,6 @@
32#include <asm/rtas.h> 32#include <asm/rtas.h>
33#include <asm/system.h> 33#include <asm/system.h>
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/iseries/it_exp_vpd_panel.h>
36#include <asm/prom.h> 35#include <asm/prom.h>
37#include <asm/vdso_datapage.h> 36#include <asm/vdso_datapage.h>
38 37
@@ -183,8 +182,14 @@ static unsigned int h_get_ppp(unsigned long *entitled,
183 unsigned long *resource) 182 unsigned long *resource)
184{ 183{
185 unsigned long rc; 184 unsigned long rc;
186 rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated, 185 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
187 aggregation, resource); 186
187 rc = plpar_hcall(H_GET_PPP, retbuf);
188
189 *entitled = retbuf[0];
190 *unallocated = retbuf[1];
191 *aggregation = retbuf[2];
192 *resource = retbuf[3];
188 193
189 log_plpar_hcall_return(rc, "H_GET_PPP"); 194 log_plpar_hcall_return(rc, "H_GET_PPP");
190 195
@@ -194,8 +199,12 @@ static unsigned int h_get_ppp(unsigned long *entitled,
194static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) 199static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
195{ 200{
196 unsigned long rc; 201 unsigned long rc;
197 unsigned long dummy; 202 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
198 rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy); 203
204 rc = plpar_hcall(H_PIC, retbuf);
205
206 *pool_idle_time = retbuf[0];
207 *num_procs = retbuf[1];
199 208
200 if (rc != H_AUTHORITY) 209 if (rc != H_AUTHORITY)
201 log_plpar_hcall_return(rc, "H_PIC"); 210 log_plpar_hcall_return(rc, "H_PIC");
@@ -310,12 +319,11 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
310 int partition_potential_processors; 319 int partition_potential_processors;
311 int partition_active_processors; 320 int partition_active_processors;
312 struct device_node *rtas_node; 321 struct device_node *rtas_node;
313 int *lrdrp = NULL; 322 const int *lrdrp = NULL;
314 323
315 rtas_node = find_path_device("/rtas"); 324 rtas_node = find_path_device("/rtas");
316 if (rtas_node) 325 if (rtas_node)
317 lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", 326 lrdrp = get_property(rtas_node, "ibm,lrdr-capacity", NULL);
318 NULL);
319 327
320 if (lrdrp == NULL) { 328 if (lrdrp == NULL) {
321 partition_potential_processors = vdso_data->processorCount; 329 partition_potential_processors = vdso_data->processorCount;
@@ -520,7 +528,8 @@ static int lparcfg_data(struct seq_file *m, void *v)
520 const char *model = ""; 528 const char *model = "";
521 const char *system_id = ""; 529 const char *system_id = "";
522 const char *tmp; 530 const char *tmp;
523 unsigned int *lp_index_ptr, lp_index = 0; 531 const unsigned int *lp_index_ptr;
532 unsigned int lp_index = 0;
524 533
525 seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); 534 seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
526 535
@@ -540,8 +549,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
540 if (firmware_has_feature(FW_FEATURE_ISERIES)) 549 if (firmware_has_feature(FW_FEATURE_ISERIES))
541 system_id += 4; 550 system_id += 4;
542 } 551 }
543 lp_index_ptr = (unsigned int *) 552 lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL);
544 get_property(rootdn, "ibm,partition-no", NULL);
545 if (lp_index_ptr) 553 if (lp_index_ptr)
546 lp_index = *lp_index_ptr; 554 lp_index = *lp_index_ptr;
547 } 555 }
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index be58985c7681..a24b09c27718 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -31,8 +31,8 @@ int default_machine_kexec_prepare(struct kimage *image)
31 unsigned long begin, end; /* limits of segment */ 31 unsigned long begin, end; /* limits of segment */
32 unsigned long low, high; /* limits of blocked memory range */ 32 unsigned long low, high; /* limits of blocked memory range */
33 struct device_node *node; 33 struct device_node *node;
34 unsigned long *basep; 34 const unsigned long *basep;
35 unsigned int *sizep; 35 const unsigned int *sizep;
36 36
37 if (!ppc_md.hpte_clear_all) 37 if (!ppc_md.hpte_clear_all)
38 return -ENOENT; 38 return -ENOENT;
@@ -72,10 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image)
72 /* We also should not overwrite the tce tables */ 72 /* We also should not overwrite the tce tables */
73 for (node = of_find_node_by_type(NULL, "pci"); node != NULL; 73 for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
74 node = of_find_node_by_type(node, "pci")) { 74 node = of_find_node_by_type(node, "pci")) {
75 basep = (unsigned long *)get_property(node, "linux,tce-base", 75 basep = get_property(node, "linux,tce-base", NULL);
76 NULL); 76 sizep = get_property(node, "linux,tce-size", NULL);
77 sizep = (unsigned int *)get_property(node, "linux,tce-size",
78 NULL);
79 if (basep == NULL || sizep == NULL) 77 if (basep == NULL || sizep == NULL)
80 continue; 78 continue;
81 79
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index f770805f1215..330c9dc7db86 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -43,162 +43,3 @@ _GLOBAL(add_reloc_offset)
43 add r3,r3,r5 43 add r3,r3,r5
44 mtlr r0 44 mtlr r0
45 blr 45 blr
46
47/*
48 * I/O string operations
49 *
50 * insb(port, buf, len)
51 * outsb(port, buf, len)
52 * insw(port, buf, len)
53 * outsw(port, buf, len)
54 * insl(port, buf, len)
55 * outsl(port, buf, len)
56 * insw_ns(port, buf, len)
57 * outsw_ns(port, buf, len)
58 * insl_ns(port, buf, len)
59 * outsl_ns(port, buf, len)
60 *
61 * The *_ns versions don't do byte-swapping.
62 */
63_GLOBAL(_insb)
64 sync
65 cmpwi 0,r5,0
66 mtctr r5
67 subi r4,r4,1
68 blelr-
6900: lbz r5,0(r3)
70 eieio
71 stbu r5,1(r4)
72 bdnz 00b
73 twi 0,r5,0
74 isync
75 blr
76
77_GLOBAL(_outsb)
78 cmpwi 0,r5,0
79 mtctr r5
80 subi r4,r4,1
81 blelr-
82 sync
8300: lbzu r5,1(r4)
84 stb r5,0(r3)
85 bdnz 00b
86 sync
87 blr
88
89_GLOBAL(_insw)
90 sync
91 cmpwi 0,r5,0
92 mtctr r5
93 subi r4,r4,2
94 blelr-
9500: lhbrx r5,0,r3
96 eieio
97 sthu r5,2(r4)
98 bdnz 00b
99 twi 0,r5,0
100 isync
101 blr
102
103_GLOBAL(_outsw)
104 cmpwi 0,r5,0
105 mtctr r5
106 subi r4,r4,2
107 blelr-
108 sync
10900: lhzu r5,2(r4)
110 sthbrx r5,0,r3
111 bdnz 00b
112 sync
113 blr
114
115_GLOBAL(_insl)
116 sync
117 cmpwi 0,r5,0
118 mtctr r5
119 subi r4,r4,4
120 blelr-
12100: lwbrx r5,0,r3
122 eieio
123 stwu r5,4(r4)
124 bdnz 00b
125 twi 0,r5,0
126 isync
127 blr
128
129_GLOBAL(_outsl)
130 cmpwi 0,r5,0
131 mtctr r5
132 subi r4,r4,4
133 blelr-
134 sync
13500: lwzu r5,4(r4)
136 stwbrx r5,0,r3
137 bdnz 00b
138 sync
139 blr
140
141#ifdef CONFIG_PPC32
142_GLOBAL(__ide_mm_insw)
143#endif
144_GLOBAL(_insw_ns)
145 sync
146 cmpwi 0,r5,0
147 mtctr r5
148 subi r4,r4,2
149 blelr-
15000: lhz r5,0(r3)
151 eieio
152 sthu r5,2(r4)
153 bdnz 00b
154 twi 0,r5,0
155 isync
156 blr
157
158#ifdef CONFIG_PPC32
159_GLOBAL(__ide_mm_outsw)
160#endif
161_GLOBAL(_outsw_ns)
162 cmpwi 0,r5,0
163 mtctr r5
164 subi r4,r4,2
165 blelr-
166 sync
16700: lhzu r5,2(r4)
168 sth r5,0(r3)
169 bdnz 00b
170 sync
171 blr
172
173#ifdef CONFIG_PPC32
174_GLOBAL(__ide_mm_insl)
175#endif
176_GLOBAL(_insl_ns)
177 sync
178 cmpwi 0,r5,0
179 mtctr r5
180 subi r4,r4,4
181 blelr-
18200: lwz r5,0(r3)
183 eieio
184 stwu r5,4(r4)
185 bdnz 00b
186 twi 0,r5,0
187 isync
188 blr
189
190#ifdef CONFIG_PPC32
191_GLOBAL(__ide_mm_outsl)
192#endif
193_GLOBAL(_outsl_ns)
194 cmpwi 0,r5,0
195 mtctr r5
196 subi r4,r4,4
197 blelr-
198 sync
19900: lwzu r5,4(r4)
200 stw r5,0(r3)
201 bdnz 00b
202 sync
203 blr
204
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 3262b73a3a68..397c83eda20e 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -189,27 +189,9 @@ void of_release_dev(struct device *dev)
189int of_device_register(struct of_device *ofdev) 189int of_device_register(struct of_device *ofdev)
190{ 190{
191 int rc; 191 int rc;
192 struct of_device **odprop;
193 192
194 BUG_ON(ofdev->node == NULL); 193 BUG_ON(ofdev->node == NULL);
195 194
196 odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
197 if (!odprop) {
198 struct property *new_prop;
199
200 new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
201 GFP_KERNEL);
202 if (new_prop == NULL)
203 return -ENOMEM;
204 new_prop->name = "linux,device";
205 new_prop->length = sizeof(sizeof(struct of_device *));
206 new_prop->value = (unsigned char *)&new_prop[1];
207 odprop = (struct of_device **)new_prop->value;
208 *odprop = NULL;
209 prom_add_property(ofdev->node, new_prop);
210 }
211 *odprop = ofdev;
212
213 rc = device_register(&ofdev->dev); 195 rc = device_register(&ofdev->dev);
214 if (rc) 196 if (rc)
215 return rc; 197 return rc;
@@ -221,14 +203,8 @@ int of_device_register(struct of_device *ofdev)
221 203
222void of_device_unregister(struct of_device *ofdev) 204void of_device_unregister(struct of_device *ofdev)
223{ 205{
224 struct of_device **odprop;
225
226 device_remove_file(&ofdev->dev, &dev_attr_devspec); 206 device_remove_file(&ofdev->dev, &dev_attr_devspec);
227 207
228 odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
229 if (odprop)
230 *odprop = NULL;
231
232 device_unregister(&ofdev->dev); 208 device_unregister(&ofdev->dev);
233} 209}
234 210
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index c68741fed14b..55f1a25085cd 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -17,6 +17,7 @@
17#include <asm/lppaca.h> 17#include <asm/lppaca.h>
18#include <asm/iseries/it_lp_reg_save.h> 18#include <asm/iseries/it_lp_reg_save.h>
19#include <asm/paca.h> 19#include <asm/paca.h>
20#include <asm/mmu.h>
20 21
21 22
22/* This symbol is provided by the linker - let it fill in the paca 23/* This symbol is provided by the linker - let it fill in the paca
@@ -45,6 +46,17 @@ struct lppaca lppaca[] = {
45 }, 46 },
46}; 47};
47 48
49/*
50 * 3 persistent SLBs are registered here. The buffer will be zero
51 * initially, hence will all be invaild until we actually write them.
52 */
53struct slb_shadow slb_shadow[] __cacheline_aligned = {
54 [0 ... (NR_CPUS-1)] = {
55 .persistent = SLB_NUM_BOLTED,
56 .buffer_length = sizeof(struct slb_shadow),
57 },
58};
59
48/* The Paca is an array with one entry per processor. Each contains an 60/* The Paca is an array with one entry per processor. Each contains an
49 * lppaca, which contains the information shared between the 61 * lppaca, which contains the information shared between the
50 * hypervisor and Linux. 62 * hypervisor and Linux.
@@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
59 .lock_token = 0x8000, \ 71 .lock_token = 0x8000, \
60 .paca_index = (number), /* Paca Index */ \ 72 .paca_index = (number), /* Paca Index */ \
61 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 73 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
62 .hw_cpu_id = 0xffff, 74 .hw_cpu_id = 0xffff, \
75 .slb_shadow_ptr = &slb_shadow[number],
63 76
64#ifdef CONFIG_PPC_ISERIES 77#ifdef CONFIG_PPC_ISERIES
65#define PACA_INIT_ISERIES(number) \ 78#define PACA_INIT_ISERIES(number) \
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 09b1e1bbb29b..9b49f8691d29 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -633,12 +633,12 @@ pcibios_alloc_controller(void)
633static void 633static void
634make_one_node_map(struct device_node* node, u8 pci_bus) 634make_one_node_map(struct device_node* node, u8 pci_bus)
635{ 635{
636 int *bus_range; 636 const int *bus_range;
637 int len; 637 int len;
638 638
639 if (pci_bus >= pci_bus_count) 639 if (pci_bus >= pci_bus_count)
640 return; 640 return;
641 bus_range = (int *) get_property(node, "bus-range", &len); 641 bus_range = get_property(node, "bus-range", &len);
642 if (bus_range == NULL || len < 2 * sizeof(int)) { 642 if (bus_range == NULL || len < 2 * sizeof(int)) {
643 printk(KERN_WARNING "Can't get bus-range for %s, " 643 printk(KERN_WARNING "Can't get bus-range for %s, "
644 "assuming it starts at 0\n", node->full_name); 644 "assuming it starts at 0\n", node->full_name);
@@ -648,13 +648,13 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
648 648
649 for (node=node->child; node != 0;node = node->sibling) { 649 for (node=node->child; node != 0;node = node->sibling) {
650 struct pci_dev* dev; 650 struct pci_dev* dev;
651 unsigned int *class_code, *reg; 651 const unsigned int *class_code, *reg;
652 652
653 class_code = (unsigned int *) get_property(node, "class-code", NULL); 653 class_code = get_property(node, "class-code", NULL);
654 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 654 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
655 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 655 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
656 continue; 656 continue;
657 reg = (unsigned int *)get_property(node, "reg", NULL); 657 reg = get_property(node, "reg", NULL);
658 if (!reg) 658 if (!reg)
659 continue; 659 continue;
660 dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); 660 dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
@@ -669,7 +669,7 @@ pcibios_make_OF_bus_map(void)
669{ 669{
670 int i; 670 int i;
671 struct pci_controller* hose; 671 struct pci_controller* hose;
672 u8* of_prop_map; 672 struct property *map_prop;
673 673
674 pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); 674 pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
675 if (!pci_to_OF_bus_map) { 675 if (!pci_to_OF_bus_map) {
@@ -691,9 +691,12 @@ pcibios_make_OF_bus_map(void)
691 continue; 691 continue;
692 make_one_node_map(node, hose->first_busno); 692 make_one_node_map(node, hose->first_busno);
693 } 693 }
694 of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL); 694 map_prop = of_find_property(find_path_device("/"),
695 if (of_prop_map) 695 "pci-OF-bus-map", NULL);
696 memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); 696 if (map_prop) {
697 BUG_ON(pci_bus_count > map_prop->length);
698 memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
699 }
697#ifdef DEBUG 700#ifdef DEBUG
698 printk("PCI->OF bus map:\n"); 701 printk("PCI->OF bus map:\n");
699 for (i=0; i<pci_bus_count; i++) { 702 for (i=0; i<pci_bus_count; i++) {
@@ -712,7 +715,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
712 struct device_node* sub_node; 715 struct device_node* sub_node;
713 716
714 for (; node != 0;node = node->sibling) { 717 for (; node != 0;node = node->sibling) {
715 unsigned int *class_code; 718 const unsigned int *class_code;
716 719
717 if (filter(node, data)) 720 if (filter(node, data))
718 return node; 721 return node;
@@ -722,7 +725,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
722 * a fake root for all functions of a multi-function device, 725 * a fake root for all functions of a multi-function device,
723 * we go down them as well. 726 * we go down them as well.
724 */ 727 */
725 class_code = (unsigned int *) get_property(node, "class-code", NULL); 728 class_code = get_property(node, "class-code", NULL);
726 if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 729 if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
727 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && 730 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
728 strcmp(node->name, "multifunc-device")) 731 strcmp(node->name, "multifunc-device"))
@@ -737,10 +740,10 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
737static int 740static int
738scan_OF_pci_childs_iterator(struct device_node* node, void* data) 741scan_OF_pci_childs_iterator(struct device_node* node, void* data)
739{ 742{
740 unsigned int *reg; 743 const unsigned int *reg;
741 u8* fdata = (u8*)data; 744 u8* fdata = (u8*)data;
742 745
743 reg = (unsigned int *) get_property(node, "reg", NULL); 746 reg = get_property(node, "reg", NULL);
744 if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] 747 if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
745 && ((reg[0] >> 16) & 0xff) == fdata[0]) 748 && ((reg[0] >> 16) & 0xff) == fdata[0])
746 return 1; 749 return 1;
@@ -841,7 +844,7 @@ find_OF_pci_device_filter(struct device_node* node, void* data)
841int 844int
842pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) 845pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
843{ 846{
844 unsigned int *reg; 847 const unsigned int *reg;
845 struct pci_controller* hose; 848 struct pci_controller* hose;
846 struct pci_dev* dev = NULL; 849 struct pci_dev* dev = NULL;
847 850
@@ -854,7 +857,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
854 if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, 857 if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
855 find_OF_pci_device_filter, (void *)node)) 858 find_OF_pci_device_filter, (void *)node))
856 return -ENODEV; 859 return -ENODEV;
857 reg = (unsigned int *) get_property(node, "reg", NULL); 860 reg = get_property(node, "reg", NULL);
858 if (!reg) 861 if (!reg)
859 return -ENODEV; 862 return -ENODEV;
860 *bus = (reg[0] >> 16) & 0xff; 863 *bus = (reg[0] >> 16) & 0xff;
@@ -885,8 +888,8 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
885 struct device_node *dev, int primary) 888 struct device_node *dev, int primary)
886{ 889{
887 static unsigned int static_lc_ranges[256] __initdata; 890 static unsigned int static_lc_ranges[256] __initdata;
888 unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; 891 const unsigned int *dt_ranges;
889 unsigned int size; 892 unsigned int *lc_ranges, *ranges, *prev, size;
890 int rlen = 0, orig_rlen; 893 int rlen = 0, orig_rlen;
891 int memno = 0; 894 int memno = 0;
892 struct resource *res; 895 struct resource *res;
@@ -897,7 +900,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
897 * that can have more than 3 ranges, fortunately using contiguous 900 * that can have more than 3 ranges, fortunately using contiguous
898 * addresses -- BenH 901 * addresses -- BenH
899 */ 902 */
900 dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); 903 dt_ranges = get_property(dev, "ranges", &rlen);
901 if (!dt_ranges) 904 if (!dt_ranges)
902 return; 905 return;
903 /* Sanity check, though hopefully that never happens */ 906 /* Sanity check, though hopefully that never happens */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 138134c8c17d..c1b1e14775e4 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -185,34 +185,6 @@ static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
185 spin_unlock(&hose_spinlock); 185 spin_unlock(&hose_spinlock);
186} 186}
187 187
188static void add_linux_pci_domain(struct device_node *dev,
189 struct pci_controller *phb)
190{
191 struct property *of_prop;
192 unsigned int size;
193
194 of_prop = (struct property *)
195 get_property(dev, "linux,pci-domain", &size);
196 if (of_prop != NULL)
197 return;
198 WARN_ON(of_prop && size < sizeof(int));
199 if (of_prop && size < sizeof(int))
200 of_prop = NULL;
201 size = sizeof(struct property) + sizeof(int);
202 if (of_prop == NULL) {
203 if (mem_init_done)
204 of_prop = kmalloc(size, GFP_KERNEL);
205 else
206 of_prop = alloc_bootmem(size);
207 }
208 memset(of_prop, 0, sizeof(struct property));
209 of_prop->name = "linux,pci-domain";
210 of_prop->length = sizeof(int);
211 of_prop->value = (unsigned char *)&of_prop[1];
212 *((int *)of_prop->value) = phb->global_number;
213 prom_add_property(dev, of_prop);
214}
215
216struct pci_controller * pcibios_alloc_controller(struct device_node *dev) 188struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
217{ 189{
218 struct pci_controller *phb; 190 struct pci_controller *phb;
@@ -226,22 +198,13 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
226 pci_setup_pci_controller(phb); 198 pci_setup_pci_controller(phb);
227 phb->arch_data = dev; 199 phb->arch_data = dev;
228 phb->is_dynamic = mem_init_done; 200 phb->is_dynamic = mem_init_done;
229 if (dev) { 201 if (dev)
230 PHB_SET_NODE(phb, of_node_to_nid(dev)); 202 PHB_SET_NODE(phb, of_node_to_nid(dev));
231 add_linux_pci_domain(dev, phb);
232 }
233 return phb; 203 return phb;
234} 204}
235 205
236void pcibios_free_controller(struct pci_controller *phb) 206void pcibios_free_controller(struct pci_controller *phb)
237{ 207{
238 if (phb->arch_data) {
239 struct device_node *np = phb->arch_data;
240 int *domain = (int *)get_property(np,
241 "linux,pci-domain", NULL);
242 if (domain)
243 *domain = -1;
244 }
245 if (phb->is_dynamic) 208 if (phb->is_dynamic)
246 kfree(phb); 209 kfree(phb);
247} 210}
@@ -283,10 +246,10 @@ static void __init pcibios_claim_of_setup(void)
283#ifdef CONFIG_PPC_MULTIPLATFORM 246#ifdef CONFIG_PPC_MULTIPLATFORM
284static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 247static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
285{ 248{
286 u32 *prop; 249 const u32 *prop;
287 int len; 250 int len;
288 251
289 prop = (u32 *) get_property(np, name, &len); 252 prop = get_property(np, name, &len);
290 if (prop && len >= 4) 253 if (prop && len >= 4)
291 return *prop; 254 return *prop;
292 return def; 255 return def;
@@ -315,10 +278,11 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
315 u64 base, size; 278 u64 base, size;
316 unsigned int flags; 279 unsigned int flags;
317 struct resource *res; 280 struct resource *res;
318 u32 *addrs, i; 281 const u32 *addrs;
282 u32 i;
319 int proplen; 283 int proplen;
320 284
321 addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); 285 addrs = get_property(node, "assigned-addresses", &proplen);
322 if (!addrs) 286 if (!addrs)
323 return; 287 return;
324 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); 288 DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
@@ -418,7 +382,7 @@ void __devinit of_scan_bus(struct device_node *node,
418 struct pci_bus *bus) 382 struct pci_bus *bus)
419{ 383{
420 struct device_node *child = NULL; 384 struct device_node *child = NULL;
421 u32 *reg; 385 const u32 *reg;
422 int reglen, devfn; 386 int reglen, devfn;
423 struct pci_dev *dev; 387 struct pci_dev *dev;
424 388
@@ -426,7 +390,7 @@ void __devinit of_scan_bus(struct device_node *node,
426 390
427 while ((child = of_get_next_child(node, child)) != NULL) { 391 while ((child = of_get_next_child(node, child)) != NULL) {
428 DBG(" * %s\n", child->full_name); 392 DBG(" * %s\n", child->full_name);
429 reg = (u32 *) get_property(child, "reg", &reglen); 393 reg = get_property(child, "reg", &reglen);
430 if (reg == NULL || reglen < 20) 394 if (reg == NULL || reglen < 20)
431 continue; 395 continue;
432 devfn = (reg[0] >> 8) & 0xff; 396 devfn = (reg[0] >> 8) & 0xff;
@@ -450,7 +414,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
450 struct pci_dev *dev) 414 struct pci_dev *dev)
451{ 415{
452 struct pci_bus *bus; 416 struct pci_bus *bus;
453 u32 *busrange, *ranges; 417 const u32 *busrange, *ranges;
454 int len, i, mode; 418 int len, i, mode;
455 struct resource *res; 419 struct resource *res;
456 unsigned int flags; 420 unsigned int flags;
@@ -459,13 +423,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
459 DBG("of_scan_pci_bridge(%s)\n", node->full_name); 423 DBG("of_scan_pci_bridge(%s)\n", node->full_name);
460 424
461 /* parse bus-range property */ 425 /* parse bus-range property */
462 busrange = (u32 *) get_property(node, "bus-range", &len); 426 busrange = get_property(node, "bus-range", &len);
463 if (busrange == NULL || len != 8) { 427 if (busrange == NULL || len != 8) {
464 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", 428 printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
465 node->full_name); 429 node->full_name);
466 return; 430 return;
467 } 431 }
468 ranges = (u32 *) get_property(node, "ranges", &len); 432 ranges = get_property(node, "ranges", &len);
469 if (ranges == NULL) { 433 if (ranges == NULL) {
470 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", 434 printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
471 node->full_name); 435 node->full_name);
@@ -929,13 +893,13 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
929 unsigned int size; 893 unsigned int size;
930 }; 894 };
931 895
932 struct isa_range *range; 896 const struct isa_range *range;
933 unsigned long pci_addr; 897 unsigned long pci_addr;
934 unsigned int isa_addr; 898 unsigned int isa_addr;
935 unsigned int size; 899 unsigned int size;
936 int rlen = 0; 900 int rlen = 0;
937 901
938 range = (struct isa_range *) get_property(isa_node, "ranges", &rlen); 902 range = get_property(isa_node, "ranges", &rlen);
939 if (range == NULL || (rlen < sizeof(struct isa_range))) { 903 if (range == NULL || (rlen < sizeof(struct isa_range))) {
940 printk(KERN_ERR "no ISA ranges or unexpected isa range size," 904 printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
941 "mapping 64k\n"); 905 "mapping 64k\n");
@@ -976,7 +940,8 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
976void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, 940void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
977 struct device_node *dev, int prim) 941 struct device_node *dev, int prim)
978{ 942{
979 unsigned int *ranges, pci_space; 943 const unsigned int *ranges;
944 unsigned int pci_space;
980 unsigned long size; 945 unsigned long size;
981 int rlen = 0; 946 int rlen = 0;
982 int memno = 0; 947 int memno = 0;
@@ -994,7 +959,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
994 * (size depending on dev->n_addr_cells) 959 * (size depending on dev->n_addr_cells)
995 * cells 4+5 or 5+6: the size of the range 960 * cells 4+5 or 5+6: the size of the range
996 */ 961 */
997 ranges = (unsigned int *) get_property(dev, "ranges", &rlen); 962 ranges = get_property(dev, "ranges", &rlen);
998 if (ranges == NULL) 963 if (ranges == NULL)
999 return; 964 return;
1000 hose->io_base_phys = 0; 965 hose->io_base_phys = 0;
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index 1c18953514c3..68df018dae0e 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -40,8 +40,8 @@
40static void * __devinit update_dn_pci_info(struct device_node *dn, void *data) 40static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
41{ 41{
42 struct pci_controller *phb = data; 42 struct pci_controller *phb = data;
43 int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL); 43 const int *type = get_property(dn, "ibm,pci-config-space-type", NULL);
44 u32 *regs; 44 const u32 *regs;
45 struct pci_dn *pdn; 45 struct pci_dn *pdn;
46 46
47 if (mem_init_done) 47 if (mem_init_done)
@@ -54,14 +54,14 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
54 dn->data = pdn; 54 dn->data = pdn;
55 pdn->node = dn; 55 pdn->node = dn;
56 pdn->phb = phb; 56 pdn->phb = phb;
57 regs = (u32 *)get_property(dn, "reg", NULL); 57 regs = get_property(dn, "reg", NULL);
58 if (regs) { 58 if (regs) {
59 /* First register entry is addr (00BBSS00) */ 59 /* First register entry is addr (00BBSS00) */
60 pdn->busno = (regs[0] >> 16) & 0xff; 60 pdn->busno = (regs[0] >> 16) & 0xff;
61 pdn->devfn = (regs[0] >> 8) & 0xff; 61 pdn->devfn = (regs[0] >> 8) & 0xff;
62 } 62 }
63 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 63 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
64 u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL); 64 const u32 *busp = get_property(dn, "linux,subbus", NULL);
65 if (busp) 65 if (busp)
66 pdn->bussubno = *busp; 66 pdn->bussubno = *busp;
67 } 67 }
@@ -96,10 +96,11 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
96 96
97 /* We started with a phb, iterate all childs */ 97 /* We started with a phb, iterate all childs */
98 for (dn = start->child; dn; dn = nextdn) { 98 for (dn = start->child; dn; dn = nextdn) {
99 u32 *classp, class; 99 const u32 *classp;
100 u32 class;
100 101
101 nextdn = NULL; 102 nextdn = NULL;
102 classp = (u32 *)get_property(dn, "class-code", NULL); 103 classp = get_property(dn, "class-code", NULL);
103 class = classp ? *classp : 0; 104 class = classp ? *classp : 0;
104 105
105 if (pre && ((ret = pre(dn, data)) != NULL)) 106 if (pre && ((ret = pre(dn, data)) != NULL))
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 39d3bfcabcd2..807193a3c784 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -91,25 +91,10 @@ EXPORT_SYMBOL(__copy_tofrom_user);
91EXPORT_SYMBOL(__clear_user); 91EXPORT_SYMBOL(__clear_user);
92EXPORT_SYMBOL(__strncpy_from_user); 92EXPORT_SYMBOL(__strncpy_from_user);
93EXPORT_SYMBOL(__strnlen_user); 93EXPORT_SYMBOL(__strnlen_user);
94 94#ifdef CONFIG_PPC64
95#ifndef __powerpc64__ 95EXPORT_SYMBOL(copy_4K_page);
96EXPORT_SYMBOL(__ide_mm_insl);
97EXPORT_SYMBOL(__ide_mm_outsw);
98EXPORT_SYMBOL(__ide_mm_insw);
99EXPORT_SYMBOL(__ide_mm_outsl);
100#endif 96#endif
101 97
102EXPORT_SYMBOL(_insb);
103EXPORT_SYMBOL(_outsb);
104EXPORT_SYMBOL(_insw);
105EXPORT_SYMBOL(_outsw);
106EXPORT_SYMBOL(_insl);
107EXPORT_SYMBOL(_outsl);
108EXPORT_SYMBOL(_insw_ns);
109EXPORT_SYMBOL(_outsw_ns);
110EXPORT_SYMBOL(_insl_ns);
111EXPORT_SYMBOL(_outsl_ns);
112
113#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)) 98#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
114EXPORT_SYMBOL(ppc_ide_md); 99EXPORT_SYMBOL(ppc_ide_md);
115#endif 100#endif
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index a1787ffb6319..eb913f80bfb1 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -757,24 +757,9 @@ static int __init early_init_dt_scan_root(unsigned long node,
757static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) 757static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
758{ 758{
759 cell_t *p = *cellp; 759 cell_t *p = *cellp;
760 unsigned long r;
761 760
762 /* Ignore more than 2 cells */ 761 *cellp = p + s;
763 while (s > sizeof(unsigned long) / 4) { 762 return of_read_ulong(p, s);
764 p++;
765 s--;
766 }
767 r = *p++;
768#ifdef CONFIG_PPC64
769 if (s > 1) {
770 r <<= 32;
771 r |= *(p++);
772 s--;
773 }
774#endif
775
776 *cellp = p;
777 return r;
778} 763}
779 764
780 765
@@ -942,11 +927,11 @@ void __init early_init_devtree(void *params)
942int 927int
943prom_n_addr_cells(struct device_node* np) 928prom_n_addr_cells(struct device_node* np)
944{ 929{
945 int* ip; 930 const int *ip;
946 do { 931 do {
947 if (np->parent) 932 if (np->parent)
948 np = np->parent; 933 np = np->parent;
949 ip = (int *) get_property(np, "#address-cells", NULL); 934 ip = get_property(np, "#address-cells", NULL);
950 if (ip != NULL) 935 if (ip != NULL)
951 return *ip; 936 return *ip;
952 } while (np->parent); 937 } while (np->parent);
@@ -958,11 +943,11 @@ EXPORT_SYMBOL(prom_n_addr_cells);
958int 943int
959prom_n_size_cells(struct device_node* np) 944prom_n_size_cells(struct device_node* np)
960{ 945{
961 int* ip; 946 const int* ip;
962 do { 947 do {
963 if (np->parent) 948 if (np->parent)
964 np = np->parent; 949 np = np->parent;
965 ip = (int *) get_property(np, "#size-cells", NULL); 950 ip = get_property(np, "#size-cells", NULL);
966 if (ip != NULL) 951 if (ip != NULL)
967 return *ip; 952 return *ip;
968 } while (np->parent); 953 } while (np->parent);
@@ -1034,7 +1019,7 @@ int device_is_compatible(struct device_node *device, const char *compat)
1034 const char* cp; 1019 const char* cp;
1035 int cplen, l; 1020 int cplen, l;
1036 1021
1037 cp = (char *) get_property(device, "compatible", &cplen); 1022 cp = get_property(device, "compatible", &cplen);
1038 if (cp == NULL) 1023 if (cp == NULL)
1039 return 0; 1024 return 0;
1040 while (cplen > 0) { 1025 while (cplen > 0) {
@@ -1449,7 +1434,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1449{ 1434{
1450 struct device_node *parent = of_get_parent(node); 1435 struct device_node *parent = of_get_parent(node);
1451 int err = 0; 1436 int err = 0;
1452 phandle *ibm_phandle; 1437 const phandle *ibm_phandle;
1453 1438
1454 node->name = get_property(node, "name", NULL); 1439 node->name = get_property(node, "name", NULL);
1455 node->type = get_property(node, "device_type", NULL); 1440 node->type = get_property(node, "device_type", NULL);
@@ -1466,8 +1451,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1466 return -ENODEV; 1451 return -ENODEV;
1467 1452
1468 /* fix up new node's linux_phandle field */ 1453 /* fix up new node's linux_phandle field */
1469 if ((ibm_phandle = (unsigned int *)get_property(node, 1454 if ((ibm_phandle = get_property(node, "ibm,phandle", NULL)))
1470 "ibm,phandle", NULL)))
1471 node->linux_phandle = *ibm_phandle; 1455 node->linux_phandle = *ibm_phandle;
1472 1456
1473out: 1457out:
@@ -1528,7 +1512,7 @@ struct property *of_find_property(struct device_node *np, const char *name,
1528 * Find a property with a given name for a given node 1512 * Find a property with a given name for a given node
1529 * and return the value. 1513 * and return the value.
1530 */ 1514 */
1531void *get_property(struct device_node *np, const char *name, int *lenp) 1515const void *get_property(struct device_node *np, const char *name, int *lenp)
1532{ 1516{
1533 struct property *pp = of_find_property(np,name,lenp); 1517 struct property *pp = of_find_property(np,name,lenp);
1534 return pp ? pp->value : NULL; 1518 return pp ? pp->value : NULL;
@@ -1658,16 +1642,16 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
1658 hardid = get_hard_smp_processor_id(cpu); 1642 hardid = get_hard_smp_processor_id(cpu);
1659 1643
1660 for_each_node_by_type(np, "cpu") { 1644 for_each_node_by_type(np, "cpu") {
1661 u32 *intserv; 1645 const u32 *intserv;
1662 unsigned int plen, t; 1646 unsigned int plen, t;
1663 1647
1664 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist 1648 /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
1665 * fallback to "reg" property and assume no threads 1649 * fallback to "reg" property and assume no threads
1666 */ 1650 */
1667 intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", 1651 intserv = get_property(np, "ibm,ppc-interrupt-server#s",
1668 &plen); 1652 &plen);
1669 if (intserv == NULL) { 1653 if (intserv == NULL) {
1670 u32 *reg = (u32 *)get_property(np, "reg", NULL); 1654 const u32 *reg = get_property(np, "reg", NULL);
1671 if (reg == NULL) 1655 if (reg == NULL)
1672 continue; 1656 continue;
1673 if (*reg == hardid) { 1657 if (*reg == hardid) {
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 4394e545f9f7..b91761639d96 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2033,16 +2033,22 @@ static void __init fixup_device_tree_maple(void)
2033#endif 2033#endif
2034 2034
2035#ifdef CONFIG_PPC_CHRP 2035#ifdef CONFIG_PPC_CHRP
2036/* Pegasos lacks the "ranges" property in the isa node */ 2036/* Pegasos and BriQ lacks the "ranges" property in the isa node */
2037static void __init fixup_device_tree_chrp(void) 2037static void __init fixup_device_tree_chrp(void)
2038{ 2038{
2039 phandle isa; 2039 phandle isa;
2040 u32 isa_ranges[6]; 2040 u32 isa_ranges[6];
2041 u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
2041 char *name; 2042 char *name;
2042 int rc; 2043 int rc;
2043 2044
2044 name = "/pci@80000000/isa@c"; 2045 name = "/pci@80000000/isa@c";
2045 isa = call_prom("finddevice", 1, 1, ADDR(name)); 2046 isa = call_prom("finddevice", 1, 1, ADDR(name));
2047 if (!PHANDLE_VALID(isa)) {
2048 name = "/pci@ff500000/isa@6";
2049 isa = call_prom("finddevice", 1, 1, ADDR(name));
2050 rloc = 0x01003000; /* IO space; PCI device = 6 */
2051 }
2046 if (!PHANDLE_VALID(isa)) 2052 if (!PHANDLE_VALID(isa))
2047 return; 2053 return;
2048 2054
@@ -2054,7 +2060,7 @@ static void __init fixup_device_tree_chrp(void)
2054 2060
2055 isa_ranges[0] = 0x1; 2061 isa_ranges[0] = 0x1;
2056 isa_ranges[1] = 0x0; 2062 isa_ranges[1] = 0x0;
2057 isa_ranges[2] = 0x01006000; 2063 isa_ranges[2] = rloc;
2058 isa_ranges[3] = 0x0; 2064 isa_ranges[3] = 0x0;
2059 isa_ranges[4] = 0x0; 2065 isa_ranges[4] = 0x0;
2060 isa_ranges[5] = 0x00010000; 2066 isa_ranges[5] = 0x00010000;
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index a10825a5dfe6..603dff3ad62a 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -27,7 +27,7 @@
27 27
28/* Debug utility */ 28/* Debug utility */
29#ifdef DEBUG 29#ifdef DEBUG
30static void of_dump_addr(const char *s, u32 *addr, int na) 30static void of_dump_addr(const char *s, const u32 *addr, int na)
31{ 31{
32 printk("%s", s); 32 printk("%s", s);
33 while(na--) 33 while(na--)
@@ -35,7 +35,7 @@ static void of_dump_addr(const char *s, u32 *addr, int na)
35 printk("\n"); 35 printk("\n");
36} 36}
37#else 37#else
38static void of_dump_addr(const char *s, u32 *addr, int na) { } 38static void of_dump_addr(const char *s, const u32 *addr, int na) { }
39#endif 39#endif
40 40
41 41
@@ -46,9 +46,10 @@ struct of_bus {
46 int (*match)(struct device_node *parent); 46 int (*match)(struct device_node *parent);
47 void (*count_cells)(struct device_node *child, 47 void (*count_cells)(struct device_node *child,
48 int *addrc, int *sizec); 48 int *addrc, int *sizec);
49 u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); 49 u64 (*map)(u32 *addr, const u32 *range,
50 int na, int ns, int pna);
50 int (*translate)(u32 *addr, u64 offset, int na); 51 int (*translate)(u32 *addr, u64 offset, int na);
51 unsigned int (*get_flags)(u32 *addr); 52 unsigned int (*get_flags)(const u32 *addr);
52}; 53};
53 54
54 55
@@ -65,7 +66,8 @@ static void of_bus_default_count_cells(struct device_node *dev,
65 *sizec = prom_n_size_cells(dev); 66 *sizec = prom_n_size_cells(dev);
66} 67}
67 68
68static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) 69static u64 of_bus_default_map(u32 *addr, const u32 *range,
70 int na, int ns, int pna)
69{ 71{
70 u64 cp, s, da; 72 u64 cp, s, da;
71 73
@@ -93,7 +95,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
93 return 0; 95 return 0;
94} 96}
95 97
96static unsigned int of_bus_default_get_flags(u32 *addr) 98static unsigned int of_bus_default_get_flags(const u32 *addr)
97{ 99{
98 return IORESOURCE_MEM; 100 return IORESOURCE_MEM;
99} 101}
@@ -118,7 +120,7 @@ static void of_bus_pci_count_cells(struct device_node *np,
118 *sizec = 2; 120 *sizec = 2;
119} 121}
120 122
121static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) 123static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
122{ 124{
123 u64 cp, s, da; 125 u64 cp, s, da;
124 126
@@ -143,7 +145,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
143 return of_bus_default_translate(addr + 1, offset, na - 1); 145 return of_bus_default_translate(addr + 1, offset, na - 1);
144} 146}
145 147
146static unsigned int of_bus_pci_get_flags(u32 *addr) 148static unsigned int of_bus_pci_get_flags(const u32 *addr)
147{ 149{
148 unsigned int flags = 0; 150 unsigned int flags = 0;
149 u32 w = addr[0]; 151 u32 w = addr[0];
@@ -178,7 +180,7 @@ static void of_bus_isa_count_cells(struct device_node *child,
178 *sizec = 1; 180 *sizec = 1;
179} 181}
180 182
181static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) 183static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
182{ 184{
183 u64 cp, s, da; 185 u64 cp, s, da;
184 186
@@ -203,7 +205,7 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
203 return of_bus_default_translate(addr + 1, offset, na - 1); 205 return of_bus_default_translate(addr + 1, offset, na - 1);
204} 206}
205 207
206static unsigned int of_bus_isa_get_flags(u32 *addr) 208static unsigned int of_bus_isa_get_flags(const u32 *addr)
207{ 209{
208 unsigned int flags = 0; 210 unsigned int flags = 0;
209 u32 w = addr[0]; 211 u32 w = addr[0];
@@ -268,7 +270,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
268 struct of_bus *pbus, u32 *addr, 270 struct of_bus *pbus, u32 *addr,
269 int na, int ns, int pna) 271 int na, int ns, int pna)
270{ 272{
271 u32 *ranges; 273 const u32 *ranges;
272 unsigned int rlen; 274 unsigned int rlen;
273 int rone; 275 int rone;
274 u64 offset = OF_BAD_ADDR; 276 u64 offset = OF_BAD_ADDR;
@@ -285,7 +287,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
285 * to translate addresses that aren't supposed to be translated in 287 * to translate addresses that aren't supposed to be translated in
286 * the first place. --BenH. 288 * the first place. --BenH.
287 */ 289 */
288 ranges = (u32 *)get_property(parent, "ranges", &rlen); 290 ranges = get_property(parent, "ranges", &rlen);
289 if (ranges == NULL || rlen == 0) { 291 if (ranges == NULL || rlen == 0) {
290 offset = of_read_number(addr, na); 292 offset = of_read_number(addr, na);
291 memset(addr, 0, pna * 4); 293 memset(addr, 0, pna * 4);
@@ -328,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
328 * that can be mapped to a cpu physical address). This is not really specified 330 * that can be mapped to a cpu physical address). This is not really specified
329 * that way, but this is traditionally the way IBM at least do things 331 * that way, but this is traditionally the way IBM at least do things
330 */ 332 */
331u64 of_translate_address(struct device_node *dev, u32 *in_addr) 333u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
332{ 334{
333 struct device_node *parent = NULL; 335 struct device_node *parent = NULL;
334 struct of_bus *bus, *pbus; 336 struct of_bus *bus, *pbus;
@@ -405,10 +407,10 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr)
405} 407}
406EXPORT_SYMBOL(of_translate_address); 408EXPORT_SYMBOL(of_translate_address);
407 409
408u32 *of_get_address(struct device_node *dev, int index, u64 *size, 410const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
409 unsigned int *flags) 411 unsigned int *flags)
410{ 412{
411 u32 *prop; 413 const u32 *prop;
412 unsigned int psize; 414 unsigned int psize;
413 struct device_node *parent; 415 struct device_node *parent;
414 struct of_bus *bus; 416 struct of_bus *bus;
@@ -425,7 +427,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
425 return NULL; 427 return NULL;
426 428
427 /* Get "reg" or "assigned-addresses" property */ 429 /* Get "reg" or "assigned-addresses" property */
428 prop = (u32 *)get_property(dev, bus->addresses, &psize); 430 prop = get_property(dev, bus->addresses, &psize);
429 if (prop == NULL) 431 if (prop == NULL)
430 return NULL; 432 return NULL;
431 psize /= 4; 433 psize /= 4;
@@ -443,10 +445,10 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
443} 445}
444EXPORT_SYMBOL(of_get_address); 446EXPORT_SYMBOL(of_get_address);
445 447
446u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, 448const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
447 unsigned int *flags) 449 unsigned int *flags)
448{ 450{
449 u32 *prop; 451 const u32 *prop;
450 unsigned int psize; 452 unsigned int psize;
451 struct device_node *parent; 453 struct device_node *parent;
452 struct of_bus *bus; 454 struct of_bus *bus;
@@ -467,7 +469,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
467 return NULL; 469 return NULL;
468 470
469 /* Get "reg" or "assigned-addresses" property */ 471 /* Get "reg" or "assigned-addresses" property */
470 prop = (u32 *)get_property(dev, bus->addresses, &psize); 472 prop = get_property(dev, bus->addresses, &psize);
471 if (prop == NULL) 473 if (prop == NULL)
472 return NULL; 474 return NULL;
473 psize /= 4; 475 psize /= 4;
@@ -485,7 +487,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
485} 487}
486EXPORT_SYMBOL(of_get_pci_address); 488EXPORT_SYMBOL(of_get_pci_address);
487 489
488static int __of_address_to_resource(struct device_node *dev, u32 *addrp, 490static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
489 u64 size, unsigned int flags, 491 u64 size, unsigned int flags,
490 struct resource *r) 492 struct resource *r)
491{ 493{
@@ -516,7 +518,7 @@ static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
516int of_address_to_resource(struct device_node *dev, int index, 518int of_address_to_resource(struct device_node *dev, int index,
517 struct resource *r) 519 struct resource *r)
518{ 520{
519 u32 *addrp; 521 const u32 *addrp;
520 u64 size; 522 u64 size;
521 unsigned int flags; 523 unsigned int flags;
522 524
@@ -530,7 +532,7 @@ EXPORT_SYMBOL_GPL(of_address_to_resource);
530int of_pci_address_to_resource(struct device_node *dev, int bar, 532int of_pci_address_to_resource(struct device_node *dev, int bar,
531 struct resource *r) 533 struct resource *r)
532{ 534{
533 u32 *addrp; 535 const u32 *addrp;
534 u64 size; 536 u64 size;
535 unsigned int flags; 537 unsigned int flags;
536 538
@@ -541,13 +543,14 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
541} 543}
542EXPORT_SYMBOL_GPL(of_pci_address_to_resource); 544EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
543 545
544void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop, 546void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
545 unsigned long *busno, unsigned long *phys, unsigned long *size) 547 unsigned long *busno, unsigned long *phys, unsigned long *size)
546{ 548{
547 u32 *dma_window, cells; 549 const u32 *dma_window;
548 unsigned char *prop; 550 u32 cells;
551 const unsigned char *prop;
549 552
550 dma_window = (u32 *)dma_window_prop; 553 dma_window = dma_window_prop;
551 554
552 /* busno is always one cell */ 555 /* busno is always one cell */
553 *busno = *(dma_window++); 556 *busno = *(dma_window++);
@@ -576,13 +579,13 @@ static struct device_node *of_irq_dflt_pic;
576static struct device_node *of_irq_find_parent(struct device_node *child) 579static struct device_node *of_irq_find_parent(struct device_node *child)
577{ 580{
578 struct device_node *p; 581 struct device_node *p;
579 phandle *parp; 582 const phandle *parp;
580 583
581 if (!of_node_get(child)) 584 if (!of_node_get(child))
582 return NULL; 585 return NULL;
583 586
584 do { 587 do {
585 parp = (phandle *)get_property(child, "interrupt-parent", NULL); 588 parp = get_property(child, "interrupt-parent", NULL);
586 if (parp == NULL) 589 if (parp == NULL)
587 p = of_get_parent(child); 590 p = of_get_parent(child);
588 else { 591 else {
@@ -639,11 +642,11 @@ void of_irq_map_init(unsigned int flags)
639 642
640} 643}
641 644
642int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize, 645int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
643 u32 *addr, struct of_irq *out_irq) 646 const u32 *addr, struct of_irq *out_irq)
644{ 647{
645 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; 648 struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
646 u32 *tmp, *imap, *imask; 649 const u32 *tmp, *imap, *imask;
647 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; 650 u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
648 int imaplen, match, i; 651 int imaplen, match, i;
649 652
@@ -657,7 +660,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
657 * is none, we are nice and just walk up the tree 660 * is none, we are nice and just walk up the tree
658 */ 661 */
659 do { 662 do {
660 tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL); 663 tmp = get_property(ipar, "#interrupt-cells", NULL);
661 if (tmp != NULL) { 664 if (tmp != NULL) {
662 intsize = *tmp; 665 intsize = *tmp;
663 break; 666 break;
@@ -681,7 +684,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
681 */ 684 */
682 old = of_node_get(ipar); 685 old = of_node_get(ipar);
683 do { 686 do {
684 tmp = (u32 *)get_property(old, "#address-cells", NULL); 687 tmp = get_property(old, "#address-cells", NULL);
685 tnode = of_get_parent(old); 688 tnode = of_get_parent(old);
686 of_node_put(old); 689 of_node_put(old);
687 old = tnode; 690 old = tnode;
@@ -708,7 +711,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
708 } 711 }
709 712
710 /* Now look for an interrupt-map */ 713 /* Now look for an interrupt-map */
711 imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen); 714 imap = get_property(ipar, "interrupt-map", &imaplen);
712 /* No interrupt map, check for an interrupt parent */ 715 /* No interrupt map, check for an interrupt parent */
713 if (imap == NULL) { 716 if (imap == NULL) {
714 DBG(" -> no map, getting parent\n"); 717 DBG(" -> no map, getting parent\n");
@@ -718,7 +721,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
718 imaplen /= sizeof(u32); 721 imaplen /= sizeof(u32);
719 722
720 /* Look for a mask */ 723 /* Look for a mask */
721 imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL); 724 imask = get_property(ipar, "interrupt-map-mask", NULL);
722 725
723 /* If we were passed no "reg" property and we attempt to parse 726 /* If we were passed no "reg" property and we attempt to parse
724 * an interrupt-map, then #address-cells must be 0. 727 * an interrupt-map, then #address-cells must be 0.
@@ -765,14 +768,14 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
765 /* Get #interrupt-cells and #address-cells of new 768 /* Get #interrupt-cells and #address-cells of new
766 * parent 769 * parent
767 */ 770 */
768 tmp = (u32 *)get_property(newpar, "#interrupt-cells", 771 tmp = get_property(newpar, "#interrupt-cells",
769 NULL); 772 NULL);
770 if (tmp == NULL) { 773 if (tmp == NULL) {
771 DBG(" -> parent lacks #interrupt-cells !\n"); 774 DBG(" -> parent lacks #interrupt-cells !\n");
772 goto fail; 775 goto fail;
773 } 776 }
774 newintsize = *tmp; 777 newintsize = *tmp;
775 tmp = (u32 *)get_property(newpar, "#address-cells", 778 tmp = get_property(newpar, "#address-cells",
776 NULL); 779 NULL);
777 newaddrsize = (tmp == NULL) ? 0 : *tmp; 780 newaddrsize = (tmp == NULL) ? 0 : *tmp;
778 781
@@ -818,14 +821,14 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
818static int of_irq_map_oldworld(struct device_node *device, int index, 821static int of_irq_map_oldworld(struct device_node *device, int index,
819 struct of_irq *out_irq) 822 struct of_irq *out_irq)
820{ 823{
821 u32 *ints; 824 const u32 *ints;
822 int intlen; 825 int intlen;
823 826
824 /* 827 /*
825 * Old machines just have a list of interrupt numbers 828 * Old machines just have a list of interrupt numbers
826 * and no interrupt-controller nodes. 829 * and no interrupt-controller nodes.
827 */ 830 */
828 ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen); 831 ints = get_property(device, "AAPL,interrupts", &intlen);
829 if (ints == NULL) 832 if (ints == NULL)
830 return -EINVAL; 833 return -EINVAL;
831 intlen /= sizeof(u32); 834 intlen /= sizeof(u32);
@@ -850,7 +853,8 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
850int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) 853int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
851{ 854{
852 struct device_node *p; 855 struct device_node *p;
853 u32 *intspec, *tmp, intsize, intlen, *addr; 856 const u32 *intspec, *tmp, *addr;
857 u32 intsize, intlen;
854 int res; 858 int res;
855 859
856 DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); 860 DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
@@ -860,13 +864,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
860 return of_irq_map_oldworld(device, index, out_irq); 864 return of_irq_map_oldworld(device, index, out_irq);
861 865
862 /* Get the interrupts property */ 866 /* Get the interrupts property */
863 intspec = (u32 *)get_property(device, "interrupts", &intlen); 867 intspec = get_property(device, "interrupts", &intlen);
864 if (intspec == NULL) 868 if (intspec == NULL)
865 return -EINVAL; 869 return -EINVAL;
866 intlen /= sizeof(u32); 870 intlen /= sizeof(u32);
867 871
868 /* Get the reg property (if any) */ 872 /* Get the reg property (if any) */
869 addr = (u32 *)get_property(device, "reg", NULL); 873 addr = get_property(device, "reg", NULL);
870 874
871 /* Look for the interrupt parent. */ 875 /* Look for the interrupt parent. */
872 p = of_irq_find_parent(device); 876 p = of_irq_find_parent(device);
@@ -874,7 +878,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
874 return -EINVAL; 878 return -EINVAL;
875 879
876 /* Get size of interrupt specifier */ 880 /* Get size of interrupt specifier */
877 tmp = (u32 *)get_property(p, "#interrupt-cells", NULL); 881 tmp = get_property(p, "#interrupt-cells", NULL);
878 if (tmp == NULL) { 882 if (tmp == NULL) {
879 of_node_put(p); 883 of_node_put(p);
880 return -EINVAL; 884 return -EINVAL;
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 9c9ad1fa9cce..2fe82abf1c52 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -246,12 +246,12 @@ struct file_operations ppc_rtas_rmo_buf_ops = {
246 246
247static int ppc_rtas_find_all_sensors(void); 247static int ppc_rtas_find_all_sensors(void);
248static void ppc_rtas_process_sensor(struct seq_file *m, 248static void ppc_rtas_process_sensor(struct seq_file *m,
249 struct individual_sensor *s, int state, int error, char *loc); 249 struct individual_sensor *s, int state, int error, const char *loc);
250static char *ppc_rtas_process_error(int error); 250static char *ppc_rtas_process_error(int error);
251static void get_location_code(struct seq_file *m, 251static void get_location_code(struct seq_file *m,
252 struct individual_sensor *s, char *loc); 252 struct individual_sensor *s, const char *loc);
253static void check_location_string(struct seq_file *m, char *c); 253static void check_location_string(struct seq_file *m, const char *c);
254static void check_location(struct seq_file *m, char *c); 254static void check_location(struct seq_file *m, const char *c);
255 255
256static int __init proc_rtas_init(void) 256static int __init proc_rtas_init(void)
257{ 257{
@@ -446,11 +446,11 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
446 for (i=0; i<sensors.quant; i++) { 446 for (i=0; i<sensors.quant; i++) {
447 struct individual_sensor *p = &sensors.sensor[i]; 447 struct individual_sensor *p = &sensors.sensor[i];
448 char rstr[64]; 448 char rstr[64];
449 char *loc; 449 const char *loc;
450 int llen, offs; 450 int llen, offs;
451 451
452 sprintf (rstr, SENSOR_PREFIX"%04d", p->token); 452 sprintf (rstr, SENSOR_PREFIX"%04d", p->token);
453 loc = (char *) get_property(rtas_node, rstr, &llen); 453 loc = get_property(rtas_node, rstr, &llen);
454 454
455 /* A sensor may have multiple instances */ 455 /* A sensor may have multiple instances */
456 for (j = 0, offs = 0; j <= p->quant; j++) { 456 for (j = 0, offs = 0; j <= p->quant; j++) {
@@ -474,10 +474,10 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
474 474
475static int ppc_rtas_find_all_sensors(void) 475static int ppc_rtas_find_all_sensors(void)
476{ 476{
477 unsigned int *utmp; 477 const unsigned int *utmp;
478 int len, i; 478 int len, i;
479 479
480 utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len); 480 utmp = get_property(rtas_node, "rtas-sensors", &len);
481 if (utmp == NULL) { 481 if (utmp == NULL) {
482 printk (KERN_ERR "error: could not get rtas-sensors\n"); 482 printk (KERN_ERR "error: could not get rtas-sensors\n");
483 return 1; 483 return 1;
@@ -530,7 +530,7 @@ static char *ppc_rtas_process_error(int error)
530 */ 530 */
531 531
532static void ppc_rtas_process_sensor(struct seq_file *m, 532static void ppc_rtas_process_sensor(struct seq_file *m,
533 struct individual_sensor *s, int state, int error, char *loc) 533 struct individual_sensor *s, int state, int error, const char *loc)
534{ 534{
535 /* Defined return vales */ 535 /* Defined return vales */
536 const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", 536 const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t",
@@ -682,7 +682,7 @@ static void ppc_rtas_process_sensor(struct seq_file *m,
682 682
683/* ****************************************************************** */ 683/* ****************************************************************** */
684 684
685static void check_location(struct seq_file *m, char *c) 685static void check_location(struct seq_file *m, const char *c)
686{ 686{
687 switch (c[0]) { 687 switch (c[0]) {
688 case LOC_PLANAR: 688 case LOC_PLANAR:
@@ -719,7 +719,7 @@ static void check_location(struct seq_file *m, char *c)
719 * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] 719 * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
720 * the '.' may be an abbrevation 720 * the '.' may be an abbrevation
721 */ 721 */
722static void check_location_string(struct seq_file *m, char *c) 722static void check_location_string(struct seq_file *m, const char *c)
723{ 723{
724 while (*c) { 724 while (*c) {
725 if (isalpha(*c) || *c == '.') 725 if (isalpha(*c) || *c == '.')
@@ -733,7 +733,8 @@ static void check_location_string(struct seq_file *m, char *c)
733 733
734/* ****************************************************************** */ 734/* ****************************************************************** */
735 735
736static void get_location_code(struct seq_file *m, struct individual_sensor *s, char *loc) 736static void get_location_code(struct seq_file *m, struct individual_sensor *s,
737 const char *loc)
737{ 738{
738 if (!loc || !*loc) { 739 if (!loc || !*loc) {
739 seq_printf(m, "---");/* does not have a location */ 740 seq_printf(m, "---");/* does not have a location */
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 77f1e06d208d..6ef80d4e38d3 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -177,10 +177,12 @@ void __init udbg_init_rtas_console(void)
177void rtas_progress(char *s, unsigned short hex) 177void rtas_progress(char *s, unsigned short hex)
178{ 178{
179 struct device_node *root; 179 struct device_node *root;
180 int width, *p; 180 int width;
181 const int *p;
181 char *os; 182 char *os;
182 static int display_character, set_indicator; 183 static int display_character, set_indicator;
183 static int display_width, display_lines, *row_width, form_feed; 184 static int display_width, display_lines, form_feed;
185 const static int *row_width;
184 static DEFINE_SPINLOCK(progress_lock); 186 static DEFINE_SPINLOCK(progress_lock);
185 static int current_line; 187 static int current_line;
186 static int pending_newline = 0; /* did last write end with unprinted newline? */ 188 static int pending_newline = 0; /* did last write end with unprinted newline? */
@@ -191,16 +193,16 @@ void rtas_progress(char *s, unsigned short hex)
191 if (display_width == 0) { 193 if (display_width == 0) {
192 display_width = 0x10; 194 display_width = 0x10;
193 if ((root = find_path_device("/rtas"))) { 195 if ((root = find_path_device("/rtas"))) {
194 if ((p = (unsigned int *)get_property(root, 196 if ((p = get_property(root,
195 "ibm,display-line-length", NULL))) 197 "ibm,display-line-length", NULL)))
196 display_width = *p; 198 display_width = *p;
197 if ((p = (unsigned int *)get_property(root, 199 if ((p = get_property(root,
198 "ibm,form-feed", NULL))) 200 "ibm,form-feed", NULL)))
199 form_feed = *p; 201 form_feed = *p;
200 if ((p = (unsigned int *)get_property(root, 202 if ((p = get_property(root,
201 "ibm,display-number-of-lines", NULL))) 203 "ibm,display-number-of-lines", NULL)))
202 display_lines = *p; 204 display_lines = *p;
203 row_width = (unsigned int *)get_property(root, 205 row_width = get_property(root,
204 "ibm,display-truncation-length", NULL); 206 "ibm,display-truncation-length", NULL);
205 } 207 }
206 display_character = rtas_token("display-character"); 208 display_character = rtas_token("display-character");
@@ -293,10 +295,10 @@ EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
293 295
294int rtas_token(const char *service) 296int rtas_token(const char *service)
295{ 297{
296 int *tokp; 298 const int *tokp;
297 if (rtas.dev == NULL) 299 if (rtas.dev == NULL)
298 return RTAS_UNKNOWN_SERVICE; 300 return RTAS_UNKNOWN_SERVICE;
299 tokp = (int *) get_property(rtas.dev, service, NULL); 301 tokp = get_property(rtas.dev, service, NULL);
300 return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; 302 return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
301} 303}
302EXPORT_SYMBOL(rtas_token); 304EXPORT_SYMBOL(rtas_token);
@@ -626,6 +628,9 @@ void rtas_os_term(char *str)
626{ 628{
627 int status; 629 int status;
628 630
631 if (panic_timeout)
632 return;
633
629 if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term")) 634 if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
630 return; 635 return;
631 636
@@ -687,15 +692,14 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
687 int i; 692 int i;
688 long state; 693 long state;
689 long rc; 694 long rc;
690 unsigned long dummy; 695 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
691
692 struct rtas_suspend_me_data data; 696 struct rtas_suspend_me_data data;
693 697
694 /* Make sure the state is valid */ 698 /* Make sure the state is valid */
695 rc = plpar_hcall(H_VASI_STATE, 699 rc = plpar_hcall(H_VASI_STATE, retbuf,
696 ((u64)args->args[0] << 32) | args->args[1], 700 ((u64)args->args[0] << 32) | args->args[1]);
697 0, 0, 0, 701
698 &state, &dummy, &dummy); 702 state = retbuf[0];
699 703
700 if (rc) { 704 if (rc) {
701 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc); 705 printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
@@ -845,15 +849,15 @@ void __init rtas_initialize(void)
845 */ 849 */
846 rtas.dev = of_find_node_by_name(NULL, "rtas"); 850 rtas.dev = of_find_node_by_name(NULL, "rtas");
847 if (rtas.dev) { 851 if (rtas.dev) {
848 u32 *basep, *entryp; 852 const u32 *basep, *entryp, *sizep;
849 u32 *sizep;
850 853
851 basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL); 854 basep = get_property(rtas.dev, "linux,rtas-base", NULL);
852 sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL); 855 sizep = get_property(rtas.dev, "rtas-size", NULL);
853 if (basep != NULL && sizep != NULL) { 856 if (basep != NULL && sizep != NULL) {
854 rtas.base = *basep; 857 rtas.base = *basep;
855 rtas.size = *sizep; 858 rtas.size = *sizep;
856 entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL); 859 entryp = get_property(rtas.dev,
860 "linux,rtas-entry", NULL);
857 if (entryp == NULL) /* Ugh */ 861 if (entryp == NULL) /* Ugh */
858 rtas.entry = rtas.base; 862 rtas.entry = rtas.base;
859 else 863 else
@@ -909,6 +913,11 @@ int __init early_init_dt_scan_rtas(unsigned long node,
909 basep = of_get_flat_dt_prop(node, "get-term-char", NULL); 913 basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
910 if (basep) 914 if (basep)
911 rtas_getchar_token = *basep; 915 rtas_getchar_token = *basep;
916
917 if (rtas_putchar_token != RTAS_UNKNOWN_SERVICE &&
918 rtas_getchar_token != RTAS_UNKNOWN_SERVICE)
919 udbg_init_rtas_console();
920
912#endif 921#endif
913 922
914 /* break now */ 923 /* break now */
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index cda022657324..b4a0de79c060 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -57,7 +57,7 @@ static inline int config_access_valid(struct pci_dn *dn, int where)
57 57
58static int of_device_available(struct device_node * dn) 58static int of_device_available(struct device_node * dn)
59{ 59{
60 char * status; 60 const char *status;
61 61
62 status = get_property(dn, "status", NULL); 62 status = get_property(dn, "status", NULL);
63 63
@@ -81,8 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
81 if (!config_access_valid(pdn, where)) 81 if (!config_access_valid(pdn, where))
82 return PCIBIOS_BAD_REGISTER_NUMBER; 82 return PCIBIOS_BAD_REGISTER_NUMBER;
83 83
84 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | 84 addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
85 (pdn->devfn << 8) | (where & 0xff);
86 buid = pdn->phb->buid; 85 buid = pdn->phb->buid;
87 if (buid) { 86 if (buid) {
88 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, 87 ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
@@ -134,8 +133,7 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
134 if (!config_access_valid(pdn, where)) 133 if (!config_access_valid(pdn, where))
135 return PCIBIOS_BAD_REGISTER_NUMBER; 134 return PCIBIOS_BAD_REGISTER_NUMBER;
136 135
137 addr = ((where & 0xf00) << 20) | (pdn->busno << 16) | 136 addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
138 (pdn->devfn << 8) | (where & 0xff);
139 buid = pdn->phb->buid; 137 buid = pdn->phb->buid;
140 if (buid) { 138 if (buid) {
141 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, 139 ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
@@ -178,7 +176,7 @@ struct pci_ops rtas_pci_ops = {
178 176
179int is_python(struct device_node *dev) 177int is_python(struct device_node *dev)
180{ 178{
181 char *model = (char *)get_property(dev, "model", NULL); 179 const char *model = get_property(dev, "model", NULL);
182 180
183 if (model && strstr(model, "Python")) 181 if (model && strstr(model, "Python"))
184 return 1; 182 return 1;
@@ -234,7 +232,7 @@ void __init init_pci_config_tokens (void)
234unsigned long __devinit get_phb_buid (struct device_node *phb) 232unsigned long __devinit get_phb_buid (struct device_node *phb)
235{ 233{
236 int addr_cells; 234 int addr_cells;
237 unsigned int *buid_vals; 235 const unsigned int *buid_vals;
238 unsigned int len; 236 unsigned int len;
239 unsigned long buid; 237 unsigned long buid;
240 238
@@ -247,7 +245,7 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
247 if (phb->parent->parent) 245 if (phb->parent->parent)
248 return 0; 246 return 0;
249 247
250 buid_vals = (unsigned int *) get_property(phb, "reg", &len); 248 buid_vals = get_property(phb, "reg", &len);
251 if (buid_vals == NULL) 249 if (buid_vals == NULL)
252 return 0; 250 return 0;
253 251
@@ -264,10 +262,10 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
264static int phb_set_bus_ranges(struct device_node *dev, 262static int phb_set_bus_ranges(struct device_node *dev,
265 struct pci_controller *phb) 263 struct pci_controller *phb)
266{ 264{
267 int *bus_range; 265 const int *bus_range;
268 unsigned int len; 266 unsigned int len;
269 267
270 bus_range = (int *) get_property(dev, "bus-range", &len); 268 bus_range = get_property(dev, "bus-range", &len);
271 if (bus_range == NULL || len < 2 * sizeof(int)) { 269 if (bus_range == NULL || len < 2 * sizeof(int)) {
272 return 1; 270 return 1;
273 } 271 }
@@ -325,15 +323,15 @@ unsigned long __init find_and_init_phbs(void)
325 * in chosen. 323 * in chosen.
326 */ 324 */
327 if (of_chosen) { 325 if (of_chosen) {
328 int *prop; 326 const int *prop;
329 327
330 prop = (int *)get_property(of_chosen, "linux,pci-probe-only", 328 prop = get_property(of_chosen,
331 NULL); 329 "linux,pci-probe-only", NULL);
332 if (prop) 330 if (prop)
333 pci_probe_only = *prop; 331 pci_probe_only = *prop;
334 332
335 prop = (int *)get_property(of_chosen, 333 prop = get_property(of_chosen,
336 "linux,pci-assign-all-buses", NULL); 334 "linux,pci-assign-all-buses", NULL);
337 if (prop) 335 if (prop)
338 pci_assign_all_buses = *prop; 336 pci_assign_all_buses = *prop;
339 } 337 }
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 499c3861074f..0af3fc1bdcc9 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -304,19 +304,21 @@ struct seq_operations cpuinfo_op = {
304void __init check_for_initrd(void) 304void __init check_for_initrd(void)
305{ 305{
306#ifdef CONFIG_BLK_DEV_INITRD 306#ifdef CONFIG_BLK_DEV_INITRD
307 unsigned long *prop; 307 const unsigned int *prop;
308 int len;
308 309
309 DBG(" -> check_for_initrd()\n"); 310 DBG(" -> check_for_initrd()\n");
310 311
311 if (of_chosen) { 312 if (of_chosen) {
312 prop = (unsigned long *)get_property(of_chosen, 313 prop = get_property(of_chosen, "linux,initrd-start", &len);
313 "linux,initrd-start", NULL);
314 if (prop != NULL) { 314 if (prop != NULL) {
315 initrd_start = (unsigned long)__va(*prop); 315 initrd_start = (unsigned long)
316 prop = (unsigned long *)get_property(of_chosen, 316 __va(of_read_ulong(prop, len / 4));
317 "linux,initrd-end", NULL); 317 prop = get_property(of_chosen,
318 "linux,initrd-end", &len);
318 if (prop != NULL) { 319 if (prop != NULL) {
319 initrd_end = (unsigned long)__va(*prop); 320 initrd_end = (unsigned long)
321 __va(of_read_ulong(prop, len / 4));
320 initrd_below_start_ok = 1; 322 initrd_below_start_ok = 1;
321 } else 323 } else
322 initrd_start = 0; 324 initrd_start = 0;
@@ -366,15 +368,14 @@ void __init smp_setup_cpu_maps(void)
366 int cpu = 0; 368 int cpu = 0;
367 369
368 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 370 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
369 int *intserv; 371 const int *intserv;
370 int j, len = sizeof(u32), nthreads = 1; 372 int j, len = sizeof(u32), nthreads = 1;
371 373
372 intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s", 374 intserv = get_property(dn, "ibm,ppc-interrupt-server#s", &len);
373 &len);
374 if (intserv) 375 if (intserv)
375 nthreads = len / sizeof(int); 376 nthreads = len / sizeof(int);
376 else { 377 else {
377 intserv = (int *) get_property(dn, "reg", NULL); 378 intserv = get_property(dn, "reg", NULL);
378 if (!intserv) 379 if (!intserv)
379 intserv = &cpu; /* assume logical == phys */ 380 intserv = &cpu; /* assume logical == phys */
380 } 381 }
@@ -395,13 +396,12 @@ void __init smp_setup_cpu_maps(void)
395 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && 396 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
396 (dn = of_find_node_by_path("/rtas"))) { 397 (dn = of_find_node_by_path("/rtas"))) {
397 int num_addr_cell, num_size_cell, maxcpus; 398 int num_addr_cell, num_size_cell, maxcpus;
398 unsigned int *ireg; 399 const unsigned int *ireg;
399 400
400 num_addr_cell = prom_n_addr_cells(dn); 401 num_addr_cell = prom_n_addr_cells(dn);
401 num_size_cell = prom_n_size_cells(dn); 402 num_size_cell = prom_n_size_cells(dn);
402 403
403 ireg = (unsigned int *) 404 ireg = get_property(dn, "ibm,lrdr-capacity", NULL);
404 get_property(dn, "ibm,lrdr-capacity", NULL);
405 405
406 if (!ireg) 406 if (!ireg)
407 goto out; 407 goto out;
@@ -444,6 +444,8 @@ void __init smp_setup_cpu_maps(void)
444 444
445int __initdata do_early_xmon; 445int __initdata do_early_xmon;
446#ifdef CONFIG_XMON 446#ifdef CONFIG_XMON
447extern int xmon_no_auto_backtrace;
448
447static int __init early_xmon(char *p) 449static int __init early_xmon(char *p)
448{ 450{
449 /* ensure xmon is enabled */ 451 /* ensure xmon is enabled */
@@ -452,6 +454,8 @@ static int __init early_xmon(char *p)
452 xmon_init(1); 454 xmon_init(1);
453 if (strncmp(p, "off", 3) == 0) 455 if (strncmp(p, "off", 3) == 0)
454 xmon_init(0); 456 xmon_init(0);
457 if (strncmp(p, "nobt", 4) == 0)
458 xmon_no_auto_backtrace = 1;
455 if (strncmp(p, "early", 5) != 0) 459 if (strncmp(p, "early", 5) != 0)
456 return 0; 460 return 0;
457 } 461 }
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index fd1785e4c9bb..00d6b8addd78 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -56,7 +56,6 @@
56#include <asm/page.h> 56#include <asm/page.h>
57#include <asm/mmu.h> 57#include <asm/mmu.h>
58#include <asm/lmb.h> 58#include <asm/lmb.h>
59#include <asm/iseries/it_lp_naca.h>
60#include <asm/firmware.h> 59#include <asm/firmware.h>
61#include <asm/xmon.h> 60#include <asm/xmon.h>
62#include <asm/udbg.h> 61#include <asm/udbg.h>
@@ -79,10 +78,10 @@ u64 ppc64_pft_size;
79 * before we've read this from the device tree. 78 * before we've read this from the device tree.
80 */ 79 */
81struct ppc64_caches ppc64_caches = { 80struct ppc64_caches ppc64_caches = {
82 .dline_size = 0x80, 81 .dline_size = 0x40,
83 .log_dline_size = 7, 82 .log_dline_size = 6,
84 .iline_size = 0x80, 83 .iline_size = 0x40,
85 .log_iline_size = 7 84 .log_iline_size = 6
86}; 85};
87EXPORT_SYMBOL_GPL(ppc64_caches); 86EXPORT_SYMBOL_GPL(ppc64_caches);
88 87
@@ -107,7 +106,7 @@ static int smt_enabled_cmdline;
107static void check_smt_enabled(void) 106static void check_smt_enabled(void)
108{ 107{
109 struct device_node *dn; 108 struct device_node *dn;
110 char *smt_option; 109 const char *smt_option;
111 110
112 /* Allow the command line to overrule the OF option */ 111 /* Allow the command line to overrule the OF option */
113 if (smt_enabled_cmdline) 112 if (smt_enabled_cmdline)
@@ -116,7 +115,7 @@ static void check_smt_enabled(void)
116 dn = of_find_node_by_path("/options"); 115 dn = of_find_node_by_path("/options");
117 116
118 if (dn) { 117 if (dn) {
119 smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL); 118 smt_option = get_property(dn, "ibm,smt-enabled", NULL);
120 119
121 if (smt_option) { 120 if (smt_option) {
122 if (!strcmp(smt_option, "on")) 121 if (!strcmp(smt_option, "on"))
@@ -293,7 +292,7 @@ static void __init initialize_cache_info(void)
293 */ 292 */
294 293
295 if ( num_cpus == 1 ) { 294 if ( num_cpus == 1 ) {
296 u32 *sizep, *lsizep; 295 const u32 *sizep, *lsizep;
297 u32 size, lsize; 296 u32 size, lsize;
298 const char *dc, *ic; 297 const char *dc, *ic;
299 298
@@ -308,10 +307,10 @@ static void __init initialize_cache_info(void)
308 307
309 size = 0; 308 size = 0;
310 lsize = cur_cpu_spec->dcache_bsize; 309 lsize = cur_cpu_spec->dcache_bsize;
311 sizep = (u32 *)get_property(np, "d-cache-size", NULL); 310 sizep = get_property(np, "d-cache-size", NULL);
312 if (sizep != NULL) 311 if (sizep != NULL)
313 size = *sizep; 312 size = *sizep;
314 lsizep = (u32 *) get_property(np, dc, NULL); 313 lsizep = get_property(np, dc, NULL);
315 if (lsizep != NULL) 314 if (lsizep != NULL)
316 lsize = *lsizep; 315 lsize = *lsizep;
317 if (sizep == 0 || lsizep == 0) 316 if (sizep == 0 || lsizep == 0)
@@ -325,10 +324,10 @@ static void __init initialize_cache_info(void)
325 324
326 size = 0; 325 size = 0;
327 lsize = cur_cpu_spec->icache_bsize; 326 lsize = cur_cpu_spec->icache_bsize;
328 sizep = (u32 *)get_property(np, "i-cache-size", NULL); 327 sizep = get_property(np, "i-cache-size", NULL);
329 if (sizep != NULL) 328 if (sizep != NULL)
330 size = *sizep; 329 size = *sizep;
331 lsizep = (u32 *)get_property(np, ic, NULL); 330 lsizep = get_property(np, ic, NULL);
332 if (lsizep != NULL) 331 if (lsizep != NULL)
333 lsize = *lsizep; 332 lsize = *lsizep;
334 if (sizep == 0 || lsizep == 0) 333 if (sizep == 0 || lsizep == 0)
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index fec228cd0163..406f308ddead 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -60,7 +60,7 @@ static int smt_snooze_cmdline;
60static int __init smt_setup(void) 60static int __init smt_setup(void)
61{ 61{
62 struct device_node *options; 62 struct device_node *options;
63 unsigned int *val; 63 const unsigned int *val;
64 unsigned int cpu; 64 unsigned int cpu;
65 65
66 if (!cpu_has_feature(CPU_FTR_SMT)) 66 if (!cpu_has_feature(CPU_FTR_SMT))
@@ -70,8 +70,7 @@ static int __init smt_setup(void)
70 if (!options) 70 if (!options)
71 return -ENODEV; 71 return -ENODEV;
72 72
73 val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", 73 val = get_property(options, "ibm,smt-snooze-delay", NULL);
74 NULL);
75 if (!smt_snooze_cmdline && val) { 74 if (!smt_snooze_cmdline && val) {
76 for_each_possible_cpu(cpu) 75 for_each_possible_cpu(cpu)
77 per_cpu(smt_snooze_delay, cpu) = *val; 76 per_cpu(smt_snooze_delay, cpu) = *val;
@@ -231,7 +230,7 @@ static void register_cpu_online(unsigned int cpu)
231 if (cur_cpu_spec->num_pmcs >= 8) 230 if (cur_cpu_spec->num_pmcs >= 8)
232 sysdev_create_file(s, &attr_pmc8); 231 sysdev_create_file(s, &attr_pmc8);
233 232
234 if (cpu_has_feature(CPU_FTR_SMT)) 233 if (cpu_has_feature(CPU_FTR_PURR))
235 sysdev_create_file(s, &attr_purr); 234 sysdev_create_file(s, &attr_purr);
236} 235}
237 236
@@ -273,7 +272,7 @@ static void unregister_cpu_online(unsigned int cpu)
273 if (cur_cpu_spec->num_pmcs >= 8) 272 if (cur_cpu_spec->num_pmcs >= 8)
274 sysdev_remove_file(s, &attr_pmc8); 273 sysdev_remove_file(s, &attr_pmc8);
275 274
276 if (cpu_has_feature(CPU_FTR_SMT)) 275 if (cpu_has_feature(CPU_FTR_PURR))
277 sysdev_remove_file(s, &attr_purr); 276 sysdev_remove_file(s, &attr_purr);
278} 277}
279#endif /* CONFIG_HOTPLUG_CPU */ 278#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index a124499e65d9..7a3c3f791ade 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -860,19 +860,17 @@ EXPORT_SYMBOL(do_settimeofday);
860static int __init get_freq(char *name, int cells, unsigned long *val) 860static int __init get_freq(char *name, int cells, unsigned long *val)
861{ 861{
862 struct device_node *cpu; 862 struct device_node *cpu;
863 unsigned int *fp; 863 const unsigned int *fp;
864 int found = 0; 864 int found = 0;
865 865
866 /* The cpu node should have timebase and clock frequency properties */ 866 /* The cpu node should have timebase and clock frequency properties */
867 cpu = of_find_node_by_type(NULL, "cpu"); 867 cpu = of_find_node_by_type(NULL, "cpu");
868 868
869 if (cpu) { 869 if (cpu) {
870 fp = (unsigned int *)get_property(cpu, name, NULL); 870 fp = get_property(cpu, name, NULL);
871 if (fp) { 871 if (fp) {
872 found = 1; 872 found = 1;
873 *val = 0; 873 *val = of_read_ulong(fp, cells);
874 while (cells--)
875 *val = (*val << 32) | *fp++;
876 } 874 }
877 875
878 of_node_put(cpu); 876 of_node_put(cpu);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 9b352bd0a460..d9f10f2fc372 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -598,6 +598,9 @@ static void parse_fpe(struct pt_regs *regs)
598#define INST_STSWI 0x7c0005aa 598#define INST_STSWI 0x7c0005aa
599#define INST_STSWX 0x7c00052a 599#define INST_STSWX 0x7c00052a
600 600
601#define INST_POPCNTB 0x7c0000f4
602#define INST_POPCNTB_MASK 0xfc0007fe
603
601static int emulate_string_inst(struct pt_regs *regs, u32 instword) 604static int emulate_string_inst(struct pt_regs *regs, u32 instword)
602{ 605{
603 u8 rT = (instword >> 21) & 0x1f; 606 u8 rT = (instword >> 21) & 0x1f;
@@ -666,6 +669,23 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
666 return 0; 669 return 0;
667} 670}
668 671
672static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
673{
674 u32 ra,rs;
675 unsigned long tmp;
676
677 ra = (instword >> 16) & 0x1f;
678 rs = (instword >> 21) & 0x1f;
679
680 tmp = regs->gpr[rs];
681 tmp = tmp - ((tmp >> 1) & 0x5555555555555555ULL);
682 tmp = (tmp & 0x3333333333333333ULL) + ((tmp >> 2) & 0x3333333333333333ULL);
683 tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
684 regs->gpr[ra] = tmp;
685
686 return 0;
687}
688
669static int emulate_instruction(struct pt_regs *regs) 689static int emulate_instruction(struct pt_regs *regs)
670{ 690{
671 u32 instword; 691 u32 instword;
@@ -703,6 +723,11 @@ static int emulate_instruction(struct pt_regs *regs)
703 if ((instword & INST_STRING_GEN_MASK) == INST_STRING) 723 if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
704 return emulate_string_inst(regs, instword); 724 return emulate_string_inst(regs, instword);
705 725
726 /* Emulate the popcntb (Population Count Bytes) instruction. */
727 if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
728 return emulate_popcntb_inst(regs, instword);
729 }
730
706 return -EINVAL; 731 return -EINVAL;
707} 732}
708 733
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index fad8580f9081..cb87e71eec66 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -77,7 +77,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
77 } else 77 } else
78#endif 78#endif
79 { 79 {
80 unsigned char *dma_window; 80 const unsigned char *dma_window;
81 struct iommu_table *tbl; 81 struct iommu_table *tbl;
82 unsigned long offset, size; 82 unsigned long offset, size;
83 83
@@ -217,7 +217,7 @@ static void __devinit vio_dev_release(struct device *dev)
217struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) 217struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
218{ 218{
219 struct vio_dev *viodev; 219 struct vio_dev *viodev;
220 unsigned int *unit_address; 220 const unsigned int *unit_address;
221 221
222 /* we need the 'device_type' property, in order to match with drivers */ 222 /* we need the 'device_type' property, in order to match with drivers */
223 if (of_node->type == NULL) { 223 if (of_node->type == NULL) {
@@ -227,7 +227,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
227 return NULL; 227 return NULL;
228 } 228 }
229 229
230 unit_address = (unsigned int *)get_property(of_node, "reg", NULL); 230 unit_address = get_property(of_node, "reg", NULL);
231 if (unit_address == NULL) { 231 if (unit_address == NULL) {
232 printk(KERN_WARNING "%s: node %s missing 'reg'\n", 232 printk(KERN_WARNING "%s: node %s missing 'reg'\n",
233 __FUNCTION__, 233 __FUNCTION__,
@@ -249,7 +249,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
249 viodev->type = of_node->type; 249 viodev->type = of_node->type;
250 viodev->unit_address = *unit_address; 250 viodev->unit_address = *unit_address;
251 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 251 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
252 unit_address = (unsigned int *)get_property(of_node, 252 unit_address = get_property(of_node,
253 "linux,unit_address", NULL); 253 "linux,unit_address", NULL);
254 if (unit_address != NULL) 254 if (unit_address != NULL)
255 viodev->unit_address = *unit_address; 255 viodev->unit_address = *unit_address;
@@ -423,7 +423,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
423{ 423{
424 const struct vio_dev *vio_dev = to_vio_dev(dev); 424 const struct vio_dev *vio_dev = to_vio_dev(dev);
425 struct device_node *dn = dev->platform_data; 425 struct device_node *dn = dev->platform_data;
426 char *cp; 426 const char *cp;
427 int length; 427 int length;
428 428
429 if (!num_envp) 429 if (!num_envp)
@@ -431,7 +431,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
431 431
432 if (!dn) 432 if (!dn)
433 return -ENODEV; 433 return -ENODEV;
434 cp = (char *)get_property(dn, "compatible", &length); 434 cp = get_property(dn, "compatible", &length);
435 if (!cp) 435 if (!cp)
436 return -ENODEV; 436 return -ENODEV;
437 437
@@ -493,11 +493,11 @@ static struct vio_dev *vio_find_name(const char *kobj_name)
493 */ 493 */
494struct vio_dev *vio_find_node(struct device_node *vnode) 494struct vio_dev *vio_find_node(struct device_node *vnode)
495{ 495{
496 uint32_t *unit_address; 496 const uint32_t *unit_address;
497 char kobj_name[BUS_ID_SIZE]; 497 char kobj_name[BUS_ID_SIZE];
498 498
499 /* construct the kobject name from the device node */ 499 /* construct the kobject name from the device node */
500 unit_address = (uint32_t *)get_property(vnode, "reg", NULL); 500 unit_address = get_property(vnode, "reg", NULL);
501 if (!unit_address) 501 if (!unit_address)
502 return NULL; 502 return NULL;
503 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); 503 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index ff7096458249..336dd191f768 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -14,7 +14,6 @@ endif
14obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ 14obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
15 memcpy_64.o usercopy_64.o mem_64.o string.o \ 15 memcpy_64.o usercopy_64.o mem_64.o string.o \
16 strcase.o 16 strcase.o
17obj-$(CONFIG_PPC_ISERIES) += e2a.o
18obj-$(CONFIG_XMON) += sstep.o 17obj-$(CONFIG_XMON) += sstep.o
19 18
20ifeq ($(CONFIG_PPC64),y) 19ifeq ($(CONFIG_PPC64),y)
diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c
deleted file mode 100644
index 4b72ed8fd50e..000000000000
--- a/arch/powerpc/lib/e2a.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * EBCDIC to ASCII conversion
3 *
4 * This function moved here from arch/powerpc/platforms/iseries/viopath.c
5 *
6 * (C) Copyright 2000-2004 IBM Corporation
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) anyu later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/module.h>
25
26unsigned char e2a(unsigned char x)
27{
28 switch (x) {
29 case 0xF0:
30 return '0';
31 case 0xF1:
32 return '1';
33 case 0xF2:
34 return '2';
35 case 0xF3:
36 return '3';
37 case 0xF4:
38 return '4';
39 case 0xF5:
40 return '5';
41 case 0xF6:
42 return '6';
43 case 0xF7:
44 return '7';
45 case 0xF8:
46 return '8';
47 case 0xF9:
48 return '9';
49 case 0xC1:
50 return 'A';
51 case 0xC2:
52 return 'B';
53 case 0xC3:
54 return 'C';
55 case 0xC4:
56 return 'D';
57 case 0xC5:
58 return 'E';
59 case 0xC6:
60 return 'F';
61 case 0xC7:
62 return 'G';
63 case 0xC8:
64 return 'H';
65 case 0xC9:
66 return 'I';
67 case 0xD1:
68 return 'J';
69 case 0xD2:
70 return 'K';
71 case 0xD3:
72 return 'L';
73 case 0xD4:
74 return 'M';
75 case 0xD5:
76 return 'N';
77 case 0xD6:
78 return 'O';
79 case 0xD7:
80 return 'P';
81 case 0xD8:
82 return 'Q';
83 case 0xD9:
84 return 'R';
85 case 0xE2:
86 return 'S';
87 case 0xE3:
88 return 'T';
89 case 0xE4:
90 return 'U';
91 case 0xE5:
92 return 'V';
93 case 0xE6:
94 return 'W';
95 case 0xE7:
96 return 'X';
97 case 0xE8:
98 return 'Y';
99 case 0xE9:
100 return 'Z';
101 }
102 return ' ';
103}
104EXPORT_SYMBOL(e2a);
105
106unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n)
107{
108 int i;
109
110 n = strnlen(src, n);
111
112 for (i = 0; i < n; i++)
113 dest[i] = e2a(src[i]);
114
115 return dest;
116}
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index 077bed7dc52b..80b482ca30df 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -23,6 +23,7 @@
23#include <asm/hvcall.h> 23#include <asm/hvcall.h>
24#include <asm/iseries/hv_call.h> 24#include <asm/iseries/hv_call.h>
25#include <asm/smp.h> 25#include <asm/smp.h>
26#include <asm/firmware.h>
26 27
27void __spin_yield(raw_spinlock_t *lock) 28void __spin_yield(raw_spinlock_t *lock)
28{ 29{
@@ -39,13 +40,12 @@ void __spin_yield(raw_spinlock_t *lock)
39 rmb(); 40 rmb();
40 if (lock->slock != lock_value) 41 if (lock->slock != lock_value)
41 return; /* something has changed */ 42 return; /* something has changed */
42#ifdef CONFIG_PPC_ISERIES 43 if (firmware_has_feature(FW_FEATURE_ISERIES))
43 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, 44 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
44 ((u64)holder_cpu << 32) | yield_count); 45 ((u64)holder_cpu << 32) | yield_count);
45#else 46 else
46 plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), 47 plpar_hcall_norets(H_CONFER,
47 yield_count); 48 get_hard_smp_processor_id(holder_cpu), yield_count);
48#endif
49} 49}
50 50
51/* 51/*
@@ -69,13 +69,12 @@ void __rw_yield(raw_rwlock_t *rw)
69 rmb(); 69 rmb();
70 if (rw->lock != lock_value) 70 if (rw->lock != lock_value)
71 return; /* something has changed */ 71 return; /* something has changed */
72#ifdef CONFIG_PPC_ISERIES 72 if (firmware_has_feature(FW_FEATURE_ISERIES))
73 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc, 73 HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
74 ((u64)holder_cpu << 32) | yield_count); 74 ((u64)holder_cpu << 32) | yield_count);
75#else 75 else
76 plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu), 76 plpar_hcall_norets(H_CONFER,
77 yield_count); 77 get_hard_smp_processor_id(holder_cpu), yield_count);
78#endif
79} 78}
80#endif 79#endif
81 80
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index fbe23933f731..6c0f1c7d83e5 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -159,12 +159,12 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
159{ 159{
160 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu); 160 unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
161 struct device_node *cpu_node = NULL; 161 struct device_node *cpu_node = NULL;
162 unsigned int *interrupt_server, *reg; 162 const unsigned int *interrupt_server, *reg;
163 int len; 163 int len;
164 164
165 while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) { 165 while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
166 /* Try interrupt server first */ 166 /* Try interrupt server first */
167 interrupt_server = (unsigned int *)get_property(cpu_node, 167 interrupt_server = get_property(cpu_node,
168 "ibm,ppc-interrupt-server#s", &len); 168 "ibm,ppc-interrupt-server#s", &len);
169 169
170 len = len / sizeof(u32); 170 len = len / sizeof(u32);
@@ -175,8 +175,7 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
175 return cpu_node; 175 return cpu_node;
176 } 176 }
177 } else { 177 } else {
178 reg = (unsigned int *)get_property(cpu_node, 178 reg = get_property(cpu_node, "reg", &len);
179 "reg", &len);
180 if (reg && (len > 0) && (reg[0] == hw_cpuid)) 179 if (reg && (len > 0) && (reg[0] == hw_cpuid))
181 return cpu_node; 180 return cpu_node;
182 } 181 }
@@ -186,9 +185,9 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
186} 185}
187 186
188/* must hold reference to node during call */ 187/* must hold reference to node during call */
189static int *of_get_associativity(struct device_node *dev) 188static const int *of_get_associativity(struct device_node *dev)
190{ 189{
191 return (unsigned int *)get_property(dev, "ibm,associativity", NULL); 190 return get_property(dev, "ibm,associativity", NULL);
192} 191}
193 192
194/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa 193/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
@@ -197,7 +196,7 @@ static int *of_get_associativity(struct device_node *dev)
197static int of_node_to_nid_single(struct device_node *device) 196static int of_node_to_nid_single(struct device_node *device)
198{ 197{
199 int nid = -1; 198 int nid = -1;
200 unsigned int *tmp; 199 const unsigned int *tmp;
201 200
202 if (min_common_depth == -1) 201 if (min_common_depth == -1)
203 goto out; 202 goto out;
@@ -255,7 +254,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
255static int __init find_min_common_depth(void) 254static int __init find_min_common_depth(void)
256{ 255{
257 int depth; 256 int depth;
258 unsigned int *ref_points; 257 const unsigned int *ref_points;
259 struct device_node *rtas_root; 258 struct device_node *rtas_root;
260 unsigned int len; 259 unsigned int len;
261 260
@@ -270,7 +269,7 @@ static int __init find_min_common_depth(void)
270 * configuration (should be all 0's) and the second is for a normal 269 * configuration (should be all 0's) and the second is for a normal
271 * NUMA configuration. 270 * NUMA configuration.
272 */ 271 */
273 ref_points = (unsigned int *)get_property(rtas_root, 272 ref_points = get_property(rtas_root,
274 "ibm,associativity-reference-points", &len); 273 "ibm,associativity-reference-points", &len);
275 274
276 if ((len >= 1) && ref_points) { 275 if ((len >= 1) && ref_points) {
@@ -297,7 +296,7 @@ static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
297 of_node_put(memory); 296 of_node_put(memory);
298} 297}
299 298
300static unsigned long __devinit read_n_cells(int n, unsigned int **buf) 299static unsigned long __devinit read_n_cells(int n, const unsigned int **buf)
301{ 300{
302 unsigned long result = 0; 301 unsigned long result = 0;
303 302
@@ -435,15 +434,13 @@ static int __init parse_numa_properties(void)
435 unsigned long size; 434 unsigned long size;
436 int nid; 435 int nid;
437 int ranges; 436 int ranges;
438 unsigned int *memcell_buf; 437 const unsigned int *memcell_buf;
439 unsigned int len; 438 unsigned int len;
440 439
441 memcell_buf = (unsigned int *)get_property(memory, 440 memcell_buf = get_property(memory,
442 "linux,usable-memory", &len); 441 "linux,usable-memory", &len);
443 if (!memcell_buf || len <= 0) 442 if (!memcell_buf || len <= 0)
444 memcell_buf = 443 memcell_buf = get_property(memory, "reg", &len);
445 (unsigned int *)get_property(memory, "reg",
446 &len);
447 if (!memcell_buf || len <= 0) 444 if (!memcell_buf || len <= 0)
448 continue; 445 continue;
449 446
@@ -787,10 +784,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
787 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { 784 while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
788 unsigned long start, size; 785 unsigned long start, size;
789 int ranges; 786 int ranges;
790 unsigned int *memcell_buf; 787 const unsigned int *memcell_buf;
791 unsigned int len; 788 unsigned int len;
792 789
793 memcell_buf = (unsigned int *)get_property(memory, "reg", &len); 790 memcell_buf = get_property(memory, "reg", &len);
794 if (!memcell_buf || len <= 0) 791 if (!memcell_buf || len <= 0)
795 continue; 792 continue;
796 793
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index de0c8842415c..d3733912adb4 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -22,6 +22,8 @@
22#include <asm/paca.h> 22#include <asm/paca.h>
23#include <asm/cputable.h> 23#include <asm/cputable.h>
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/smp.h>
26#include <linux/compiler.h>
25 27
26#ifdef DEBUG 28#ifdef DEBUG
27#define DBG(fmt...) udbg_printf(fmt) 29#define DBG(fmt...) udbg_printf(fmt)
@@ -50,9 +52,32 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
50 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; 52 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
51} 53}
52 54
53static inline void create_slbe(unsigned long ea, unsigned long flags, 55static inline void slb_shadow_update(unsigned long esid, unsigned long vsid,
54 unsigned long entry) 56 unsigned long entry)
55{ 57{
58 /*
59 * Clear the ESID first so the entry is not valid while we are
60 * updating it.
61 */
62 get_slb_shadow()->save_area[entry].esid = 0;
63 barrier();
64 get_slb_shadow()->save_area[entry].vsid = vsid;
65 barrier();
66 get_slb_shadow()->save_area[entry].esid = esid;
67
68}
69
70static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
71 unsigned long entry)
72{
73 /*
74 * Updating the shadow buffer before writing the SLB ensures
75 * we don't get a stale entry here if we get preempted by PHYP
76 * between these two statements.
77 */
78 slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags),
79 entry);
80
56 asm volatile("slbmte %0,%1" : 81 asm volatile("slbmte %0,%1" :
57 : "r" (mk_vsid_data(ea, flags)), 82 : "r" (mk_vsid_data(ea, flags)),
58 "r" (mk_esid_data(ea, entry)) 83 "r" (mk_esid_data(ea, entry))
@@ -77,6 +102,10 @@ void slb_flush_and_rebolt(void)
77 if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) 102 if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
78 ksp_esid_data &= ~SLB_ESID_V; 103 ksp_esid_data &= ~SLB_ESID_V;
79 104
105 /* Only third entry (stack) may change here so only resave that */
106 slb_shadow_update(ksp_esid_data,
107 mk_vsid_data(ksp_esid_data, lflags), 2);
108
80 /* We need to do this all in asm, so we're sure we don't touch 109 /* We need to do this all in asm, so we're sure we don't touch
81 * the stack between the slbia and rebolting it. */ 110 * the stack between the slbia and rebolting it. */
82 asm volatile("isync\n" 111 asm volatile("isync\n"
@@ -209,9 +238,9 @@ void slb_initialize(void)
209 asm volatile("isync":::"memory"); 238 asm volatile("isync":::"memory");
210 asm volatile("slbmte %0,%0"::"r" (0) : "memory"); 239 asm volatile("slbmte %0,%0"::"r" (0) : "memory");
211 asm volatile("isync; slbia; isync":::"memory"); 240 asm volatile("isync; slbia; isync":::"memory");
212 create_slbe(PAGE_OFFSET, lflags, 0); 241 create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
213 242
214 create_slbe(VMALLOC_START, vflags, 1); 243 create_shadowed_slbe(VMALLOC_START, vflags, 1);
215 244
216 /* We don't bolt the stack for the time being - we're in boot, 245 /* We don't bolt the stack for the time being - we're in boot,
217 * so the stack is in the bolted segment. By the time it goes 246 * so the stack is in the bolted segment. By the time it goes
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index f6eef78efd29..b58baa65c4a7 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -146,6 +146,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
146 psize = mmu_huge_psize; 146 psize = mmu_huge_psize;
147#else 147#else
148 BUG(); 148 BUG();
149 psize = pte_pagesize_index(pte); /* shutup gcc */
149#endif 150#endif
150 } else 151 } else
151 psize = pte_pagesize_index(pte); 152 psize = pte_pagesize_index(pte);
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index cf3967a66fb5..969fbb6d8c46 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -60,8 +60,8 @@ static void __init mpc834x_itx_setup_arch(void)
60 60
61 np = of_find_node_by_type(NULL, "cpu"); 61 np = of_find_node_by_type(NULL, "cpu");
62 if (np != 0) { 62 if (np != 0) {
63 unsigned int *fp = 63 const unsigned int *fp =
64 (int *)get_property(np, "clock-frequency", NULL); 64 get_property(np, "clock-frequency", NULL);
65 if (fp != 0) 65 if (fp != 0)
66 loops_per_jiffy = *fp / HZ; 66 loops_per_jiffy = *fp / HZ;
67 else 67 else
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 32df239d1c48..677196187a4e 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -57,8 +57,8 @@ static void __init mpc834x_sys_setup_arch(void)
57 57
58 np = of_find_node_by_type(NULL, "cpu"); 58 np = of_find_node_by_type(NULL, "cpu");
59 if (np != 0) { 59 if (np != 0) {
60 unsigned int *fp = 60 const unsigned int *fp =
61 (int *)get_property(np, "clock-frequency", NULL); 61 get_property(np, "clock-frequency", NULL);
62 if (fp != 0) 62 if (fp != 0)
63 loops_per_jiffy = *fp / HZ; 63 loops_per_jiffy = *fp / HZ;
64 else 64 else
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 5d84a9ccd103..4557ac5255c1 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -59,7 +59,7 @@ int __init add_bridge(struct device_node *dev)
59 int len; 59 int len;
60 struct pci_controller *hose; 60 struct pci_controller *hose;
61 struct resource rsrc; 61 struct resource rsrc;
62 int *bus_range; 62 const int *bus_range;
63 int primary = 1, has_address = 0; 63 int primary = 1, has_address = 0;
64 phys_addr_t immr = get_immrbase(); 64 phys_addr_t immr = get_immrbase();
65 65
@@ -69,7 +69,7 @@ int __init add_bridge(struct device_node *dev)
69 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 69 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
70 70
71 /* Get bus range if any */ 71 /* Get bus range if any */
72 bus_range = (int *)get_property(dev, "bus-range", &len); 72 bus_range = get_property(dev, "bus-range", &len);
73 if (bus_range == NULL || len < 2 * sizeof(int)) { 73 if (bus_range == NULL || len < 2 * sizeof(int)) {
74 printk(KERN_WARNING "Can't get bus-range for %s, assume" 74 printk(KERN_WARNING "Can't get bus-range for %s, assume"
75 " bus 0\n", dev->full_name); 75 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 9d2acfbbeccd..cae6b73357d5 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -121,9 +121,9 @@ static void __init mpc85xx_ads_setup_arch(void)
121 121
122 cpu = of_find_node_by_type(NULL, "cpu"); 122 cpu = of_find_node_by_type(NULL, "cpu");
123 if (cpu != 0) { 123 if (cpu != 0) {
124 unsigned int *fp; 124 const unsigned int *fp;
125 125
126 fp = (int *)get_property(cpu, "clock-frequency", NULL); 126 fp = get_property(cpu, "clock-frequency", NULL);
127 if (fp != 0) 127 if (fp != 0)
128 loops_per_jiffy = *fp / HZ; 128 loops_per_jiffy = *fp / HZ;
129 else 129 else
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 1d357d32a29f..4c1fede6470e 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -241,9 +241,9 @@ mpc85xx_cds_setup_arch(void)
241 241
242 cpu = of_find_node_by_type(NULL, "cpu"); 242 cpu = of_find_node_by_type(NULL, "cpu");
243 if (cpu != 0) { 243 if (cpu != 0) {
244 unsigned int *fp; 244 const unsigned int *fp;
245 245
246 fp = (int *)get_property(cpu, "clock-frequency", NULL); 246 fp = get_property(cpu, "clock-frequency", NULL);
247 if (fp != 0) 247 if (fp != 0)
248 loops_per_jiffy = *fp / HZ; 248 loops_per_jiffy = *fp / HZ;
249 else 249 else
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index 1d51f3242ab1..05930eeb6e7f 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -41,7 +41,7 @@ int __init add_bridge(struct device_node *dev)
41 int len; 41 int len;
42 struct pci_controller *hose; 42 struct pci_controller *hose;
43 struct resource rsrc; 43 struct resource rsrc;
44 int *bus_range; 44 const int *bus_range;
45 int primary = 1, has_address = 0; 45 int primary = 1, has_address = 0;
46 phys_addr_t immr = get_immrbase(); 46 phys_addr_t immr = get_immrbase();
47 47
@@ -51,7 +51,7 @@ int __init add_bridge(struct device_node *dev)
51 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 51 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
52 52
53 /* Get bus range if any */ 53 /* Get bus range if any */
54 bus_range = (int *) get_property(dev, "bus-range", &len); 54 bus_range = get_property(dev, "bus-range", &len);
55 if (bus_range == NULL || len < 2 * sizeof(int)) { 55 if (bus_range == NULL || len < 2 * sizeof(int)) {
56 printk(KERN_WARNING "Can't get bus-range for %s, assume" 56 printk(KERN_WARNING "Can't get bus-range for %s, assume"
57 " bus 0\n", dev->full_name); 57 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 5e583cf38786..b637e8157f7b 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -347,9 +347,9 @@ mpc86xx_hpcn_setup_arch(void)
347 347
348 np = of_find_node_by_type(NULL, "cpu"); 348 np = of_find_node_by_type(NULL, "cpu");
349 if (np != 0) { 349 if (np != 0) {
350 unsigned int *fp; 350 const unsigned int *fp;
351 351
352 fp = (int *)get_property(np, "clock-frequency", NULL); 352 fp = get_property(np, "clock-frequency", NULL);
353 if (fp != 0) 353 if (fp != 0)
354 loops_per_jiffy = *fp / HZ; 354 loops_per_jiffy = *fp / HZ;
355 else 355 else
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index a8c8f0a44055..481e18ed5be9 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -153,7 +153,7 @@ int __init add_bridge(struct device_node *dev)
153 int len; 153 int len;
154 struct pci_controller *hose; 154 struct pci_controller *hose;
155 struct resource rsrc; 155 struct resource rsrc;
156 int *bus_range; 156 const int *bus_range;
157 int has_address = 0; 157 int has_address = 0;
158 int primary = 0; 158 int primary = 0;
159 159
@@ -163,7 +163,7 @@ int __init add_bridge(struct device_node *dev)
163 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 163 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
164 164
165 /* Get bus range if any */ 165 /* Get bus range if any */
166 bus_range = (int *) get_property(dev, "bus-range", &len); 166 bus_range = get_property(dev, "bus-range", &len);
167 if (bus_range == NULL || len < 2 * sizeof(int)) 167 if (bus_range == NULL || len < 2 * sizeof(int))
168 printk(KERN_WARNING "Can't get bus-range for %s, assume" 168 printk(KERN_WARNING "Can't get bus-range for %s, assume"
169 " bus 0\n", dev->full_name); 169 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 5cf46dc57895..e58fa953a50b 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
13obj-$(CONFIG_PPC_PSERIES) += pseries/ 13obj-$(CONFIG_PPC_PSERIES) += pseries/
14obj-$(CONFIG_PPC_ISERIES) += iseries/ 14obj-$(CONFIG_PPC_ISERIES) += iseries/
15obj-$(CONFIG_PPC_MAPLE) += maple/ 15obj-$(CONFIG_PPC_MAPLE) += maple/
16obj-$(CONFIG_PPC_PASEMI) += pasemi/
16obj-$(CONFIG_PPC_CELL) += cell/ 17obj-$(CONFIG_PPC_CELL) += cell/
17obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ 18obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index ce696c1cca75..3f3859d12e00 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -97,7 +97,7 @@ void __init cbe_regs_init(void)
97 struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++]; 97 struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
98 98
99 /* That hack must die die die ! */ 99 /* That hack must die die die ! */
100 struct address_prop { 100 const struct address_prop {
101 unsigned long address; 101 unsigned long address;
102 unsigned int len; 102 unsigned int len;
103 } __attribute__((packed)) *prop; 103 } __attribute__((packed)) *prop;
@@ -114,13 +114,11 @@ void __init cbe_regs_init(void)
114 if (cbe_thread_map[i].cpu_node == cpu) 114 if (cbe_thread_map[i].cpu_node == cpu)
115 cbe_thread_map[i].regs = map; 115 cbe_thread_map[i].regs = map;
116 116
117 prop = (struct address_prop *)get_property(cpu, "pervasive", 117 prop = get_property(cpu, "pervasive", NULL);
118 NULL);
119 if (prop != NULL) 118 if (prop != NULL)
120 map->pmd_regs = ioremap(prop->address, prop->len); 119 map->pmd_regs = ioremap(prop->address, prop->len);
121 120
122 prop = (struct address_prop *)get_property(cpu, "iic", 121 prop = get_property(cpu, "iic", NULL);
123 NULL);
124 if (prop != NULL) 122 if (prop != NULL)
125 map->iic_regs = ioremap(prop->address, prop->len); 123 map->iic_regs = ioremap(prop->address, prop->len);
126 } 124 }
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index d7bbb61109f9..6b57a47c5d37 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -89,17 +89,17 @@ static struct irq_chip iic_chip = {
89/* Get an IRQ number from the pending state register of the IIC */ 89/* Get an IRQ number from the pending state register of the IIC */
90static unsigned int iic_get_irq(struct pt_regs *regs) 90static unsigned int iic_get_irq(struct pt_regs *regs)
91{ 91{
92 struct cbe_iic_pending_bits pending; 92 struct cbe_iic_pending_bits pending;
93 struct iic *iic; 93 struct iic *iic;
94 94
95 iic = &__get_cpu_var(iic); 95 iic = &__get_cpu_var(iic);
96 *(unsigned long *) &pending = 96 *(unsigned long *) &pending =
97 in_be64((unsigned long __iomem *) &iic->regs->pending_destr); 97 in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
98 iic->eoi_stack[++iic->eoi_ptr] = pending.prio; 98 iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
99 BUG_ON(iic->eoi_ptr > 15); 99 BUG_ON(iic->eoi_ptr > 15);
100 if (pending.flags & CBE_IIC_IRQ_VALID) 100 if (pending.flags & CBE_IIC_IRQ_VALID)
101 return irq_linear_revmap(iic->host, 101 return irq_linear_revmap(iic->host,
102 iic_pending_to_hwnum(pending)); 102 iic_pending_to_hwnum(pending));
103 return NO_IRQ; 103 return NO_IRQ;
104} 104}
105 105
@@ -250,16 +250,15 @@ static int __init setup_iic(void)
250 struct resource r0, r1; 250 struct resource r0, r1;
251 struct irq_host *host; 251 struct irq_host *host;
252 int found = 0; 252 int found = 0;
253 u32 *np; 253 const u32 *np;
254 254
255 for (dn = NULL; 255 for (dn = NULL;
256 (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) { 256 (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
257 if (!device_is_compatible(dn, 257 if (!device_is_compatible(dn,
258 "IBM,CBEA-Internal-Interrupt-Controller")) 258 "IBM,CBEA-Internal-Interrupt-Controller"))
259 continue; 259 continue;
260 np = (u32 *)get_property(dn, "ibm,interrupt-server-ranges", 260 np = get_property(dn, "ibm,interrupt-server-ranges", NULL);
261 NULL); 261 if (np == NULL) {
262 if (np == NULL) {
263 printk(KERN_WARNING "IIC: CPU association not found\n"); 262 printk(KERN_WARNING "IIC: CPU association not found\n");
264 of_node_put(dn); 263 of_node_put(dn);
265 return -ENODEV; 264 return -ENODEV;
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index a35004e14c69..d2b20eba5b87 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -308,15 +308,16 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
308 308
309static void iommu_devnode_setup(struct device_node *d) 309static void iommu_devnode_setup(struct device_node *d)
310{ 310{
311 unsigned int *ioid; 311 const unsigned int *ioid;
312 unsigned long *dma_window, map_start, map_size, token; 312 unsigned long map_start, map_size, token;
313 const unsigned long *dma_window;
313 struct cell_iommu *iommu; 314 struct cell_iommu *iommu;
314 315
315 ioid = (unsigned int *)get_property(d, "ioid", NULL); 316 ioid = get_property(d, "ioid", NULL);
316 if (!ioid) 317 if (!ioid)
317 pr_debug("No ioid entry found !\n"); 318 pr_debug("No ioid entry found !\n");
318 319
319 dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL); 320 dma_window = get_property(d, "ibm,dma-window", NULL);
320 if (!dma_window) 321 if (!dma_window)
321 pr_debug("No ibm,dma-window entry found !\n"); 322 pr_debug("No ibm,dma-window entry found !\n");
322 323
@@ -371,8 +372,9 @@ static int cell_map_iommu_hardcoded(int num_nodes)
371 372
372static int cell_map_iommu(void) 373static int cell_map_iommu(void)
373{ 374{
374 unsigned int num_nodes = 0, *node_id; 375 unsigned int num_nodes = 0;
375 unsigned long *base, *mmio_base; 376 const unsigned int *node_id;
377 const unsigned long *base, *mmio_base;
376 struct device_node *dn; 378 struct device_node *dn;
377 struct cell_iommu *iommu = NULL; 379 struct cell_iommu *iommu = NULL;
378 380
@@ -381,7 +383,7 @@ static int cell_map_iommu(void)
381 for(dn = of_find_node_by_type(NULL, "cpu"); 383 for(dn = of_find_node_by_type(NULL, "cpu");
382 dn; 384 dn;
383 dn = of_find_node_by_type(dn, "cpu")) { 385 dn = of_find_node_by_type(dn, "cpu")) {
384 node_id = (unsigned int *)get_property(dn, "node-id", NULL); 386 node_id = get_property(dn, "node-id", NULL);
385 387
386 if (num_nodes < *node_id) 388 if (num_nodes < *node_id)
387 num_nodes = *node_id; 389 num_nodes = *node_id;
@@ -396,9 +398,9 @@ static int cell_map_iommu(void)
396 dn; 398 dn;
397 dn = of_find_node_by_type(dn, "cpu")) { 399 dn = of_find_node_by_type(dn, "cpu")) {
398 400
399 node_id = (unsigned int *)get_property(dn, "node-id", NULL); 401 node_id = get_property(dn, "node-id", NULL);
400 base = (unsigned long *)get_property(dn, "ioc-cache", NULL); 402 base = get_property(dn, "ioc-cache", NULL);
401 mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL); 403 mmio_base = get_property(dn, "ioc-translation", NULL);
402 404
403 if (!base || !mmio_base || !node_id) 405 if (!base || !mmio_base || !node_id)
404 return cell_map_iommu_hardcoded(num_nodes); 406 return cell_map_iommu_hardcoded(num_nodes);
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 282987d6d4a2..22c228a49c33 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -150,10 +150,6 @@ static int __init cell_probe(void)
150 !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) 150 !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
151 return 0; 151 return 0;
152 152
153#ifdef CONFIG_UDBG_RTAS_CONSOLE
154 udbg_init_rtas_console();
155#endif
156
157 hpte_init_native(); 153 hpte_init_native();
158 154
159 return 1; 155 return 1;
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index 46aef0640742..1c0acbad7425 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -57,7 +57,7 @@
57 */ 57 */
58static cpumask_t of_spin_map; 58static cpumask_t of_spin_map;
59 59
60extern void pSeries_secondary_smp_init(unsigned long); 60extern void generic_secondary_smp_init(unsigned long);
61 61
62/** 62/**
63 * smp_startup_cpu() - start the given cpu 63 * smp_startup_cpu() - start the given cpu
@@ -74,7 +74,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
74{ 74{
75 int status; 75 int status;
76 unsigned long start_here = __pa((u32)*((unsigned long *) 76 unsigned long start_here = __pa((u32)*((unsigned long *)
77 pSeries_secondary_smp_init)); 77 generic_secondary_smp_init));
78 unsigned int pcpu; 78 unsigned int pcpu;
79 int start_cpu; 79 int start_cpu;
80 80
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 15217bb0402f..742a03282b44 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -240,7 +240,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc,
240static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic) 240static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
241{ 241{
242 unsigned int virq; 242 unsigned int virq;
243 u32 *imap, *tmp; 243 const u32 *imap, *tmp;
244 int imaplen, intsize, unit; 244 int imaplen, intsize, unit;
245 struct device_node *iic; 245 struct device_node *iic;
246 struct irq_host *iic_host; 246 struct irq_host *iic_host;
@@ -258,25 +258,25 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
258#endif 258#endif
259 259
260 /* Now do the horrible hacks */ 260 /* Now do the horrible hacks */
261 tmp = (u32 *)get_property(pic->of_node, "#interrupt-cells", NULL); 261 tmp = get_property(pic->of_node, "#interrupt-cells", NULL);
262 if (tmp == NULL) 262 if (tmp == NULL)
263 return NO_IRQ; 263 return NO_IRQ;
264 intsize = *tmp; 264 intsize = *tmp;
265 imap = (u32 *)get_property(pic->of_node, "interrupt-map", &imaplen); 265 imap = get_property(pic->of_node, "interrupt-map", &imaplen);
266 if (imap == NULL || imaplen < (intsize + 1)) 266 if (imap == NULL || imaplen < (intsize + 1))
267 return NO_IRQ; 267 return NO_IRQ;
268 iic = of_find_node_by_phandle(imap[intsize]); 268 iic = of_find_node_by_phandle(imap[intsize]);
269 if (iic == NULL) 269 if (iic == NULL)
270 return NO_IRQ; 270 return NO_IRQ;
271 imap += intsize + 1; 271 imap += intsize + 1;
272 tmp = (u32 *)get_property(iic, "#interrupt-cells", NULL); 272 tmp = get_property(iic, "#interrupt-cells", NULL);
273 if (tmp == NULL) 273 if (tmp == NULL)
274 return NO_IRQ; 274 return NO_IRQ;
275 intsize = *tmp; 275 intsize = *tmp;
276 /* Assume unit is last entry of interrupt specifier */ 276 /* Assume unit is last entry of interrupt specifier */
277 unit = imap[intsize - 1]; 277 unit = imap[intsize - 1];
278 /* Ok, we have a unit, now let's try to get the node */ 278 /* Ok, we have a unit, now let's try to get the node */
279 tmp = (u32 *)get_property(iic, "ibm,interrupt-server-ranges", NULL); 279 tmp = get_property(iic, "ibm,interrupt-server-ranges", NULL);
280 if (tmp == NULL) { 280 if (tmp == NULL) {
281 of_node_put(iic); 281 of_node_put(iic);
282 return NO_IRQ; 282 return NO_IRQ;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index d06042deb021..3bd36d46ab4a 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -488,10 +488,10 @@ int spu_irq_class_1_bottom(struct spu *spu)
488 488
489static int __init find_spu_node_id(struct device_node *spe) 489static int __init find_spu_node_id(struct device_node *spe)
490{ 490{
491 unsigned int *id; 491 const unsigned int *id;
492 struct device_node *cpu; 492 struct device_node *cpu;
493 cpu = spe->parent->parent; 493 cpu = spe->parent->parent;
494 id = (unsigned int *)get_property(cpu, "node-id", NULL); 494 id = get_property(cpu, "node-id", NULL);
495 return id ? *id : 0; 495 return id ? *id : 0;
496} 496}
497 497
@@ -500,7 +500,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
500{ 500{
501 static DEFINE_MUTEX(add_spumem_mutex); 501 static DEFINE_MUTEX(add_spumem_mutex);
502 502
503 struct address_prop { 503 const struct address_prop {
504 unsigned long address; 504 unsigned long address;
505 unsigned int len; 505 unsigned int len;
506 } __attribute__((packed)) *p; 506 } __attribute__((packed)) *p;
@@ -511,7 +511,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
511 struct zone *zone; 511 struct zone *zone;
512 int ret; 512 int ret;
513 513
514 p = (void*)get_property(spe, prop, &proplen); 514 p = get_property(spe, prop, &proplen);
515 WARN_ON(proplen != sizeof (*p)); 515 WARN_ON(proplen != sizeof (*p));
516 516
517 start_pfn = p->address >> PAGE_SHIFT; 517 start_pfn = p->address >> PAGE_SHIFT;
@@ -531,12 +531,12 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
531static void __iomem * __init map_spe_prop(struct spu *spu, 531static void __iomem * __init map_spe_prop(struct spu *spu,
532 struct device_node *n, const char *name) 532 struct device_node *n, const char *name)
533{ 533{
534 struct address_prop { 534 const struct address_prop {
535 unsigned long address; 535 unsigned long address;
536 unsigned int len; 536 unsigned int len;
537 } __attribute__((packed)) *prop; 537 } __attribute__((packed)) *prop;
538 538
539 void *p; 539 const void *p;
540 int proplen; 540 int proplen;
541 void* ret = NULL; 541 void* ret = NULL;
542 int err = 0; 542 int err = 0;
@@ -570,14 +570,14 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
570{ 570{
571 struct irq_host *host; 571 struct irq_host *host;
572 unsigned int isrc; 572 unsigned int isrc;
573 u32 *tmp; 573 const u32 *tmp;
574 574
575 host = iic_get_irq_host(spu->node); 575 host = iic_get_irq_host(spu->node);
576 if (host == NULL) 576 if (host == NULL)
577 return -ENODEV; 577 return -ENODEV;
578 578
579 /* Get the interrupt source from the device-tree */ 579 /* Get the interrupt source from the device-tree */
580 tmp = (u32 *)get_property(np, "isrc", NULL); 580 tmp = get_property(np, "isrc", NULL);
581 if (!tmp) 581 if (!tmp)
582 return -ENODEV; 582 return -ENODEV;
583 spu->isrc = isrc = tmp[0]; 583 spu->isrc = isrc = tmp[0];
@@ -593,7 +593,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
593 593
594static int __init spu_map_device(struct spu *spu, struct device_node *node) 594static int __init spu_map_device(struct spu *spu, struct device_node *node)
595{ 595{
596 char *prop; 596 const char *prop;
597 int ret; 597 int ret;
598 598
599 ret = -ENODEV; 599 ret = -ENODEV;
diff --git a/arch/powerpc/platforms/chrp/nvram.c b/arch/powerpc/platforms/chrp/nvram.c
index 150f67d6f90c..0dd4a64757d9 100644
--- a/arch/powerpc/platforms/chrp/nvram.c
+++ b/arch/powerpc/platforms/chrp/nvram.c
@@ -67,13 +67,14 @@ static void chrp_nvram_write(int addr, unsigned char val)
67void __init chrp_nvram_init(void) 67void __init chrp_nvram_init(void)
68{ 68{
69 struct device_node *nvram; 69 struct device_node *nvram;
70 unsigned int *nbytes_p, proplen; 70 const unsigned int *nbytes_p;
71 unsigned int proplen;
71 72
72 nvram = of_find_node_by_type(NULL, "nvram"); 73 nvram = of_find_node_by_type(NULL, "nvram");
73 if (nvram == NULL) 74 if (nvram == NULL)
74 return; 75 return;
75 76
76 nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); 77 nbytes_p = get_property(nvram, "#bytes", &proplen);
77 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) 78 if (nbytes_p == NULL || proplen != sizeof(unsigned int))
78 return; 79 return;
79 80
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 6802cdc3168a..0f4340506c75 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -214,11 +214,11 @@ void __init
214chrp_find_bridges(void) 214chrp_find_bridges(void)
215{ 215{
216 struct device_node *dev; 216 struct device_node *dev;
217 int *bus_range; 217 const int *bus_range;
218 int len, index = -1; 218 int len, index = -1;
219 struct pci_controller *hose; 219 struct pci_controller *hose;
220 unsigned int *dma; 220 const unsigned int *dma;
221 char *model, *machine; 221 const char *model, *machine;
222 int is_longtrail = 0, is_mot = 0, is_pegasos = 0; 222 int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
223 struct device_node *root = find_path_device("/"); 223 struct device_node *root = find_path_device("/");
224 struct resource r; 224 struct resource r;
@@ -246,7 +246,7 @@ chrp_find_bridges(void)
246 dev->full_name); 246 dev->full_name);
247 continue; 247 continue;
248 } 248 }
249 bus_range = (int *) get_property(dev, "bus-range", &len); 249 bus_range = get_property(dev, "bus-range", &len);
250 if (bus_range == NULL || len < 2 * sizeof(int)) { 250 if (bus_range == NULL || len < 2 * sizeof(int)) {
251 printk(KERN_WARNING "Can't get bus-range for %s\n", 251 printk(KERN_WARNING "Can't get bus-range for %s\n",
252 dev->full_name); 252 dev->full_name);
@@ -257,7 +257,7 @@ chrp_find_bridges(void)
257 else 257 else
258 printk(KERN_INFO "PCI buses %d..%d", 258 printk(KERN_INFO "PCI buses %d..%d",
259 bus_range[0], bus_range[1]); 259 bus_range[0], bus_range[1]);
260 printk(" controlled by %s", dev->type); 260 printk(" controlled by %s", dev->full_name);
261 if (!is_longtrail) 261 if (!is_longtrail)
262 printk(" at %llx", (unsigned long long)r.start); 262 printk(" at %llx", (unsigned long long)r.start);
263 printk("\n"); 263 printk("\n");
@@ -289,6 +289,19 @@ chrp_find_bridges(void)
289 setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); 289 setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
290 } else if (is_pegasos == 2) { 290 } else if (is_pegasos == 2) {
291 setup_peg2(hose, dev); 291 setup_peg2(hose, dev);
292 } else if (!strncmp(model, "IBM,CPC710", 10)) {
293 setup_indirect_pci(hose,
294 r.start + 0x000f8000,
295 r.start + 0x000f8010);
296 if (index == 0) {
297 dma = get_property(dev, "system-dma-base",&len);
298 if (dma && len >= sizeof(*dma)) {
299 dma = (unsigned int *)
300 (((unsigned long)dma) +
301 len - sizeof(*dma));
302 pci_dram_offset = *dma;
303 }
304 }
292 } else { 305 } else {
293 printk("No methods for %s (model %s), using RTAS\n", 306 printk("No methods for %s (model %s), using RTAS\n",
294 dev->full_name, model); 307 dev->full_name, model);
@@ -299,15 +312,35 @@ chrp_find_bridges(void)
299 312
300 /* check the first bridge for a property that we can 313 /* check the first bridge for a property that we can
301 use to set pci_dram_offset */ 314 use to set pci_dram_offset */
302 dma = (unsigned int *) 315 dma = get_property(dev, "ibm,dma-ranges", &len);
303 get_property(dev, "ibm,dma-ranges", &len);
304 if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { 316 if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
305 pci_dram_offset = dma[2] - dma[3]; 317 pci_dram_offset = dma[2] - dma[3];
306 printk("pci_dram_offset = %lx\n", pci_dram_offset); 318 printk("pci_dram_offset = %lx\n", pci_dram_offset);
307 } 319 }
308 } 320 }
321}
322
323/* SL82C105 IDE Control/Status Register */
324#define SL82C105_IDECSR 0x40
325
326/* Fixup for Winbond ATA quirk, required for briq */
327void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105)
328{
329 u8 progif;
309 330
310 /* Do not fixup interrupts from OF tree on pegasos */ 331 /* If non-briq machines need that fixup too, please speak up */
311 if (is_pegasos) 332 if (!machine_is(chrp) || _chrp_type != _CHRP_briq)
312 ppc_md.pcibios_fixup = NULL; 333 return;
334
335 if ((sl82c105->class & 5) != 5) {
336 printk("W83C553: Switching SL82C105 IDE to PCI native mode\n");
337 /* Enable SL82C105 PCI native IDE mode */
338 pci_read_config_byte(sl82c105, PCI_CLASS_PROG, &progif);
339 pci_write_config_byte(sl82c105, PCI_CLASS_PROG, progif | 0x05);
340 sl82c105->class |= 0x05;
341 /* Disable SL82C105 second port */
342 pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003);
343 }
313} 344}
345DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
346 chrp_pci_fixup_winbond_ata);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 9c08ff322290..488dbd9b51ae 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -74,6 +74,9 @@ extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
74 74
75extern unsigned long loops_per_jiffy; 75extern unsigned long loops_per_jiffy;
76 76
77/* To be replaced by RTAS when available */
78static unsigned int *briq_SPOR;
79
77#ifdef CONFIG_SMP 80#ifdef CONFIG_SMP
78extern struct smp_ops_t chrp_smp_ops; 81extern struct smp_ops_t chrp_smp_ops;
79#endif 82#endif
@@ -92,6 +95,15 @@ static const char *gg2_cachemodes[4] = {
92 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" 95 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
93}; 96};
94 97
98static const char *chrp_names[] = {
99 "Unknown",
100 "","","",
101 "Motorola",
102 "IBM or Longtrail",
103 "Genesi Pegasos",
104 "Total Impact Briq"
105};
106
95void chrp_show_cpuinfo(struct seq_file *m) 107void chrp_show_cpuinfo(struct seq_file *m)
96{ 108{
97 int i, sdramen; 109 int i, sdramen;
@@ -214,8 +226,7 @@ static void __init pegasos_set_l2cr(void)
214 /* Enable L2 cache if needed */ 226 /* Enable L2 cache if needed */
215 np = find_type_devices("cpu"); 227 np = find_type_devices("cpu");
216 if (np != NULL) { 228 if (np != NULL) {
217 unsigned int *l2cr = (unsigned int *) 229 const unsigned int *l2cr = get_property(np, "l2cr", NULL);
218 get_property (np, "l2cr", NULL);
219 if (l2cr == NULL) { 230 if (l2cr == NULL) {
220 printk ("Pegasos l2cr : no cpu l2cr property found\n"); 231 printk ("Pegasos l2cr : no cpu l2cr property found\n");
221 return; 232 return;
@@ -229,10 +240,18 @@ static void __init pegasos_set_l2cr(void)
229 } 240 }
230} 241}
231 242
243static void briq_restart(char *cmd)
244{
245 local_irq_disable();
246 if (briq_SPOR)
247 out_be32(briq_SPOR, 0);
248 for(;;);
249}
250
232void __init chrp_setup_arch(void) 251void __init chrp_setup_arch(void)
233{ 252{
234 struct device_node *root = find_path_device ("/"); 253 struct device_node *root = find_path_device ("/");
235 char *machine = NULL; 254 const char *machine = NULL;
236 255
237 /* init to some ~sane value until calibrate_delay() runs */ 256 /* init to some ~sane value until calibrate_delay() runs */
238 loops_per_jiffy = 50000000/HZ; 257 loops_per_jiffy = 50000000/HZ;
@@ -245,11 +264,16 @@ void __init chrp_setup_arch(void)
245 _chrp_type = _CHRP_IBM; 264 _chrp_type = _CHRP_IBM;
246 } else if (machine && strncmp(machine, "MOT", 3) == 0) { 265 } else if (machine && strncmp(machine, "MOT", 3) == 0) {
247 _chrp_type = _CHRP_Motorola; 266 _chrp_type = _CHRP_Motorola;
267 } else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) {
268 _chrp_type = _CHRP_briq;
269 /* Map the SPOR register on briq and change the restart hook */
270 briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4);
271 ppc_md.restart = briq_restart;
248 } else { 272 } else {
249 /* Let's assume it is an IBM chrp if all else fails */ 273 /* Let's assume it is an IBM chrp if all else fails */
250 _chrp_type = _CHRP_IBM; 274 _chrp_type = _CHRP_IBM;
251 } 275 }
252 printk("chrp type = %x\n", _chrp_type); 276 printk("chrp type = %x [%s]\n", _chrp_type, chrp_names[_chrp_type]);
253 277
254 rtas_initialize(); 278 rtas_initialize();
255 if (rtas_token("display-character") >= 0) 279 if (rtas_token("display-character") >= 0)
@@ -328,7 +352,7 @@ static void __init chrp_find_openpic(void)
328 struct device_node *np, *root; 352 struct device_node *np, *root;
329 int len, i, j; 353 int len, i, j;
330 int isu_size, idu_size; 354 int isu_size, idu_size;
331 unsigned int *iranges, *opprop = NULL; 355 const unsigned int *iranges, *opprop = NULL;
332 int oplen = 0; 356 int oplen = 0;
333 unsigned long opaddr; 357 unsigned long opaddr;
334 int na = 1; 358 int na = 1;
@@ -338,8 +362,7 @@ static void __init chrp_find_openpic(void)
338 return; 362 return;
339 root = of_find_node_by_path("/"); 363 root = of_find_node_by_path("/");
340 if (root) { 364 if (root) {
341 opprop = (unsigned int *) get_property 365 opprop = get_property(root, "platform-open-pic", &oplen);
342 (root, "platform-open-pic", &oplen);
343 na = prom_n_addr_cells(root); 366 na = prom_n_addr_cells(root);
344 } 367 }
345 if (opprop && oplen >= na * sizeof(unsigned int)) { 368 if (opprop && oplen >= na * sizeof(unsigned int)) {
@@ -356,7 +379,7 @@ static void __init chrp_find_openpic(void)
356 379
357 printk(KERN_INFO "OpenPIC at %lx\n", opaddr); 380 printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
358 381
359 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); 382 iranges = get_property(np, "interrupt-ranges", &len);
360 if (iranges == NULL) 383 if (iranges == NULL)
361 len = 0; /* non-distributed mpic */ 384 len = 0; /* non-distributed mpic */
362 else 385 else
@@ -442,8 +465,8 @@ static void __init chrp_find_8259(void)
442 * from anyway 465 * from anyway
443 */ 466 */
444 for (np = find_devices("pci"); np != NULL; np = np->next) { 467 for (np = find_devices("pci"); np != NULL; np = np->next) {
445 unsigned int *addrp = (unsigned int *) 468 const unsigned int *addrp = get_property(np,
446 get_property(np, "8259-interrupt-acknowledge", NULL); 469 "8259-interrupt-acknowledge", NULL);
447 470
448 if (addrp == NULL) 471 if (addrp == NULL)
449 continue; 472 continue;
@@ -502,7 +525,7 @@ void __init
502chrp_init2(void) 525chrp_init2(void)
503{ 526{
504 struct device_node *device; 527 struct device_node *device;
505 unsigned int *p = NULL; 528 const unsigned int *p = NULL;
506 529
507#ifdef CONFIG_NVRAM 530#ifdef CONFIG_NVRAM
508 chrp_nvram_init(); 531 chrp_nvram_init();
@@ -520,8 +543,7 @@ chrp_init2(void)
520 */ 543 */
521 device = find_devices("rtas"); 544 device = find_devices("rtas");
522 if (device) 545 if (device)
523 p = (unsigned int *) get_property 546 p = get_property(device, "rtas-event-scan-rate", NULL);
524 (device, "rtas-event-scan-rate", NULL);
525 if (p && *p) { 547 if (p && *p) {
526 /* 548 /*
527 * Arrange to call chrp_event_scan at least *p times 549 * Arrange to call chrp_event_scan at least *p times
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 5d393eb94935..e4f2b9df5e17 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -95,7 +95,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
95{ 95{
96 struct pci_controller *hose; 96 struct pci_controller *hose;
97 struct device_node *node; 97 struct device_node *node;
98 unsigned int *interrupt; 98 const unsigned int *interrupt;
99 int busnr; 99 int busnr;
100 int len; 100 int len;
101 u8 slot; 101 u8 slot;
@@ -112,7 +112,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
112 if (!node) 112 if (!node)
113 printk(KERN_ERR "No pci node found\n"); 113 printk(KERN_ERR "No pci node found\n");
114 114
115 interrupt = (unsigned int *) get_property(node, "interrupt-map", &len); 115 interrupt = get_property(node, "interrupt-map", &len);
116 slot = find_slot_by_devfn(interrupt, dev->devfn); 116 slot = find_slot_by_devfn(interrupt, dev->devfn);
117 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 117 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
118 if (pin == 0 || pin > 4) 118 if (pin == 0 || pin > 4)
@@ -141,9 +141,9 @@ static void __init mpc7448_hpc2_setup_arch(void)
141 141
142 cpu = of_find_node_by_type(NULL, "cpu"); 142 cpu = of_find_node_by_type(NULL, "cpu");
143 if (cpu != 0) { 143 if (cpu != 0) {
144 unsigned int *fp; 144 const unsigned int *fp;
145 145
146 fp = (int *)get_property(cpu, "clock-frequency", NULL); 146 fp = get_property(cpu, "clock-frequency", NULL);
147 if (fp != 0) 147 if (fp != 0)
148 loops_per_jiffy = *fp / HZ; 148 loops_per_jiffy = *fp / HZ;
149 else 149 else
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index 3d957a30c8c2..887b68804e6d 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -3,13 +3,17 @@ menu "iSeries device drivers"
3 depends on PPC_ISERIES 3 depends on PPC_ISERIES
4 4
5config VIOCONS 5config VIOCONS
6 tristate "iSeries Virtual Console Support" 6 tristate "iSeries Virtual Console Support (Obsolete)"
7 help
8 This is the old virtual console driver for legacy iSeries.
9 You should use the iSeries Hypervisor Virtual Console
10 support instead.
7 11
8config VIODASD 12config VIODASD
9 tristate "iSeries Virtual I/O disk support" 13 tristate "iSeries Virtual I/O disk support"
10 help 14 help
11 If you are running on an iSeries system and you want to use 15 If you are running on an iSeries system and you want to use
12 virtual disks created and managed by OS/400, say Y. 16 virtual disks created and managed by OS/400, say Y.
13 17
14config VIOCD 18config VIOCD
15 tristate "iSeries Virtual I/O CD support" 19 tristate "iSeries Virtual I/O CD support"
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index d194140c1ebf..e305deee7f44 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation 2 * Copyright (C) 2005-2006 Michael Ellerman, IBM Corporation
3 * Copyright (C) 2000-2004, IBM Corporation
3 * 4 *
4 * Description: 5 * Description:
5 * This file contains all the routines to build a flattened device 6 * This file contains all the routines to build a flattened device
@@ -33,13 +34,13 @@
33#include <asm/iseries/hv_types.h> 34#include <asm/iseries/hv_types.h>
34#include <asm/iseries/hv_lp_config.h> 35#include <asm/iseries/hv_lp_config.h>
35#include <asm/iseries/hv_call_xm.h> 36#include <asm/iseries/hv_call_xm.h>
36#include <asm/iseries/it_exp_vpd_panel.h>
37#include <asm/udbg.h> 37#include <asm/udbg.h>
38 38
39#include "processor_vpd.h" 39#include "processor_vpd.h"
40#include "call_hpt.h" 40#include "call_hpt.h"
41#include "call_pci.h" 41#include "call_pci.h"
42#include "pci.h" 42#include "pci.h"
43#include "it_exp_vpd_panel.h"
43 44
44#ifdef DEBUG 45#ifdef DEBUG
45#define DBG(fmt...) udbg_printf(fmt) 46#define DBG(fmt...) udbg_printf(fmt)
@@ -76,6 +77,43 @@ static char __initdata device_type_pci[] = "pci";
76static char __initdata device_type_vdevice[] = "vdevice"; 77static char __initdata device_type_vdevice[] = "vdevice";
77static char __initdata device_type_vscsi[] = "vscsi"; 78static char __initdata device_type_vscsi[] = "vscsi";
78 79
80
81/* EBCDIC to ASCII conversion routines */
82
83static unsigned char __init e2a(unsigned char x)
84{
85 switch (x) {
86 case 0x81 ... 0x89:
87 return x - 0x81 + 'a';
88 case 0x91 ... 0x99:
89 return x - 0x91 + 'j';
90 case 0xA2 ... 0xA9:
91 return x - 0xA2 + 's';
92 case 0xC1 ... 0xC9:
93 return x - 0xC1 + 'A';
94 case 0xD1 ... 0xD9:
95 return x - 0xD1 + 'J';
96 case 0xE2 ... 0xE9:
97 return x - 0xE2 + 'S';
98 case 0xF0 ... 0xF9:
99 return x - 0xF0 + '0';
100 }
101 return ' ';
102}
103
104static unsigned char * __init strne2a(unsigned char *dest,
105 const unsigned char *src, size_t n)
106{
107 int i;
108
109 n = strnlen(src, n);
110
111 for (i = 0; i < n; i++)
112 dest[i] = e2a(src[i]);
113
114 return dest;
115}
116
79static struct iseries_flat_dt * __init dt_init(void) 117static struct iseries_flat_dt * __init dt_init(void)
80{ 118{
81 struct iseries_flat_dt *dt; 119 struct iseries_flat_dt *dt;
@@ -298,7 +336,8 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
298 dt_prop_u32(dt, "#address-cells", 1); 336 dt_prop_u32(dt, "#address-cells", 1);
299 dt_prop_u32(dt, "#size-cells", 0); 337 dt_prop_u32(dt, "#size-cells", 0);
300 338
301 dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1); 339 dt_do_vdevice(dt, "vty", reg, -1, device_type_serial,
340 "IBM,iSeries-vty", 1);
302 reg++; 341 reg++;
303 342
304 dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi, 343 dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi,
diff --git a/arch/powerpc/platforms/iseries/hvlpconfig.c b/arch/powerpc/platforms/iseries/hvlpconfig.c
index 663a1affb4bb..f0475f0b1853 100644
--- a/arch/powerpc/platforms/iseries/hvlpconfig.c
+++ b/arch/powerpc/platforms/iseries/hvlpconfig.c
@@ -18,9 +18,22 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <asm/iseries/hv_lp_config.h> 20#include <asm/iseries/hv_lp_config.h>
21#include "it_lp_naca.h"
21 22
22HvLpIndex HvLpConfig_getLpIndex_outline(void) 23HvLpIndex HvLpConfig_getLpIndex_outline(void)
23{ 24{
24 return HvLpConfig_getLpIndex(); 25 return HvLpConfig_getLpIndex();
25} 26}
26EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline); 27EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
28
29HvLpIndex HvLpConfig_getLpIndex(void)
30{
31 return itLpNaca.xLpIndex;
32}
33EXPORT_SYMBOL(HvLpConfig_getLpIndex);
34
35HvLpIndex HvLpConfig_getPrimaryLpIndex(void)
36{
37 return itLpNaca.xPrimaryLpIndex;
38}
39EXPORT_SYMBOL_GPL(HvLpConfig_getPrimaryLpIndex);
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index e3bd2015f2c9..f4cbbcf8773a 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -88,6 +88,23 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
88} 88}
89 89
90/* 90/*
91 * Structure passed to HvCallXm_getTceTableParms
92 */
93struct iommu_table_cb {
94 unsigned long itc_busno; /* Bus number for this tce table */
95 unsigned long itc_start; /* Will be NULL for secondary */
96 unsigned long itc_totalsize; /* Size (in pages) of whole table */
97 unsigned long itc_offset; /* Index into real tce table of the
98 start of our section */
99 unsigned long itc_size; /* Size (in pages) of our section */
100 unsigned long itc_index; /* Index of this tce table */
101 unsigned short itc_maxtables; /* Max num of tables for partition */
102 unsigned char itc_virtbus; /* Flag to indicate virtual bus */
103 unsigned char itc_slotno; /* IOA Tce Slot Index */
104 unsigned char itc_rsvd[4];
105};
106
107/*
91 * Call Hv with the architected data structure to get TCE table info. 108 * Call Hv with the architected data structure to get TCE table info.
92 * info. Put the returned data into the Linux representation of the 109 * info. Put the returned data into the Linux representation of the
93 * TCE table data. 110 * TCE table data.
@@ -162,7 +179,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
162{ 179{
163 struct iommu_table *tbl; 180 struct iommu_table *tbl;
164 struct pci_dn *pdn = PCI_DN(dn); 181 struct pci_dn *pdn = PCI_DN(dn);
165 u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL); 182 const u32 *lsn = get_property(dn, "linux,logical-slot-number", NULL);
166 183
167 BUG_ON(lsn == NULL); 184 BUG_ON(lsn == NULL);
168 185
diff --git a/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h
new file mode 100644
index 000000000000..6de9097b7f57
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/it_exp_vpd_panel.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2002 Dave Boutcher IBM Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H
19#define _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H
20
21/*
22 * This struct maps the panel information
23 *
24 * Warning:
25 * This data must match the architecture for the panel information
26 */
27
28#include <asm/types.h>
29
30struct ItExtVpdPanel {
31 /* Definition of the Extended Vpd On Panel Data Area */
32 char systemSerial[8];
33 char mfgID[4];
34 char reserved1[24];
35 char machineType[4];
36 char systemID[6];
37 char somUniqueCnt[4];
38 char serialNumberCount;
39 char reserved2[7];
40 u16 bbu3;
41 u16 bbu2;
42 u16 bbu1;
43 char xLocationLabel[8];
44 u8 xRsvd1[6];
45 u16 xFrameId;
46 u8 xRsvd2[48];
47};
48
49extern struct ItExtVpdPanel xItExtVpdPanel;
50
51#endif /* _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H */
diff --git a/arch/powerpc/platforms/iseries/it_lp_naca.h b/arch/powerpc/platforms/iseries/it_lp_naca.h
new file mode 100644
index 000000000000..9bbf58986819
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/it_lp_naca.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2001 Mike Corrigan IBM Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _PLATFORMS_ISERIES_IT_LP_NACA_H
19#define _PLATFORMS_ISERIES_IT_LP_NACA_H
20
21#include <linux/types.h>
22
23/*
24 * This control block contains the data that is shared between the
25 * hypervisor (PLIC) and the OS.
26 */
27
28struct ItLpNaca {
29// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
30 u32 xDesc; // Eye catcher x00-x03
31 u16 xSize; // Size of this class x04-x05
32 u16 xIntHdlrOffset; // Offset to IntHdlr array x06-x07
33 u8 xMaxIntHdlrEntries; // Number of entries in array x08-x08
34 u8 xPrimaryLpIndex; // LP Index of Primary x09-x09
35 u8 xServiceLpIndex; // LP Ind of Service Focal Pointx0A-x0A
36 u8 xLpIndex; // LP Index x0B-x0B
37 u16 xMaxLpQueues; // Number of allocated queues x0C-x0D
38 u16 xLpQueueOffset; // Offset to start of LP queues x0E-x0F
39 u8 xPirEnvironMode; // Piranha or hardware x10-x10
40 u8 xPirConsoleMode; // Piranha console indicator x11-x11
41 u8 xPirDasdMode; // Piranha dasd indicator x12-x12
42 u8 xRsvd1_0[5]; // Reserved for Piranha related x13-x17
43 u8 flags; // flags, see below x18-x1F
44 u8 xSpVpdFormat; // VPD areas are in CSP format ...
45 u8 xIntProcRatio; // Ratio of int procs to procs ...
46 u8 xRsvd1_2[5]; // Reserved ...
47 u16 xRsvd1_3; // Reserved x20-x21
48 u16 xPlicVrmIndex; // VRM index of PLIC x22-x23
49 u16 xMinSupportedSlicVrmInd;// Min supported OS VRM index x24-x25
50 u16 xMinCompatableSlicVrmInd;// Min compatible OS VRM index x26-x27
51 u64 xLoadAreaAddr; // ER address of load area x28-x2F
52 u32 xLoadAreaChunks; // Chunks for the load area x30-x33
53 u32 xPaseSysCallCRMask; // Mask used to test CR before x34-x37
54 // doing an ASR switch on PASE
55 // system call.
56 u64 xSlicSegmentTablePtr; // Pointer to Slic seg table. x38-x3f
57 u8 xRsvd1_4[64]; // x40-x7F
58
59// CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
60 u8 xRsvd2_0[128]; // Reserved x00-x7F
61
62// CACHE_LINE_3-6 0x0100 - 0x02FF Contains LP Queue indicators
63// NB: Padding required to keep xInterrruptHdlr at x300 which is required
64// for v4r4 PLIC.
65 u8 xOldLpQueue[128]; // LP Queue needed for v4r4 100-17F
66 u8 xRsvd3_0[384]; // Reserved 180-2FF
67
68// CACHE_LINE_7-8 0x0300 - 0x03FF Contains the address of the OS interrupt
69// handlers
70 u64 xInterruptHdlr[32]; // Interrupt handlers 300-x3FF
71};
72
73extern struct ItLpNaca itLpNaca;
74
75#define ITLPNACA_LPAR 0x80 /* Is LPAR installed on the system */
76#define ITLPNACA_PARTITIONED 0x40 /* Is the system partitioned */
77#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */
78#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */
79
80#endif /* _PLATFORMS_ISERIES_IT_LP_NACA_H */
diff --git a/arch/powerpc/platforms/iseries/lpardata.c b/arch/powerpc/platforms/iseries/lpardata.c
index a7769445d6c7..8162049bb04d 100644
--- a/arch/powerpc/platforms/iseries/lpardata.c
+++ b/arch/powerpc/platforms/iseries/lpardata.c
@@ -13,12 +13,10 @@
13#include <asm/processor.h> 13#include <asm/processor.h>
14#include <asm/ptrace.h> 14#include <asm/ptrace.h>
15#include <asm/abs_addr.h> 15#include <asm/abs_addr.h>
16#include <asm/iseries/it_lp_naca.h>
17#include <asm/lppaca.h> 16#include <asm/lppaca.h>
18#include <asm/iseries/it_lp_reg_save.h> 17#include <asm/iseries/it_lp_reg_save.h>
19#include <asm/paca.h> 18#include <asm/paca.h>
20#include <asm/iseries/lpar_map.h> 19#include <asm/iseries/lpar_map.h>
21#include <asm/iseries/it_exp_vpd_panel.h>
22#include <asm/iseries/it_lp_queue.h> 20#include <asm/iseries/it_lp_queue.h>
23 21
24#include "naca.h" 22#include "naca.h"
@@ -27,6 +25,8 @@
27#include "ipl_parms.h" 25#include "ipl_parms.h"
28#include "processor_vpd.h" 26#include "processor_vpd.h"
29#include "release_data.h" 27#include "release_data.h"
28#include "it_exp_vpd_panel.h"
29#include "it_lp_naca.h"
30 30
31/* The HvReleaseData is the root of the information shared between 31/* The HvReleaseData is the root of the information shared between
32 * the hypervisor and Linux. 32 * the hypervisor and Linux.
@@ -127,14 +127,12 @@ struct ItLpNaca itLpNaca = {
127 (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */ 127 (u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
128 } 128 }
129}; 129};
130EXPORT_SYMBOL(itLpNaca);
131 130
132/* May be filled in by the hypervisor so cannot end up in the BSS */ 131/* May be filled in by the hypervisor so cannot end up in the BSS */
133struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); 132struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
134 133
135/* May be filled in by the hypervisor so cannot end up in the BSS */ 134/* May be filled in by the hypervisor so cannot end up in the BSS */
136struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data"))); 135struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
137EXPORT_SYMBOL(xItExtVpdPanel);
138 136
139#define maxPhysicalProcessors 32 137#define maxPhysicalProcessors 32
140 138
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index 2a9f81ea27d6..98c1c2440aad 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -20,7 +20,7 @@
20#include <asm/iseries/it_lp_queue.h> 20#include <asm/iseries/it_lp_queue.h>
21#include <asm/iseries/hv_lp_event.h> 21#include <asm/iseries/hv_lp_event.h>
22#include <asm/iseries/hv_call_event.h> 22#include <asm/iseries/hv_call_event.h>
23#include <asm/iseries/it_lp_naca.h> 23#include "it_lp_naca.h"
24 24
25/* 25/*
26 * The LpQueue is used to pass event data from the hypervisor to 26 * The LpQueue is used to pass event data from the hypervisor to
diff --git a/arch/powerpc/platforms/iseries/main_store.h b/arch/powerpc/platforms/iseries/main_store.h
index 74f6889f834f..1a7a3f50e40b 100644
--- a/arch/powerpc/platforms/iseries/main_store.h
+++ b/arch/powerpc/platforms/iseries/main_store.h
@@ -61,9 +61,9 @@ struct IoHriMainStoreSegment4 {
61}; 61};
62 62
63/* Main Store VPD for Power4 */ 63/* Main Store VPD for Power4 */
64struct IoHriMainStoreChipInfo1 { 64struct __attribute((packed)) IoHriMainStoreChipInfo1 {
65 u32 chipMfgID __attribute((packed)); 65 u32 chipMfgID;
66 char chipECLevel[4] __attribute((packed)); 66 char chipECLevel[4];
67}; 67};
68 68
69struct IoHriMainStoreVpdIdData { 69struct IoHriMainStoreVpdIdData {
@@ -73,72 +73,72 @@ struct IoHriMainStoreVpdIdData {
73 char serialNumber[12]; 73 char serialNumber[12];
74}; 74};
75 75
76struct IoHriMainStoreVpdFruData { 76struct __attribute((packed)) IoHriMainStoreVpdFruData {
77 char fruLabel[8] __attribute((packed)); 77 char fruLabel[8];
78 u8 numberOfSlots __attribute((packed)); 78 u8 numberOfSlots;
79 u8 pluggingType __attribute((packed)); 79 u8 pluggingType;
80 u16 slotMapIndex __attribute((packed)); 80 u16 slotMapIndex;
81}; 81};
82 82
83struct IoHriMainStoreAdrRangeBlock { 83struct __attribute((packed)) IoHriMainStoreAdrRangeBlock {
84 void *blockStart __attribute((packed)); 84 void *blockStart;
85 void *blockEnd __attribute((packed)); 85 void *blockEnd;
86 u32 blockProcChipId __attribute((packed)); 86 u32 blockProcChipId;
87}; 87};
88 88
89#define MaxAreaAdrRangeBlocks 4 89#define MaxAreaAdrRangeBlocks 4
90 90
91struct IoHriMainStoreArea4 { 91struct __attribute((packed)) IoHriMainStoreArea4 {
92 u32 msVpdFormat __attribute((packed)); 92 u32 msVpdFormat;
93 u8 containedVpdType __attribute((packed)); 93 u8 containedVpdType;
94 u8 reserved1 __attribute((packed)); 94 u8 reserved1;
95 u16 reserved2 __attribute((packed)); 95 u16 reserved2;
96 96
97 u64 msExists __attribute((packed)); 97 u64 msExists;
98 u64 msFunctional __attribute((packed)); 98 u64 msFunctional;
99 99
100 u32 memorySize __attribute((packed)); 100 u32 memorySize;
101 u32 procNodeId __attribute((packed)); 101 u32 procNodeId;
102 102
103 u32 numAdrRangeBlocks __attribute((packed)); 103 u32 numAdrRangeBlocks;
104 struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed)); 104 struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks];
105 105
106 struct IoHriMainStoreChipInfo1 chipInfo0 __attribute((packed)); 106 struct IoHriMainStoreChipInfo1 chipInfo0;
107 struct IoHriMainStoreChipInfo1 chipInfo1 __attribute((packed)); 107 struct IoHriMainStoreChipInfo1 chipInfo1;
108 struct IoHriMainStoreChipInfo1 chipInfo2 __attribute((packed)); 108 struct IoHriMainStoreChipInfo1 chipInfo2;
109 struct IoHriMainStoreChipInfo1 chipInfo3 __attribute((packed)); 109 struct IoHriMainStoreChipInfo1 chipInfo3;
110 struct IoHriMainStoreChipInfo1 chipInfo4 __attribute((packed)); 110 struct IoHriMainStoreChipInfo1 chipInfo4;
111 struct IoHriMainStoreChipInfo1 chipInfo5 __attribute((packed)); 111 struct IoHriMainStoreChipInfo1 chipInfo5;
112 struct IoHriMainStoreChipInfo1 chipInfo6 __attribute((packed)); 112 struct IoHriMainStoreChipInfo1 chipInfo6;
113 struct IoHriMainStoreChipInfo1 chipInfo7 __attribute((packed)); 113 struct IoHriMainStoreChipInfo1 chipInfo7;
114 114
115 void *msRamAreaArray __attribute((packed)); 115 void *msRamAreaArray;
116 u32 msRamAreaArrayNumEntries __attribute((packed)); 116 u32 msRamAreaArrayNumEntries;
117 u32 msRamAreaArrayEntrySize __attribute((packed)); 117 u32 msRamAreaArrayEntrySize;
118 118
119 u32 numaDimmExists __attribute((packed)); 119 u32 numaDimmExists;
120 u32 numaDimmFunctional __attribute((packed)); 120 u32 numaDimmFunctional;
121 void *numaDimmArray __attribute((packed)); 121 void *numaDimmArray;
122 u32 numaDimmArrayNumEntries __attribute((packed)); 122 u32 numaDimmArrayNumEntries;
123 u32 numaDimmArrayEntrySize __attribute((packed)); 123 u32 numaDimmArrayEntrySize;
124 124
125 struct IoHriMainStoreVpdIdData idData __attribute((packed)); 125 struct IoHriMainStoreVpdIdData idData;
126 126
127 u64 powerData __attribute((packed)); 127 u64 powerData;
128 u64 cardAssemblyPartNum __attribute((packed)); 128 u64 cardAssemblyPartNum;
129 u64 chipSerialNum __attribute((packed)); 129 u64 chipSerialNum;
130 130
131 u64 reserved3 __attribute((packed)); 131 u64 reserved3;
132 char reserved4[16] __attribute((packed)); 132 char reserved4[16];
133 133
134 struct IoHriMainStoreVpdFruData fruData __attribute((packed)); 134 struct IoHriMainStoreVpdFruData fruData;
135 135
136 u8 vpdPortNum __attribute((packed)); 136 u8 vpdPortNum;
137 u8 reserved5 __attribute((packed)); 137 u8 reserved5;
138 u8 frameId __attribute((packed)); 138 u8 frameId;
139 u8 rackUnit __attribute((packed)); 139 u8 rackUnit;
140 char asciiKeywordVpd[256] __attribute((packed)); 140 char asciiKeywordVpd[256];
141 u32 reserved6 __attribute((packed)); 141 u32 reserved6;
142}; 142};
143 143
144 144
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 35bcc98111f5..3eb12065df23 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -34,6 +34,7 @@
34#include <asm/pci-bridge.h> 34#include <asm/pci-bridge.h>
35#include <asm/iommu.h> 35#include <asm/iommu.h>
36#include <asm/abs_addr.h> 36#include <asm/abs_addr.h>
37#include <asm/firmware.h>
37 38
38#include <asm/iseries/hv_call_xm.h> 39#include <asm/iseries/hv_call_xm.h>
39#include <asm/iseries/mf.h> 40#include <asm/iseries/mf.h>
@@ -176,12 +177,12 @@ void iSeries_pcibios_init(void)
176 } 177 }
177 while ((node = of_get_next_child(root, node)) != NULL) { 178 while ((node = of_get_next_child(root, node)) != NULL) {
178 HvBusNumber bus; 179 HvBusNumber bus;
179 u32 *busp; 180 const u32 *busp;
180 181
181 if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) 182 if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
182 continue; 183 continue;
183 184
184 busp = (u32 *)get_property(node, "bus-range", NULL); 185 busp = get_property(node, "bus-range", NULL);
185 if (busp == NULL) 186 if (busp == NULL)
186 continue; 187 continue;
187 bus = *busp; 188 bus = *busp;
@@ -221,10 +222,9 @@ void __init iSeries_pci_final_fixup(void)
221 222
222 if (node != NULL) { 223 if (node != NULL) {
223 struct pci_dn *pdn = PCI_DN(node); 224 struct pci_dn *pdn = PCI_DN(node);
224 u32 *agent; 225 const u32 *agent;
225 226
226 agent = (u32 *)get_property(node, "linux,agent-id", 227 agent = get_property(node, "linux,agent-id", NULL);
227 NULL);
228 if ((pdn != NULL) && (agent != NULL)) { 228 if ((pdn != NULL) && (agent != NULL)) {
229 u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, 229 u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
230 pdn->bussubno); 230 pdn->bussubno);
@@ -271,46 +271,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev)
271} 271}
272 272
273/* 273/*
274 * I/0 Memory copy MUST use mmio commands on iSeries
275 * To do; For performance, include the hv call directly
276 */
277void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
278{
279 u8 ByteValue = c;
280 long NumberOfBytes = Count;
281
282 while (NumberOfBytes > 0) {
283 iSeries_Write_Byte(ByteValue, dest++);
284 -- NumberOfBytes;
285 }
286}
287EXPORT_SYMBOL(iSeries_memset_io);
288
289void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
290{
291 char *src = source;
292 long NumberOfBytes = count;
293
294 while (NumberOfBytes > 0) {
295 iSeries_Write_Byte(*src++, dest++);
296 -- NumberOfBytes;
297 }
298}
299EXPORT_SYMBOL(iSeries_memcpy_toio);
300
301void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
302{
303 char *dst = dest;
304 long NumberOfBytes = count;
305
306 while (NumberOfBytes > 0) {
307 *dst++ = iSeries_Read_Byte(src++);
308 -- NumberOfBytes;
309 }
310}
311EXPORT_SYMBOL(iSeries_memcpy_fromio);
312
313/*
314 * Look down the chain to find the matching Device Device 274 * Look down the chain to find the matching Device Device
315 */ 275 */
316static struct device_node *find_Device_Node(int bus, int devfn) 276static struct device_node *find_Device_Node(int bus, int devfn)
@@ -492,7 +452,7 @@ static inline struct device_node *xlate_iomm_address(
492 * iSeries_Read_Word = Read Word (16 bit) 452 * iSeries_Read_Word = Read Word (16 bit)
493 * iSeries_Read_Long = Read Long (32 bit) 453 * iSeries_Read_Long = Read Long (32 bit)
494 */ 454 */
495u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) 455static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
496{ 456{
497 u64 BarOffset; 457 u64 BarOffset;
498 u64 dsa; 458 u64 dsa;
@@ -519,9 +479,8 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
519 479
520 return (u8)ret.value; 480 return (u8)ret.value;
521} 481}
522EXPORT_SYMBOL(iSeries_Read_Byte);
523 482
524u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) 483static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
525{ 484{
526 u64 BarOffset; 485 u64 BarOffset;
527 u64 dsa; 486 u64 dsa;
@@ -549,9 +508,8 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
549 508
550 return swab16((u16)ret.value); 509 return swab16((u16)ret.value);
551} 510}
552EXPORT_SYMBOL(iSeries_Read_Word);
553 511
554u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) 512static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
555{ 513{
556 u64 BarOffset; 514 u64 BarOffset;
557 u64 dsa; 515 u64 dsa;
@@ -579,7 +537,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
579 537
580 return swab32((u32)ret.value); 538 return swab32((u32)ret.value);
581} 539}
582EXPORT_SYMBOL(iSeries_Read_Long);
583 540
584/* 541/*
585 * Write MM I/O Instructions for the iSeries 542 * Write MM I/O Instructions for the iSeries
@@ -588,7 +545,7 @@ EXPORT_SYMBOL(iSeries_Read_Long);
588 * iSeries_Write_Word = Write Word(16 bit) 545 * iSeries_Write_Word = Write Word(16 bit)
589 * iSeries_Write_Long = Write Long(32 bit) 546 * iSeries_Write_Long = Write Long(32 bit)
590 */ 547 */
591void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) 548static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
592{ 549{
593 u64 BarOffset; 550 u64 BarOffset;
594 u64 dsa; 551 u64 dsa;
@@ -613,9 +570,8 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
613 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); 570 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
614 } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); 571 } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
615} 572}
616EXPORT_SYMBOL(iSeries_Write_Byte);
617 573
618void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) 574static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
619{ 575{
620 u64 BarOffset; 576 u64 BarOffset;
621 u64 dsa; 577 u64 dsa;
@@ -640,9 +596,8 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
640 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); 596 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
641 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); 597 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
642} 598}
643EXPORT_SYMBOL(iSeries_Write_Word);
644 599
645void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) 600static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
646{ 601{
647 u64 BarOffset; 602 u64 BarOffset;
648 u64 dsa; 603 u64 dsa;
@@ -667,4 +622,224 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
667 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); 622 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
668 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); 623 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
669} 624}
670EXPORT_SYMBOL(iSeries_Write_Long); 625
626extern unsigned char __raw_readb(const volatile void __iomem *addr)
627{
628 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
629
630 return *(volatile unsigned char __force *)addr;
631}
632EXPORT_SYMBOL(__raw_readb);
633
634extern unsigned short __raw_readw(const volatile void __iomem *addr)
635{
636 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
637
638 return *(volatile unsigned short __force *)addr;
639}
640EXPORT_SYMBOL(__raw_readw);
641
642extern unsigned int __raw_readl(const volatile void __iomem *addr)
643{
644 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
645
646 return *(volatile unsigned int __force *)addr;
647}
648EXPORT_SYMBOL(__raw_readl);
649
650extern unsigned long __raw_readq(const volatile void __iomem *addr)
651{
652 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
653
654 return *(volatile unsigned long __force *)addr;
655}
656EXPORT_SYMBOL(__raw_readq);
657
658extern void __raw_writeb(unsigned char v, volatile void __iomem *addr)
659{
660 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
661
662 *(volatile unsigned char __force *)addr = v;
663}
664EXPORT_SYMBOL(__raw_writeb);
665
666extern void __raw_writew(unsigned short v, volatile void __iomem *addr)
667{
668 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
669
670 *(volatile unsigned short __force *)addr = v;
671}
672EXPORT_SYMBOL(__raw_writew);
673
674extern void __raw_writel(unsigned int v, volatile void __iomem *addr)
675{
676 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
677
678 *(volatile unsigned int __force *)addr = v;
679}
680EXPORT_SYMBOL(__raw_writel);
681
682extern void __raw_writeq(unsigned long v, volatile void __iomem *addr)
683{
684 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
685
686 *(volatile unsigned long __force *)addr = v;
687}
688EXPORT_SYMBOL(__raw_writeq);
689
690int in_8(const volatile unsigned char __iomem *addr)
691{
692 if (firmware_has_feature(FW_FEATURE_ISERIES))
693 return iSeries_Read_Byte(addr);
694 return __in_8(addr);
695}
696EXPORT_SYMBOL(in_8);
697
698void out_8(volatile unsigned char __iomem *addr, int val)
699{
700 if (firmware_has_feature(FW_FEATURE_ISERIES))
701 iSeries_Write_Byte(val, addr);
702 else
703 __out_8(addr, val);
704}
705EXPORT_SYMBOL(out_8);
706
707int in_le16(const volatile unsigned short __iomem *addr)
708{
709 if (firmware_has_feature(FW_FEATURE_ISERIES))
710 return iSeries_Read_Word(addr);
711 return __in_le16(addr);
712}
713EXPORT_SYMBOL(in_le16);
714
715int in_be16(const volatile unsigned short __iomem *addr)
716{
717 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
718
719 return __in_be16(addr);
720}
721EXPORT_SYMBOL(in_be16);
722
723void out_le16(volatile unsigned short __iomem *addr, int val)
724{
725 if (firmware_has_feature(FW_FEATURE_ISERIES))
726 iSeries_Write_Word(val, addr);
727 else
728 __out_le16(addr, val);
729}
730EXPORT_SYMBOL(out_le16);
731
732void out_be16(volatile unsigned short __iomem *addr, int val)
733{
734 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
735
736 __out_be16(addr, val);
737}
738EXPORT_SYMBOL(out_be16);
739
740unsigned in_le32(const volatile unsigned __iomem *addr)
741{
742 if (firmware_has_feature(FW_FEATURE_ISERIES))
743 return iSeries_Read_Long(addr);
744 return __in_le32(addr);
745}
746EXPORT_SYMBOL(in_le32);
747
748unsigned in_be32(const volatile unsigned __iomem *addr)
749{
750 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
751
752 return __in_be32(addr);
753}
754EXPORT_SYMBOL(in_be32);
755
756void out_le32(volatile unsigned __iomem *addr, int val)
757{
758 if (firmware_has_feature(FW_FEATURE_ISERIES))
759 iSeries_Write_Long(val, addr);
760 else
761 __out_le32(addr, val);
762}
763EXPORT_SYMBOL(out_le32);
764
765void out_be32(volatile unsigned __iomem *addr, int val)
766{
767 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
768
769 __out_be32(addr, val);
770}
771EXPORT_SYMBOL(out_be32);
772
773unsigned long in_le64(const volatile unsigned long __iomem *addr)
774{
775 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
776
777 return __in_le64(addr);
778}
779EXPORT_SYMBOL(in_le64);
780
781unsigned long in_be64(const volatile unsigned long __iomem *addr)
782{
783 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
784
785 return __in_be64(addr);
786}
787EXPORT_SYMBOL(in_be64);
788
789void out_le64(volatile unsigned long __iomem *addr, unsigned long val)
790{
791 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
792
793 __out_le64(addr, val);
794}
795EXPORT_SYMBOL(out_le64);
796
797void out_be64(volatile unsigned long __iomem *addr, unsigned long val)
798{
799 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
800
801 __out_be64(addr, val);
802}
803EXPORT_SYMBOL(out_be64);
804
805void memset_io(volatile void __iomem *addr, int c, unsigned long n)
806{
807 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
808 volatile char __iomem *d = addr;
809
810 while (n-- > 0) {
811 iSeries_Write_Byte(c, d++);
812 }
813 } else
814 eeh_memset_io(addr, c, n);
815}
816EXPORT_SYMBOL(memset_io);
817
818void memcpy_fromio(void *dest, const volatile void __iomem *src,
819 unsigned long n)
820{
821 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
822 char *d = dest;
823 const volatile char __iomem *s = src;
824
825 while (n-- > 0) {
826 *d++ = iSeries_Read_Byte(s++);
827 }
828 } else
829 eeh_memcpy_fromio(dest, src, n);
830}
831EXPORT_SYMBOL(memcpy_fromio);
832
833void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
834{
835 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
836 const char *s = src;
837 volatile char __iomem *d = dest;
838
839 while (n-- > 0) {
840 iSeries_Write_Byte(*s++, d++);
841 }
842 } else
843 eeh_memcpy_toio(dest, src, n);
844}
845EXPORT_SYMBOL(memcpy_toio);
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index c9605d773a77..7f1953066ff8 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -59,6 +59,7 @@
59#include "irq.h" 59#include "irq.h"
60#include "vpd_areas.h" 60#include "vpd_areas.h"
61#include "processor_vpd.h" 61#include "processor_vpd.h"
62#include "it_lp_naca.h"
62#include "main_store.h" 63#include "main_store.h"
63#include "call_sm.h" 64#include "call_sm.h"
64#include "call_hpt.h" 65#include "call_hpt.h"
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 622a30149b48..9baa4ee82592 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -41,8 +41,8 @@
41 41
42#include <asm/system.h> 42#include <asm/system.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/prom.h>
44#include <asm/iseries/hv_types.h> 45#include <asm/iseries/hv_types.h>
45#include <asm/iseries/it_exp_vpd_panel.h>
46#include <asm/iseries/hv_lp_event.h> 46#include <asm/iseries/hv_lp_event.h>
47#include <asm/iseries/hv_lp_config.h> 47#include <asm/iseries/hv_lp_config.h>
48#include <asm/iseries/mf.h> 48#include <asm/iseries/mf.h>
@@ -116,6 +116,8 @@ static int proc_viopath_show(struct seq_file *m, void *v)
116 dma_addr_t handle; 116 dma_addr_t handle;
117 HvLpEvent_Rc hvrc; 117 HvLpEvent_Rc hvrc;
118 DECLARE_MUTEX_LOCKED(Semaphore); 118 DECLARE_MUTEX_LOCKED(Semaphore);
119 struct device_node *node;
120 const char *sysid;
119 121
120 buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL); 122 buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL);
121 if (!buf) 123 if (!buf)
@@ -143,20 +145,26 @@ static int proc_viopath_show(struct seq_file *m, void *v)
143 145
144 buf[HW_PAGE_SIZE-1] = '\0'; 146 buf[HW_PAGE_SIZE-1] = '\0';
145 seq_printf(m, "%s", buf); 147 seq_printf(m, "%s", buf);
146 seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
147 seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
148 e2a(xItExtVpdPanel.mfgID[2]),
149 e2a(xItExtVpdPanel.mfgID[3]),
150 e2a(xItExtVpdPanel.systemSerial[1]),
151 e2a(xItExtVpdPanel.systemSerial[2]),
152 e2a(xItExtVpdPanel.systemSerial[3]),
153 e2a(xItExtVpdPanel.systemSerial[4]),
154 e2a(xItExtVpdPanel.systemSerial[5]));
155 148
156 dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE, 149 dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
157 DMA_FROM_DEVICE); 150 DMA_FROM_DEVICE);
158 kfree(buf); 151 kfree(buf);
159 152
153 seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
154
155 node = of_find_node_by_path("/");
156 sysid = NULL;
157 if (node != NULL)
158 sysid = get_property(node, "system-id", NULL);
159
160 if (sysid == NULL)
161 seq_printf(m, "SRLNBR=<UNKNOWN>\n");
162 else
163 /* Skip "IBM," on front of serial number, see dt.c */
164 seq_printf(m, "SRLNBR=%s\n", sysid + 4);
165
166 of_node_put(node);
167
160 return 0; 168 return 0;
161} 169}
162 170
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
index 23a6d1e5b429..9f83878a0c2e 100644
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ b/arch/powerpc/platforms/iseries/vpdinfo.c
@@ -188,7 +188,7 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
188{ 188{
189 u8 *TagPtr = VpdData; 189 u8 *TagPtr = VpdData;
190 int DataLen = VpdDataLen - 3; 190 int DataLen = VpdDataLen - 3;
191 u8 PhbId; 191 u8 PhbId = 0xff;
192 192
193 while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { 193 while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
194 int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); 194 int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
@@ -205,15 +205,16 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
205 } 205 }
206} 206}
207 207
208static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, 208static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
209 u8 *frame, char card[4]) 209 u8 *frame, char card[4])
210{ 210{
211 int status = 0;
211 int BusVpdLen = 0; 212 int BusVpdLen = 0;
212 u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); 213 u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
213 214
214 if (BusVpdPtr == NULL) { 215 if (BusVpdPtr == NULL) {
215 printk("PCI: Bus VPD Buffer allocation failure.\n"); 216 printk("PCI: Bus VPD Buffer allocation failure.\n");
216 return; 217 return 0;
217 } 218 }
218 BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr), 219 BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
219 BUS_VPDSIZE); 220 BUS_VPDSIZE);
@@ -228,8 +229,10 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
228 goto out_free; 229 goto out_free;
229 } 230 }
230 iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); 231 iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
232 status = 1;
231out_free: 233out_free:
232 kfree(BusVpdPtr); 234 kfree(BusVpdPtr);
235 return status;
233} 236}
234 237
235/* 238/*
@@ -246,7 +249,7 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
246 struct device_node *DevNode = PciDev->sysdata; 249 struct device_node *DevNode = PciDev->sysdata;
247 struct pci_dn *pdn; 250 struct pci_dn *pdn;
248 u16 bus; 251 u16 bus;
249 u8 frame; 252 u8 frame = 0;
250 char card[4]; 253 char card[4];
251 HvSubBusNumber subbus; 254 HvSubBusNumber subbus;
252 HvAgentId agent; 255 HvAgentId agent;
@@ -262,10 +265,11 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
262 subbus = pdn->bussubno; 265 subbus = pdn->bussubno;
263 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), 266 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
264 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); 267 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
265 iSeries_Get_Location_Code(bus, agent, &frame, card);
266 268
267 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", 269 if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
268 count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, 270 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
269 frame, card); 271 "Card %4s 0x%04X\n", count, bus,
270 printk("0x%04X\n", (int)(PciDev->class >> 8)); 272 PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
273 card, (int)(PciDev->class >> 8));
274 }
271} 275}
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 63a1670d3bfd..c3aa46b8e2b9 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -38,16 +38,16 @@ static struct pci_controller *u3_agp, *u3_ht;
38static int __init fixup_one_level_bus_range(struct device_node *node, int higher) 38static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
39{ 39{
40 for (; node != 0;node = node->sibling) { 40 for (; node != 0;node = node->sibling) {
41 int * bus_range; 41 const int *bus_range;
42 unsigned int *class_code; 42 const unsigned int *class_code;
43 int len; 43 int len;
44 44
45 /* For PCI<->PCI bridges or CardBus bridges, we go down */ 45 /* For PCI<->PCI bridges or CardBus bridges, we go down */
46 class_code = (unsigned int *) get_property(node, "class-code", NULL); 46 class_code = get_property(node, "class-code", NULL);
47 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 47 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
48 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 48 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
49 continue; 49 continue;
50 bus_range = (int *) get_property(node, "bus-range", &len); 50 bus_range = get_property(node, "bus-range", &len);
51 if (bus_range != NULL && len > 2 * sizeof(int)) { 51 if (bus_range != NULL && len > 2 * sizeof(int)) {
52 if (bus_range[1] > higher) 52 if (bus_range[1] > higher)
53 higher = bus_range[1]; 53 higher = bus_range[1];
@@ -65,30 +65,36 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher
65 */ 65 */
66static void __init fixup_bus_range(struct device_node *bridge) 66static void __init fixup_bus_range(struct device_node *bridge)
67{ 67{
68 int * bus_range; 68 int *bus_range;
69 struct property *prop;
69 int len; 70 int len;
70 71
71 /* Lookup the "bus-range" property for the hose */ 72 /* Lookup the "bus-range" property for the hose */
72 bus_range = (int *) get_property(bridge, "bus-range", &len); 73 prop = of_find_property(bridge, "bus-range", &len);
73 if (bus_range == NULL || len < 2 * sizeof(int)) { 74 if (prop == NULL || prop->value == NULL || len < 2 * sizeof(int)) {
74 printk(KERN_WARNING "Can't get bus-range for %s\n", 75 printk(KERN_WARNING "Can't get bus-range for %s\n",
75 bridge->full_name); 76 bridge->full_name);
76 return; 77 return;
77 } 78 }
79 bus_range = (int *)prop->value;
78 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); 80 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
79} 81}
80 82
81 83
82#define U3_AGP_CFA0(devfn, off) \ 84static unsigned long u3_agp_cfa0(u8 devfn, u8 off)
83 ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ 85{
84 | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ 86 return (1 << (unsigned long)PCI_SLOT(devfn)) |
85 | (((unsigned long)(off)) & 0xFCUL)) 87 ((unsigned long)PCI_FUNC(devfn) << 8) |
88 ((unsigned long)off & 0xFCUL);
89}
86 90
87#define U3_AGP_CFA1(bus, devfn, off) \ 91static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off)
88 ((((unsigned long)(bus)) << 16) \ 92{
89 |(((unsigned long)(devfn)) << 8) \ 93 return ((unsigned long)bus << 16) |
90 |(((unsigned long)(off)) & 0xFCUL) \ 94 ((unsigned long)devfn << 8) |
91 |1UL) 95 ((unsigned long)off & 0xFCUL) |
96 1UL;
97}
92 98
93static unsigned long u3_agp_cfg_access(struct pci_controller* hose, 99static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
94 u8 bus, u8 dev_fn, u8 offset) 100 u8 bus, u8 dev_fn, u8 offset)
@@ -98,9 +104,9 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
98 if (bus == hose->first_busno) { 104 if (bus == hose->first_busno) {
99 if (dev_fn < (11 << 3)) 105 if (dev_fn < (11 << 3))
100 return 0; 106 return 0;
101 caddr = U3_AGP_CFA0(dev_fn, offset); 107 caddr = u3_agp_cfa0(dev_fn, offset);
102 } else 108 } else
103 caddr = U3_AGP_CFA1(bus, dev_fn, offset); 109 caddr = u3_agp_cfa1(bus, dev_fn, offset);
104 110
105 /* Uninorth will return garbage if we don't read back the value ! */ 111 /* Uninorth will return garbage if we don't read back the value ! */
106 do { 112 do {
@@ -182,13 +188,15 @@ static struct pci_ops u3_agp_pci_ops =
182 u3_agp_write_config 188 u3_agp_write_config
183}; 189};
184 190
191static unsigned long u3_ht_cfa0(u8 devfn, u8 off)
192{
193 return (devfn << 8) | off;
194}
185 195
186#define U3_HT_CFA0(devfn, off) \ 196static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off)
187 ((((unsigned long)devfn) << 8) | offset) 197{
188#define U3_HT_CFA1(bus, devfn, off) \ 198 return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
189 (U3_HT_CFA0(devfn, off) \ 199}
190 + (((unsigned long)bus) << 16) \
191 + 0x01000000UL)
192 200
193static unsigned long u3_ht_cfg_access(struct pci_controller* hose, 201static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
194 u8 bus, u8 devfn, u8 offset) 202 u8 bus, u8 devfn, u8 offset)
@@ -196,9 +204,9 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
196 if (bus == hose->first_busno) { 204 if (bus == hose->first_busno) {
197 if (PCI_SLOT(devfn) == 0) 205 if (PCI_SLOT(devfn) == 0)
198 return 0; 206 return 0;
199 return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); 207 return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset);
200 } else 208 } else
201 return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); 209 return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset);
202} 210}
203 211
204static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, 212static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
@@ -211,6 +219,9 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
211 if (hose == NULL) 219 if (hose == NULL)
212 return PCIBIOS_DEVICE_NOT_FOUND; 220 return PCIBIOS_DEVICE_NOT_FOUND;
213 221
222 if (offset > 0xff)
223 return PCIBIOS_BAD_REGISTER_NUMBER;
224
214 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 225 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
215 if (!addr) 226 if (!addr)
216 return PCIBIOS_DEVICE_NOT_FOUND; 227 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -243,6 +254,9 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
243 if (hose == NULL) 254 if (hose == NULL)
244 return PCIBIOS_DEVICE_NOT_FOUND; 255 return PCIBIOS_DEVICE_NOT_FOUND;
245 256
257 if (offset > 0xff)
258 return PCIBIOS_BAD_REGISTER_NUMBER;
259
246 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 260 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
247 if (!addr) 261 if (!addr)
248 return PCIBIOS_DEVICE_NOT_FOUND; 262 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -314,12 +328,12 @@ static int __init add_bridge(struct device_node *dev)
314 int len; 328 int len;
315 struct pci_controller *hose; 329 struct pci_controller *hose;
316 char* disp_name; 330 char* disp_name;
317 int *bus_range; 331 const int *bus_range;
318 int primary = 1; 332 int primary = 1;
319 333
320 DBG("Adding PCI host bridge %s\n", dev->full_name); 334 DBG("Adding PCI host bridge %s\n", dev->full_name);
321 335
322 bus_range = (int *) get_property(dev, "bus-range", &len); 336 bus_range = get_property(dev, "bus-range", &len);
323 if (bus_range == NULL || len < 2 * sizeof(int)) { 337 if (bus_range == NULL || len < 2 * sizeof(int)) {
324 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", 338 printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
325 dev->full_name); 339 dev->full_name);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 57567dfb9819..fe6b9bff61b9 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -99,8 +99,7 @@ static unsigned long maple_find_nvram_base(void)
99static void maple_restart(char *cmd) 99static void maple_restart(char *cmd)
100{ 100{
101 unsigned int maple_nvram_base; 101 unsigned int maple_nvram_base;
102 unsigned int maple_nvram_offset; 102 const unsigned int *maple_nvram_offset, *maple_nvram_command;
103 unsigned int maple_nvram_command;
104 struct device_node *sp; 103 struct device_node *sp;
105 104
106 maple_nvram_base = maple_find_nvram_base(); 105 maple_nvram_base = maple_find_nvram_base();
@@ -113,14 +112,12 @@ static void maple_restart(char *cmd)
113 printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); 112 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
114 goto fail; 113 goto fail;
115 } 114 }
116 maple_nvram_offset = *(unsigned int*) get_property(sp, 115 maple_nvram_offset = get_property(sp, "restart-addr", NULL);
117 "restart-addr", NULL); 116 maple_nvram_command = get_property(sp, "restart-value", NULL);
118 maple_nvram_command = *(unsigned int*) get_property(sp,
119 "restart-value", NULL);
120 of_node_put(sp); 117 of_node_put(sp);
121 118
122 /* send command */ 119 /* send command */
123 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); 120 outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);
124 for (;;) ; 121 for (;;) ;
125 fail: 122 fail:
126 printk(KERN_EMERG "Maple: Manual Restart Required\n"); 123 printk(KERN_EMERG "Maple: Manual Restart Required\n");
@@ -129,8 +126,7 @@ static void maple_restart(char *cmd)
129static void maple_power_off(void) 126static void maple_power_off(void)
130{ 127{
131 unsigned int maple_nvram_base; 128 unsigned int maple_nvram_base;
132 unsigned int maple_nvram_offset; 129 const unsigned int *maple_nvram_offset, *maple_nvram_command;
133 unsigned int maple_nvram_command;
134 struct device_node *sp; 130 struct device_node *sp;
135 131
136 maple_nvram_base = maple_find_nvram_base(); 132 maple_nvram_base = maple_find_nvram_base();
@@ -143,14 +139,12 @@ static void maple_power_off(void)
143 printk(KERN_EMERG "Maple: Unable to find Service Processor\n"); 139 printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
144 goto fail; 140 goto fail;
145 } 141 }
146 maple_nvram_offset = *(unsigned int*) get_property(sp, 142 maple_nvram_offset = get_property(sp, "power-off-addr", NULL);
147 "power-off-addr", NULL); 143 maple_nvram_command = get_property(sp, "power-off-value", NULL);
148 maple_nvram_command = *(unsigned int*) get_property(sp,
149 "power-off-value", NULL);
150 of_node_put(sp); 144 of_node_put(sp);
151 145
152 /* send command */ 146 /* send command */
153 outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset); 147 outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);
154 for (;;) ; 148 for (;;) ;
155 fail: 149 fail:
156 printk(KERN_EMERG "Maple: Manual Power-Down Required\n"); 150 printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
@@ -211,7 +205,7 @@ static void __init maple_init_early(void)
211static void __init maple_init_IRQ(void) 205static void __init maple_init_IRQ(void)
212{ 206{
213 struct device_node *root, *np, *mpic_node = NULL; 207 struct device_node *root, *np, *mpic_node = NULL;
214 unsigned int *opprop; 208 const unsigned int *opprop;
215 unsigned long openpic_addr = 0; 209 unsigned long openpic_addr = 0;
216 int naddr, n, i, opplen, has_isus = 0; 210 int naddr, n, i, opplen, has_isus = 0;
217 struct mpic *mpic; 211 struct mpic *mpic;
@@ -241,8 +235,7 @@ static void __init maple_init_IRQ(void)
241 /* Find address list in /platform-open-pic */ 235 /* Find address list in /platform-open-pic */
242 root = of_find_node_by_path("/"); 236 root = of_find_node_by_path("/");
243 naddr = prom_n_addr_cells(root); 237 naddr = prom_n_addr_cells(root);
244 opprop = (unsigned int *) get_property(root, "platform-open-pic", 238 opprop = get_property(root, "platform-open-pic", &opplen);
245 &opplen);
246 if (opprop != 0) { 239 if (opprop != 0) {
247 openpic_addr = of_read_number(opprop, naddr); 240 openpic_addr = of_read_number(opprop, naddr);
248 has_isus = (opplen > naddr); 241 has_isus = (opplen > naddr);
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile
new file mode 100644
index 000000000000..1be1a993c5f5
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/Makefile
@@ -0,0 +1 @@
obj-y += setup.o pci.o time.o
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
new file mode 100644
index 000000000000..fd71d72736b2
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -0,0 +1,8 @@
1#ifndef _PASEMI_PASEMI_H
2#define _PASEMI_PASEMI_H
3
4extern unsigned long pas_get_boot_time(void);
5extern void pas_pci_init(void);
6extern void pas_pcibios_fixup(void);
7
8#endif /* _PASEMI_PASEMI_H */
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
new file mode 100644
index 000000000000..4679c5230413
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -0,0 +1,198 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Authors: Kip Walker, PA Semi
5 * Olof Johansson, PA Semi
6 *
7 * Maintained by: Olof Johansson <olof@lixom.net>
8 *
9 * Based on arch/powerpc/platforms/maple/pci.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25
26#include <linux/kernel.h>
27#include <linux/pci.h>
28
29#include <asm/pci-bridge.h>
30#include <asm/machdep.h>
31
32#include <asm/ppc-pci.h>
33
34#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
35
36#define CONFIG_OFFSET_VALID(off) ((off) < 4096)
37
38static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
39 u8 bus, u8 devfn, int offset)
40{
41 return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
42}
43
44static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
45 int offset, int len, u32 *val)
46{
47 struct pci_controller *hose;
48 unsigned long addr;
49
50 hose = pci_bus_to_host(bus);
51 if (!hose)
52 return PCIBIOS_DEVICE_NOT_FOUND;
53
54 if (!CONFIG_OFFSET_VALID(offset))
55 return PCIBIOS_BAD_REGISTER_NUMBER;
56
57 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
58
59 /*
60 * Note: the caller has already checked that offset is
61 * suitably aligned and that len is 1, 2 or 4.
62 */
63 switch (len) {
64 case 1:
65 *val = in_8((u8 *)addr);
66 break;
67 case 2:
68 *val = in_le16((u16 *)addr);
69 break;
70 default:
71 *val = in_le32((u32 *)addr);
72 break;
73 }
74
75 return PCIBIOS_SUCCESSFUL;
76}
77
78static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
79 int offset, int len, u32 val)
80{
81 struct pci_controller *hose;
82 unsigned long addr;
83
84 hose = pci_bus_to_host(bus);
85 if (!hose)
86 return PCIBIOS_DEVICE_NOT_FOUND;
87
88 if (!CONFIG_OFFSET_VALID(offset))
89 return PCIBIOS_BAD_REGISTER_NUMBER;
90
91 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
92
93 /*
94 * Note: the caller has already checked that offset is
95 * suitably aligned and that len is 1, 2 or 4.
96 */
97 switch (len) {
98 case 1:
99 out_8((u8 *)addr, val);
100 (void) in_8((u8 *)addr);
101 break;
102 case 2:
103 out_le16((u16 *)addr, val);
104 (void) in_le16((u16 *)addr);
105 break;
106 default:
107 out_le32((u32 *)addr, val);
108 (void) in_le32((u32 *)addr);
109 break;
110 }
111 return PCIBIOS_SUCCESSFUL;
112}
113
114static struct pci_ops pa_pxp_ops = {
115 pa_pxp_read_config,
116 pa_pxp_write_config,
117};
118
119static void __init setup_pa_pxp(struct pci_controller *hose)
120{
121 hose->ops = &pa_pxp_ops;
122 hose->cfg_data = ioremap(0xe0000000, 0x10000000);
123}
124
125static int __init add_bridge(struct device_node *dev)
126{
127 struct pci_controller *hose;
128
129 pr_debug("Adding PCI host bridge %s\n", dev->full_name);
130
131 hose = pcibios_alloc_controller(dev);
132 if (!hose)
133 return -ENOMEM;
134
135 hose->first_busno = 0;
136 hose->last_busno = 0xff;
137
138 setup_pa_pxp(hose);
139
140 printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
141
142 /* Interpret the "ranges" property */
143 /* This also maps the I/O region and sets isa_io/mem_base */
144 pci_process_bridge_OF_ranges(hose, dev, 1);
145 pci_setup_phb_io(hose, 1);
146
147 return 0;
148}
149
150
151void __init pas_pcibios_fixup(void)
152{
153 struct pci_dev *dev = NULL;
154
155 for_each_pci_dev(dev)
156 pci_read_irq_line(dev);
157}
158
159static void __init pas_fixup_phb_resources(void)
160{
161 struct pci_controller *hose, *tmp;
162
163 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
164 unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
165 hose->io_resource.start += offset;
166 hose->io_resource.end += offset;
167 printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
168 hose->global_number,
169 hose->io_resource.start, hose->io_resource.end);
170 }
171}
172
173
174void __init pas_pci_init(void)
175{
176 struct device_node *np, *root;
177
178 root = of_find_node_by_path("/");
179 if (!root) {
180 printk(KERN_CRIT "pas_pci_init: can't find root "
181 "of device tree\n");
182 return;
183 }
184
185 for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
186 if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
187 of_node_get(np);
188
189 of_node_put(root);
190
191 pas_fixup_phb_resources();
192
193 /* Setup the linkage between OF nodes and PHBs */
194 pci_devs_phb_init();
195
196 /* Use the common resource allocation mechanism */
197 pci_probe_only = 1;
198}
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
new file mode 100644
index 000000000000..628482671c15
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -0,0 +1,188 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Authors: Kip Walker, PA Semi
5 * Olof Johansson, PA Semi
6 *
7 * Maintained by: Olof Johansson <olof@lixom.net>
8 *
9 * Based on arch/powerpc/platforms/maple/setup.c
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/config.h>
26#include <linux/errno.h>
27#include <linux/kernel.h>
28#include <linux/delay.h>
29#include <linux/console.h>
30
31#include <asm/prom.h>
32#include <asm/system.h>
33#include <asm/iommu.h>
34#include <asm/machdep.h>
35#include <asm/mpic.h>
36#include <asm/smp.h>
37#include <asm/time.h>
38
39#include "pasemi.h"
40
41static void pas_restart(char *cmd)
42{
43 printk("restart unimplemented, looping...\n");
44 for (;;) ;
45}
46
47static void pas_power_off(void)
48{
49 printk("power off unimplemented, looping...\n");
50 for (;;) ;
51}
52
53static void pas_halt(void)
54{
55 pas_power_off();
56}
57
58#ifdef CONFIG_SMP
59struct smp_ops_t pas_smp_ops = {
60 .probe = smp_mpic_probe,
61 .message_pass = smp_mpic_message_pass,
62 .kick_cpu = smp_generic_kick_cpu,
63 .setup_cpu = smp_mpic_setup_cpu,
64 .give_timebase = smp_generic_give_timebase,
65 .take_timebase = smp_generic_take_timebase,
66};
67#endif /* CONFIG_SMP */
68
69void __init pas_setup_arch(void)
70{
71#ifdef CONFIG_SMP
72 /* Setup SMP callback */
73 smp_ops = &pas_smp_ops;
74#endif
75 /* Lookup PCI hosts */
76 pas_pci_init();
77
78#ifdef CONFIG_DUMMY_CONSOLE
79 conswitchp = &dummy_con;
80#endif
81
82 printk(KERN_DEBUG "Using default idle loop\n");
83}
84
85static void iommu_dev_setup_null(struct pci_dev *dev) { }
86static void iommu_bus_setup_null(struct pci_bus *bus) { }
87
88static void __init pas_init_early(void)
89{
90 /* No iommu code yet */
91 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
92 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
93 pci_direct_iommu_init();
94}
95
96/* No legacy IO on our parts */
97static int pas_check_legacy_ioport(unsigned int baseport)
98{
99 return -ENODEV;
100}
101
102static __init void pas_init_IRQ(void)
103{
104 struct device_node *np;
105 struct device_node *root, *mpic_node;
106 unsigned long openpic_addr;
107 const unsigned int *opprop;
108 int naddr, opplen;
109 struct mpic *mpic;
110
111 mpic_node = NULL;
112
113 for_each_node_by_type(np, "interrupt-controller")
114 if (device_is_compatible(np, "open-pic")) {
115 mpic_node = np;
116 break;
117 }
118 if (!mpic_node)
119 for_each_node_by_type(np, "open-pic") {
120 mpic_node = np;
121 break;
122 }
123 if (!mpic_node) {
124 printk(KERN_ERR
125 "Failed to locate the MPIC interrupt controller\n");
126 return;
127 }
128
129 /* Find address list in /platform-open-pic */
130 root = of_find_node_by_path("/");
131 naddr = prom_n_addr_cells(root);
132 opprop = get_property(root, "platform-open-pic", &opplen);
133 if (!opprop) {
134 printk(KERN_ERR "No platform-open-pic property.\n");
135 of_node_put(root);
136 return;
137 }
138 openpic_addr = of_read_number(opprop, naddr);
139 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
140 of_node_put(root);
141
142 mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0,
143 " PAS-OPIC ");
144 BUG_ON(!mpic);
145
146 mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
147 mpic_init(mpic);
148 of_node_put(mpic_node);
149 of_node_put(root);
150}
151
152static void __init pas_progress(char *s, unsigned short hex)
153{
154 printk("[%04x] : %s\n", hex, s ? s : "");
155}
156
157
158/*
159 * Called very early, MMU is off, device-tree isn't unflattened
160 */
161static int __init pas_probe(void)
162{
163 unsigned long root = of_get_flat_dt_root();
164
165 if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
166 return 0;
167
168 hpte_init_native();
169
170 return 1;
171}
172
173define_machine(pas) {
174 .name = "PA Semi PA6T-1682M",
175 .probe = pas_probe,
176 .setup_arch = pas_setup_arch,
177 .init_early = pas_init_early,
178 .init_IRQ = pas_init_IRQ,
179 .get_irq = mpic_get_irq,
180 .pcibios_fixup = pas_pcibios_fixup,
181 .restart = pas_restart,
182 .power_off = pas_power_off,
183 .halt = pas_halt,
184 .get_boot_time = pas_get_boot_time,
185 .calibrate_decr = generic_calibrate_decr,
186 .check_legacy_ioport = pas_check_legacy_ioport,
187 .progress = pas_progress,
188};
diff --git a/arch/powerpc/platforms/pasemi/time.c b/arch/powerpc/platforms/pasemi/time.c
new file mode 100644
index 000000000000..9bd410b8fec6
--- /dev/null
+++ b/arch/powerpc/platforms/pasemi/time.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2006 PA Semi, Inc
3 *
4 * Maintained by: Olof Johansson <olof@lixom.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/config.h>
21#include <linux/time.h>
22
23#include <asm/time.h>
24
25unsigned long __init pas_get_boot_time(void)
26{
27 /* Let's just return a fake date right now */
28 return mktime(2006, 1, 1, 12, 0, 0);
29}
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index d66415491055..afa593a8544a 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -60,7 +60,8 @@ int pmac_has_backlight_type(const char *type)
60 struct device_node* bk_node = find_devices("backlight"); 60 struct device_node* bk_node = find_devices("backlight");
61 61
62 if (bk_node) { 62 if (bk_node) {
63 char *prop = get_property(bk_node, "backlight-control", NULL); 63 const char *prop = get_property(bk_node,
64 "backlight-control", NULL);
64 if (prop && strncmp(prop, type, strlen(type)) == 0) 65 if (prop && strncmp(prop, type, strlen(type)) == 0)
65 return 1; 66 return 1;
66 } 67 }
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 62926248bdb8..c2b6b4134f68 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -421,7 +421,7 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
421 421
422static u32 read_gpio(struct device_node *np) 422static u32 read_gpio(struct device_node *np)
423{ 423{
424 u32 *reg = (u32 *)get_property(np, "reg", NULL); 424 const u32 *reg = get_property(np, "reg", NULL);
425 u32 offset; 425 u32 offset;
426 426
427 if (reg == NULL) 427 if (reg == NULL)
@@ -497,7 +497,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
497 "frequency-gpio"); 497 "frequency-gpio");
498 struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, 498 struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
499 "slewing-done"); 499 "slewing-done");
500 u32 *value; 500 const u32 *value;
501 501
502 /* 502 /*
503 * Check to see if it's GPIO driven or PMU only 503 * Check to see if it's GPIO driven or PMU only
@@ -519,15 +519,15 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
519 */ 519 */
520 if (frequency_gpio && slew_done_gpio) { 520 if (frequency_gpio && slew_done_gpio) {
521 int lenp, rc; 521 int lenp, rc;
522 u32 *freqs, *ratio; 522 const u32 *freqs, *ratio;
523 523
524 freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp); 524 freqs = get_property(cpunode, "bus-frequencies", &lenp);
525 lenp /= sizeof(u32); 525 lenp /= sizeof(u32);
526 if (freqs == NULL || lenp != 2) { 526 if (freqs == NULL || lenp != 2) {
527 printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n"); 527 printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
528 return 1; 528 return 1;
529 } 529 }
530 ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL); 530 ratio = get_property(cpunode, "processor-to-bus-ratio*2", NULL);
531 if (ratio == NULL) { 531 if (ratio == NULL) {
532 printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n"); 532 printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
533 return 1; 533 return 1;
@@ -562,7 +562,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
562 /* If we use the PMU, look for the min & max frequencies in the 562 /* If we use the PMU, look for the min & max frequencies in the
563 * device-tree 563 * device-tree
564 */ 564 */
565 value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL); 565 value = get_property(cpunode, "min-clock-frequency", NULL);
566 if (!value) 566 if (!value)
567 return 1; 567 return 1;
568 low_freq = (*value) / 1000; 568 low_freq = (*value) / 1000;
@@ -571,7 +571,7 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
571 if (low_freq < 100000) 571 if (low_freq < 100000)
572 low_freq *= 10; 572 low_freq *= 10;
573 573
574 value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL); 574 value = get_property(cpunode, "max-clock-frequency", NULL);
575 if (!value) 575 if (!value)
576 return 1; 576 return 1;
577 hi_freq = (*value) / 1000; 577 hi_freq = (*value) / 1000;
@@ -611,13 +611,14 @@ static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
611static int pmac_cpufreq_init_750FX(struct device_node *cpunode) 611static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
612{ 612{
613 struct device_node *volt_gpio_np; 613 struct device_node *volt_gpio_np;
614 u32 pvr, *value; 614 u32 pvr;
615 const u32 *value;
615 616
616 if (get_property(cpunode, "dynamic-power-step", NULL) == NULL) 617 if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
617 return 1; 618 return 1;
618 619
619 hi_freq = cur_freq; 620 hi_freq = cur_freq;
620 value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL); 621 value = get_property(cpunode, "reduced-clock-frequency", NULL);
621 if (!value) 622 if (!value)
622 return 1; 623 return 1;
623 low_freq = (*value) / 1000; 624 low_freq = (*value) / 1000;
@@ -650,7 +651,7 @@ static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
650static int __init pmac_cpufreq_setup(void) 651static int __init pmac_cpufreq_setup(void)
651{ 652{
652 struct device_node *cpunode; 653 struct device_node *cpunode;
653 u32 *value; 654 const u32 *value;
654 655
655 if (strstr(cmd_line, "nocpufreq")) 656 if (strstr(cmd_line, "nocpufreq"))
656 return 0; 657 return 0;
@@ -661,7 +662,7 @@ static int __init pmac_cpufreq_setup(void)
661 goto out; 662 goto out;
662 663
663 /* Get current cpu clock freq */ 664 /* Get current cpu clock freq */
664 value = (u32 *)get_property(cpunode, "clock-frequency", NULL); 665 value = get_property(cpunode, "clock-frequency", NULL);
665 if (!value) 666 if (!value)
666 goto out; 667 goto out;
667 cur_freq = (*value) / 1000; 668 cur_freq = (*value) / 1000;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 7b1156ea5341..d30466d74194 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -89,7 +89,7 @@ static DEFINE_MUTEX(g5_switch_mutex);
89 89
90#ifdef CONFIG_PMAC_SMU 90#ifdef CONFIG_PMAC_SMU
91 91
92static u32 *g5_pmode_data; 92static const u32 *g5_pmode_data;
93static int g5_pmode_max; 93static int g5_pmode_max;
94 94
95static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ 95static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
@@ -391,7 +391,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
391 unsigned int psize, ssize; 391 unsigned int psize, ssize;
392 unsigned long max_freq; 392 unsigned long max_freq;
393 char *freq_method, *volt_method; 393 char *freq_method, *volt_method;
394 u32 *valp, pvr_hi; 394 const u32 *valp;
395 u32 pvr_hi;
395 int use_volts_vdnap = 0; 396 int use_volts_vdnap = 0;
396 int use_volts_smu = 0; 397 int use_volts_smu = 0;
397 int rc = -ENODEV; 398 int rc = -ENODEV;
@@ -409,8 +410,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
409 /* Get first CPU node */ 410 /* Get first CPU node */
410 for (cpunode = NULL; 411 for (cpunode = NULL;
411 (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { 412 (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
412 u32 *reg = 413 const u32 *reg = get_property(cpunode, "reg", NULL);
413 (u32 *)get_property(cpunode, "reg", NULL);
414 if (reg == NULL || (*reg) != 0) 414 if (reg == NULL || (*reg) != 0)
415 continue; 415 continue;
416 if (!strcmp(cpunode->type, "cpu")) 416 if (!strcmp(cpunode->type, "cpu"))
@@ -422,7 +422,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
422 } 422 }
423 423
424 /* Check 970FX for now */ 424 /* Check 970FX for now */
425 valp = (u32 *)get_property(cpunode, "cpu-version", NULL); 425 valp = get_property(cpunode, "cpu-version", NULL);
426 if (!valp) { 426 if (!valp) {
427 DBG("No cpu-version property !\n"); 427 DBG("No cpu-version property !\n");
428 goto bail_noprops; 428 goto bail_noprops;
@@ -434,7 +434,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
434 } 434 }
435 435
436 /* Look for the powertune data in the device-tree */ 436 /* Look for the powertune data in the device-tree */
437 g5_pmode_data = (u32 *)get_property(cpunode, "power-mode-data",&psize); 437 g5_pmode_data = get_property(cpunode, "power-mode-data",&psize);
438 if (!g5_pmode_data) { 438 if (!g5_pmode_data) {
439 DBG("No power-mode-data !\n"); 439 DBG("No power-mode-data !\n");
440 goto bail_noprops; 440 goto bail_noprops;
@@ -442,7 +442,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
442 g5_pmode_max = psize / sizeof(u32) - 1; 442 g5_pmode_max = psize / sizeof(u32) - 1;
443 443
444 if (use_volts_smu) { 444 if (use_volts_smu) {
445 struct smu_sdbp_header *shdr; 445 const struct smu_sdbp_header *shdr;
446 446
447 /* Look for the FVT table */ 447 /* Look for the FVT table */
448 shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL); 448 shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
@@ -493,7 +493,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
493 * half freq in this version. So far, I haven't yet seen a machine 493 * half freq in this version. So far, I haven't yet seen a machine
494 * supporting anything else. 494 * supporting anything else.
495 */ 495 */
496 valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); 496 valp = get_property(cpunode, "clock-frequency", NULL);
497 if (!valp) 497 if (!valp)
498 return -ENODEV; 498 return -ENODEV;
499 max_freq = (*valp)/1000; 499 max_freq = (*valp)/1000;
@@ -541,8 +541,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
541static int __init g5_pm72_cpufreq_init(struct device_node *cpus) 541static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
542{ 542{
543 struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; 543 struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
544 u8 *eeprom = NULL; 544 const u8 *eeprom = NULL;
545 u32 *valp; 545 const u32 *valp;
546 u64 max_freq, min_freq, ih, il; 546 u64 max_freq, min_freq, ih, il;
547 int has_volt = 1, rc = 0; 547 int has_volt = 1, rc = 0;
548 548
@@ -563,7 +563,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
563 /* Lookup the cpuid eeprom node */ 563 /* Lookup the cpuid eeprom node */
564 cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); 564 cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
565 if (cpuid != NULL) 565 if (cpuid != NULL)
566 eeprom = (u8 *)get_property(cpuid, "cpuid", NULL); 566 eeprom = get_property(cpuid, "cpuid", NULL);
567 if (eeprom == NULL) { 567 if (eeprom == NULL) {
568 printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n"); 568 printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
569 rc = -ENODEV; 569 rc = -ENODEV;
@@ -573,7 +573,8 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
573 /* Lookup the i2c hwclock */ 573 /* Lookup the i2c hwclock */
574 for (hwclock = NULL; 574 for (hwclock = NULL;
575 (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){ 575 (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
576 char *loc = get_property(hwclock, "hwctrl-location", NULL); 576 const char *loc = get_property(hwclock,
577 "hwctrl-location", NULL);
577 if (loc == NULL) 578 if (loc == NULL)
578 continue; 579 continue;
579 if (strcmp(loc, "CPU CLOCK")) 580 if (strcmp(loc, "CPU CLOCK"))
@@ -637,7 +638,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
637 */ 638 */
638 639
639 /* Get max frequency from device-tree */ 640 /* Get max frequency from device-tree */
640 valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); 641 valp = get_property(cpunode, "clock-frequency", NULL);
641 if (!valp) { 642 if (!valp) {
642 printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n"); 643 printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
643 rc = -ENODEV; 644 rc = -ENODEV;
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index f8313bf9a9f7..e49621be6640 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1058,8 +1058,8 @@ core99_reset_cpu(struct device_node *node, long param, long value)
1058 if (np == NULL) 1058 if (np == NULL)
1059 return -ENODEV; 1059 return -ENODEV;
1060 for (np = np->child; np != NULL; np = np->sibling) { 1060 for (np = np->child; np != NULL; np = np->sibling) {
1061 u32 *num = (u32 *)get_property(np, "reg", NULL); 1061 const u32 *num = get_property(np, "reg", NULL);
1062 u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); 1062 const u32 *rst = get_property(np, "soft-reset", NULL);
1063 if (num == NULL || rst == NULL) 1063 if (num == NULL || rst == NULL)
1064 continue; 1064 continue;
1065 if (param == *num) { 1065 if (param == *num) {
@@ -1087,7 +1087,7 @@ core99_usb_enable(struct device_node *node, long param, long value)
1087{ 1087{
1088 struct macio_chip *macio; 1088 struct macio_chip *macio;
1089 unsigned long flags; 1089 unsigned long flags;
1090 char *prop; 1090 const char *prop;
1091 int number; 1091 int number;
1092 u32 reg; 1092 u32 reg;
1093 1093
@@ -1096,7 +1096,7 @@ core99_usb_enable(struct device_node *node, long param, long value)
1096 macio->type != macio_intrepid) 1096 macio->type != macio_intrepid)
1097 return -ENODEV; 1097 return -ENODEV;
1098 1098
1099 prop = (char *)get_property(node, "AAPL,clock-id", NULL); 1099 prop = get_property(node, "AAPL,clock-id", NULL);
1100 if (!prop) 1100 if (!prop)
1101 return -ENODEV; 1101 return -ENODEV;
1102 if (strncmp(prop, "usb0u048", 8) == 0) 1102 if (strncmp(prop, "usb0u048", 8) == 0)
@@ -1507,8 +1507,8 @@ static long g5_reset_cpu(struct device_node *node, long param, long value)
1507 if (np == NULL) 1507 if (np == NULL)
1508 return -ENODEV; 1508 return -ENODEV;
1509 for (np = np->child; np != NULL; np = np->sibling) { 1509 for (np = np->child; np != NULL; np = np->sibling) {
1510 u32 *num = (u32 *)get_property(np, "reg", NULL); 1510 const u32 *num = get_property(np, "reg", NULL);
1511 u32 *rst = (u32 *)get_property(np, "soft-reset", NULL); 1511 const u32 *rst = get_property(np, "soft-reset", NULL);
1512 if (num == NULL || rst == NULL) 1512 if (num == NULL || rst == NULL)
1513 continue; 1513 continue;
1514 if (param == *num) { 1514 if (param == *num) {
@@ -2408,7 +2408,7 @@ static int __init probe_motherboard(void)
2408 */ 2408 */
2409 dt = find_devices("device-tree"); 2409 dt = find_devices("device-tree");
2410 if (dt != NULL) 2410 if (dt != NULL)
2411 model = (const char *) get_property(dt, "model", NULL); 2411 model = get_property(dt, "model", NULL);
2412 for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) { 2412 for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
2413 if (strcmp(model, pmac_mb_defs[i].model_string) == 0) { 2413 if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
2414 pmac_mb = pmac_mb_defs[i]; 2414 pmac_mb = pmac_mb_defs[i];
@@ -2536,7 +2536,7 @@ found:
2536 */ 2536 */
2537static void __init probe_uninorth(void) 2537static void __init probe_uninorth(void)
2538{ 2538{
2539 u32 *addrp; 2539 const u32 *addrp;
2540 phys_addr_t address; 2540 phys_addr_t address;
2541 unsigned long actrl; 2541 unsigned long actrl;
2542 2542
@@ -2555,7 +2555,7 @@ static void __init probe_uninorth(void)
2555 if (uninorth_node == NULL) 2555 if (uninorth_node == NULL)
2556 return; 2556 return;
2557 2557
2558 addrp = (u32 *)get_property(uninorth_node, "reg", NULL); 2558 addrp = get_property(uninorth_node, "reg", NULL);
2559 if (addrp == NULL) 2559 if (addrp == NULL)
2560 return; 2560 return;
2561 address = of_translate_address(uninorth_node, addrp); 2561 address = of_translate_address(uninorth_node, addrp);
@@ -2596,7 +2596,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2596 struct device_node* node; 2596 struct device_node* node;
2597 int i; 2597 int i;
2598 volatile u32 __iomem *base; 2598 volatile u32 __iomem *base;
2599 u32 *addrp, *revp; 2599 const u32 *addrp, *revp;
2600 phys_addr_t addr; 2600 phys_addr_t addr;
2601 u64 size; 2601 u64 size;
2602 2602
@@ -2639,7 +2639,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2639 return; 2639 return;
2640 } 2640 }
2641 if (type == macio_keylargo || type == macio_keylargo2) { 2641 if (type == macio_keylargo || type == macio_keylargo2) {
2642 u32 *did = (u32 *)get_property(node, "device-id", NULL); 2642 const u32 *did = get_property(node, "device-id", NULL);
2643 if (*did == 0x00000025) 2643 if (*did == 0x00000025)
2644 type = macio_pangea; 2644 type = macio_pangea;
2645 if (*did == 0x0000003e) 2645 if (*did == 0x0000003e)
@@ -2652,7 +2652,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2652 macio_chips[i].base = base; 2652 macio_chips[i].base = base;
2653 macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON; 2653 macio_chips[i].flags = MACIO_FLAG_SCCB_ON | MACIO_FLAG_SCCB_ON;
2654 macio_chips[i].name = macio_names[type]; 2654 macio_chips[i].name = macio_names[type];
2655 revp = (u32 *)get_property(node, "revision-id", NULL); 2655 revp = get_property(node, "revision-id", NULL);
2656 if (revp) 2656 if (revp)
2657 macio_chips[i].rev = *revp; 2657 macio_chips[i].rev = *revp;
2658 printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n", 2658 printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
@@ -2695,15 +2695,15 @@ static void __init
2695initial_serial_shutdown(struct device_node *np) 2695initial_serial_shutdown(struct device_node *np)
2696{ 2696{
2697 int len; 2697 int len;
2698 struct slot_names_prop { 2698 const struct slot_names_prop {
2699 int count; 2699 int count;
2700 char name[1]; 2700 char name[1];
2701 } *slots; 2701 } *slots;
2702 char *conn; 2702 const char *conn;
2703 int port_type = PMAC_SCC_ASYNC; 2703 int port_type = PMAC_SCC_ASYNC;
2704 int modem = 0; 2704 int modem = 0;
2705 2705
2706 slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); 2706 slots = get_property(np, "slot-names", &len);
2707 conn = get_property(np, "AAPL,connector", &len); 2707 conn = get_property(np, "AAPL,connector", &len);
2708 if (conn && (strcmp(conn, "infrared") == 0)) 2708 if (conn && (strcmp(conn, "infrared") == 0))
2709 port_type = PMAC_SCC_IRDA; 2709 port_type = PMAC_SCC_IRDA;
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 8677f50c2586..c2c7cf75dd5f 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -477,7 +477,8 @@ static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
477static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) 477static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
478{ 478{
479 struct pmac_i2c_host_kw *host; 479 struct pmac_i2c_host_kw *host;
480 u32 *psteps, *prate, *addrp, steps; 480 const u32 *psteps, *prate, *addrp;
481 u32 steps;
481 482
482 host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); 483 host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL);
483 if (host == NULL) { 484 if (host == NULL) {
@@ -490,7 +491,7 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
490 * on all i2c keywest nodes so far ... we would have to fallback 491 * on all i2c keywest nodes so far ... we would have to fallback
491 * to macio parsing if that wasn't the case 492 * to macio parsing if that wasn't the case
492 */ 493 */
493 addrp = (u32 *)get_property(np, "AAPL,address", NULL); 494 addrp = get_property(np, "AAPL,address", NULL);
494 if (addrp == NULL) { 495 if (addrp == NULL) {
495 printk(KERN_ERR "low_i2c: Can't find address for %s\n", 496 printk(KERN_ERR "low_i2c: Can't find address for %s\n",
496 np->full_name); 497 np->full_name);
@@ -504,13 +505,13 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
504 host->timeout_timer.function = kw_i2c_timeout; 505 host->timeout_timer.function = kw_i2c_timeout;
505 host->timeout_timer.data = (unsigned long)host; 506 host->timeout_timer.data = (unsigned long)host;
506 507
507 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); 508 psteps = get_property(np, "AAPL,address-step", NULL);
508 steps = psteps ? (*psteps) : 0x10; 509 steps = psteps ? (*psteps) : 0x10;
509 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) 510 for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
510 steps >>= 1; 511 steps >>= 1;
511 /* Select interface rate */ 512 /* Select interface rate */
512 host->speed = KW_I2C_MODE_25KHZ; 513 host->speed = KW_I2C_MODE_25KHZ;
513 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); 514 prate = get_property(np, "AAPL,i2c-rate", NULL);
514 if (prate) switch(*prate) { 515 if (prate) switch(*prate) {
515 case 100: 516 case 100:
516 host->speed = KW_I2C_MODE_100KHZ; 517 host->speed = KW_I2C_MODE_100KHZ;
@@ -618,8 +619,8 @@ static void __init kw_i2c_probe(void)
618 } else { 619 } else {
619 for (child = NULL; 620 for (child = NULL;
620 (child = of_get_next_child(np, child)) != NULL;) { 621 (child = of_get_next_child(np, child)) != NULL;) {
621 u32 *reg = 622 const u32 *reg = get_property(child,
622 (u32 *)get_property(child, "reg", NULL); 623 "reg", NULL);
623 if (reg == NULL) 624 if (reg == NULL)
624 continue; 625 continue;
625 kw_i2c_add(host, np, child, *reg); 626 kw_i2c_add(host, np, child, *reg);
@@ -881,7 +882,7 @@ static void __init smu_i2c_probe(void)
881{ 882{
882 struct device_node *controller, *busnode; 883 struct device_node *controller, *busnode;
883 struct pmac_i2c_bus *bus; 884 struct pmac_i2c_bus *bus;
884 u32 *reg; 885 const u32 *reg;
885 int sz; 886 int sz;
886 887
887 if (!smu_present()) 888 if (!smu_present())
@@ -904,7 +905,7 @@ static void __init smu_i2c_probe(void)
904 if (strcmp(busnode->type, "i2c") && 905 if (strcmp(busnode->type, "i2c") &&
905 strcmp(busnode->type, "i2c-bus")) 906 strcmp(busnode->type, "i2c-bus"))
906 continue; 907 continue;
907 reg = (u32 *)get_property(busnode, "reg", NULL); 908 reg = get_property(busnode, "reg", NULL);
908 if (reg == NULL) 909 if (reg == NULL)
909 continue; 910 continue;
910 911
@@ -948,9 +949,8 @@ struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node)
948 list_for_each_entry(bus, &pmac_i2c_busses, link) { 949 list_for_each_entry(bus, &pmac_i2c_busses, link) {
949 if (p == bus->busnode) { 950 if (p == bus->busnode) {
950 if (prev && bus->flags & pmac_i2c_multibus) { 951 if (prev && bus->flags & pmac_i2c_multibus) {
951 u32 *reg; 952 const u32 *reg;
952 reg = (u32 *)get_property(prev, "reg", 953 reg = get_property(prev, "reg", NULL);
953 NULL);
954 if (!reg) 954 if (!reg)
955 continue; 955 continue;
956 if (((*reg) >> 8) != bus->channel) 956 if (((*reg) >> 8) != bus->channel)
@@ -971,7 +971,7 @@ EXPORT_SYMBOL_GPL(pmac_i2c_find_bus);
971 971
972u8 pmac_i2c_get_dev_addr(struct device_node *device) 972u8 pmac_i2c_get_dev_addr(struct device_node *device)
973{ 973{
974 u32 *reg = (u32 *)get_property(device, "reg", NULL); 974 const u32 *reg = get_property(device, "reg", NULL);
975 975
976 if (reg == NULL) 976 if (reg == NULL)
977 return 0; 977 return 0;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 205d04471161..9923adc5248e 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -66,16 +66,16 @@ struct device_node *k2_skiplist[2];
66static int __init fixup_one_level_bus_range(struct device_node *node, int higher) 66static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
67{ 67{
68 for (; node != 0;node = node->sibling) { 68 for (; node != 0;node = node->sibling) {
69 int * bus_range; 69 const int * bus_range;
70 unsigned int *class_code; 70 const unsigned int *class_code;
71 int len; 71 int len;
72 72
73 /* For PCI<->PCI bridges or CardBus bridges, we go down */ 73 /* For PCI<->PCI bridges or CardBus bridges, we go down */
74 class_code = (unsigned int *) get_property(node, "class-code", NULL); 74 class_code = get_property(node, "class-code", NULL);
75 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && 75 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
76 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) 76 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
77 continue; 77 continue;
78 bus_range = (int *) get_property(node, "bus-range", &len); 78 bus_range = get_property(node, "bus-range", &len);
79 if (bus_range != NULL && len > 2 * sizeof(int)) { 79 if (bus_range != NULL && len > 2 * sizeof(int)) {
80 if (bus_range[1] > higher) 80 if (bus_range[1] > higher)
81 higher = bus_range[1]; 81 higher = bus_range[1];
@@ -93,13 +93,15 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher
93 */ 93 */
94static void __init fixup_bus_range(struct device_node *bridge) 94static void __init fixup_bus_range(struct device_node *bridge)
95{ 95{
96 int * bus_range; 96 int *bus_range, len;
97 int len; 97 struct property *prop;
98 98
99 /* Lookup the "bus-range" property for the hose */ 99 /* Lookup the "bus-range" property for the hose */
100 bus_range = (int *) get_property(bridge, "bus-range", &len); 100 prop = of_find_property(bridge, "bus-range", &len);
101 if (bus_range == NULL || len < 2 * sizeof(int)) 101 if (prop == NULL || prop->length < 2 * sizeof(int))
102 return; 102 return;
103
104 bus_range = (int *)prop->value;
103 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); 105 bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
104} 106}
105 107
@@ -237,7 +239,7 @@ static struct pci_ops macrisc_pci_ops =
237static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) 239static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
238{ 240{
239 struct device_node *np; 241 struct device_node *np;
240 u32 *vendor, *device; 242 const u32 *vendor, *device;
241 243
242 if (offset >= 0x100) 244 if (offset >= 0x100)
243 return PCIBIOS_BAD_REGISTER_NUMBER; 245 return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -245,8 +247,8 @@ static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
245 if (np == NULL) 247 if (np == NULL)
246 return PCIBIOS_DEVICE_NOT_FOUND; 248 return PCIBIOS_DEVICE_NOT_FOUND;
247 249
248 vendor = (u32 *)get_property(np, "vendor-id", NULL); 250 vendor = get_property(np, "vendor-id", NULL);
249 device = (u32 *)get_property(np, "device-id", NULL); 251 device = get_property(np, "device-id", NULL);
250 if (vendor == NULL || device == NULL) 252 if (vendor == NULL || device == NULL)
251 return PCIBIOS_DEVICE_NOT_FOUND; 253 return PCIBIOS_DEVICE_NOT_FOUND;
252 254
@@ -686,20 +688,21 @@ static void __init fixup_nec_usb2(void)
686 688
687 for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) { 689 for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
688 struct pci_controller *hose; 690 struct pci_controller *hose;
689 u32 data, *prop; 691 u32 data;
692 const u32 *prop;
690 u8 bus, devfn; 693 u8 bus, devfn;
691 694
692 prop = (u32 *)get_property(nec, "vendor-id", NULL); 695 prop = get_property(nec, "vendor-id", NULL);
693 if (prop == NULL) 696 if (prop == NULL)
694 continue; 697 continue;
695 if (0x1033 != *prop) 698 if (0x1033 != *prop)
696 continue; 699 continue;
697 prop = (u32 *)get_property(nec, "device-id", NULL); 700 prop = get_property(nec, "device-id", NULL);
698 if (prop == NULL) 701 if (prop == NULL)
699 continue; 702 continue;
700 if (0x0035 != *prop) 703 if (0x0035 != *prop)
701 continue; 704 continue;
702 prop = (u32 *)get_property(nec, "reg", NULL); 705 prop = get_property(nec, "reg", NULL);
703 if (prop == NULL) 706 if (prop == NULL)
704 continue; 707 continue;
705 devfn = (prop[0] >> 8) & 0xff; 708 devfn = (prop[0] >> 8) & 0xff;
@@ -898,7 +901,7 @@ static int __init add_bridge(struct device_node *dev)
898 struct pci_controller *hose; 901 struct pci_controller *hose;
899 struct resource rsrc; 902 struct resource rsrc;
900 char *disp_name; 903 char *disp_name;
901 int *bus_range; 904 const int *bus_range;
902 int primary = 1, has_address = 0; 905 int primary = 1, has_address = 0;
903 906
904 DBG("Adding PCI host bridge %s\n", dev->full_name); 907 DBG("Adding PCI host bridge %s\n", dev->full_name);
@@ -907,7 +910,7 @@ static int __init add_bridge(struct device_node *dev)
907 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 910 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
908 911
909 /* Get bus range if any */ 912 /* Get bus range if any */
910 bus_range = (int *) get_property(dev, "bus-range", &len); 913 bus_range = get_property(dev, "bus-range", &len);
911 if (bus_range == NULL || len < 2 * sizeof(int)) { 914 if (bus_range == NULL || len < 2 * sizeof(int)) {
912 printk(KERN_WARNING "Can't get bus-range for %s, assume" 915 printk(KERN_WARNING "Can't get bus-range for %s, assume"
913 " bus 0\n", dev->full_name); 916 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index aacfa59595d1..ee3b223ab17a 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -114,7 +114,7 @@ static void macio_gpio_init_one(struct macio_chip *macio)
114 * we just create them all 114 * we just create them all
115 */ 115 */
116 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) { 116 for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) {
117 u32 *reg = (u32 *)get_property(gp, "reg", NULL); 117 const u32 *reg = get_property(gp, "reg", NULL);
118 unsigned long offset; 118 unsigned long offset;
119 if (reg == NULL) 119 if (reg == NULL)
120 continue; 120 continue;
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c
index b117adbf9571..7651f278615a 100644
--- a/arch/powerpc/platforms/powermac/pfunc_core.c
+++ b/arch/powerpc/platforms/powermac/pfunc_core.c
@@ -813,14 +813,15 @@ struct pmf_function *__pmf_find_function(struct device_node *target,
813 struct pmf_device *dev; 813 struct pmf_device *dev;
814 struct pmf_function *func, *result = NULL; 814 struct pmf_function *func, *result = NULL;
815 char fname[64]; 815 char fname[64];
816 u32 *prop, ph; 816 const u32 *prop;
817 u32 ph;
817 818
818 /* 819 /*
819 * Look for a "platform-*" function reference. If we can't find 820 * Look for a "platform-*" function reference. If we can't find
820 * one, then we fallback to a direct call attempt 821 * one, then we fallback to a direct call attempt
821 */ 822 */
822 snprintf(fname, 63, "platform-%s", name); 823 snprintf(fname, 63, "platform-%s", name);
823 prop = (u32 *)get_property(target, fname, NULL); 824 prop = get_property(target, fname, NULL);
824 if (prop == NULL) 825 if (prop == NULL)
825 goto find_it; 826 goto find_it;
826 ph = *prop; 827 ph = *prop;
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 31a9da769fa2..824a618396ab 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -116,7 +116,7 @@ extern struct smp_ops_t core99_smp_ops;
116static void pmac_show_cpuinfo(struct seq_file *m) 116static void pmac_show_cpuinfo(struct seq_file *m)
117{ 117{
118 struct device_node *np; 118 struct device_node *np;
119 char *pp; 119 const char *pp;
120 int plen; 120 int plen;
121 int mbmodel; 121 int mbmodel;
122 unsigned int mbflags; 122 unsigned int mbflags;
@@ -134,12 +134,12 @@ static void pmac_show_cpuinfo(struct seq_file *m)
134 seq_printf(m, "machine\t\t: "); 134 seq_printf(m, "machine\t\t: ");
135 np = of_find_node_by_path("/"); 135 np = of_find_node_by_path("/");
136 if (np != NULL) { 136 if (np != NULL) {
137 pp = (char *) get_property(np, "model", NULL); 137 pp = get_property(np, "model", NULL);
138 if (pp != NULL) 138 if (pp != NULL)
139 seq_printf(m, "%s\n", pp); 139 seq_printf(m, "%s\n", pp);
140 else 140 else
141 seq_printf(m, "PowerMac\n"); 141 seq_printf(m, "PowerMac\n");
142 pp = (char *) get_property(np, "compatible", &plen); 142 pp = get_property(np, "compatible", &plen);
143 if (pp != NULL) { 143 if (pp != NULL) {
144 seq_printf(m, "motherboard\t:"); 144 seq_printf(m, "motherboard\t:");
145 while (plen > 0) { 145 while (plen > 0) {
@@ -163,10 +163,8 @@ static void pmac_show_cpuinfo(struct seq_file *m)
163 if (np == NULL) 163 if (np == NULL)
164 np = of_find_node_by_type(NULL, "cache"); 164 np = of_find_node_by_type(NULL, "cache");
165 if (np != NULL) { 165 if (np != NULL) {
166 unsigned int *ic = (unsigned int *) 166 const unsigned int *ic = get_property(np, "i-cache-size", NULL);
167 get_property(np, "i-cache-size", NULL); 167 const unsigned int *dc = get_property(np, "d-cache-size", NULL);
168 unsigned int *dc = (unsigned int *)
169 get_property(np, "d-cache-size", NULL);
170 seq_printf(m, "L2 cache\t:"); 168 seq_printf(m, "L2 cache\t:");
171 has_l2cache = 1; 169 has_l2cache = 1;
172 if (get_property(np, "cache-unified", NULL) != 0 && dc) { 170 if (get_property(np, "cache-unified", NULL) != 0 && dc) {
@@ -254,7 +252,7 @@ static void __init l2cr_init(void)
254 if (np == 0) 252 if (np == 0)
255 np = find_type_devices("cpu"); 253 np = find_type_devices("cpu");
256 if (np != 0) { 254 if (np != 0) {
257 unsigned int *l2cr = (unsigned int *) 255 const unsigned int *l2cr =
258 get_property(np, "l2cr-value", NULL); 256 get_property(np, "l2cr-value", NULL);
259 if (l2cr != 0) { 257 if (l2cr != 0) {
260 ppc_override_l2cr = 1; 258 ppc_override_l2cr = 1;
@@ -277,7 +275,7 @@ static void __init l2cr_init(void)
277static void __init pmac_setup_arch(void) 275static void __init pmac_setup_arch(void)
278{ 276{
279 struct device_node *cpu, *ic; 277 struct device_node *cpu, *ic;
280 int *fp; 278 const int *fp;
281 unsigned long pvr; 279 unsigned long pvr;
282 280
283 pvr = PVR_VER(mfspr(SPRN_PVR)); 281 pvr = PVR_VER(mfspr(SPRN_PVR));
@@ -287,7 +285,7 @@ static void __init pmac_setup_arch(void)
287 loops_per_jiffy = 50000000 / HZ; 285 loops_per_jiffy = 50000000 / HZ;
288 cpu = of_find_node_by_type(NULL, "cpu"); 286 cpu = of_find_node_by_type(NULL, "cpu");
289 if (cpu != NULL) { 287 if (cpu != NULL) {
290 fp = (int *) get_property(cpu, "clock-frequency", NULL); 288 fp = get_property(cpu, "clock-frequency", NULL);
291 if (fp != NULL) { 289 if (fp != NULL) {
292 if (pvr >= 0x30 && pvr < 0x80) 290 if (pvr >= 0x30 && pvr < 0x80)
293 /* PPC970 etc. */ 291 /* PPC970 etc. */
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 827b7121ffb8..1949b657b092 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -548,7 +548,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
548 struct device_node *cc = NULL; 548 struct device_node *cc = NULL;
549 struct device_node *p; 549 struct device_node *p;
550 const char *name = NULL; 550 const char *name = NULL;
551 u32 *reg; 551 const u32 *reg;
552 int ok; 552 int ok;
553 553
554 /* Look for the clock chip */ 554 /* Look for the clock chip */
@@ -562,7 +562,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus)
562 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc); 562 pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
563 if (pmac_tb_clock_chip_host == NULL) 563 if (pmac_tb_clock_chip_host == NULL)
564 continue; 564 continue;
565 reg = (u32 *)get_property(cc, "reg", NULL); 565 reg = get_property(cc, "reg", NULL);
566 if (reg == NULL) 566 if (reg == NULL)
567 continue; 567 continue;
568 switch (*reg) { 568 switch (*reg) {
@@ -702,13 +702,12 @@ static void __init smp_core99_setup(int ncpus)
702 /* GPIO based HW sync on ppc32 Core99 */ 702 /* GPIO based HW sync on ppc32 Core99 */
703 if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) { 703 if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) {
704 struct device_node *cpu; 704 struct device_node *cpu;
705 u32 *tbprop = NULL; 705 const u32 *tbprop = NULL;
706 706
707 core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ 707 core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
708 cpu = of_find_node_by_type(NULL, "cpu"); 708 cpu = of_find_node_by_type(NULL, "cpu");
709 if (cpu != NULL) { 709 if (cpu != NULL) {
710 tbprop = (u32 *)get_property(cpu, "timebase-enable", 710 tbprop = get_property(cpu, "timebase-enable", NULL);
711 NULL);
712 if (tbprop) 711 if (tbprop)
713 core99_tb_gpio = *tbprop; 712 core99_tb_gpio = *tbprop;
714 of_node_put(cpu); 713 of_node_put(cpu);
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index 37e5b1eff911..ce1a235855f7 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -68,11 +68,11 @@ static unsigned char scc_inittab[] = {
68 68
69void udbg_scc_init(int force_scc) 69void udbg_scc_init(int force_scc)
70{ 70{
71 u32 *reg; 71 const u32 *reg;
72 unsigned long addr; 72 unsigned long addr;
73 struct device_node *stdout = NULL, *escc = NULL, *macio = NULL; 73 struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
74 struct device_node *ch, *ch_def = NULL, *ch_a = NULL; 74 struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
75 char *path; 75 const char *path;
76 int i, x; 76 int i, x;
77 77
78 escc = of_find_node_by_name(NULL, "escc"); 78 escc = of_find_node_by_name(NULL, "escc");
@@ -81,7 +81,7 @@ void udbg_scc_init(int force_scc)
81 macio = of_get_parent(escc); 81 macio = of_get_parent(escc);
82 if (macio == NULL) 82 if (macio == NULL)
83 goto bail; 83 goto bail;
84 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 84 path = get_property(of_chosen, "linux,stdout-path", NULL);
85 if (path != NULL) 85 if (path != NULL)
86 stdout = of_find_node_by_path(path); 86 stdout = of_find_node_by_path(path);
87 for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) { 87 for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
@@ -96,13 +96,13 @@ void udbg_scc_init(int force_scc)
96 ch = ch_def ? ch_def : ch_a; 96 ch = ch_def ? ch_def : ch_a;
97 97
98 /* Get address within mac-io ASIC */ 98 /* Get address within mac-io ASIC */
99 reg = (u32 *)get_property(escc, "reg", NULL); 99 reg = get_property(escc, "reg", NULL);
100 if (reg == NULL) 100 if (reg == NULL)
101 goto bail; 101 goto bail;
102 addr = reg[0]; 102 addr = reg[0];
103 103
104 /* Get address of mac-io PCI itself */ 104 /* Get address of mac-io PCI itself */
105 reg = (u32 *)get_property(macio, "assigned-addresses", NULL); 105 reg = get_property(macio, "assigned-addresses", NULL);
106 if (reg == NULL) 106 if (reg == NULL)
107 goto bail; 107 goto bail;
108 addr += reg[2]; 108 addr += reg[2];
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index e5e0ff466904..997243a91be8 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
12 12
13obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 13obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
14obj-$(CONFIG_HVCS) += hvcserver.o 14obj-$(CONFIG_HVCS) += hvcserver.o
15obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 32eaddfa5470..84bc8f7e17ef 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -449,7 +449,11 @@ EXPORT_SYMBOL(eeh_check_failure);
449/* ------------------------------------------------------------- */ 449/* ------------------------------------------------------------- */
450/* The code below deals with error recovery */ 450/* The code below deals with error recovery */
451 451
452/** Return negative value if a permanent error, else return 452/**
453 * eeh_slot_availability - returns error status of slot
454 * @pdn pci device node
455 *
456 * Return negative value if a permanent error, else return
453 * a number of milliseconds to wait until the PCI slot is 457 * a number of milliseconds to wait until the PCI slot is
454 * ready to be used. 458 * ready to be used.
455 */ 459 */
@@ -474,11 +478,42 @@ eeh_slot_availability(struct pci_dn *pdn)
474 478
475 printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", 479 printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n",
476 rc, rets[0], rets[1], rets[2]); 480 rc, rets[0], rets[1], rets[2]);
477 return -1; 481 return -2;
482}
483
484/**
485 * rtas_pci_enable - enable MMIO or DMA transfers for this slot
486 * @pdn pci device node
487 */
488
489int
490rtas_pci_enable(struct pci_dn *pdn, int function)
491{
492 int config_addr;
493 int rc;
494
495 /* Use PE configuration address, if present */
496 config_addr = pdn->eeh_config_addr;
497 if (pdn->eeh_pe_config_addr)
498 config_addr = pdn->eeh_pe_config_addr;
499
500 rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
501 config_addr,
502 BUID_HI(pdn->phb->buid),
503 BUID_LO(pdn->phb->buid),
504 function);
505
506 if (rc)
507 printk(KERN_WARNING "EEH: Cannot enable function %d, err=%d dn=%s\n",
508 function, rc, pdn->node->full_name);
509
510 return rc;
478} 511}
479 512
480/** rtas_pci_slot_reset raises/lowers the pci #RST line 513/**
481 * state: 1/0 to raise/lower the #RST 514 * rtas_pci_slot_reset - raises/lowers the pci #RST line
515 * @pdn pci device node
516 * @state: 1/0 to raise/lower the #RST
482 * 517 *
483 * Clear the EEH-frozen condition on a slot. This routine 518 * Clear the EEH-frozen condition on a slot. This routine
484 * asserts the PCI #RST line if the 'state' argument is '1', 519 * asserts the PCI #RST line if the 'state' argument is '1',
@@ -511,24 +546,21 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
511 BUID_HI(pdn->phb->buid), 546 BUID_HI(pdn->phb->buid),
512 BUID_LO(pdn->phb->buid), 547 BUID_LO(pdn->phb->buid),
513 state); 548 state);
514 if (rc) { 549 if (rc)
515 printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n", 550 printk (KERN_WARNING "EEH: Unable to reset the failed slot,"
551 " (%d) #RST=%d dn=%s\n",
516 rc, state, pdn->node->full_name); 552 rc, state, pdn->node->full_name);
517 return;
518 }
519} 553}
520 554
521/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second 555/**
522 * dn -- device node to be reset. 556 * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
557 * @pdn: pci device node to be reset.
523 * 558 *
524 * Return 0 if success, else a non-zero value. 559 * Return 0 if success, else a non-zero value.
525 */ 560 */
526 561
527int 562static void __rtas_set_slot_reset(struct pci_dn *pdn)
528rtas_set_slot_reset(struct pci_dn *pdn)
529{ 563{
530 int i, rc;
531
532 rtas_pci_slot_reset (pdn, 1); 564 rtas_pci_slot_reset (pdn, 1);
533 565
534 /* The PCI bus requires that the reset be held high for at least 566 /* The PCI bus requires that the reset be held high for at least
@@ -549,17 +581,33 @@ rtas_set_slot_reset(struct pci_dn *pdn)
549 * up traffic. */ 581 * up traffic. */
550#define PCI_BUS_SETTLE_TIME_MSEC 1800 582#define PCI_BUS_SETTLE_TIME_MSEC 1800
551 msleep (PCI_BUS_SETTLE_TIME_MSEC); 583 msleep (PCI_BUS_SETTLE_TIME_MSEC);
584}
585
586int rtas_set_slot_reset(struct pci_dn *pdn)
587{
588 int i, rc;
589
590 __rtas_set_slot_reset(pdn);
552 591
553 /* Now double check with the firmware to make sure the device is 592 /* Now double check with the firmware to make sure the device is
554 * ready to be used; if not, wait for recovery. */ 593 * ready to be used; if not, wait for recovery. */
555 for (i=0; i<10; i++) { 594 for (i=0; i<10; i++) {
556 rc = eeh_slot_availability (pdn); 595 rc = eeh_slot_availability (pdn);
557 if (rc < 0)
558 printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name);
559 if (rc == 0) 596 if (rc == 0)
560 return 0; 597 return 0;
561 if (rc < 0) 598
599 if (rc == -2) {
600 printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n",
601 i, pdn->node->full_name);
602 __rtas_set_slot_reset(pdn);
603 continue;
604 }
605
606 if (rc < 0) {
607 printk (KERN_ERR "EEH: unrecoverable slot failure %s\n",
608 pdn->node->full_name);
562 return -1; 609 return -1;
610 }
563 611
564 msleep (rc+100); 612 msleep (rc+100);
565 } 613 }
@@ -582,6 +630,8 @@ rtas_set_slot_reset(struct pci_dn *pdn)
582 630
583/** 631/**
584 * __restore_bars - Restore the Base Address Registers 632 * __restore_bars - Restore the Base Address Registers
633 * @pdn: pci device node
634 *
585 * Loads the PCI configuration space base address registers, 635 * Loads the PCI configuration space base address registers,
586 * the expansion ROM base address, the latency timer, and etc. 636 * the expansion ROM base address, the latency timer, and etc.
587 * from the saved values in the device node. 637 * from the saved values in the device node.
@@ -691,11 +741,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
691{ 741{
692 struct eeh_early_enable_info *info = data; 742 struct eeh_early_enable_info *info = data;
693 int ret; 743 int ret;
694 char *status = get_property(dn, "status", NULL); 744 const char *status = get_property(dn, "status", NULL);
695 u32 *class_code = (u32 *)get_property(dn, "class-code", NULL); 745 const u32 *class_code = get_property(dn, "class-code", NULL);
696 u32 *vendor_id = (u32 *)get_property(dn, "vendor-id", NULL); 746 const u32 *vendor_id = get_property(dn, "vendor-id", NULL);
697 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); 747 const u32 *device_id = get_property(dn, "device-id", NULL);
698 u32 *regs; 748 const u32 *regs;
699 int enable; 749 int enable;
700 struct pci_dn *pdn = PCI_DN(dn); 750 struct pci_dn *pdn = PCI_DN(dn);
701 751
@@ -737,7 +787,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
737 787
738 /* Ok... see if this device supports EEH. Some do, some don't, 788 /* Ok... see if this device supports EEH. Some do, some don't,
739 * and the only way to find out is to check each and every one. */ 789 * and the only way to find out is to check each and every one. */
740 regs = (u32 *)get_property(dn, "reg", NULL); 790 regs = get_property(dn, "reg", NULL);
741 if (regs) { 791 if (regs) {
742 /* First register entry is addr (00BBSS00) */ 792 /* First register entry is addr (00BBSS00) */
743 /* Try to enable eeh */ 793 /* Try to enable eeh */
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index c37a8497c60f..b6b462d3c604 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -157,6 +157,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
157 if (!piar) 157 if (!piar)
158 return NULL; 158 return NULL;
159 159
160 pci_dev_get(dev);
160 piar->addr_lo = alo; 161 piar->addr_lo = alo;
161 piar->addr_hi = ahi; 162 piar->addr_hi = ahi;
162 piar->pcidev = dev; 163 piar->pcidev = dev;
@@ -178,7 +179,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
178 struct device_node *dn; 179 struct device_node *dn;
179 struct pci_dn *pdn; 180 struct pci_dn *pdn;
180 int i; 181 int i;
181 int inserted = 0;
182 182
183 dn = pci_device_to_OF_node(dev); 183 dn = pci_device_to_OF_node(dev);
184 if (!dn) { 184 if (!dn) {
@@ -197,9 +197,6 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
197 return; 197 return;
198 } 198 }
199 199
200 /* The cache holds a reference to the device... */
201 pci_dev_get(dev);
202
203 /* Walk resources on this device, poke them into the tree */ 200 /* Walk resources on this device, poke them into the tree */
204 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 201 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
205 unsigned long start = pci_resource_start(dev,i); 202 unsigned long start = pci_resource_start(dev,i);
@@ -212,12 +209,7 @@ static void __pci_addr_cache_insert_device(struct pci_dev *dev)
212 if (start == 0 || ~start == 0 || end == 0 || ~end == 0) 209 if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
213 continue; 210 continue;
214 pci_addr_cache_insert(dev, start, end, flags); 211 pci_addr_cache_insert(dev, start, end, flags);
215 inserted = 1;
216 } 212 }
217
218 /* If there was nothing to add, the cache has no reference... */
219 if (!inserted)
220 pci_dev_put(dev);
221} 213}
222 214
223/** 215/**
@@ -240,7 +232,6 @@ void pci_addr_cache_insert_device(struct pci_dev *dev)
240static inline void __pci_addr_cache_remove_device(struct pci_dev *dev) 232static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
241{ 233{
242 struct rb_node *n; 234 struct rb_node *n;
243 int removed = 0;
244 235
245restart: 236restart:
246 n = rb_first(&pci_io_addr_cache_root.rb_root); 237 n = rb_first(&pci_io_addr_cache_root.rb_root);
@@ -250,16 +241,12 @@ restart:
250 241
251 if (piar->pcidev == dev) { 242 if (piar->pcidev == dev) {
252 rb_erase(n, &pci_io_addr_cache_root.rb_root); 243 rb_erase(n, &pci_io_addr_cache_root.rb_root);
253 removed = 1; 244 pci_dev_put(piar->pcidev);
254 kfree(piar); 245 kfree(piar);
255 goto restart; 246 goto restart;
256 } 247 }
257 n = rb_next(n); 248 n = rb_next(n);
258 } 249 }
259
260 /* The cache no longer holds its reference to this device... */
261 if (removed)
262 pci_dev_put(dev);
263} 250}
264 251
265/** 252/**
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index aaad2c0afcbf..c2bc9904f1cb 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -77,8 +77,12 @@ static int irq_in_use(unsigned int irq)
77} 77}
78 78
79/* ------------------------------------------------------- */ 79/* ------------------------------------------------------- */
80/** eeh_report_error - report an EEH error to each device, 80/**
81 * collect up and merge the device responses. 81 * eeh_report_error - report pci error to each device driver
82 *
83 * Report an EEH error to each device driver, collect up and
84 * merge the device driver responses. Cumulative response
85 * passed back in "userdata".
82 */ 86 */
83 87
84static void eeh_report_error(struct pci_dev *dev, void *userdata) 88static void eeh_report_error(struct pci_dev *dev, void *userdata)
@@ -96,24 +100,49 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
96 PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED; 100 PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
97 disable_irq_nosync(dev->irq); 101 disable_irq_nosync(dev->irq);
98 } 102 }
99 if (!driver->err_handler) 103 if (!driver->err_handler ||
100 return; 104 !driver->err_handler->error_detected)
101 if (!driver->err_handler->error_detected)
102 return; 105 return;
103 106
104 rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); 107 rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
105 if (*res == PCI_ERS_RESULT_NONE) *res = rc; 108 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
106 if (*res == PCI_ERS_RESULT_NEED_RESET) return;
107 if (*res == PCI_ERS_RESULT_DISCONNECT && 109 if (*res == PCI_ERS_RESULT_DISCONNECT &&
108 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; 110 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
109} 111}
110 112
111/** eeh_report_reset -- tell this device that the pci slot 113/**
112 * has been reset. 114 * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
115 *
116 * Report an EEH error to each device driver, collect up and
117 * merge the device driver responses. Cumulative response
118 * passed back in "userdata".
119 */
120
121static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
122{
123 enum pci_ers_result rc, *res = userdata;
124 struct pci_driver *driver = dev->driver;
125
126 // dev->error_state = pci_channel_mmio_enabled;
127
128 if (!driver ||
129 !driver->err_handler ||
130 !driver->err_handler->mmio_enabled)
131 return;
132
133 rc = driver->err_handler->mmio_enabled (dev);
134 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
135 if (*res == PCI_ERS_RESULT_DISCONNECT &&
136 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
137}
138
139/**
140 * eeh_report_reset - tell device that slot has been reset
113 */ 141 */
114 142
115static void eeh_report_reset(struct pci_dev *dev, void *userdata) 143static void eeh_report_reset(struct pci_dev *dev, void *userdata)
116{ 144{
145 enum pci_ers_result rc, *res = userdata;
117 struct pci_driver *driver = dev->driver; 146 struct pci_driver *driver = dev->driver;
118 struct device_node *dn = pci_device_to_OF_node(dev); 147 struct device_node *dn = pci_device_to_OF_node(dev);
119 148
@@ -124,14 +153,20 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
124 PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; 153 PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
125 enable_irq(dev->irq); 154 enable_irq(dev->irq);
126 } 155 }
127 if (!driver->err_handler) 156 if (!driver->err_handler ||
128 return; 157 !driver->err_handler->slot_reset)
129 if (!driver->err_handler->slot_reset)
130 return; 158 return;
131 159
132 driver->err_handler->slot_reset(dev); 160 rc = driver->err_handler->slot_reset(dev);
161 if (*res == PCI_ERS_RESULT_NONE) *res = rc;
162 if (*res == PCI_ERS_RESULT_DISCONNECT &&
163 rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
133} 164}
134 165
166/**
167 * eeh_report_resume - tell device to resume normal operations
168 */
169
135static void eeh_report_resume(struct pci_dev *dev, void *userdata) 170static void eeh_report_resume(struct pci_dev *dev, void *userdata)
136{ 171{
137 struct pci_driver *driver = dev->driver; 172 struct pci_driver *driver = dev->driver;
@@ -148,6 +183,13 @@ static void eeh_report_resume(struct pci_dev *dev, void *userdata)
148 driver->err_handler->resume(dev); 183 driver->err_handler->resume(dev);
149} 184}
150 185
186/**
187 * eeh_report_failure - tell device driver that device is dead.
188 *
189 * This informs the device driver that the device is permanently
190 * dead, and that no further recovery attempts will be made on it.
191 */
192
151static void eeh_report_failure(struct pci_dev *dev, void *userdata) 193static void eeh_report_failure(struct pci_dev *dev, void *userdata)
152{ 194{
153 struct pci_driver *driver = dev->driver; 195 struct pci_driver *driver = dev->driver;
@@ -190,11 +232,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
190 232
191/** 233/**
192 * eeh_reset_device() -- perform actual reset of a pci slot 234 * eeh_reset_device() -- perform actual reset of a pci slot
193 * Args: bus: pointer to the pci bus structure corresponding 235 * @bus: pointer to the pci bus structure corresponding
194 * to the isolated slot. A non-null value will 236 * to the isolated slot. A non-null value will
195 * cause all devices under the bus to be removed 237 * cause all devices under the bus to be removed
196 * and then re-added. 238 * and then re-added.
197 * pe_dn: pointer to a "Partionable Endpoint" device node. 239 * @pe_dn: pointer to a "Partionable Endpoint" device node.
198 * This is the top-level structure on which pci 240 * This is the top-level structure on which pci
199 * bus resets can be performed. 241 * bus resets can be performed.
200 */ 242 */
@@ -268,14 +310,14 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
268 310
269 if (!frozen_dn) { 311 if (!frozen_dn) {
270 312
271 location = (char *) get_property(event->dn, "ibm,loc-code", NULL); 313 location = get_property(event->dn, "ibm,loc-code", NULL);
272 location = location ? location : "unknown"; 314 location = location ? location : "unknown";
273 printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " 315 printk(KERN_ERR "EEH: Error: Cannot find partition endpoint "
274 "for location=%s pci addr=%s\n", 316 "for location=%s pci addr=%s\n",
275 location, pci_name(event->dev)); 317 location, pci_name(event->dev));
276 return NULL; 318 return NULL;
277 } 319 }
278 location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL); 320 location = get_property(frozen_dn, "ibm,loc-code", NULL);
279 location = location ? location : "unknown"; 321 location = location ? location : "unknown";
280 322
281 /* There are two different styles for coming up with the PE. 323 /* There are two different styles for coming up with the PE.
@@ -347,23 +389,43 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
347 goto hard_fail; 389 goto hard_fail;
348 } 390 }
349 391
350 /* If any device called out for a reset, then reset the slot */ 392 /* If all devices reported they can proceed, then re-enable MMIO */
351 if (result == PCI_ERS_RESULT_NEED_RESET) { 393 if (result == PCI_ERS_RESULT_CAN_RECOVER) {
352 rc = eeh_reset_device(frozen_pdn, NULL); 394 rc = rtas_pci_enable(frozen_pdn, EEH_THAW_MMIO);
353 if (rc) 395
354 goto hard_fail; 396 if (rc) {
355 pci_walk_bus(frozen_bus, eeh_report_reset, NULL); 397 result = PCI_ERS_RESULT_NEED_RESET;
398 } else {
399 result = PCI_ERS_RESULT_NONE;
400 pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result);
401 }
356 } 402 }
357 403
358 /* If all devices reported they can proceed, the re-enable PIO */ 404 /* If all devices reported they can proceed, then re-enable DMA */
359 if (result == PCI_ERS_RESULT_CAN_RECOVER) { 405 if (result == PCI_ERS_RESULT_CAN_RECOVER) {
360 /* XXX Not supported; we brute-force reset the device */ 406 rc = rtas_pci_enable(frozen_pdn, EEH_THAW_DMA);
407
408 if (rc)
409 result = PCI_ERS_RESULT_NEED_RESET;
410 }
411
412 /* If any device has a hard failure, then shut off everything. */
413 if (result == PCI_ERS_RESULT_DISCONNECT)
414 goto hard_fail;
415
416 /* If any device called out for a reset, then reset the slot */
417 if (result == PCI_ERS_RESULT_NEED_RESET) {
361 rc = eeh_reset_device(frozen_pdn, NULL); 418 rc = eeh_reset_device(frozen_pdn, NULL);
362 if (rc) 419 if (rc)
363 goto hard_fail; 420 goto hard_fail;
364 pci_walk_bus(frozen_bus, eeh_report_reset, NULL); 421 result = PCI_ERS_RESULT_NONE;
422 pci_walk_bus(frozen_bus, eeh_report_reset, &result);
365 } 423 }
366 424
425 /* All devices should claim they have recovered by now. */
426 if (result != PCI_ERS_RESULT_RECOVERED)
427 goto hard_fail;
428
367 /* Tell all device drivers that they can resume operations */ 429 /* Tell all device drivers that they can resume operations */
368 pci_walk_bus(frozen_bus, eeh_report_resume, NULL); 430 pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
369 431
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index 45ccc687e57c..137077451316 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -124,11 +124,11 @@ int eeh_send_failure_event (struct device_node *dn,
124{ 124{
125 unsigned long flags; 125 unsigned long flags;
126 struct eeh_event *event; 126 struct eeh_event *event;
127 char *location; 127 const char *location;
128 128
129 if (!mem_init_done) { 129 if (!mem_init_done) {
130 printk(KERN_ERR "EEH: event during early boot not handled\n"); 130 printk(KERN_ERR "EEH: event during early boot not handled\n");
131 location = (char *) get_property(dn, "ibm,loc-code", NULL); 131 location = get_property(dn, "ibm,loc-code", NULL);
132 printk(KERN_ERR "EEH: device node = %s\n", dn->full_name); 132 printk(KERN_ERR "EEH: device node = %s\n", dn->full_name);
133 printk(KERN_ERR "EEH: PCI location = %s\n", location); 133 printk(KERN_ERR "EEH: PCI location = %s\n", location);
134 return 1; 134 return 1;
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index c01d8f0cbe6d..1c7b2baa5f73 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -68,7 +68,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
68void __init fw_feature_init(void) 68void __init fw_feature_init(void)
69{ 69{
70 struct device_node *dn; 70 struct device_node *dn;
71 char *hypertas, *s; 71 const char *hypertas, *s;
72 int len, i; 72 int len, i;
73 73
74 DBG(" -> fw_feature_init()\n"); 74 DBG(" -> fw_feature_init()\n");
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index c9ff547f9d25..c00cfed7af2c 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -1,7 +1,6 @@
1/* 1/*
2 * This file contains the generic code to perform a call to the 2 * This file contains the generic code to perform a call to the
3 * pSeries LPAR hypervisor. 3 * pSeries LPAR hypervisor.
4 * NOTE: this file will go away when we move to inline this work.
5 * 4 *
6 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
@@ -11,217 +10,153 @@
11#include <asm/hvcall.h> 10#include <asm/hvcall.h>
12#include <asm/processor.h> 11#include <asm/processor.h>
13#include <asm/ppc_asm.h> 12#include <asm/ppc_asm.h>
13#include <asm/asm-offsets.h>
14 14
15#define STK_PARM(i) (48 + ((i)-3)*8) 15#define STK_PARM(i) (48 + ((i)-3)*8)
16 16
17 .text 17#ifdef CONFIG_HCALL_STATS
18 18/*
19/* long plpar_hcall(unsigned long opcode, R3 19 * precall must preserve all registers. use unused STK_PARM()
20 unsigned long arg1, R4 20 * areas to save snapshots and opcode.
21 unsigned long arg2, R5
22 unsigned long arg3, R6
23 unsigned long arg4, R7
24 unsigned long *out1, R8
25 unsigned long *out2, R9
26 unsigned long *out3); R10
27 */ 21 */
28_GLOBAL(plpar_hcall) 22#define HCALL_INST_PRECALL \
29 HMT_MEDIUM 23 std r3,STK_PARM(r3)(r1); /* save opcode */ \
30 24 mftb r0; /* get timebase and */ \
31 mfcr r0 25 std r0,STK_PARM(r5)(r1); /* save for later */ \
32 26BEGIN_FTR_SECTION; \
33 std r8,STK_PARM(r8)(r1) /* Save out ptrs */ 27 mfspr r0,SPRN_PURR; /* get PURR and */ \
34 std r9,STK_PARM(r9)(r1) 28 std r0,STK_PARM(r6)(r1); /* save for later */ \
35 std r10,STK_PARM(r10)(r1) 29END_FTR_SECTION_IFCLR(CPU_FTR_PURR);
36 30
37 stw r0,8(r1) 31/*
38 32 * postcall is performed immediately before function return which
39 HVSC /* invoke the hypervisor */ 33 * allows liberal use of volatile registers.
40 34 */
41 lwz r0,8(r1) 35#define HCALL_INST_POSTCALL \
42 36 ld r4,STK_PARM(r3)(r1); /* validate opcode */ \
43 ld r8,STK_PARM(r8)(r1) /* Fetch r4-r6 ret args */ 37 cmpldi cr7,r4,MAX_HCALL_OPCODE; \
44 ld r9,STK_PARM(r9)(r1) 38 bgt- cr7,1f; \
45 ld r10,STK_PARM(r10)(r1) 39 \
46 std r4,0(r8) 40 /* get time and PURR snapshots after hcall */ \
47 std r5,0(r9) 41 mftb r7; /* timebase after */ \
48 std r6,0(r10) 42BEGIN_FTR_SECTION; \
49 43 mfspr r8,SPRN_PURR; /* PURR after */ \
50 mtcrf 0xff,r0 44 ld r6,STK_PARM(r6)(r1); /* PURR before */ \
51 blr /* return r3 = status */ 45 subf r6,r6,r8; /* delta */ \
46END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
47 ld r5,STK_PARM(r5)(r1); /* timebase before */ \
48 subf r5,r5,r7; /* time delta */ \
49 \
50 /* calculate address of stat structure r4 = opcode */ \
51 srdi r4,r4,2; /* index into array */ \
52 mulli r4,r4,HCALL_STAT_SIZE; \
53 LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
54 add r4,r4,r7; \
55 ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
56 add r4,r4,r7; \
57 \
58 /* update stats */ \
59 ld r7,HCALL_STAT_CALLS(r4); /* count */ \
60 addi r7,r7,1; \
61 std r7,HCALL_STAT_CALLS(r4); \
62 ld r7,HCALL_STAT_TB(r4); /* timebase */ \
63 add r7,r7,r5; \
64 std r7,HCALL_STAT_TB(r4); \
65BEGIN_FTR_SECTION; \
66 ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
67 add r7,r7,r6; \
68 std r7,HCALL_STAT_PURR(r4); \
69END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
701:
71#else
72#define HCALL_INST_PRECALL
73#define HCALL_INST_POSTCALL
74#endif
52 75
76 .text
53 77
54/* Simple interface with no output values (other than status) */
55_GLOBAL(plpar_hcall_norets) 78_GLOBAL(plpar_hcall_norets)
56 HMT_MEDIUM 79 HMT_MEDIUM
57 80
58 mfcr r0 81 mfcr r0
59 stw r0,8(r1) 82 stw r0,8(r1)
60 83
61 HVSC /* invoke the hypervisor */ 84 HCALL_INST_PRECALL
62
63 lwz r0,8(r1)
64 mtcrf 0xff,r0
65 blr /* return r3 = status */
66
67
68/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3
69 unsigned long arg1, R4
70 unsigned long arg2, R5
71 unsigned long arg3, R6
72 unsigned long arg4, R7
73 unsigned long arg5, R8
74 unsigned long arg6, R9
75 unsigned long arg7, R10
76 unsigned long arg8, 112(R1)
77 unsigned long *out1); 120(R1)
78 */
79_GLOBAL(plpar_hcall_8arg_2ret)
80 HMT_MEDIUM
81
82 mfcr r0
83 ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */
84 stw r0,8(r1)
85 85
86 HVSC /* invoke the hypervisor */ 86 HVSC /* invoke the hypervisor */
87 87
88 HCALL_INST_POSTCALL
89
88 lwz r0,8(r1) 90 lwz r0,8(r1)
89 ld r10,STK_PARM(r12)(r1) /* Fetch r4 ret arg */
90 std r4,0(r10)
91 mtcrf 0xff,r0 91 mtcrf 0xff,r0
92 blr /* return r3 = status */ 92 blr /* return r3 = status */
93 93
94 94_GLOBAL(plpar_hcall)
95/* long plpar_hcall_4out(unsigned long opcode, R3
96 unsigned long arg1, R4
97 unsigned long arg2, R5
98 unsigned long arg3, R6
99 unsigned long arg4, R7
100 unsigned long *out1, R8
101 unsigned long *out2, R9
102 unsigned long *out3, R10
103 unsigned long *out4); 112(R1)
104 */
105_GLOBAL(plpar_hcall_4out)
106 HMT_MEDIUM 95 HMT_MEDIUM
107 96
108 mfcr r0 97 mfcr r0
109 stw r0,8(r1) 98 stw r0,8(r1)
110 99
111 std r8,STK_PARM(r8)(r1) /* Save out ptrs */ 100 HCALL_INST_PRECALL
112 std r9,STK_PARM(r9)(r1)
113 std r10,STK_PARM(r10)(r1)
114
115 HVSC /* invoke the hypervisor */
116
117 lwz r0,8(r1)
118 101
119 ld r8,STK_PARM(r8)(r1) /* Fetch r4-r7 ret args */ 102 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
120 ld r9,STK_PARM(r9)(r1)
121 ld r10,STK_PARM(r10)(r1)
122 ld r11,STK_PARM(r11)(r1)
123 std r4,0(r8)
124 std r5,0(r9)
125 std r6,0(r10)
126 std r7,0(r11)
127 103
128 mtcrf 0xff,r0 104 mr r4,r5
129 blr /* return r3 = status */ 105 mr r5,r6
130 106 mr r6,r7
131/* plpar_hcall_7arg_7ret(unsigned long opcode, R3 107 mr r7,r8
132 unsigned long arg1, R4 108 mr r8,r9
133 unsigned long arg2, R5 109 mr r9,r10
134 unsigned long arg3, R6
135 unsigned long arg4, R7
136 unsigned long arg5, R8
137 unsigned long arg6, R9
138 unsigned long arg7, R10
139 unsigned long *out1, 112(R1)
140 unsigned long *out2, 110(R1)
141 unsigned long *out3, 108(R1)
142 unsigned long *out4, 106(R1)
143 unsigned long *out5, 104(R1)
144 unsigned long *out6, 102(R1)
145 unsigned long *out7); 100(R1)
146*/
147_GLOBAL(plpar_hcall_7arg_7ret)
148 HMT_MEDIUM
149
150 mfcr r0
151 stw r0,8(r1)
152 110
153 HVSC /* invoke the hypervisor */ 111 HVSC /* invoke the hypervisor */
154 112
155 lwz r0,8(r1) 113 ld r12,STK_PARM(r4)(r1)
114 std r4, 0(r12)
115 std r5, 8(r12)
116 std r6, 16(r12)
117 std r7, 24(r12)
156 118
157 ld r11,STK_PARM(r11)(r1) /* Fetch r4 ret arg */ 119 HCALL_INST_POSTCALL
158 std r4,0(r11)
159 ld r11,STK_PARM(r12)(r1) /* Fetch r5 ret arg */
160 std r5,0(r11)
161 ld r11,STK_PARM(r13)(r1) /* Fetch r6 ret arg */
162 std r6,0(r11)
163 ld r11,STK_PARM(r14)(r1) /* Fetch r7 ret arg */
164 std r7,0(r11)
165 ld r11,STK_PARM(r15)(r1) /* Fetch r8 ret arg */
166 std r8,0(r11)
167 ld r11,STK_PARM(r16)(r1) /* Fetch r9 ret arg */
168 std r9,0(r11)
169 ld r11,STK_PARM(r17)(r1) /* Fetch r10 ret arg */
170 std r10,0(r11)
171 120
121 lwz r0,8(r1)
172 mtcrf 0xff,r0 122 mtcrf 0xff,r0
173 123
174 blr /* return r3 = status */ 124 blr /* return r3 = status */
175 125
176/* plpar_hcall_9arg_9ret(unsigned long opcode, R3 126_GLOBAL(plpar_hcall9)
177 unsigned long arg1, R4
178 unsigned long arg2, R5
179 unsigned long arg3, R6
180 unsigned long arg4, R7
181 unsigned long arg5, R8
182 unsigned long arg6, R9
183 unsigned long arg7, R10
184 unsigned long arg8, 112(R1)
185 unsigned long arg9, 110(R1)
186 unsigned long *out1, 108(R1)
187 unsigned long *out2, 106(R1)
188 unsigned long *out3, 104(R1)
189 unsigned long *out4, 102(R1)
190 unsigned long *out5, 100(R1)
191 unsigned long *out6, 98(R1)
192 unsigned long *out7); 96(R1)
193 unsigned long *out8, 94(R1)
194 unsigned long *out9, 92(R1)
195*/
196_GLOBAL(plpar_hcall_9arg_9ret)
197 HMT_MEDIUM 127 HMT_MEDIUM
198 128
199 mfcr r0 129 mfcr r0
200 stw r0,8(r1) 130 stw r0,8(r1)
201 131
202 ld r11,STK_PARM(r11)(r1) /* put arg8 in R11 */ 132 HCALL_INST_PRECALL
203 ld r12,STK_PARM(r12)(r1) /* put arg9 in R12 */ 133
134 std r4,STK_PARM(r4)(r1) /* Save ret buffer */
135
136 mr r4,r5
137 mr r5,r6
138 mr r6,r7
139 mr r7,r8
140 mr r8,r9
141 mr r9,r10
142 ld r10,STK_PARM(r11)(r1) /* put arg7 in R10 */
143 ld r11,STK_PARM(r12)(r1) /* put arg8 in R11 */
144 ld r12,STK_PARM(r13)(r1) /* put arg9 in R12 */
204 145
205 HVSC /* invoke the hypervisor */ 146 HVSC /* invoke the hypervisor */
206 147
207 ld r0,STK_PARM(r13)(r1) /* Fetch r4 ret arg */ 148 ld r12,STK_PARM(r4)(r1)
208 stdx r4,r0,r0 149 std r4, 0(r12)
209 ld r0,STK_PARM(r14)(r1) /* Fetch r5 ret arg */ 150 std r5, 8(r12)
210 stdx r5,r0,r0 151 std r6, 16(r12)
211 ld r0,STK_PARM(r15)(r1) /* Fetch r6 ret arg */ 152 std r7, 24(r12)
212 stdx r6,r0,r0 153 std r8, 32(r12)
213 ld r0,STK_PARM(r16)(r1) /* Fetch r7 ret arg */ 154 std r9, 40(r12)
214 stdx r7,r0,r0 155 std r10,48(r12)
215 ld r0,STK_PARM(r17)(r1) /* Fetch r8 ret arg */ 156 std r11,56(r12)
216 stdx r8,r0,r0 157 std r12,64(r12)
217 ld r0,STK_PARM(r18)(r1) /* Fetch r9 ret arg */ 158
218 stdx r9,r0,r0 159 HCALL_INST_POSTCALL
219 ld r0,STK_PARM(r19)(r1) /* Fetch r10 ret arg */
220 stdx r10,r0,r0
221 ld r0,STK_PARM(r20)(r1) /* Fetch r11 ret arg */
222 stdx r11,r0,r0
223 ld r0,STK_PARM(r21)(r1) /* Fetch r12 ret arg */
224 stdx r12,r0,r0
225 160
226 lwz r0,8(r1) 161 lwz r0,8(r1)
227 mtcrf 0xff,r0 162 mtcrf 0xff,r0
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
new file mode 100644
index 000000000000..641e6511cf06
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (C) 2006 Mike Kravetz IBM Corporation
3 *
4 * Hypervisor Call Instrumentation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/percpu.h>
23#include <linux/debugfs.h>
24#include <linux/seq_file.h>
25#include <linux/cpumask.h>
26#include <asm/hvcall.h>
27#include <asm/firmware.h>
28#include <asm/cputable.h>
29
30DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
31
32/*
33 * Routines for displaying the statistics in debugfs
34 */
35static void *hc_start(struct seq_file *m, loff_t *pos)
36{
37 if ((int)*pos < HCALL_STAT_ARRAY_SIZE)
38 return (void *)(unsigned long)(*pos + 1);
39
40 return NULL;
41}
42
43static void *hc_next(struct seq_file *m, void *p, loff_t * pos)
44{
45 ++*pos;
46
47 return hc_start(m, pos);
48}
49
50static void hc_stop(struct seq_file *m, void *p)
51{
52}
53
54static int hc_show(struct seq_file *m, void *p)
55{
56 unsigned long h_num = (unsigned long)p;
57 struct hcall_stats *hs = (struct hcall_stats *)m->private;
58
59 if (hs[h_num].num_calls) {
60 if (!cpu_has_feature(CPU_FTR_PURR))
61 seq_printf(m, "%lu %lu %lu %lu\n", h_num<<2,
62 hs[h_num].num_calls,
63 hs[h_num].tb_total,
64 hs[h_num].purr_total);
65 else
66 seq_printf(m, "%lu %lu %lu\n", h_num<<2,
67 hs[h_num].num_calls,
68 hs[h_num].tb_total);
69 }
70
71 return 0;
72}
73
74static struct seq_operations hcall_inst_seq_ops = {
75 .start = hc_start,
76 .next = hc_next,
77 .stop = hc_stop,
78 .show = hc_show
79};
80
81static int hcall_inst_seq_open(struct inode *inode, struct file *file)
82{
83 int rc;
84 struct seq_file *seq;
85
86 rc = seq_open(file, &hcall_inst_seq_ops);
87 seq = file->private_data;
88 seq->private = file->f_dentry->d_inode->u.generic_ip;
89
90 return rc;
91}
92
93static struct file_operations hcall_inst_seq_fops = {
94 .open = hcall_inst_seq_open,
95 .read = seq_read,
96 .llseek = seq_lseek,
97 .release = seq_release,
98};
99
100#define HCALL_ROOT_DIR "hcall_inst"
101#define CPU_NAME_BUF_SIZE 32
102
103static int __init hcall_inst_init(void)
104{
105 struct dentry *hcall_root;
106 struct dentry *hcall_file;
107 char cpu_name_buf[CPU_NAME_BUF_SIZE];
108 int cpu;
109
110 if (!firmware_has_feature(FW_FEATURE_LPAR))
111 return 0;
112
113 hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
114 if (!hcall_root)
115 return -ENOMEM;
116
117 for_each_possible_cpu(cpu) {
118 snprintf(cpu_name_buf, CPU_NAME_BUF_SIZE, "cpu%d", cpu);
119 hcall_file = debugfs_create_file(cpu_name_buf, S_IRUGO,
120 hcall_root,
121 per_cpu(hcall_stats, cpu),
122 &hcall_inst_seq_fops);
123 if (!hcall_file)
124 return -ENOMEM;
125 }
126
127 return 0;
128}
129__initcall(hcall_inst_init);
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index a72a987f1d4d..3f6a89b09816 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <asm/hvcall.h> 28#include <asm/hvcall.h>
29#include <asm/hvconsole.h> 29#include <asm/hvconsole.h>
30#include "plpar_wrappers.h"
30 31
31/** 32/**
32 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper 33 * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
@@ -40,9 +41,9 @@ int hvc_get_chars(uint32_t vtermno, char *buf, int count)
40{ 41{
41 unsigned long got; 42 unsigned long got;
42 43
43 if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got, 44 if (plpar_get_term_char(vtermno, &got, buf) == H_SUCCESS)
44 (unsigned long *)buf, (unsigned long *)buf+1) == H_SUCCESS)
45 return got; 45 return got;
46
46 return 0; 47 return 0;
47} 48}
48 49
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index d67af2c65754..bbf2e34dc358 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -267,13 +267,12 @@ static void iommu_table_setparms(struct pci_controller *phb,
267 struct iommu_table *tbl) 267 struct iommu_table *tbl)
268{ 268{
269 struct device_node *node; 269 struct device_node *node;
270 unsigned long *basep; 270 const unsigned long *basep, *sizep;
271 unsigned int *sizep;
272 271
273 node = (struct device_node *)phb->arch_data; 272 node = (struct device_node *)phb->arch_data;
274 273
275 basep = (unsigned long *)get_property(node, "linux,tce-base", NULL); 274 basep = get_property(node, "linux,tce-base", NULL);
276 sizep = (unsigned int *)get_property(node, "linux,tce-size", NULL); 275 sizep = get_property(node, "linux,tce-size", NULL);
277 if (basep == NULL || sizep == NULL) { 276 if (basep == NULL || sizep == NULL) {
278 printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has " 277 printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has "
279 "missing tce entries !\n", dn->full_name); 278 "missing tce entries !\n", dn->full_name);
@@ -315,7 +314,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
315static void iommu_table_setparms_lpar(struct pci_controller *phb, 314static void iommu_table_setparms_lpar(struct pci_controller *phb,
316 struct device_node *dn, 315 struct device_node *dn,
317 struct iommu_table *tbl, 316 struct iommu_table *tbl,
318 unsigned char *dma_window) 317 const void *dma_window)
319{ 318{
320 unsigned long offset, size; 319 unsigned long offset, size;
321 320
@@ -415,7 +414,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
415 struct iommu_table *tbl; 414 struct iommu_table *tbl;
416 struct device_node *dn, *pdn; 415 struct device_node *dn, *pdn;
417 struct pci_dn *ppci; 416 struct pci_dn *ppci;
418 unsigned char *dma_window = NULL; 417 const void *dma_window = NULL;
419 418
420 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); 419 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
421 420
@@ -519,7 +518,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
519{ 518{
520 struct device_node *pdn, *dn; 519 struct device_node *pdn, *dn;
521 struct iommu_table *tbl; 520 struct iommu_table *tbl;
522 unsigned char *dma_window = NULL; 521 const void *dma_window = NULL;
523 struct pci_dn *pci; 522 struct pci_dn *pci;
524 523
525 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); 524 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 3aeb40699042..1820a0b0a8c6 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -48,13 +48,11 @@
48#define DBG_LOW(fmt...) do { } while(0) 48#define DBG_LOW(fmt...) do { } while(0)
49#endif 49#endif
50 50
51/* in pSeries_hvCall.S */ 51/* in hvCall.S */
52EXPORT_SYMBOL(plpar_hcall); 52EXPORT_SYMBOL(plpar_hcall);
53EXPORT_SYMBOL(plpar_hcall_4out); 53EXPORT_SYMBOL(plpar_hcall9);
54EXPORT_SYMBOL(plpar_hcall_norets); 54EXPORT_SYMBOL(plpar_hcall_norets);
55EXPORT_SYMBOL(plpar_hcall_8arg_2ret); 55
56EXPORT_SYMBOL(plpar_hcall_7arg_7ret);
57EXPORT_SYMBOL(plpar_hcall_9arg_9ret);
58extern void pSeries_find_serial_port(void); 56extern void pSeries_find_serial_port(void);
59 57
60 58
@@ -204,20 +202,20 @@ void __init udbg_init_debug_lpar(void)
204void __init find_udbg_vterm(void) 202void __init find_udbg_vterm(void)
205{ 203{
206 struct device_node *stdout_node; 204 struct device_node *stdout_node;
207 u32 *termno; 205 const u32 *termno;
208 char *name; 206 const char *name;
209 int add_console; 207 int add_console;
210 208
211 /* find the boot console from /chosen/stdout */ 209 /* find the boot console from /chosen/stdout */
212 if (!of_chosen) 210 if (!of_chosen)
213 return; 211 return;
214 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 212 name = get_property(of_chosen, "linux,stdout-path", NULL);
215 if (name == NULL) 213 if (name == NULL)
216 return; 214 return;
217 stdout_node = of_find_node_by_path(name); 215 stdout_node = of_find_node_by_path(name);
218 if (!stdout_node) 216 if (!stdout_node)
219 return; 217 return;
220 name = (char *)get_property(stdout_node, "name", NULL); 218 name = get_property(stdout_node, "name", NULL);
221 if (!name) { 219 if (!name) {
222 printk(KERN_WARNING "stdout node missing 'name' property!\n"); 220 printk(KERN_WARNING "stdout node missing 'name' property!\n");
223 goto out; 221 goto out;
@@ -228,7 +226,7 @@ void __init find_udbg_vterm(void)
228 /* Check if it's a virtual terminal */ 226 /* Check if it's a virtual terminal */
229 if (strncmp(name, "vty", 3) != 0) 227 if (strncmp(name, "vty", 3) != 0)
230 goto out; 228 goto out;
231 termno = (u32 *)get_property(stdout_node, "reg", NULL); 229 termno = get_property(stdout_node, "reg", NULL);
232 if (termno == NULL) 230 if (termno == NULL)
233 goto out; 231 goto out;
234 vtermno = termno[0]; 232 vtermno = termno[0];
@@ -254,18 +252,34 @@ out:
254void vpa_init(int cpu) 252void vpa_init(int cpu)
255{ 253{
256 int hwcpu = get_hard_smp_processor_id(cpu); 254 int hwcpu = get_hard_smp_processor_id(cpu);
257 unsigned long vpa = __pa(&lppaca[cpu]); 255 unsigned long addr;
258 long ret; 256 long ret;
259 257
260 if (cpu_has_feature(CPU_FTR_ALTIVEC)) 258 if (cpu_has_feature(CPU_FTR_ALTIVEC))
261 lppaca[cpu].vmxregs_in_use = 1; 259 lppaca[cpu].vmxregs_in_use = 1;
262 260
263 ret = register_vpa(hwcpu, vpa); 261 addr = __pa(&lppaca[cpu]);
262 ret = register_vpa(hwcpu, addr);
264 263
265 if (ret) 264 if (ret) {
266 printk(KERN_ERR "WARNING: vpa_init: VPA registration for " 265 printk(KERN_ERR "WARNING: vpa_init: VPA registration for "
267 "cpu %d (hw %d) of area %lx returns %ld\n", 266 "cpu %d (hw %d) of area %lx returns %ld\n",
268 cpu, hwcpu, vpa, ret); 267 cpu, hwcpu, addr, ret);
268 return;
269 }
270 /*
271 * PAPR says this feature is SLB-Buffer but firmware never
272 * reports that. All SPLPAR support SLB shadow buffer.
273 */
274 addr = __pa(&slb_shadow[cpu]);
275 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
276 ret = register_slb_shadow(hwcpu, addr);
277 if (ret)
278 printk(KERN_ERR
279 "WARNING: vpa_init: SLB shadow buffer "
280 "registration for cpu %d (hw %d) of area %lx "
281 "returns %ld\n", cpu, hwcpu, addr, ret);
282 }
269} 283}
270 284
271long pSeries_lpar_hpte_insert(unsigned long hpte_group, 285long pSeries_lpar_hpte_insert(unsigned long hpte_group,
@@ -277,7 +291,6 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
277 unsigned long flags; 291 unsigned long flags;
278 unsigned long slot; 292 unsigned long slot;
279 unsigned long hpte_v, hpte_r; 293 unsigned long hpte_v, hpte_r;
280 unsigned long dummy0, dummy1;
281 294
282 if (!(vflags & HPTE_V_BOLTED)) 295 if (!(vflags & HPTE_V_BOLTED))
283 DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " 296 DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
@@ -302,8 +315,7 @@ long pSeries_lpar_hpte_insert(unsigned long hpte_group,
302 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE)) 315 if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
303 hpte_r &= ~_PAGE_COHERENT; 316 hpte_r &= ~_PAGE_COHERENT;
304 317
305 lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v, 318 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
306 hpte_r, &slot, &dummy0, &dummy1);
307 if (unlikely(lpar_rc == H_PTEG_FULL)) { 319 if (unlikely(lpar_rc == H_PTEG_FULL)) {
308 if (!(vflags & HPTE_V_BOLTED)) 320 if (!(vflags & HPTE_V_BOLTED))
309 DBG_LOW(" full\n"); 321 DBG_LOW(" full\n");
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 18abfb1f4e24..64163cecdf93 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -123,13 +123,14 @@ static ssize_t pSeries_nvram_get_size(void)
123int __init pSeries_nvram_init(void) 123int __init pSeries_nvram_init(void)
124{ 124{
125 struct device_node *nvram; 125 struct device_node *nvram;
126 unsigned int *nbytes_p, proplen; 126 const unsigned int *nbytes_p;
127 unsigned int proplen;
127 128
128 nvram = of_find_node_by_type(NULL, "nvram"); 129 nvram = of_find_node_by_type(NULL, "nvram");
129 if (nvram == NULL) 130 if (nvram == NULL)
130 return -ENODEV; 131 return -ENODEV;
131 132
132 nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); 133 nbytes_p = get_property(nvram, "#bytes", &proplen);
133 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) 134 if (nbytes_p == NULL || proplen != sizeof(unsigned int))
134 return -EIO; 135 return -EIO;
135 136
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index e97e67f5e079..410a6bcc4ca0 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -60,7 +60,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
60static void __devinit check_s7a(void) 60static void __devinit check_s7a(void)
61{ 61{
62 struct device_node *root; 62 struct device_node *root;
63 char *model; 63 const char *model;
64 64
65 s7a_workaround = 0; 65 s7a_workaround = 0;
66 root = of_find_node_by_path("/"); 66 root = of_find_node_by_path("/");
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 3bd1b3e06003..3eb7b294d92f 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -5,20 +5,17 @@
5 5
6static inline long poll_pending(void) 6static inline long poll_pending(void)
7{ 7{
8 unsigned long dummy; 8 return plpar_hcall_norets(H_POLL_PENDING);
9 return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0, &dummy, &dummy, &dummy);
10} 9}
11 10
12static inline long prod_processor(void) 11static inline long prod_processor(void)
13{ 12{
14 plpar_hcall_norets(H_PROD); 13 return plpar_hcall_norets(H_PROD);
15 return 0;
16} 14}
17 15
18static inline long cede_processor(void) 16static inline long cede_processor(void)
19{ 17{
20 plpar_hcall_norets(H_CEDE); 18 return plpar_hcall_norets(H_CEDE);
21 return 0;
22} 19}
23 20
24static inline long vpa_call(unsigned long flags, unsigned long cpu, 21static inline long vpa_call(unsigned long flags, unsigned long cpu,
@@ -40,23 +37,59 @@ static inline long register_vpa(unsigned long cpu, unsigned long vpa)
40 return vpa_call(0x1, cpu, vpa); 37 return vpa_call(0x1, cpu, vpa);
41} 38}
42 39
40static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa)
41{
42 return vpa_call(0x7, cpu, vpa);
43}
44
45static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
46{
47 return vpa_call(0x3, cpu, vpa);
48}
49
43extern void vpa_init(int cpu); 50extern void vpa_init(int cpu);
44 51
52static inline long plpar_pte_enter(unsigned long flags,
53 unsigned long hpte_group, unsigned long hpte_v,
54 unsigned long hpte_r, unsigned long *slot)
55{
56 long rc;
57 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
58
59 rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
60
61 *slot = retbuf[0];
62
63 return rc;
64}
65
45static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex, 66static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
46 unsigned long avpn, unsigned long *old_pteh_ret, 67 unsigned long avpn, unsigned long *old_pteh_ret,
47 unsigned long *old_ptel_ret) 68 unsigned long *old_ptel_ret)
48{ 69{
49 unsigned long dummy; 70 long rc;
50 return plpar_hcall(H_REMOVE, flags, ptex, avpn, 0, old_pteh_ret, 71 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
51 old_ptel_ret, &dummy); 72
73 rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
74
75 *old_pteh_ret = retbuf[0];
76 *old_ptel_ret = retbuf[1];
77
78 return rc;
52} 79}
53 80
54static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, 81static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
55 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) 82 unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
56{ 83{
57 unsigned long dummy; 84 long rc;
58 return plpar_hcall(H_READ, flags, ptex, 0, 0, old_pteh_ret, 85 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
59 old_ptel_ret, &dummy); 86
87 rc = plpar_hcall(H_READ, retbuf, flags, ptex);
88
89 *old_pteh_ret = retbuf[0];
90 *old_ptel_ret = retbuf[1];
91
92 return rc;
60} 93}
61 94
62static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, 95static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
@@ -68,9 +101,14 @@ static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
68static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba, 101static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
69 unsigned long *tce_ret) 102 unsigned long *tce_ret)
70{ 103{
71 unsigned long dummy; 104 long rc;
72 return plpar_hcall(H_GET_TCE, liobn, ioba, 0, 0, tce_ret, &dummy, 105 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
73 &dummy); 106
107 rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
108
109 *tce_ret = retbuf[0];
110
111 return rc;
74} 112}
75 113
76static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba, 114static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
@@ -94,9 +132,17 @@ static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
94static inline long plpar_get_term_char(unsigned long termno, 132static inline long plpar_get_term_char(unsigned long termno,
95 unsigned long *len_ret, char *buf_ret) 133 unsigned long *len_ret, char *buf_ret)
96{ 134{
135 long rc;
136 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
97 unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */ 137 unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */
98 return plpar_hcall(H_GET_TERM_CHAR, termno, 0, 0, 0, len_ret, 138
99 lbuf + 0, lbuf + 1); 139 rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
140
141 *len_ret = retbuf[0];
142 lbuf[0] = retbuf[1];
143 lbuf[1] = retbuf[2];
144
145 return rc;
100} 146}
101 147
102static inline long plpar_put_term_char(unsigned long termno, unsigned long len, 148static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
@@ -107,4 +153,31 @@ static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
107 lbuf[1]); 153 lbuf[1]);
108} 154}
109 155
156static inline long plpar_eoi(unsigned long xirr)
157{
158 return plpar_hcall_norets(H_EOI, xirr);
159}
160
161static inline long plpar_cppr(unsigned long cppr)
162{
163 return plpar_hcall_norets(H_CPPR, cppr);
164}
165
166static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
167{
168 return plpar_hcall_norets(H_IPI, servernum, mfrr);
169}
170
171static inline long plpar_xirr(unsigned long *xirr_ret)
172{
173 long rc;
174 unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
175
176 rc = plpar_hcall(H_XIRR, retbuf);
177
178 *xirr_ret = retbuf[0];
179
180 return rc;
181}
182
110#endif /* _PSERIES_PLPAR_WRAPPERS_H */ 183#endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index c7ffde1a614e..903115d67fdc 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -79,7 +79,7 @@ static void request_ras_irqs(struct device_node *np,
79{ 79{
80 int i, index, count = 0; 80 int i, index, count = 0;
81 struct of_irq oirq; 81 struct of_irq oirq;
82 u32 *opicprop; 82 const u32 *opicprop;
83 unsigned int opicplen; 83 unsigned int opicplen;
84 unsigned int virqs[16]; 84 unsigned int virqs[16];
85 85
@@ -87,7 +87,7 @@ static void request_ras_irqs(struct device_node *np,
87 * map those interrupts using the default interrupt host and default 87 * map those interrupts using the default interrupt host and default
88 * trigger 88 * trigger
89 */ 89 */
90 opicprop = (u32 *)get_property(np, "open-pic-interrupt", &opicplen); 90 opicprop = get_property(np, "open-pic-interrupt", &opicplen);
91 if (opicprop) { 91 if (opicprop) {
92 opicplen /= sizeof(u32); 92 opicplen /= sizeof(u32);
93 for (i = 0; i < opicplen; i++) { 93 for (i = 0; i < opicplen; i++) {
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index 2e4e04042d85..8ca2612221d6 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -359,11 +359,11 @@ static int enable_surveillance(int timeout)
359static int get_eventscan_parms(void) 359static int get_eventscan_parms(void)
360{ 360{
361 struct device_node *node; 361 struct device_node *node;
362 int *ip; 362 const int *ip;
363 363
364 node = of_find_node_by_path("/rtas"); 364 node = of_find_node_by_path("/rtas");
365 365
366 ip = (int *)get_property(node, "rtas-event-scan-rate", NULL); 366 ip = get_property(node, "rtas-event-scan-rate", NULL);
367 if (ip == NULL) { 367 if (ip == NULL) {
368 printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n"); 368 printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n");
369 of_node_put(node); 369 of_node_put(node);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 31867a701fcb..a6398fbe530d 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -133,9 +133,9 @@ void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc,
133static void __init pseries_mpic_init_IRQ(void) 133static void __init pseries_mpic_init_IRQ(void)
134{ 134{
135 struct device_node *np, *old, *cascade = NULL; 135 struct device_node *np, *old, *cascade = NULL;
136 unsigned int *addrp; 136 const unsigned int *addrp;
137 unsigned long intack = 0; 137 unsigned long intack = 0;
138 unsigned int *opprop; 138 const unsigned int *opprop;
139 unsigned long openpic_addr = 0; 139 unsigned long openpic_addr = 0;
140 unsigned int cascade_irq; 140 unsigned int cascade_irq;
141 int naddr, n, i, opplen; 141 int naddr, n, i, opplen;
@@ -143,7 +143,7 @@ static void __init pseries_mpic_init_IRQ(void)
143 143
144 np = of_find_node_by_path("/"); 144 np = of_find_node_by_path("/");
145 naddr = prom_n_addr_cells(np); 145 naddr = prom_n_addr_cells(np);
146 opprop = (unsigned int *) get_property(np, "platform-open-pic", &opplen); 146 opprop = get_property(np, "platform-open-pic", &opplen);
147 if (opprop != 0) { 147 if (opprop != 0) {
148 openpic_addr = of_read_number(opprop, naddr); 148 openpic_addr = of_read_number(opprop, naddr);
149 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); 149 printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
@@ -192,7 +192,7 @@ static void __init pseries_mpic_init_IRQ(void)
192 break; 192 break;
193 if (strcmp(np->name, "pci") != 0) 193 if (strcmp(np->name, "pci") != 0)
194 continue; 194 continue;
195 addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", 195 addrp = get_property(np, "8259-interrupt-acknowledge",
196 NULL); 196 NULL);
197 if (addrp == NULL) 197 if (addrp == NULL)
198 continue; 198 continue;
@@ -223,23 +223,37 @@ static void pseries_lpar_enable_pmcs(void)
223} 223}
224 224
225#ifdef CONFIG_KEXEC 225#ifdef CONFIG_KEXEC
226static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary) 226static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
227{
228 mpic_teardown_this_cpu(secondary);
229}
230
231static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
232{ 227{
233 /* Don't risk a hypervisor call if we're crashing */ 228 /* Don't risk a hypervisor call if we're crashing */
234 if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { 229 if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
235 unsigned long vpa = __pa(get_lppaca()); 230 unsigned long addr;
236 231
237 if (unregister_vpa(hard_smp_processor_id(), vpa)) { 232 addr = __pa(get_slb_shadow());
233 if (unregister_slb_shadow(hard_smp_processor_id(), addr))
234 printk("SLB shadow buffer deregistration of "
235 "cpu %u (hw_cpu_id %d) failed\n",
236 smp_processor_id(),
237 hard_smp_processor_id());
238
239 addr = __pa(get_lppaca());
240 if (unregister_vpa(hard_smp_processor_id(), addr)) {
238 printk("VPA deregistration of cpu %u (hw_cpu_id %d) " 241 printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
239 "failed\n", smp_processor_id(), 242 "failed\n", smp_processor_id(),
240 hard_smp_processor_id()); 243 hard_smp_processor_id());
241 } 244 }
242 } 245 }
246}
247
248static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary)
249{
250 pseries_kexec_cpu_down(crash_shutdown, secondary);
251 mpic_teardown_this_cpu(secondary);
252}
253
254static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
255{
256 pseries_kexec_cpu_down(crash_shutdown, secondary);
243 xics_teardown_cpu(secondary); 257 xics_teardown_cpu(secondary);
244} 258}
245#endif /* CONFIG_KEXEC */ 259#endif /* CONFIG_KEXEC */
@@ -247,11 +261,11 @@ static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
247static void __init pseries_discover_pic(void) 261static void __init pseries_discover_pic(void)
248{ 262{
249 struct device_node *np; 263 struct device_node *np;
250 char *typep; 264 const char *typep;
251 265
252 for (np = NULL; (np = of_find_node_by_name(np, 266 for (np = NULL; (np = of_find_node_by_name(np,
253 "interrupt-controller"));) { 267 "interrupt-controller"));) {
254 typep = (char *)get_property(np, "compatible", NULL); 268 typep = get_property(np, "compatible", NULL);
255 if (strstr(typep, "open-pic")) { 269 if (strstr(typep, "open-pic")) {
256 pSeries_mpic_node = of_node_get(np); 270 pSeries_mpic_node = of_node_get(np);
257 ppc_md.init_IRQ = pseries_mpic_init_IRQ; 271 ppc_md.init_IRQ = pseries_mpic_init_IRQ;
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index ac61098ff401..c6624b8a0e77 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -62,7 +62,7 @@
62 */ 62 */
63static cpumask_t of_spin_map; 63static cpumask_t of_spin_map;
64 64
65extern void pSeries_secondary_smp_init(unsigned long); 65extern void generic_secondary_smp_init(unsigned long);
66 66
67#ifdef CONFIG_HOTPLUG_CPU 67#ifdef CONFIG_HOTPLUG_CPU
68 68
@@ -145,9 +145,9 @@ static int pSeries_add_processor(struct device_node *np)
145 unsigned int cpu; 145 unsigned int cpu;
146 cpumask_t candidate_map, tmp = CPU_MASK_NONE; 146 cpumask_t candidate_map, tmp = CPU_MASK_NONE;
147 int err = -ENOSPC, len, nthreads, i; 147 int err = -ENOSPC, len, nthreads, i;
148 u32 *intserv; 148 const u32 *intserv;
149 149
150 intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len); 150 intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
151 if (!intserv) 151 if (!intserv)
152 return 0; 152 return 0;
153 153
@@ -205,9 +205,9 @@ static void pSeries_remove_processor(struct device_node *np)
205{ 205{
206 unsigned int cpu; 206 unsigned int cpu;
207 int len, nthreads, i; 207 int len, nthreads, i;
208 u32 *intserv; 208 const u32 *intserv;
209 209
210 intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s", &len); 210 intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
211 if (!intserv) 211 if (!intserv)
212 return; 212 return;
213 213
@@ -270,7 +270,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
270{ 270{
271 int status; 271 int status;
272 unsigned long start_here = __pa((u32)*((unsigned long *) 272 unsigned long start_here = __pa((u32)*((unsigned long *)
273 pSeries_secondary_smp_init)); 273 generic_secondary_smp_init));
274 unsigned int pcpu; 274 unsigned int pcpu;
275 int start_cpu; 275 int start_cpu;
276 276
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index e98863025721..253972e5479f 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -34,6 +34,7 @@
34#include <asm/i8259.h> 34#include <asm/i8259.h>
35 35
36#include "xics.h" 36#include "xics.h"
37#include "plpar_wrappers.h"
37 38
38#define XICS_IPI 2 39#define XICS_IPI 2
39#define XICS_IRQ_SPURIOUS 0 40#define XICS_IRQ_SPURIOUS 0
@@ -110,27 +111,6 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
110/* LPAR low level accessors */ 111/* LPAR low level accessors */
111 112
112 113
113static inline long plpar_eoi(unsigned long xirr)
114{
115 return plpar_hcall_norets(H_EOI, xirr);
116}
117
118static inline long plpar_cppr(unsigned long cppr)
119{
120 return plpar_hcall_norets(H_CPPR, cppr);
121}
122
123static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
124{
125 return plpar_hcall_norets(H_IPI, servernum, mfrr);
126}
127
128static inline long plpar_xirr(unsigned long *xirr_ret)
129{
130 unsigned long dummy;
131 return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
132}
133
134static inline unsigned int lpar_xirr_info_get(int n_cpu) 114static inline unsigned int lpar_xirr_info_get(int n_cpu)
135{ 115{
136 unsigned long lpar_rc; 116 unsigned long lpar_rc;
@@ -590,14 +570,14 @@ static void __init xics_init_one_node(struct device_node *np,
590 unsigned int *indx) 570 unsigned int *indx)
591{ 571{
592 unsigned int ilen; 572 unsigned int ilen;
593 u32 *ireg; 573 const u32 *ireg;
594 574
595 /* This code does the theorically broken assumption that the interrupt 575 /* This code does the theorically broken assumption that the interrupt
596 * server numbers are the same as the hard CPU numbers. 576 * server numbers are the same as the hard CPU numbers.
597 * This happens to be the case so far but we are playing with fire... 577 * This happens to be the case so far but we are playing with fire...
598 * should be fixed one of these days. -BenH. 578 * should be fixed one of these days. -BenH.
599 */ 579 */
600 ireg = (u32 *)get_property(np, "ibm,interrupt-server-ranges", NULL); 580 ireg = get_property(np, "ibm,interrupt-server-ranges", NULL);
601 581
602 /* Do that ever happen ? we'll know soon enough... but even good'old 582 /* Do that ever happen ? we'll know soon enough... but even good'old
603 * f80 does have that property .. 583 * f80 does have that property ..
@@ -609,7 +589,7 @@ static void __init xics_init_one_node(struct device_node *np,
609 */ 589 */
610 *indx = *ireg; 590 *indx = *ireg;
611 } 591 }
612 ireg = (u32 *)get_property(np, "reg", &ilen); 592 ireg = get_property(np, "reg", &ilen);
613 if (!ireg) 593 if (!ireg)
614 panic("xics_init_IRQ: can't find interrupt reg property"); 594 panic("xics_init_IRQ: can't find interrupt reg property");
615 595
@@ -635,7 +615,7 @@ static void __init xics_setup_8259_cascade(void)
635{ 615{
636 struct device_node *np, *old, *found = NULL; 616 struct device_node *np, *old, *found = NULL;
637 int cascade, naddr; 617 int cascade, naddr;
638 u32 *addrp; 618 const u32 *addrp;
639 unsigned long intack = 0; 619 unsigned long intack = 0;
640 620
641 for_each_node_by_type(np, "interrupt-controller") 621 for_each_node_by_type(np, "interrupt-controller")
@@ -661,7 +641,7 @@ static void __init xics_setup_8259_cascade(void)
661 break; 641 break;
662 if (strcmp(np->name, "pci") != 0) 642 if (strcmp(np->name, "pci") != 0)
663 continue; 643 continue;
664 addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", NULL); 644 addrp = get_property(np, "8259-interrupt-acknowledge", NULL);
665 if (addrp == NULL) 645 if (addrp == NULL)
666 continue; 646 continue;
667 naddr = prom_n_addr_cells(np); 647 naddr = prom_n_addr_cells(np);
@@ -680,7 +660,8 @@ void __init xics_init_IRQ(void)
680{ 660{
681 int i; 661 int i;
682 struct device_node *np; 662 struct device_node *np;
683 u32 *ireg, ilen, indx = 0; 663 u32 ilen, indx = 0;
664 const u32 *ireg;
684 int found = 0; 665 int found = 0;
685 666
686 ppc64_boot_msg(0x20, "XICS Init"); 667 ppc64_boot_msg(0x20, "XICS Init");
@@ -705,18 +686,17 @@ void __init xics_init_IRQ(void)
705 for (np = of_find_node_by_type(NULL, "cpu"); 686 for (np = of_find_node_by_type(NULL, "cpu");
706 np; 687 np;
707 np = of_find_node_by_type(np, "cpu")) { 688 np = of_find_node_by_type(np, "cpu")) {
708 ireg = (u32 *)get_property(np, "reg", &ilen); 689 ireg = get_property(np, "reg", &ilen);
709 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { 690 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
710 ireg = (u32 *)get_property(np, 691 ireg = get_property(np,
711 "ibm,ppc-interrupt-gserver#s", 692 "ibm,ppc-interrupt-gserver#s", &ilen);
712 &ilen);
713 i = ilen / sizeof(int); 693 i = ilen / sizeof(int);
714 if (ireg && i > 0) { 694 if (ireg && i > 0) {
715 default_server = ireg[0]; 695 default_server = ireg[0];
716 /* take last element */ 696 /* take last element */
717 default_distrib_server = ireg[i-1]; 697 default_distrib_server = ireg[i-1];
718 } 698 }
719 ireg = (u32 *)get_property(np, 699 ireg = get_property(np,
720 "ibm,interrupt-server#-size", NULL); 700 "ibm,interrupt-server#-size", NULL);
721 if (ireg) 701 if (ireg)
722 interrupt_server_size = *ireg; 702 interrupt_server_size = *ireg;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ef10bcf2d943..92ba378b7990 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -41,7 +41,7 @@ phys_addr_t get_immrbase(void)
41 soc = of_find_node_by_type(NULL, "soc"); 41 soc = of_find_node_by_type(NULL, "soc");
42 if (soc) { 42 if (soc) {
43 unsigned int size; 43 unsigned int size;
44 void *prop = get_property(soc, "reg", &size); 44 const void *prop = get_property(soc, "reg", &size);
45 immrbase = of_translate_address(soc, prop); 45 immrbase = of_translate_address(soc, prop);
46 of_node_put(soc); 46 of_node_put(soc);
47 }; 47 };
@@ -85,7 +85,7 @@ static int __init gfar_mdio_of_init(void)
85 mdio_data.irq[k] = -1; 85 mdio_data.irq[k] = -1;
86 86
87 while ((child = of_get_next_child(np, child)) != NULL) { 87 while ((child = of_get_next_child(np, child)) != NULL) {
88 u32 *id = get_property(child, "reg", NULL); 88 const u32 *id = get_property(child, "reg", NULL);
89 mdio_data.irq[*id] = irq_of_parse_and_map(child, 0); 89 mdio_data.irq[*id] = irq_of_parse_and_map(child, 0);
90 } 90 }
91 91
@@ -124,10 +124,10 @@ static int __init gfar_of_init(void)
124 struct resource r[4]; 124 struct resource r[4];
125 struct device_node *phy, *mdio; 125 struct device_node *phy, *mdio;
126 struct gianfar_platform_data gfar_data; 126 struct gianfar_platform_data gfar_data;
127 unsigned int *id; 127 const unsigned int *id;
128 char *model; 128 const char *model;
129 void *mac_addr; 129 const void *mac_addr;
130 phandle *ph; 130 const phandle *ph;
131 int n_res = 1; 131 int n_res = 1;
132 132
133 memset(r, 0, sizeof(r)); 133 memset(r, 0, sizeof(r));
@@ -193,7 +193,7 @@ static int __init gfar_of_init(void)
193 FSL_GIANFAR_DEV_HAS_VLAN | 193 FSL_GIANFAR_DEV_HAS_VLAN |
194 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; 194 FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
195 195
196 ph = (phandle *) get_property(np, "phy-handle", NULL); 196 ph = get_property(np, "phy-handle", NULL);
197 phy = of_find_node_by_phandle(*ph); 197 phy = of_find_node_by_phandle(*ph);
198 198
199 if (phy == NULL) { 199 if (phy == NULL) {
@@ -203,7 +203,7 @@ static int __init gfar_of_init(void)
203 203
204 mdio = of_get_parent(phy); 204 mdio = of_get_parent(phy);
205 205
206 id = (u32 *) get_property(phy, "reg", NULL); 206 id = get_property(phy, "reg", NULL);
207 ret = of_address_to_resource(mdio, 0, &res); 207 ret = of_address_to_resource(mdio, 0, &res);
208 if (ret) { 208 if (ret) {
209 of_node_put(phy); 209 of_node_put(phy);
@@ -247,7 +247,7 @@ static int __init fsl_i2c_of_init(void)
247 i++) { 247 i++) {
248 struct resource r[2]; 248 struct resource r[2];
249 struct fsl_i2c_platform_data i2c_data; 249 struct fsl_i2c_platform_data i2c_data;
250 unsigned char *flags = NULL; 250 const unsigned char *flags = NULL;
251 251
252 memset(&r, 0, sizeof(r)); 252 memset(&r, 0, sizeof(r));
253 memset(&i2c_data, 0, sizeof(i2c_data)); 253 memset(&i2c_data, 0, sizeof(i2c_data));
@@ -298,7 +298,7 @@ static int __init mpc83xx_wdt_init(void)
298 struct resource r; 298 struct resource r;
299 struct device_node *soc, *np; 299 struct device_node *soc, *np;
300 struct platform_device *dev; 300 struct platform_device *dev;
301 unsigned int *freq; 301 const unsigned int *freq;
302 int ret; 302 int ret;
303 303
304 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); 304 np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt");
@@ -315,7 +315,7 @@ static int __init mpc83xx_wdt_init(void)
315 goto nosoc; 315 goto nosoc;
316 } 316 }
317 317
318 freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); 318 freq = get_property(soc, "bus-frequency", NULL);
319 if (!freq) { 319 if (!freq) {
320 ret = -ENODEV; 320 ret = -ENODEV;
321 goto err; 321 goto err;
@@ -355,7 +355,7 @@ nodev:
355arch_initcall(mpc83xx_wdt_init); 355arch_initcall(mpc83xx_wdt_init);
356#endif 356#endif
357 357
358static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type) 358static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
359{ 359{
360 if (!phy_type) 360 if (!phy_type)
361 return FSL_USB2_PHY_NONE; 361 return FSL_USB2_PHY_NONE;
@@ -383,7 +383,7 @@ static int __init fsl_usb_of_init(void)
383 i++) { 383 i++) {
384 struct resource r[2]; 384 struct resource r[2];
385 struct fsl_usb2_platform_data usb_data; 385 struct fsl_usb2_platform_data usb_data;
386 unsigned char *prop = NULL; 386 const unsigned char *prop = NULL;
387 387
388 memset(&r, 0, sizeof(r)); 388 memset(&r, 0, sizeof(r));
389 memset(&usb_data, 0, sizeof(usb_data)); 389 memset(&usb_data, 0, sizeof(usb_data));
@@ -431,7 +431,7 @@ static int __init fsl_usb_of_init(void)
431 i++) { 431 i++) {
432 struct resource r[2]; 432 struct resource r[2];
433 struct fsl_usb2_platform_data usb_data; 433 struct fsl_usb2_platform_data usb_data;
434 unsigned char *prop = NULL; 434 const unsigned char *prop = NULL;
435 435
436 memset(&r, 0, sizeof(r)); 436 memset(&r, 0, sizeof(r));
437 memset(&usb_data, 0, sizeof(usb_data)); 437 memset(&usb_data, 0, sizeof(usb_data));
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index c433d3f39edd..5a3dd480d2fd 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -2,6 +2,8 @@
2#define __PPC_FSL_SOC_H 2#define __PPC_FSL_SOC_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <asm/mmu.h>
6
5extern phys_addr_t get_immrbase(void); 7extern phys_addr_t get_immrbase(void);
6 8
7#endif 9#endif
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index 9855820b9548..26a6a3becd66 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -224,7 +224,7 @@ static struct irq_host_ops i8259_host_ops = {
224 .xlate = i8259_host_xlate, 224 .xlate = i8259_host_xlate,
225}; 225};
226 226
227/**** 227/**
228 * i8259_init - Initialize the legacy controller 228 * i8259_init - Initialize the legacy controller
229 * @node: device node of the legacy PIC (can be NULL, but then, it will match 229 * @node: device node of the legacy PIC (can be NULL, but then, it will match
230 * all interrupts, so beware) 230 * all interrupts, so beware)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 70e707785d49..0251b7c68d0e 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -210,7 +210,7 @@ static struct ipic_info ipic_info[] = {
210 .prio_mask = 4, 210 .prio_mask = 4,
211 }, 211 },
212 [64] = { 212 [64] = {
213 .pend = IPIC_SIPNR_H, 213 .pend = IPIC_SIPNR_L,
214 .mask = IPIC_SIMSR_L, 214 .mask = IPIC_SIMSR_L,
215 .prio = IPIC_SMPRR_A, 215 .prio = IPIC_SMPRR_A,
216 .force = IPIC_SIFCR_L, 216 .force = IPIC_SIFCR_L,
@@ -218,7 +218,7 @@ static struct ipic_info ipic_info[] = {
218 .prio_mask = 0, 218 .prio_mask = 0,
219 }, 219 },
220 [65] = { 220 [65] = {
221 .pend = IPIC_SIPNR_H, 221 .pend = IPIC_SIPNR_L,
222 .mask = IPIC_SIMSR_L, 222 .mask = IPIC_SIMSR_L,
223 .prio = IPIC_SMPRR_A, 223 .prio = IPIC_SMPRR_A,
224 .force = IPIC_SIFCR_L, 224 .force = IPIC_SIFCR_L,
@@ -226,7 +226,7 @@ static struct ipic_info ipic_info[] = {
226 .prio_mask = 1, 226 .prio_mask = 1,
227 }, 227 },
228 [66] = { 228 [66] = {
229 .pend = IPIC_SIPNR_H, 229 .pend = IPIC_SIPNR_L,
230 .mask = IPIC_SIMSR_L, 230 .mask = IPIC_SIMSR_L,
231 .prio = IPIC_SMPRR_A, 231 .prio = IPIC_SMPRR_A,
232 .force = IPIC_SIFCR_L, 232 .force = IPIC_SIFCR_L,
@@ -234,7 +234,7 @@ static struct ipic_info ipic_info[] = {
234 .prio_mask = 2, 234 .prio_mask = 2,
235 }, 235 },
236 [67] = { 236 [67] = {
237 .pend = IPIC_SIPNR_H, 237 .pend = IPIC_SIPNR_L,
238 .mask = IPIC_SIMSR_L, 238 .mask = IPIC_SIMSR_L,
239 .prio = IPIC_SMPRR_A, 239 .prio = IPIC_SMPRR_A,
240 .force = IPIC_SIFCR_L, 240 .force = IPIC_SIFCR_L,
@@ -242,7 +242,7 @@ static struct ipic_info ipic_info[] = {
242 .prio_mask = 3, 242 .prio_mask = 3,
243 }, 243 },
244 [68] = { 244 [68] = {
245 .pend = IPIC_SIPNR_H, 245 .pend = IPIC_SIPNR_L,
246 .mask = IPIC_SIMSR_L, 246 .mask = IPIC_SIMSR_L,
247 .prio = IPIC_SMPRR_B, 247 .prio = IPIC_SMPRR_B,
248 .force = IPIC_SIFCR_L, 248 .force = IPIC_SIFCR_L,
@@ -250,7 +250,7 @@ static struct ipic_info ipic_info[] = {
250 .prio_mask = 0, 250 .prio_mask = 0,
251 }, 251 },
252 [69] = { 252 [69] = {
253 .pend = IPIC_SIPNR_H, 253 .pend = IPIC_SIPNR_L,
254 .mask = IPIC_SIMSR_L, 254 .mask = IPIC_SIMSR_L,
255 .prio = IPIC_SMPRR_B, 255 .prio = IPIC_SMPRR_B,
256 .force = IPIC_SIFCR_L, 256 .force = IPIC_SIFCR_L,
@@ -258,7 +258,7 @@ static struct ipic_info ipic_info[] = {
258 .prio_mask = 1, 258 .prio_mask = 1,
259 }, 259 },
260 [70] = { 260 [70] = {
261 .pend = IPIC_SIPNR_H, 261 .pend = IPIC_SIPNR_L,
262 .mask = IPIC_SIMSR_L, 262 .mask = IPIC_SIMSR_L,
263 .prio = IPIC_SMPRR_B, 263 .prio = IPIC_SMPRR_B,
264 .force = IPIC_SIFCR_L, 264 .force = IPIC_SIFCR_L,
@@ -266,7 +266,7 @@ static struct ipic_info ipic_info[] = {
266 .prio_mask = 2, 266 .prio_mask = 2,
267 }, 267 },
268 [71] = { 268 [71] = {
269 .pend = IPIC_SIPNR_H, 269 .pend = IPIC_SIPNR_L,
270 .mask = IPIC_SIMSR_L, 270 .mask = IPIC_SIMSR_L,
271 .prio = IPIC_SMPRR_B, 271 .prio = IPIC_SMPRR_B,
272 .force = IPIC_SIFCR_L, 272 .force = IPIC_SIFCR_L,
@@ -274,91 +274,91 @@ static struct ipic_info ipic_info[] = {
274 .prio_mask = 3, 274 .prio_mask = 3,
275 }, 275 },
276 [72] = { 276 [72] = {
277 .pend = IPIC_SIPNR_H, 277 .pend = IPIC_SIPNR_L,
278 .mask = IPIC_SIMSR_L, 278 .mask = IPIC_SIMSR_L,
279 .prio = 0, 279 .prio = 0,
280 .force = IPIC_SIFCR_L, 280 .force = IPIC_SIFCR_L,
281 .bit = 8, 281 .bit = 8,
282 }, 282 },
283 [73] = { 283 [73] = {
284 .pend = IPIC_SIPNR_H, 284 .pend = IPIC_SIPNR_L,
285 .mask = IPIC_SIMSR_L, 285 .mask = IPIC_SIMSR_L,
286 .prio = 0, 286 .prio = 0,
287 .force = IPIC_SIFCR_L, 287 .force = IPIC_SIFCR_L,
288 .bit = 9, 288 .bit = 9,
289 }, 289 },
290 [74] = { 290 [74] = {
291 .pend = IPIC_SIPNR_H, 291 .pend = IPIC_SIPNR_L,
292 .mask = IPIC_SIMSR_L, 292 .mask = IPIC_SIMSR_L,
293 .prio = 0, 293 .prio = 0,
294 .force = IPIC_SIFCR_L, 294 .force = IPIC_SIFCR_L,
295 .bit = 10, 295 .bit = 10,
296 }, 296 },
297 [75] = { 297 [75] = {
298 .pend = IPIC_SIPNR_H, 298 .pend = IPIC_SIPNR_L,
299 .mask = IPIC_SIMSR_L, 299 .mask = IPIC_SIMSR_L,
300 .prio = 0, 300 .prio = 0,
301 .force = IPIC_SIFCR_L, 301 .force = IPIC_SIFCR_L,
302 .bit = 11, 302 .bit = 11,
303 }, 303 },
304 [76] = { 304 [76] = {
305 .pend = IPIC_SIPNR_H, 305 .pend = IPIC_SIPNR_L,
306 .mask = IPIC_SIMSR_L, 306 .mask = IPIC_SIMSR_L,
307 .prio = 0, 307 .prio = 0,
308 .force = IPIC_SIFCR_L, 308 .force = IPIC_SIFCR_L,
309 .bit = 12, 309 .bit = 12,
310 }, 310 },
311 [77] = { 311 [77] = {
312 .pend = IPIC_SIPNR_H, 312 .pend = IPIC_SIPNR_L,
313 .mask = IPIC_SIMSR_L, 313 .mask = IPIC_SIMSR_L,
314 .prio = 0, 314 .prio = 0,
315 .force = IPIC_SIFCR_L, 315 .force = IPIC_SIFCR_L,
316 .bit = 13, 316 .bit = 13,
317 }, 317 },
318 [78] = { 318 [78] = {
319 .pend = IPIC_SIPNR_H, 319 .pend = IPIC_SIPNR_L,
320 .mask = IPIC_SIMSR_L, 320 .mask = IPIC_SIMSR_L,
321 .prio = 0, 321 .prio = 0,
322 .force = IPIC_SIFCR_L, 322 .force = IPIC_SIFCR_L,
323 .bit = 14, 323 .bit = 14,
324 }, 324 },
325 [79] = { 325 [79] = {
326 .pend = IPIC_SIPNR_H, 326 .pend = IPIC_SIPNR_L,
327 .mask = IPIC_SIMSR_L, 327 .mask = IPIC_SIMSR_L,
328 .prio = 0, 328 .prio = 0,
329 .force = IPIC_SIFCR_L, 329 .force = IPIC_SIFCR_L,
330 .bit = 15, 330 .bit = 15,
331 }, 331 },
332 [80] = { 332 [80] = {
333 .pend = IPIC_SIPNR_H, 333 .pend = IPIC_SIPNR_L,
334 .mask = IPIC_SIMSR_L, 334 .mask = IPIC_SIMSR_L,
335 .prio = 0, 335 .prio = 0,
336 .force = IPIC_SIFCR_L, 336 .force = IPIC_SIFCR_L,
337 .bit = 16, 337 .bit = 16,
338 }, 338 },
339 [84] = { 339 [84] = {
340 .pend = IPIC_SIPNR_H, 340 .pend = IPIC_SIPNR_L,
341 .mask = IPIC_SIMSR_L, 341 .mask = IPIC_SIMSR_L,
342 .prio = 0, 342 .prio = 0,
343 .force = IPIC_SIFCR_L, 343 .force = IPIC_SIFCR_L,
344 .bit = 20, 344 .bit = 20,
345 }, 345 },
346 [85] = { 346 [85] = {
347 .pend = IPIC_SIPNR_H, 347 .pend = IPIC_SIPNR_L,
348 .mask = IPIC_SIMSR_L, 348 .mask = IPIC_SIMSR_L,
349 .prio = 0, 349 .prio = 0,
350 .force = IPIC_SIFCR_L, 350 .force = IPIC_SIFCR_L,
351 .bit = 21, 351 .bit = 21,
352 }, 352 },
353 [90] = { 353 [90] = {
354 .pend = IPIC_SIPNR_H, 354 .pend = IPIC_SIPNR_L,
355 .mask = IPIC_SIMSR_L, 355 .mask = IPIC_SIMSR_L,
356 .prio = 0, 356 .prio = 0,
357 .force = IPIC_SIFCR_L, 357 .force = IPIC_SIFCR_L,
358 .bit = 26, 358 .bit = 26,
359 }, 359 },
360 [91] = { 360 [91] = {
361 .pend = IPIC_SIPNR_H, 361 .pend = IPIC_SIPNR_L,
362 .mask = IPIC_SIMSR_L, 362 .mask = IPIC_SIMSR_L,
363 .prio = 0, 363 .prio = 0,
364 .force = IPIC_SIFCR_L, 364 .force = IPIC_SIFCR_L,
diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c
index 615350d46b52..ff23f5a4d4b9 100644
--- a/arch/powerpc/sysdev/mmio_nvram.c
+++ b/arch/powerpc/sysdev/mmio_nvram.c
@@ -80,7 +80,7 @@ static ssize_t mmio_nvram_get_size(void)
80int __init mmio_nvram_init(void) 80int __init mmio_nvram_init(void)
81{ 81{
82 struct device_node *nvram_node; 82 struct device_node *nvram_node;
83 unsigned long *buffer; 83 const unsigned long *buffer;
84 int proplen; 84 int proplen;
85 unsigned long nvram_addr; 85 unsigned long nvram_addr;
86 int ret; 86 int ret;
@@ -91,7 +91,7 @@ int __init mmio_nvram_init(void)
91 goto out; 91 goto out;
92 92
93 ret = -EIO; 93 ret = -EIO;
94 buffer = (unsigned long *)get_property(nvram_node, "reg", &proplen); 94 buffer = get_property(nvram_node, "reg", &proplen);
95 if (proplen != 2*sizeof(unsigned long)) 95 if (proplen != 2*sizeof(unsigned long))
96 goto out; 96 goto out;
97 97
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 2ab06ed3ae73..c28f69bef8e2 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -194,7 +194,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
194 int len; 194 int len;
195 struct pci_controller *hose; 195 struct pci_controller *hose;
196 struct resource rsrc; 196 struct resource rsrc;
197 int *bus_range; 197 const int *bus_range;
198 int primary = 0, has_address = 0; 198 int primary = 0, has_address = 0;
199 199
200 /* PCI Config mapping */ 200 /* PCI Config mapping */
@@ -207,7 +207,7 @@ int __init tsi108_setup_pci(struct device_node *dev)
207 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); 207 has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
208 208
209 /* Get bus range if any */ 209 /* Get bus range if any */
210 bus_range = (int *)get_property(dev, "bus-range", &len); 210 bus_range = get_property(dev, "bus-range", &len);
211 if (bus_range == NULL || len < 2 * sizeof(int)) { 211 if (bus_range == NULL || len < 2 * sizeof(int)) {
212 printk(KERN_WARNING "Can't get bus-range for %s, assume" 212 printk(KERN_WARNING "Can't get bus-range for %s, assume"
213 " bus 0\n", dev->full_name); 213 " bus 0\n", dev->full_name);
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 179b10ced8c7..8adad1444a51 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -137,10 +137,14 @@ static void bootcmds(void);
137static void proccall(void); 137static void proccall(void);
138void dump_segments(void); 138void dump_segments(void);
139static void symbol_lookup(void); 139static void symbol_lookup(void);
140static void xmon_show_stack(unsigned long sp, unsigned long lr,
141 unsigned long pc);
140static void xmon_print_symbol(unsigned long address, const char *mid, 142static void xmon_print_symbol(unsigned long address, const char *mid,
141 const char *after); 143 const char *after);
142static const char *getvecname(unsigned long vec); 144static const char *getvecname(unsigned long vec);
143 145
146int xmon_no_auto_backtrace;
147
144extern int print_insn_powerpc(unsigned long, unsigned long, int); 148extern int print_insn_powerpc(unsigned long, unsigned long, int);
145 149
146extern void xmon_enter(void); 150extern void xmon_enter(void);
@@ -736,6 +740,12 @@ cmds(struct pt_regs *excp)
736 740
737 last_cmd = NULL; 741 last_cmd = NULL;
738 xmon_regs = excp; 742 xmon_regs = excp;
743
744 if (!xmon_no_auto_backtrace) {
745 xmon_no_auto_backtrace = 1;
746 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
747 }
748
739 for(;;) { 749 for(;;) {
740#ifdef CONFIG_SMP 750#ifdef CONFIG_SMP
741 printf("%x:", smp_processor_id()); 751 printf("%x:", smp_processor_id());
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index a04cdf01596b..8fa10cf661a8 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1204,7 +1204,7 @@ config PCI_DOMAINS
1204 default PCI 1204 default PCI
1205 1205
1206config MPC83xx_PCI2 1206config MPC83xx_PCI2
1207 bool " Supprt for 2nd PCI host controller" 1207 bool "Support for 2nd PCI host controller"
1208 depends on PCI && MPC834x 1208 depends on PCI && MPC834x
1209 default y if MPC834x_SYS 1209 default y if MPC834x_SYS
1210 1210
@@ -1223,12 +1223,12 @@ config PCI_8260
1223 default y 1223 default y
1224 1224
1225config 8260_PCI9 1225config 8260_PCI9
1226 bool " Enable workaround for MPC826x erratum PCI 9" 1226 bool "Enable workaround for MPC826x erratum PCI 9"
1227 depends on PCI_8260 && !ADS8272 1227 depends on PCI_8260 && !ADS8272
1228 default y 1228 default y
1229 1229
1230choice 1230choice
1231 prompt " IDMA channel for PCI 9 workaround" 1231 prompt "IDMA channel for PCI 9 workaround"
1232 depends on 8260_PCI9 1232 depends on 8260_PCI9
1233 1233
1234config 8260_PCI9_IDMA1 1234config 8260_PCI9_IDMA1
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 2fa0075f2b5f..50b4bbd06804 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -768,91 +768,6 @@ _GLOBAL(_outsb)
768 bdnz 00b 768 bdnz 00b
769 blr 769 blr
770 770
771_GLOBAL(_insw)
772 cmpwi 0,r5,0
773 mtctr r5
774 subi r4,r4,2
775 blelr-
77600: lhbrx r5,0,r3
77701: eieio
77802: sthu r5,2(r4)
779 ISYNC_8xx
780 .section .fixup,"ax"
78103: blr
782 .text
783 .section __ex_table, "a"
784 .align 2
785 .long 00b, 03b
786 .long 01b, 03b
787 .long 02b, 03b
788 .text
789 bdnz 00b
790 blr
791
792_GLOBAL(_outsw)
793 cmpwi 0,r5,0
794 mtctr r5
795 subi r4,r4,2
796 blelr-
79700: lhzu r5,2(r4)
79801: eieio
79902: sthbrx r5,0,r3
800 ISYNC_8xx
801 .section .fixup,"ax"
80203: blr
803 .text
804 .section __ex_table, "a"
805 .align 2
806 .long 00b, 03b
807 .long 01b, 03b
808 .long 02b, 03b
809 .text
810 bdnz 00b
811 blr
812
813_GLOBAL(_insl)
814 cmpwi 0,r5,0
815 mtctr r5
816 subi r4,r4,4
817 blelr-
81800: lwbrx r5,0,r3
81901: eieio
82002: stwu r5,4(r4)
821 ISYNC_8xx
822 .section .fixup,"ax"
82303: blr
824 .text
825 .section __ex_table, "a"
826 .align 2
827 .long 00b, 03b
828 .long 01b, 03b
829 .long 02b, 03b
830 .text
831 bdnz 00b
832 blr
833
834_GLOBAL(_outsl)
835 cmpwi 0,r5,0
836 mtctr r5
837 subi r4,r4,4
838 blelr-
83900: lwzu r5,4(r4)
84001: stwbrx r5,0,r3
84102: eieio
842 ISYNC_8xx
843 .section .fixup,"ax"
84403: blr
845 .text
846 .section __ex_table, "a"
847 .align 2
848 .long 00b, 03b
849 .long 01b, 03b
850 .long 02b, 03b
851 .text
852 bdnz 00b
853 blr
854
855_GLOBAL(__ide_mm_insw)
856_GLOBAL(_insw_ns) 771_GLOBAL(_insw_ns)
857 cmpwi 0,r5,0 772 cmpwi 0,r5,0
858 mtctr r5 773 mtctr r5
@@ -874,7 +789,6 @@ _GLOBAL(_insw_ns)
874 bdnz 00b 789 bdnz 00b
875 blr 790 blr
876 791
877_GLOBAL(__ide_mm_outsw)
878_GLOBAL(_outsw_ns) 792_GLOBAL(_outsw_ns)
879 cmpwi 0,r5,0 793 cmpwi 0,r5,0
880 mtctr r5 794 mtctr r5
@@ -896,7 +810,6 @@ _GLOBAL(_outsw_ns)
896 bdnz 00b 810 bdnz 00b
897 blr 811 blr
898 812
899_GLOBAL(__ide_mm_insl)
900_GLOBAL(_insl_ns) 813_GLOBAL(_insl_ns)
901 cmpwi 0,r5,0 814 cmpwi 0,r5,0
902 mtctr r5 815 mtctr r5
@@ -918,7 +831,6 @@ _GLOBAL(_insl_ns)
918 bdnz 00b 831 bdnz 00b
919 blr 832 blr
920 833
921_GLOBAL(__ide_mm_outsl)
922_GLOBAL(_outsl_ns) 834_GLOBAL(_outsl_ns)
923 cmpwi 0,r5,0 835 cmpwi 0,r5,0
924 mtctr r5 836 mtctr r5
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index d1735401384c..c8b65ca8a350 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -115,17 +115,8 @@ EXPORT_SYMBOL(outw);
115EXPORT_SYMBOL(outl); 115EXPORT_SYMBOL(outl);
116EXPORT_SYMBOL(outsl);*/ 116EXPORT_SYMBOL(outsl);*/
117 117
118EXPORT_SYMBOL(__ide_mm_insl);
119EXPORT_SYMBOL(__ide_mm_outsw);
120EXPORT_SYMBOL(__ide_mm_insw);
121EXPORT_SYMBOL(__ide_mm_outsl);
122
123EXPORT_SYMBOL(_insb); 118EXPORT_SYMBOL(_insb);
124EXPORT_SYMBOL(_outsb); 119EXPORT_SYMBOL(_outsb);
125EXPORT_SYMBOL(_insw);
126EXPORT_SYMBOL(_outsw);
127EXPORT_SYMBOL(_insl);
128EXPORT_SYMBOL(_outsl);
129EXPORT_SYMBOL(_insw_ns); 120EXPORT_SYMBOL(_insw_ns);
130EXPORT_SYMBOL(_outsw_ns); 121EXPORT_SYMBOL(_outsw_ns);
131EXPORT_SYMBOL(_insl_ns); 122EXPORT_SYMBOL(_insl_ns);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index a74f46d9826f..5458ac5da7c3 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -127,11 +127,8 @@ void machine_restart(char *cmd)
127 ppc_md.restart(cmd); 127 ppc_md.restart(cmd);
128} 128}
129 129
130void machine_power_off(void) 130static void ppc_generic_power_off(void)
131{ 131{
132#ifdef CONFIG_NVRAM
133 nvram_sync();
134#endif
135 ppc_md.power_off(); 132 ppc_md.power_off();
136} 133}
137 134
@@ -143,7 +140,17 @@ void machine_halt(void)
143 ppc_md.halt(); 140 ppc_md.halt();
144} 141}
145 142
146void (*pm_power_off)(void) = machine_power_off; 143void (*pm_power_off)(void) = ppc_generic_power_off;
144
145void machine_power_off(void)
146{
147#ifdef CONFIG_NVRAM
148 nvram_sync();
149#endif
150 if (pm_power_off)
151 pm_power_off();
152 ppc_generic_power_off();
153}
147 154
148#ifdef CONFIG_TAU 155#ifdef CONFIG_TAU
149extern u32 cpu_temp(unsigned long cpu); 156extern u32 cpu_temp(unsigned long cpu);
diff --git a/arch/ppc/platforms/85xx/sbc8560.h b/arch/ppc/platforms/85xx/sbc8560.h
index c7d61cf3a449..e5e156f60100 100644
--- a/arch/ppc/platforms/85xx/sbc8560.h
+++ b/arch/ppc/platforms/85xx/sbc8560.h
@@ -14,6 +14,7 @@
14#define __MACH_SBC8560_H__ 14#define __MACH_SBC8560_H__
15 15
16#include <platforms/85xx/sbc85xx.h> 16#include <platforms/85xx/sbc85xx.h>
17#include <asm/irq.h>
17 18
18#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET) 19#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
19 20
diff --git a/arch/ppc/platforms/85xx/sbc85xx.h b/arch/ppc/platforms/85xx/sbc85xx.h
index 21ea7a55639b..51df4dc04e22 100644
--- a/arch/ppc/platforms/85xx/sbc85xx.h
+++ b/arch/ppc/platforms/85xx/sbc85xx.h
@@ -49,4 +49,22 @@ extern void sbc8560_init_IRQ(void) __init;
49 49
50#define MPC85XX_PCI1_IO_SIZE 0x01000000 50#define MPC85XX_PCI1_IO_SIZE 0x01000000
51 51
52/* FCC1 Clock Source Configuration. These can be
53 * redefined in the board specific file.
54 * Can only choose from CLK9-12 */
55#define F1_RXCLK 12
56#define F1_TXCLK 11
57
58/* FCC2 Clock Source Configuration. These can be
59 * redefined in the board specific file.
60 * Can only choose from CLK13-16 */
61#define F2_RXCLK 13
62#define F2_TXCLK 14
63
64/* FCC3 Clock Source Configuration. These can be
65 * redefined in the board specific file.
66 * Can only choose from CLK13-16 */
67#define F3_RXCLK 15
68#define F3_TXCLK 16
69
52#endif /* __PLATFORMS_85XX_SBC85XX_H__ */ 70#endif /* __PLATFORMS_85XX_SBC85XX_H__ */
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c
index 974581ea4849..5475709ce07b 100644
--- a/arch/ppc/syslib/m8260_pci_erratum9.c
+++ b/arch/ppc/syslib/m8260_pci_erratum9.c
@@ -339,20 +339,6 @@ void insl(unsigned port, void *buf, int nl)
339 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0); 339 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
340} 340}
341 341
342void insw_ns(unsigned port, void *buf, int ns)
343{
344 u8 *addr = (u8 *)(port + _IO_BASE);
345
346 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
347}
348
349void insl_ns(unsigned port, void *buf, int nl)
350{
351 u8 *addr = (u8 *)(port + _IO_BASE);
352
353 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
354}
355
356void *memcpy_fromio(void *dest, unsigned long src, size_t count) 342void *memcpy_fromio(void *dest, unsigned long src, size_t count)
357{ 343{
358 unsigned long pa = iopa((unsigned long) src); 344 unsigned long pa = iopa((unsigned long) src);
@@ -373,8 +359,6 @@ EXPORT_SYMBOL(inl);
373EXPORT_SYMBOL(insb); 359EXPORT_SYMBOL(insb);
374EXPORT_SYMBOL(insw); 360EXPORT_SYMBOL(insw);
375EXPORT_SYMBOL(insl); 361EXPORT_SYMBOL(insl);
376EXPORT_SYMBOL(insw_ns);
377EXPORT_SYMBOL(insl_ns);
378EXPORT_SYMBOL(memcpy_fromio); 362EXPORT_SYMBOL(memcpy_fromio);
379 363
380#endif /* ifdef CONFIG_8260_PCI9 */ 364#endif /* ifdef CONFIG_8260_PCI9 */
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index f7e92986952a..d74a883e5bde 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -15,6 +15,7 @@
15#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/delay.h> 16#include <asm/delay.h>
17#include <asm/btext.h> 17#include <asm/btext.h>
18#include <asm/ibm4xx.h>
18 19
19static volatile unsigned char *sccc, *sccd; 20static volatile unsigned char *sccc, *sccd;
20unsigned int TXRDY, RXRDY, DLAB; 21unsigned int TXRDY, RXRDY, DLAB;
@@ -57,23 +58,30 @@ static struct sysrq_key_op sysrq_xmon_op =
57void 58void
58xmon_map_scc(void) 59xmon_map_scc(void)
59{ 60{
60#ifdef CONFIG_PPC_PREP 61#if defined(CONFIG_GEMINI)
61 volatile unsigned char *base;
62
63#elif defined(CONFIG_GEMINI)
64 /* should already be mapped by the kernel boot */ 62 /* should already be mapped by the kernel boot */
65 sccc = (volatile unsigned char *) 0xffeffb0d;
66 sccd = (volatile unsigned char *) 0xffeffb08; 63 sccd = (volatile unsigned char *) 0xffeffb08;
67 TXRDY = 0x20;
68 RXRDY = 1;
69 DLAB = 0x80;
70#elif defined(CONFIG_405GP) 64#elif defined(CONFIG_405GP)
71 sccc = (volatile unsigned char *)0xef600305;
72 sccd = (volatile unsigned char *)0xef600300; 65 sccd = (volatile unsigned char *)0xef600300;
66#elif defined(CONFIG_440EP)
67 sccd = (volatile unsigned char *) ioremap(PPC440EP_UART0_ADDR, 8);
68#elif defined(CONFIG_440SP)
69 sccd = (volatile unsigned char *) ioremap64(PPC440SP_UART0_ADDR, 8);
70#elif defined(CONFIG_440SPE)
71 sccd = (volatile unsigned char *) ioremap64(PPC440SPE_UART0_ADDR, 8);
72#elif defined(CONFIG_44x)
73 /* This is the default for 44x platforms. Any boards that have a
74 different UART address need to be put in cases before this or the
75 port will be mapped incorrectly */
76 sccd = (volatile unsigned char *) ioremap64(PPC440GP_UART0_ADDR, 8);
77#endif /* platform */
78
79#ifndef CONFIG_PPC_PREP
80 sccc = sccd + 5;
73 TXRDY = 0x20; 81 TXRDY = 0x20;
74 RXRDY = 1; 82 RXRDY = 1;
75 DLAB = 0x80; 83 DLAB = 0x80;
76#endif /* platform */ 84#endif
77 85
78 register_sysrq_key('x', &sysrq_xmon_op); 86 register_sysrq_key('x', &sysrq_xmon_op);
79} 87}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 37d234f93394..b1a91744fd2d 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -153,6 +153,12 @@ static int xmon_trace[NR_CPUS];
153#define SSTEP 1 /* stepping because of 's' command */ 153#define SSTEP 1 /* stepping because of 's' command */
154#define BRSTEP 2 /* stepping over breakpoint */ 154#define BRSTEP 2 /* stepping over breakpoint */
155 155
156#ifdef CONFIG_4xx
157#define MSR_SSTEP_ENABLE 0x200
158#else
159#define MSR_SSTEP_ENABLE 0x400
160#endif
161
156static struct pt_regs *xmon_regs[NR_CPUS]; 162static struct pt_regs *xmon_regs[NR_CPUS];
157 163
158extern inline void sync(void) 164extern inline void sync(void)
@@ -211,6 +217,14 @@ static void get_tb(unsigned *p)
211 p[1] = lo; 217 p[1] = lo;
212} 218}
213 219
220static inline void xmon_enable_sstep(struct pt_regs *regs)
221{
222 regs->msr |= MSR_SSTEP_ENABLE;
223#ifdef CONFIG_4xx
224 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
225#endif
226}
227
214int xmon(struct pt_regs *excp) 228int xmon(struct pt_regs *excp)
215{ 229{
216 struct pt_regs regs; 230 struct pt_regs regs;
@@ -254,10 +268,10 @@ int xmon(struct pt_regs *excp)
254 cmd = cmds(excp); 268 cmd = cmds(excp);
255 if (cmd == 's') { 269 if (cmd == 's') {
256 xmon_trace[smp_processor_id()] = SSTEP; 270 xmon_trace[smp_processor_id()] = SSTEP;
257 excp->msr |= 0x400; 271 xmon_enable_sstep(excp);
258 } else if (at_breakpoint(excp->nip)) { 272 } else if (at_breakpoint(excp->nip)) {
259 xmon_trace[smp_processor_id()] = BRSTEP; 273 xmon_trace[smp_processor_id()] = BRSTEP;
260 excp->msr |= 0x400; 274 xmon_enable_sstep(excp);
261 } else { 275 } else {
262 xmon_trace[smp_processor_id()] = 0; 276 xmon_trace[smp_processor_id()] = 0;
263 insert_bpts(); 277 insert_bpts();
@@ -298,7 +312,7 @@ xmon_bpt(struct pt_regs *regs)
298 remove_bpts(); 312 remove_bpts();
299 excprint(regs); 313 excprint(regs);
300 xmon_trace[smp_processor_id()] = BRSTEP; 314 xmon_trace[smp_processor_id()] = BRSTEP;
301 regs->msr |= 0x400; 315 xmon_enable_sstep(regs);
302 } else { 316 } else {
303 xmon(regs); 317 xmon(regs);
304 } 318 }
@@ -385,7 +399,7 @@ insert_bpts(void)
385 } 399 }
386 store_inst((void *) bp->address); 400 store_inst((void *) bp->address);
387 } 401 }
388#if !defined(CONFIG_8xx) 402#if ! (defined(CONFIG_8xx) || defined(CONFIG_4xx))
389 if (dabr.enabled) 403 if (dabr.enabled)
390 set_dabr(dabr.address); 404 set_dabr(dabr.address);
391 if (iabr.enabled) 405 if (iabr.enabled)
@@ -400,7 +414,7 @@ remove_bpts(void)
400 struct bpt *bp; 414 struct bpt *bp;
401 unsigned instr; 415 unsigned instr;
402 416
403#if !defined(CONFIG_8xx) 417#if ! (defined(CONFIG_8xx) || defined(CONFIG_4xx))
404 set_dabr(0); 418 set_dabr(0);
405 set_iabr(0); 419 set_iabr(0);
406#endif 420#endif
@@ -677,7 +691,7 @@ bpt_cmds(void)
677 691
678 cmd = inchar(); 692 cmd = inchar();
679 switch (cmd) { 693 switch (cmd) {
680#if !defined(CONFIG_8xx) 694#if ! (defined(CONFIG_8xx) || defined(CONFIG_4xx))
681 case 'd': 695 case 'd':
682 mode = 7; 696 mode = 7;
683 cmd = inchar(); 697 cmd = inchar();
@@ -792,7 +806,7 @@ backtrace(struct pt_regs *excp)
792 for (; sp != 0; sp = stack[0]) { 806 for (; sp != 0; sp = stack[0]) {
793 if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) 807 if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
794 break; 808 break;
795 printf("[%.8lx] ", stack); 809 printf("[%.8lx] ", stack[0]);
796 xmon_print_symbol(stack[1], " ", "\n"); 810 xmon_print_symbol(stack[1], " ", "\n");
797 if (stack[1] == (unsigned) &ret_from_except 811 if (stack[1] == (unsigned) &ret_from_except
798 || stack[1] == (unsigned) &ret_from_except_full 812 || stack[1] == (unsigned) &ret_from_except_full
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2f4f70c4dbb2..b216ca659cdf 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -460,8 +460,7 @@ config S390_HYPFS_FS
460 information in an s390 hypervisor environment. 460 information in an s390 hypervisor environment.
461 461
462config KEXEC 462config KEXEC
463 bool "kexec system call (EXPERIMENTAL)" 463 bool "kexec system call"
464 depends on EXPERIMENTAL
465 help 464 help
466 kexec is a system call that implements the ability to shutdown your 465 kexec is a system call that implements the ability to shutdown your
467 current kernel, and to start another kernel. It is like a reboot 466 current kernel, and to start another kernel. It is like a reboot
@@ -487,8 +486,22 @@ source "drivers/net/Kconfig"
487 486
488source "fs/Kconfig" 487source "fs/Kconfig"
489 488
489menu "Instrumentation Support"
490
490source "arch/s390/oprofile/Kconfig" 491source "arch/s390/oprofile/Kconfig"
491 492
493config KPROBES
494 bool "Kprobes (EXPERIMENTAL)"
495 depends on EXPERIMENTAL && MODULES
496 help
497 Kprobes allows you to trap at almost any kernel address and
498 execute a callback function. register_kprobe() establishes
499 a probepoint and specifies the callback. Kprobes is useful
500 for kernel debugging, non-intrusive instrumentation and testing.
501 If in doubt, say "N".
502
503endmenu
504
492source "arch/s390/Kconfig.debug" 505source "arch/s390/Kconfig.debug"
493 506
494source "security/Kconfig" 507source "security/Kconfig"
diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h
index 71d65eb30650..0429481dea63 100644
--- a/arch/s390/appldata/appldata.h
+++ b/arch/s390/appldata/appldata.h
@@ -29,22 +29,6 @@
29#define CTL_APPLDATA_NET_SUM 2125 29#define CTL_APPLDATA_NET_SUM 2125
30#define CTL_APPLDATA_PROC 2126 30#define CTL_APPLDATA_PROC 2126
31 31
32#ifndef CONFIG_64BIT
33
34#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */
35#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */
36#define APPLDATA_GEN_EVENT_RECORD 0x02
37#define APPLDATA_START_CONFIG_REC 0x03
38
39#else
40
41#define APPLDATA_START_INTERVAL_REC 0x80
42#define APPLDATA_STOP_REC 0x81
43#define APPLDATA_GEN_EVENT_RECORD 0x82
44#define APPLDATA_START_CONFIG_REC 0x83
45
46#endif /* CONFIG_64BIT */
47
48#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) 32#define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x)
49#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) 33#define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x)
50#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) 34#define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x)
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index a0a94e0ef8d1..b69ed742f981 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -14,20 +14,20 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <asm/uaccess.h>
18#include <asm/io.h>
19#include <asm/smp.h>
20#include <linux/interrupt.h> 17#include <linux/interrupt.h>
21#include <linux/proc_fs.h> 18#include <linux/proc_fs.h>
22#include <linux/page-flags.h> 19#include <linux/page-flags.h>
23#include <linux/swap.h> 20#include <linux/swap.h>
24#include <linux/pagemap.h> 21#include <linux/pagemap.h>
25#include <linux/sysctl.h> 22#include <linux/sysctl.h>
26#include <asm/timer.h>
27//#include <linux/kernel_stat.h>
28#include <linux/notifier.h> 23#include <linux/notifier.h>
29#include <linux/cpu.h> 24#include <linux/cpu.h>
30#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include <asm/appldata.h>
27#include <asm/timer.h>
28#include <asm/uaccess.h>
29#include <asm/io.h>
30#include <asm/smp.h>
31 31
32#include "appldata.h" 32#include "appldata.h"
33 33
@@ -39,34 +39,6 @@
39 39
40#define TOD_MICRO 0x01000 /* nr. of TOD clock units 40#define TOD_MICRO 0x01000 /* nr. of TOD clock units
41 for 1 microsecond */ 41 for 1 microsecond */
42
43/*
44 * Parameter list for DIAGNOSE X'DC'
45 */
46#ifndef CONFIG_64BIT
47struct appldata_parameter_list {
48 u16 diag; /* The DIAGNOSE code X'00DC' */
49 u8 function; /* The function code for the DIAGNOSE */
50 u8 parlist_length; /* Length of the parameter list */
51 u32 product_id_addr; /* Address of the 16-byte product ID */
52 u16 reserved;
53 u16 buffer_length; /* Length of the application data buffer */
54 u32 buffer_addr; /* Address of the application data buffer */
55};
56#else
57struct appldata_parameter_list {
58 u16 diag;
59 u8 function;
60 u8 parlist_length;
61 u32 unused01;
62 u16 reserved;
63 u16 buffer_length;
64 u32 unused02;
65 u64 product_id_addr;
66 u64 buffer_addr;
67};
68#endif /* CONFIG_64BIT */
69
70/* 42/*
71 * /proc entries (sysctl) 43 * /proc entries (sysctl)
72 */ 44 */
@@ -181,46 +153,17 @@ static void appldata_work_fn(void *data)
181int appldata_diag(char record_nr, u16 function, unsigned long buffer, 153int appldata_diag(char record_nr, u16 function, unsigned long buffer,
182 u16 length, char *mod_lvl) 154 u16 length, char *mod_lvl)
183{ 155{
184 unsigned long ry; 156 struct appldata_product_id id = {
185 struct appldata_product_id {
186 char prod_nr[7]; /* product nr. */
187 char prod_fn[2]; /* product function */
188 char record_nr; /* record nr. */
189 char version_nr[2]; /* version */
190 char release_nr[2]; /* release */
191 char mod_lvl[2]; /* modification lvl. */
192 } appldata_product_id = {
193 /* all strings are EBCDIC, record_nr is byte */
194 .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4, 157 .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4,
195 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */ 158 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */
196 .prod_fn = {0xD5, 0xD3}, /* "NL" */ 159 .prod_fn = 0xD5D3, /* "NL" */
197 .record_nr = record_nr, 160 .record_nr = record_nr,
198 .version_nr = {0xF2, 0xF6}, /* "26" */ 161 .version_nr = 0xF2F6, /* "26" */
199 .release_nr = {0xF0, 0xF1}, /* "01" */ 162 .release_nr = 0xF0F1, /* "01" */
200 .mod_lvl = {mod_lvl[0], mod_lvl[1]}, 163 .mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1],
201 };
202 struct appldata_parameter_list appldata_parameter_list = {
203 .diag = 0xDC,
204 .function = function,
205 .parlist_length =
206 sizeof(appldata_parameter_list),
207 .buffer_length = length,
208 .product_id_addr =
209 (unsigned long) &appldata_product_id,
210 .buffer_addr = virt_to_phys((void *) buffer)
211 }; 164 };
212 165
213 if (!MACHINE_IS_VM) 166 return appldata_asm(&id, function, (void *) buffer, length);
214 return -ENOSYS;
215 ry = -1;
216 asm volatile(
217 "diag %1,%0,0xDC\n\t"
218 : "=d" (ry)
219 : "d" (&appldata_parameter_list),
220 "m" (appldata_parameter_list),
221 "m" (appldata_product_id)
222 : "cc");
223 return (int) ry;
224} 167}
225/************************ timer, work, DIAG <END> ****************************/ 168/************************ timer, work, DIAG <END> ****************************/
226 169
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index 161acc5c8a1b..76a15523ae9e 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -16,6 +16,7 @@
16#include <linux/kernel_stat.h> 16#include <linux/kernel_stat.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <asm/appldata.h>
19#include <asm/smp.h> 20#include <asm/smp.h>
20 21
21#include "appldata.h" 22#include "appldata.h"
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 5713c7e5bd16..15c9eec02928 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -16,9 +16,9 @@
16 * 16 *
17 */ 17 */
18 18
19#include <crypto/algapi.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/crypto.h>
22#include "crypt_s390.h" 22#include "crypt_s390.h"
23 23
24#define AES_MIN_KEY_SIZE 16 24#define AES_MIN_KEY_SIZE 16
@@ -34,13 +34,16 @@ int has_aes_256 = 0;
34struct s390_aes_ctx { 34struct s390_aes_ctx {
35 u8 iv[AES_BLOCK_SIZE]; 35 u8 iv[AES_BLOCK_SIZE];
36 u8 key[AES_MAX_KEY_SIZE]; 36 u8 key[AES_MAX_KEY_SIZE];
37 long enc;
38 long dec;
37 int key_len; 39 int key_len;
38}; 40};
39 41
40static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 42static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
41 unsigned int key_len, u32 *flags) 43 unsigned int key_len)
42{ 44{
43 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); 45 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
46 u32 *flags = &tfm->crt_flags;
44 47
45 switch (key_len) { 48 switch (key_len) {
46 case 16: 49 case 16:
@@ -110,133 +113,206 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
110 } 113 }
111} 114}
112 115
113static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
114 const u8 *in, unsigned int nbytes)
115{
116 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
117 int ret;
118 116
119 /* only use complete blocks */ 117static struct crypto_alg aes_alg = {
120 nbytes &= ~(AES_BLOCK_SIZE - 1); 118 .cra_name = "aes",
119 .cra_driver_name = "aes-s390",
120 .cra_priority = CRYPT_S390_PRIORITY,
121 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
122 .cra_blocksize = AES_BLOCK_SIZE,
123 .cra_ctxsize = sizeof(struct s390_aes_ctx),
124 .cra_module = THIS_MODULE,
125 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
126 .cra_u = {
127 .cipher = {
128 .cia_min_keysize = AES_MIN_KEY_SIZE,
129 .cia_max_keysize = AES_MAX_KEY_SIZE,
130 .cia_setkey = aes_set_key,
131 .cia_encrypt = aes_encrypt,
132 .cia_decrypt = aes_decrypt,
133 }
134 }
135};
136
137static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
138 unsigned int key_len)
139{
140 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
121 141
122 switch (sctx->key_len) { 142 switch (key_len) {
123 case 16: 143 case 16:
124 ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes); 144 sctx->enc = KM_AES_128_ENCRYPT;
125 BUG_ON((ret < 0) || (ret != nbytes)); 145 sctx->dec = KM_AES_128_DECRYPT;
126 break; 146 break;
127 case 24: 147 case 24:
128 ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes); 148 sctx->enc = KM_AES_192_ENCRYPT;
129 BUG_ON((ret < 0) || (ret != nbytes)); 149 sctx->dec = KM_AES_192_DECRYPT;
130 break; 150 break;
131 case 32: 151 case 32:
132 ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes); 152 sctx->enc = KM_AES_256_ENCRYPT;
133 BUG_ON((ret < 0) || (ret != nbytes)); 153 sctx->dec = KM_AES_256_DECRYPT;
134 break; 154 break;
135 } 155 }
136 return nbytes; 156
157 return aes_set_key(tfm, in_key, key_len);
137} 158}
138 159
139static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 160static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
140 const u8 *in, unsigned int nbytes) 161 struct blkcipher_walk *walk)
141{ 162{
142 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 163 int ret = blkcipher_walk_virt(desc, walk);
143 int ret; 164 unsigned int nbytes;
144 165
145 /* only use complete blocks */ 166 while ((nbytes = walk->nbytes)) {
146 nbytes &= ~(AES_BLOCK_SIZE - 1); 167 /* only use complete blocks */
168 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
169 u8 *out = walk->dst.virt.addr;
170 u8 *in = walk->src.virt.addr;
147 171
148 switch (sctx->key_len) { 172 ret = crypt_s390_km(func, param, out, in, n);
149 case 16: 173 BUG_ON((ret < 0) || (ret != n));
150 ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes); 174
151 BUG_ON((ret < 0) || (ret != nbytes)); 175 nbytes &= AES_BLOCK_SIZE - 1;
152 break; 176 ret = blkcipher_walk_done(desc, walk, nbytes);
153 case 24:
154 ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
155 BUG_ON((ret < 0) || (ret != nbytes));
156 break;
157 case 32:
158 ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
159 BUG_ON((ret < 0) || (ret != nbytes));
160 break;
161 } 177 }
162 return nbytes; 178
179 return ret;
163} 180}
164 181
165static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 182static int ecb_aes_encrypt(struct blkcipher_desc *desc,
166 const u8 *in, unsigned int nbytes) 183 struct scatterlist *dst, struct scatterlist *src,
184 unsigned int nbytes)
167{ 185{
168 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 186 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
169 int ret; 187 struct blkcipher_walk walk;
170 188
171 /* only use complete blocks */ 189 blkcipher_walk_init(&walk, dst, src, nbytes);
172 nbytes &= ~(AES_BLOCK_SIZE - 1); 190 return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
191}
173 192
174 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 193static int ecb_aes_decrypt(struct blkcipher_desc *desc,
175 switch (sctx->key_len) { 194 struct scatterlist *dst, struct scatterlist *src,
195 unsigned int nbytes)
196{
197 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
198 struct blkcipher_walk walk;
199
200 blkcipher_walk_init(&walk, dst, src, nbytes);
201 return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
202}
203
204static struct crypto_alg ecb_aes_alg = {
205 .cra_name = "ecb(aes)",
206 .cra_driver_name = "ecb-aes-s390",
207 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
208 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
209 .cra_blocksize = AES_BLOCK_SIZE,
210 .cra_ctxsize = sizeof(struct s390_aes_ctx),
211 .cra_type = &crypto_blkcipher_type,
212 .cra_module = THIS_MODULE,
213 .cra_list = LIST_HEAD_INIT(ecb_aes_alg.cra_list),
214 .cra_u = {
215 .blkcipher = {
216 .min_keysize = AES_MIN_KEY_SIZE,
217 .max_keysize = AES_MAX_KEY_SIZE,
218 .setkey = ecb_aes_set_key,
219 .encrypt = ecb_aes_encrypt,
220 .decrypt = ecb_aes_decrypt,
221 }
222 }
223};
224
225static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
226 unsigned int key_len)
227{
228 struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
229
230 switch (key_len) {
176 case 16: 231 case 16:
177 ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes); 232 sctx->enc = KMC_AES_128_ENCRYPT;
178 BUG_ON((ret < 0) || (ret != nbytes)); 233 sctx->dec = KMC_AES_128_DECRYPT;
179 break; 234 break;
180 case 24: 235 case 24:
181 ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes); 236 sctx->enc = KMC_AES_192_ENCRYPT;
182 BUG_ON((ret < 0) || (ret != nbytes)); 237 sctx->dec = KMC_AES_192_DECRYPT;
183 break; 238 break;
184 case 32: 239 case 32:
185 ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes); 240 sctx->enc = KMC_AES_256_ENCRYPT;
186 BUG_ON((ret < 0) || (ret != nbytes)); 241 sctx->dec = KMC_AES_256_DECRYPT;
187 break; 242 break;
188 } 243 }
189 memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
190 244
191 return nbytes; 245 return aes_set_key(tfm, in_key, key_len);
192} 246}
193 247
194static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 248static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
195 const u8 *in, unsigned int nbytes) 249 struct blkcipher_walk *walk)
196{ 250{
197 struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm); 251 int ret = blkcipher_walk_virt(desc, walk);
198 int ret; 252 unsigned int nbytes = walk->nbytes;
199 253
200 /* only use complete blocks */ 254 if (!nbytes)
201 nbytes &= ~(AES_BLOCK_SIZE - 1); 255 goto out;
202 256
203 memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE); 257 memcpy(param, walk->iv, AES_BLOCK_SIZE);
204 switch (sctx->key_len) { 258 do {
205 case 16: 259 /* only use complete blocks */
206 ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes); 260 unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
207 BUG_ON((ret < 0) || (ret != nbytes)); 261 u8 *out = walk->dst.virt.addr;
208 break; 262 u8 *in = walk->src.virt.addr;
209 case 24: 263
210 ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes); 264 ret = crypt_s390_kmc(func, param, out, in, n);
211 BUG_ON((ret < 0) || (ret != nbytes)); 265 BUG_ON((ret < 0) || (ret != n));
212 break; 266
213 case 32: 267 nbytes &= AES_BLOCK_SIZE - 1;
214 ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes); 268 ret = blkcipher_walk_done(desc, walk, nbytes);
215 BUG_ON((ret < 0) || (ret != nbytes)); 269 } while ((nbytes = walk->nbytes));
216 break; 270 memcpy(walk->iv, param, AES_BLOCK_SIZE);
217 } 271
218 return nbytes; 272out:
273 return ret;
219} 274}
220 275
276static int cbc_aes_encrypt(struct blkcipher_desc *desc,
277 struct scatterlist *dst, struct scatterlist *src,
278 unsigned int nbytes)
279{
280 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
281 struct blkcipher_walk walk;
221 282
222static struct crypto_alg aes_alg = { 283 blkcipher_walk_init(&walk, dst, src, nbytes);
223 .cra_name = "aes", 284 return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
224 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 285}
286
287static int cbc_aes_decrypt(struct blkcipher_desc *desc,
288 struct scatterlist *dst, struct scatterlist *src,
289 unsigned int nbytes)
290{
291 struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
292 struct blkcipher_walk walk;
293
294 blkcipher_walk_init(&walk, dst, src, nbytes);
295 return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
296}
297
298static struct crypto_alg cbc_aes_alg = {
299 .cra_name = "cbc(aes)",
300 .cra_driver_name = "cbc-aes-s390",
301 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
302 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
225 .cra_blocksize = AES_BLOCK_SIZE, 303 .cra_blocksize = AES_BLOCK_SIZE,
226 .cra_ctxsize = sizeof(struct s390_aes_ctx), 304 .cra_ctxsize = sizeof(struct s390_aes_ctx),
305 .cra_type = &crypto_blkcipher_type,
227 .cra_module = THIS_MODULE, 306 .cra_module = THIS_MODULE,
228 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), 307 .cra_list = LIST_HEAD_INIT(cbc_aes_alg.cra_list),
229 .cra_u = { 308 .cra_u = {
230 .cipher = { 309 .blkcipher = {
231 .cia_min_keysize = AES_MIN_KEY_SIZE, 310 .min_keysize = AES_MIN_KEY_SIZE,
232 .cia_max_keysize = AES_MAX_KEY_SIZE, 311 .max_keysize = AES_MAX_KEY_SIZE,
233 .cia_setkey = aes_set_key, 312 .ivsize = AES_BLOCK_SIZE,
234 .cia_encrypt = aes_encrypt, 313 .setkey = cbc_aes_set_key,
235 .cia_decrypt = aes_decrypt, 314 .encrypt = cbc_aes_encrypt,
236 .cia_encrypt_ecb = aes_encrypt_ecb, 315 .decrypt = cbc_aes_decrypt,
237 .cia_decrypt_ecb = aes_decrypt_ecb,
238 .cia_encrypt_cbc = aes_encrypt_cbc,
239 .cia_decrypt_cbc = aes_decrypt_cbc,
240 } 316 }
241 } 317 }
242}; 318};
@@ -256,13 +332,40 @@ static int __init aes_init(void)
256 return -ENOSYS; 332 return -ENOSYS;
257 333
258 ret = crypto_register_alg(&aes_alg); 334 ret = crypto_register_alg(&aes_alg);
259 if (ret != 0) 335 if (ret != 0) {
260 printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n"); 336 printk(KERN_INFO "crypt_s390: aes-s390 couldn't be loaded.\n");
337 goto aes_err;
338 }
339
340 ret = crypto_register_alg(&ecb_aes_alg);
341 if (ret != 0) {
342 printk(KERN_INFO
343 "crypt_s390: ecb-aes-s390 couldn't be loaded.\n");
344 goto ecb_aes_err;
345 }
346
347 ret = crypto_register_alg(&cbc_aes_alg);
348 if (ret != 0) {
349 printk(KERN_INFO
350 "crypt_s390: cbc-aes-s390 couldn't be loaded.\n");
351 goto cbc_aes_err;
352 }
353
354out:
261 return ret; 355 return ret;
356
357cbc_aes_err:
358 crypto_unregister_alg(&ecb_aes_alg);
359ecb_aes_err:
360 crypto_unregister_alg(&aes_alg);
361aes_err:
362 goto out;
262} 363}
263 364
264static void __exit aes_fini(void) 365static void __exit aes_fini(void)
265{ 366{
367 crypto_unregister_alg(&cbc_aes_alg);
368 crypto_unregister_alg(&ecb_aes_alg);
266 crypto_unregister_alg(&aes_alg); 369 crypto_unregister_alg(&aes_alg);
267} 370}
268 371
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h
index d1c259a7fe33..efd836c2e4a6 100644
--- a/arch/s390/crypto/crypt_s390.h
+++ b/arch/s390/crypto/crypt_s390.h
@@ -20,6 +20,9 @@
20#define CRYPT_S390_OP_MASK 0xFF00 20#define CRYPT_S390_OP_MASK 0xFF00
21#define CRYPT_S390_FUNC_MASK 0x00FF 21#define CRYPT_S390_FUNC_MASK 0x00FF
22 22
23#define CRYPT_S390_PRIORITY 300
24#define CRYPT_S390_COMPOSITE_PRIORITY 400
25
23/* s930 cryptographic operations */ 26/* s930 cryptographic operations */
24enum crypt_s390_operations { 27enum crypt_s390_operations {
25 CRYPT_S390_KM = 0x0100, 28 CRYPT_S390_KM = 0x0100,
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index b3f7496a79b4..2aba04852fe3 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -13,9 +13,10 @@
13 * (at your option) any later version. 13 * (at your option) any later version.
14 * 14 *
15 */ 15 */
16
17#include <crypto/algapi.h>
16#include <linux/init.h> 18#include <linux/init.h>
17#include <linux/module.h> 19#include <linux/module.h>
18#include <linux/crypto.h>
19 20
20#include "crypt_s390.h" 21#include "crypt_s390.h"
21#include "crypto_des.h" 22#include "crypto_des.h"
@@ -45,9 +46,10 @@ struct crypt_s390_des3_192_ctx {
45}; 46};
46 47
47static int des_setkey(struct crypto_tfm *tfm, const u8 *key, 48static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
48 unsigned int keylen, u32 *flags) 49 unsigned int keylen)
49{ 50{
50 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm); 51 struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
52 u32 *flags = &tfm->crt_flags;
51 int ret; 53 int ret;
52 54
53 /* test if key is valid (not a weak key) */ 55 /* test if key is valid (not a weak key) */
@@ -71,85 +73,159 @@ static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
71 crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE); 73 crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
72} 74}
73 75
74static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out, 76static struct crypto_alg des_alg = {
75 const u8 *in, unsigned int nbytes) 77 .cra_name = "des",
78 .cra_driver_name = "des-s390",
79 .cra_priority = CRYPT_S390_PRIORITY,
80 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
81 .cra_blocksize = DES_BLOCK_SIZE,
82 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
83 .cra_module = THIS_MODULE,
84 .cra_list = LIST_HEAD_INIT(des_alg.cra_list),
85 .cra_u = {
86 .cipher = {
87 .cia_min_keysize = DES_KEY_SIZE,
88 .cia_max_keysize = DES_KEY_SIZE,
89 .cia_setkey = des_setkey,
90 .cia_encrypt = des_encrypt,
91 .cia_decrypt = des_decrypt,
92 }
93 }
94};
95
96static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
97 void *param, struct blkcipher_walk *walk)
76{ 98{
77 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 99 int ret = blkcipher_walk_virt(desc, walk);
78 int ret; 100 unsigned int nbytes;
101
102 while ((nbytes = walk->nbytes)) {
103 /* only use complete blocks */
104 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
105 u8 *out = walk->dst.virt.addr;
106 u8 *in = walk->src.virt.addr;
79 107
80 /* only use complete blocks */ 108 ret = crypt_s390_km(func, param, out, in, n);
81 nbytes &= ~(DES_BLOCK_SIZE - 1); 109 BUG_ON((ret < 0) || (ret != n));
82 ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
83 BUG_ON((ret < 0) || (ret != nbytes));
84 110
85 return nbytes; 111 nbytes &= DES_BLOCK_SIZE - 1;
112 ret = blkcipher_walk_done(desc, walk, nbytes);
113 }
114
115 return ret;
86} 116}
87 117
88static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out, 118static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
89 const u8 *in, unsigned int nbytes) 119 void *param, struct blkcipher_walk *walk)
90{ 120{
91 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 121 int ret = blkcipher_walk_virt(desc, walk);
92 int ret; 122 unsigned int nbytes = walk->nbytes;
123
124 if (!nbytes)
125 goto out;
126
127 memcpy(param, walk->iv, DES_BLOCK_SIZE);
128 do {
129 /* only use complete blocks */
130 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
131 u8 *out = walk->dst.virt.addr;
132 u8 *in = walk->src.virt.addr;
93 133
94 /* only use complete blocks */ 134 ret = crypt_s390_kmc(func, param, out, in, n);
95 nbytes &= ~(DES_BLOCK_SIZE - 1); 135 BUG_ON((ret < 0) || (ret != n));
96 ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
97 BUG_ON((ret < 0) || (ret != nbytes));
98 136
99 return nbytes; 137 nbytes &= DES_BLOCK_SIZE - 1;
138 ret = blkcipher_walk_done(desc, walk, nbytes);
139 } while ((nbytes = walk->nbytes));
140 memcpy(walk->iv, param, DES_BLOCK_SIZE);
141
142out:
143 return ret;
100} 144}
101 145
102static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out, 146static int ecb_des_encrypt(struct blkcipher_desc *desc,
103 const u8 *in, unsigned int nbytes) 147 struct scatterlist *dst, struct scatterlist *src,
148 unsigned int nbytes)
104{ 149{
105 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 150 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
106 int ret; 151 struct blkcipher_walk walk;
107 152
108 /* only use complete blocks */ 153 blkcipher_walk_init(&walk, dst, src, nbytes);
109 nbytes &= ~(DES_BLOCK_SIZE - 1); 154 return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
155}
110 156
111 memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE); 157static int ecb_des_decrypt(struct blkcipher_desc *desc,
112 ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes); 158 struct scatterlist *dst, struct scatterlist *src,
113 BUG_ON((ret < 0) || (ret != nbytes)); 159 unsigned int nbytes)
160{
161 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
162 struct blkcipher_walk walk;
114 163
115 memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE); 164 blkcipher_walk_init(&walk, dst, src, nbytes);
116 return nbytes; 165 return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
117} 166}
118 167
119static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out, 168static struct crypto_alg ecb_des_alg = {
120 const u8 *in, unsigned int nbytes) 169 .cra_name = "ecb(des)",
170 .cra_driver_name = "ecb-des-s390",
171 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
172 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
173 .cra_blocksize = DES_BLOCK_SIZE,
174 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
175 .cra_type = &crypto_blkcipher_type,
176 .cra_module = THIS_MODULE,
177 .cra_list = LIST_HEAD_INIT(ecb_des_alg.cra_list),
178 .cra_u = {
179 .blkcipher = {
180 .min_keysize = DES_KEY_SIZE,
181 .max_keysize = DES_KEY_SIZE,
182 .setkey = des_setkey,
183 .encrypt = ecb_des_encrypt,
184 .decrypt = ecb_des_decrypt,
185 }
186 }
187};
188
189static int cbc_des_encrypt(struct blkcipher_desc *desc,
190 struct scatterlist *dst, struct scatterlist *src,
191 unsigned int nbytes)
121{ 192{
122 struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm); 193 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
123 int ret; 194 struct blkcipher_walk walk;
124 195
125 /* only use complete blocks */ 196 blkcipher_walk_init(&walk, dst, src, nbytes);
126 nbytes &= ~(DES_BLOCK_SIZE - 1); 197 return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
198}
127 199
128 memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE); 200static int cbc_des_decrypt(struct blkcipher_desc *desc,
129 ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes); 201 struct scatterlist *dst, struct scatterlist *src,
130 BUG_ON((ret < 0) || (ret != nbytes)); 202 unsigned int nbytes)
203{
204 struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
205 struct blkcipher_walk walk;
131 206
132 return nbytes; 207 blkcipher_walk_init(&walk, dst, src, nbytes);
208 return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
133} 209}
134 210
135static struct crypto_alg des_alg = { 211static struct crypto_alg cbc_des_alg = {
136 .cra_name = "des", 212 .cra_name = "cbc(des)",
137 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 213 .cra_driver_name = "cbc-des-s390",
214 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
215 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
138 .cra_blocksize = DES_BLOCK_SIZE, 216 .cra_blocksize = DES_BLOCK_SIZE,
139 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx), 217 .cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
218 .cra_type = &crypto_blkcipher_type,
140 .cra_module = THIS_MODULE, 219 .cra_module = THIS_MODULE,
141 .cra_list = LIST_HEAD_INIT(des_alg.cra_list), 220 .cra_list = LIST_HEAD_INIT(cbc_des_alg.cra_list),
142 .cra_u = { 221 .cra_u = {
143 .cipher = { 222 .blkcipher = {
144 .cia_min_keysize = DES_KEY_SIZE, 223 .min_keysize = DES_KEY_SIZE,
145 .cia_max_keysize = DES_KEY_SIZE, 224 .max_keysize = DES_KEY_SIZE,
146 .cia_setkey = des_setkey, 225 .ivsize = DES_BLOCK_SIZE,
147 .cia_encrypt = des_encrypt, 226 .setkey = des_setkey,
148 .cia_decrypt = des_decrypt, 227 .encrypt = cbc_des_encrypt,
149 .cia_encrypt_ecb = des_encrypt_ecb, 228 .decrypt = cbc_des_decrypt,
150 .cia_decrypt_ecb = des_decrypt_ecb,
151 .cia_encrypt_cbc = des_encrypt_cbc,
152 .cia_decrypt_cbc = des_decrypt_cbc,
153 } 229 }
154 } 230 }
155}; 231};
@@ -167,11 +243,12 @@ static struct crypto_alg des_alg = {
167 * 243 *
168 */ 244 */
169static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, 245static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key,
170 unsigned int keylen, u32 *flags) 246 unsigned int keylen)
171{ 247{
172 int i, ret; 248 int i, ret;
173 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm); 249 struct crypt_s390_des3_128_ctx *dctx = crypto_tfm_ctx(tfm);
174 const u8* temp_key = key; 250 const u8 *temp_key = key;
251 u32 *flags = &tfm->crt_flags;
175 252
176 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { 253 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
177 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; 254 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
@@ -202,89 +279,111 @@ static void des3_128_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
202 DES3_128_BLOCK_SIZE); 279 DES3_128_BLOCK_SIZE);
203} 280}
204 281
205static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc, 282static struct crypto_alg des3_128_alg = {
206 u8 *out, const u8 *in, 283 .cra_name = "des3_ede128",
207 unsigned int nbytes) 284 .cra_driver_name = "des3_ede128-s390",
208{ 285 .cra_priority = CRYPT_S390_PRIORITY,
209 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 286 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
210 int ret; 287 .cra_blocksize = DES3_128_BLOCK_SIZE,
288 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
289 .cra_module = THIS_MODULE,
290 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
291 .cra_u = {
292 .cipher = {
293 .cia_min_keysize = DES3_128_KEY_SIZE,
294 .cia_max_keysize = DES3_128_KEY_SIZE,
295 .cia_setkey = des3_128_setkey,
296 .cia_encrypt = des3_128_encrypt,
297 .cia_decrypt = des3_128_decrypt,
298 }
299 }
300};
211 301
212 /* only use complete blocks */ 302static int ecb_des3_128_encrypt(struct blkcipher_desc *desc,
213 nbytes &= ~(DES3_128_BLOCK_SIZE - 1); 303 struct scatterlist *dst,
214 ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes); 304 struct scatterlist *src, unsigned int nbytes)
215 BUG_ON((ret < 0) || (ret != nbytes)); 305{
306 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
307 struct blkcipher_walk walk;
216 308
217 return nbytes; 309 blkcipher_walk_init(&walk, dst, src, nbytes);
310 return ecb_desall_crypt(desc, KM_TDEA_128_ENCRYPT, sctx->key, &walk);
218} 311}
219 312
220static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc, 313static int ecb_des3_128_decrypt(struct blkcipher_desc *desc,
221 u8 *out, const u8 *in, 314 struct scatterlist *dst,
222 unsigned int nbytes) 315 struct scatterlist *src, unsigned int nbytes)
223{ 316{
224 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 317 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
225 int ret; 318 struct blkcipher_walk walk;
226 319
227 /* only use complete blocks */ 320 blkcipher_walk_init(&walk, dst, src, nbytes);
228 nbytes &= ~(DES3_128_BLOCK_SIZE - 1); 321 return ecb_desall_crypt(desc, KM_TDEA_128_DECRYPT, sctx->key, &walk);
229 ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
230 BUG_ON((ret < 0) || (ret != nbytes));
231
232 return nbytes;
233} 322}
234 323
235static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc, 324static struct crypto_alg ecb_des3_128_alg = {
236 u8 *out, const u8 *in, 325 .cra_name = "ecb(des3_ede128)",
237 unsigned int nbytes) 326 .cra_driver_name = "ecb-des3_ede128-s390",
238{ 327 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
239 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 328 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
240 int ret; 329 .cra_blocksize = DES3_128_BLOCK_SIZE,
241 330 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
242 /* only use complete blocks */ 331 .cra_type = &crypto_blkcipher_type,
243 nbytes &= ~(DES3_128_BLOCK_SIZE - 1); 332 .cra_module = THIS_MODULE,
333 .cra_list = LIST_HEAD_INIT(
334 ecb_des3_128_alg.cra_list),
335 .cra_u = {
336 .blkcipher = {
337 .min_keysize = DES3_128_KEY_SIZE,
338 .max_keysize = DES3_128_KEY_SIZE,
339 .setkey = des3_128_setkey,
340 .encrypt = ecb_des3_128_encrypt,
341 .decrypt = ecb_des3_128_decrypt,
342 }
343 }
344};
244 345
245 memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE); 346static int cbc_des3_128_encrypt(struct blkcipher_desc *desc,
246 ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes); 347 struct scatterlist *dst,
247 BUG_ON((ret < 0) || (ret != nbytes)); 348 struct scatterlist *src, unsigned int nbytes)
349{
350 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
351 struct blkcipher_walk walk;
248 352
249 memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE); 353 blkcipher_walk_init(&walk, dst, src, nbytes);
250 return nbytes; 354 return cbc_desall_crypt(desc, KMC_TDEA_128_ENCRYPT, sctx->iv, &walk);
251} 355}
252 356
253static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc, 357static int cbc_des3_128_decrypt(struct blkcipher_desc *desc,
254 u8 *out, const u8 *in, 358 struct scatterlist *dst,
255 unsigned int nbytes) 359 struct scatterlist *src, unsigned int nbytes)
256{ 360{
257 struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm); 361 struct crypt_s390_des3_128_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
258 int ret; 362 struct blkcipher_walk walk;
259
260 /* only use complete blocks */
261 nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
262
263 memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
264 ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
265 BUG_ON((ret < 0) || (ret != nbytes));
266 363
267 return nbytes; 364 blkcipher_walk_init(&walk, dst, src, nbytes);
365 return cbc_desall_crypt(desc, KMC_TDEA_128_DECRYPT, sctx->iv, &walk);
268} 366}
269 367
270static struct crypto_alg des3_128_alg = { 368static struct crypto_alg cbc_des3_128_alg = {
271 .cra_name = "des3_ede128", 369 .cra_name = "cbc(des3_ede128)",
272 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 370 .cra_driver_name = "cbc-des3_ede128-s390",
371 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
372 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
273 .cra_blocksize = DES3_128_BLOCK_SIZE, 373 .cra_blocksize = DES3_128_BLOCK_SIZE,
274 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx), 374 .cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
375 .cra_type = &crypto_blkcipher_type,
275 .cra_module = THIS_MODULE, 376 .cra_module = THIS_MODULE,
276 .cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list), 377 .cra_list = LIST_HEAD_INIT(
378 cbc_des3_128_alg.cra_list),
277 .cra_u = { 379 .cra_u = {
278 .cipher = { 380 .blkcipher = {
279 .cia_min_keysize = DES3_128_KEY_SIZE, 381 .min_keysize = DES3_128_KEY_SIZE,
280 .cia_max_keysize = DES3_128_KEY_SIZE, 382 .max_keysize = DES3_128_KEY_SIZE,
281 .cia_setkey = des3_128_setkey, 383 .ivsize = DES3_128_BLOCK_SIZE,
282 .cia_encrypt = des3_128_encrypt, 384 .setkey = des3_128_setkey,
283 .cia_decrypt = des3_128_decrypt, 385 .encrypt = cbc_des3_128_encrypt,
284 .cia_encrypt_ecb = des3_128_encrypt_ecb, 386 .decrypt = cbc_des3_128_decrypt,
285 .cia_decrypt_ecb = des3_128_decrypt_ecb,
286 .cia_encrypt_cbc = des3_128_encrypt_cbc,
287 .cia_decrypt_cbc = des3_128_decrypt_cbc,
288 } 387 }
289 } 388 }
290}; 389};
@@ -303,11 +402,12 @@ static struct crypto_alg des3_128_alg = {
303 * 402 *
304 */ 403 */
305static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, 404static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
306 unsigned int keylen, u32 *flags) 405 unsigned int keylen)
307{ 406{
308 int i, ret; 407 int i, ret;
309 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm); 408 struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
310 const u8* temp_key = key; 409 const u8 *temp_key = key;
410 u32 *flags = &tfm->crt_flags;
311 411
312 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 412 if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
313 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], 413 memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
@@ -341,89 +441,111 @@ static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
341 DES3_192_BLOCK_SIZE); 441 DES3_192_BLOCK_SIZE);
342} 442}
343 443
344static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc, 444static struct crypto_alg des3_192_alg = {
345 u8 *out, const u8 *in, 445 .cra_name = "des3_ede",
346 unsigned int nbytes) 446 .cra_driver_name = "des3_ede-s390",
347{ 447 .cra_priority = CRYPT_S390_PRIORITY,
348 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 448 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
349 int ret; 449 .cra_blocksize = DES3_192_BLOCK_SIZE,
450 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
451 .cra_module = THIS_MODULE,
452 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
453 .cra_u = {
454 .cipher = {
455 .cia_min_keysize = DES3_192_KEY_SIZE,
456 .cia_max_keysize = DES3_192_KEY_SIZE,
457 .cia_setkey = des3_192_setkey,
458 .cia_encrypt = des3_192_encrypt,
459 .cia_decrypt = des3_192_decrypt,
460 }
461 }
462};
350 463
351 /* only use complete blocks */ 464static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
352 nbytes &= ~(DES3_192_BLOCK_SIZE - 1); 465 struct scatterlist *dst,
353 ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes); 466 struct scatterlist *src, unsigned int nbytes)
354 BUG_ON((ret < 0) || (ret != nbytes)); 467{
468 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
469 struct blkcipher_walk walk;
355 470
356 return nbytes; 471 blkcipher_walk_init(&walk, dst, src, nbytes);
472 return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
357} 473}
358 474
359static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc, 475static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
360 u8 *out, const u8 *in, 476 struct scatterlist *dst,
361 unsigned int nbytes) 477 struct scatterlist *src, unsigned int nbytes)
362{ 478{
363 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 479 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
364 int ret; 480 struct blkcipher_walk walk;
365
366 /* only use complete blocks */
367 nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
368 ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
369 BUG_ON((ret < 0) || (ret != nbytes));
370 481
371 return nbytes; 482 blkcipher_walk_init(&walk, dst, src, nbytes);
483 return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
372} 484}
373 485
374static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc, 486static struct crypto_alg ecb_des3_192_alg = {
375 u8 *out, const u8 *in, 487 .cra_name = "ecb(des3_ede)",
376 unsigned int nbytes) 488 .cra_driver_name = "ecb-des3_ede-s390",
377{ 489 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
378 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 490 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
379 int ret; 491 .cra_blocksize = DES3_192_BLOCK_SIZE,
380 492 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
381 /* only use complete blocks */ 493 .cra_type = &crypto_blkcipher_type,
382 nbytes &= ~(DES3_192_BLOCK_SIZE - 1); 494 .cra_module = THIS_MODULE,
495 .cra_list = LIST_HEAD_INIT(
496 ecb_des3_192_alg.cra_list),
497 .cra_u = {
498 .blkcipher = {
499 .min_keysize = DES3_192_KEY_SIZE,
500 .max_keysize = DES3_192_KEY_SIZE,
501 .setkey = des3_192_setkey,
502 .encrypt = ecb_des3_192_encrypt,
503 .decrypt = ecb_des3_192_decrypt,
504 }
505 }
506};
383 507
384 memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE); 508static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
385 ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes); 509 struct scatterlist *dst,
386 BUG_ON((ret < 0) || (ret != nbytes)); 510 struct scatterlist *src, unsigned int nbytes)
511{
512 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
513 struct blkcipher_walk walk;
387 514
388 memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE); 515 blkcipher_walk_init(&walk, dst, src, nbytes);
389 return nbytes; 516 return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
390} 517}
391 518
392static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc, 519static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
393 u8 *out, const u8 *in, 520 struct scatterlist *dst,
394 unsigned int nbytes) 521 struct scatterlist *src, unsigned int nbytes)
395{ 522{
396 struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm); 523 struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
397 int ret; 524 struct blkcipher_walk walk;
398 525
399 /* only use complete blocks */ 526 blkcipher_walk_init(&walk, dst, src, nbytes);
400 nbytes &= ~(DES3_192_BLOCK_SIZE - 1); 527 return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
401
402 memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
403 ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
404 BUG_ON((ret < 0) || (ret != nbytes));
405
406 return nbytes;
407} 528}
408 529
409static struct crypto_alg des3_192_alg = { 530static struct crypto_alg cbc_des3_192_alg = {
410 .cra_name = "des3_ede", 531 .cra_name = "cbc(des3_ede)",
411 .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 532 .cra_driver_name = "cbc-des3_ede-s390",
533 .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY,
534 .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
412 .cra_blocksize = DES3_192_BLOCK_SIZE, 535 .cra_blocksize = DES3_192_BLOCK_SIZE,
413 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx), 536 .cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
537 .cra_type = &crypto_blkcipher_type,
414 .cra_module = THIS_MODULE, 538 .cra_module = THIS_MODULE,
415 .cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list), 539 .cra_list = LIST_HEAD_INIT(
540 cbc_des3_192_alg.cra_list),
416 .cra_u = { 541 .cra_u = {
417 .cipher = { 542 .blkcipher = {
418 .cia_min_keysize = DES3_192_KEY_SIZE, 543 .min_keysize = DES3_192_KEY_SIZE,
419 .cia_max_keysize = DES3_192_KEY_SIZE, 544 .max_keysize = DES3_192_KEY_SIZE,
420 .cia_setkey = des3_192_setkey, 545 .ivsize = DES3_192_BLOCK_SIZE,
421 .cia_encrypt = des3_192_encrypt, 546 .setkey = des3_192_setkey,
422 .cia_decrypt = des3_192_decrypt, 547 .encrypt = cbc_des3_192_encrypt,
423 .cia_encrypt_ecb = des3_192_encrypt_ecb, 548 .decrypt = cbc_des3_192_decrypt,
424 .cia_decrypt_ecb = des3_192_decrypt_ecb,
425 .cia_encrypt_cbc = des3_192_encrypt_cbc,
426 .cia_decrypt_cbc = des3_192_decrypt_cbc,
427 } 549 }
428 } 550 }
429}; 551};
@@ -437,22 +559,69 @@ static int init(void)
437 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)) 559 !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
438 return -ENOSYS; 560 return -ENOSYS;
439 561
440 ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1; 562 ret = crypto_register_alg(&des_alg);
441 ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2; 563 if (ret)
442 ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4; 564 goto des_err;
443 if (ret) { 565 ret = crypto_register_alg(&ecb_des_alg);
444 crypto_unregister_alg(&des3_192_alg); 566 if (ret)
445 crypto_unregister_alg(&des3_128_alg); 567 goto ecb_des_err;
446 crypto_unregister_alg(&des_alg); 568 ret = crypto_register_alg(&cbc_des_alg);
447 return -EEXIST; 569 if (ret)
448 } 570 goto cbc_des_err;
449 return 0; 571
572 ret = crypto_register_alg(&des3_128_alg);
573 if (ret)
574 goto des3_128_err;
575 ret = crypto_register_alg(&ecb_des3_128_alg);
576 if (ret)
577 goto ecb_des3_128_err;
578 ret = crypto_register_alg(&cbc_des3_128_alg);
579 if (ret)
580 goto cbc_des3_128_err;
581
582 ret = crypto_register_alg(&des3_192_alg);
583 if (ret)
584 goto des3_192_err;
585 ret = crypto_register_alg(&ecb_des3_192_alg);
586 if (ret)
587 goto ecb_des3_192_err;
588 ret = crypto_register_alg(&cbc_des3_192_alg);
589 if (ret)
590 goto cbc_des3_192_err;
591
592out:
593 return ret;
594
595cbc_des3_192_err:
596 crypto_unregister_alg(&ecb_des3_192_alg);
597ecb_des3_192_err:
598 crypto_unregister_alg(&des3_192_alg);
599des3_192_err:
600 crypto_unregister_alg(&cbc_des3_128_alg);
601cbc_des3_128_err:
602 crypto_unregister_alg(&ecb_des3_128_alg);
603ecb_des3_128_err:
604 crypto_unregister_alg(&des3_128_alg);
605des3_128_err:
606 crypto_unregister_alg(&cbc_des_alg);
607cbc_des_err:
608 crypto_unregister_alg(&ecb_des_alg);
609ecb_des_err:
610 crypto_unregister_alg(&des_alg);
611des_err:
612 goto out;
450} 613}
451 614
452static void __exit fini(void) 615static void __exit fini(void)
453{ 616{
617 crypto_unregister_alg(&cbc_des3_192_alg);
618 crypto_unregister_alg(&ecb_des3_192_alg);
454 crypto_unregister_alg(&des3_192_alg); 619 crypto_unregister_alg(&des3_192_alg);
620 crypto_unregister_alg(&cbc_des3_128_alg);
621 crypto_unregister_alg(&ecb_des3_128_alg);
455 crypto_unregister_alg(&des3_128_alg); 622 crypto_unregister_alg(&des3_128_alg);
623 crypto_unregister_alg(&cbc_des_alg);
624 crypto_unregister_alg(&ecb_des_alg);
456 crypto_unregister_alg(&des_alg); 625 crypto_unregister_alg(&des_alg);
457} 626}
458 627
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c
index 9d34a35b1aa5..49ca8690ee39 100644
--- a/arch/s390/crypto/sha1_s390.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -126,6 +126,8 @@ static void sha1_final(struct crypto_tfm *tfm, u8 *out)
126 126
127static struct crypto_alg alg = { 127static struct crypto_alg alg = {
128 .cra_name = "sha1", 128 .cra_name = "sha1",
129 .cra_driver_name = "sha1-s390",
130 .cra_priority = CRYPT_S390_PRIORITY,
129 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 131 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
130 .cra_blocksize = SHA1_BLOCK_SIZE, 132 .cra_blocksize = SHA1_BLOCK_SIZE,
131 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx), 133 .cra_ctxsize = sizeof(struct crypt_s390_sha1_ctx),
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index f573df30f31d..8e4e67503fe7 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -127,6 +127,8 @@ static void sha256_final(struct crypto_tfm *tfm, u8 *out)
127 127
128static struct crypto_alg alg = { 128static struct crypto_alg alg = {
129 .cra_name = "sha256", 129 .cra_name = "sha256",
130 .cra_driver_name = "sha256-s390",
131 .cra_priority = CRYPT_S390_PRIORITY,
130 .cra_flags = CRYPTO_ALG_TYPE_DIGEST, 132 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
131 .cra_blocksize = SHA256_BLOCK_SIZE, 133 .cra_blocksize = SHA256_BLOCK_SIZE,
132 .cra_ctxsize = sizeof(struct s390_sha256_ctx), 134 .cra_ctxsize = sizeof(struct s390_sha256_ctx),
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index f1d4591eddbb..35da53986b1b 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -428,6 +428,7 @@ CONFIG_S390_TAPE_34XX=m
428# CONFIG_VMLOGRDR is not set 428# CONFIG_VMLOGRDR is not set
429# CONFIG_VMCP is not set 429# CONFIG_VMCP is not set
430# CONFIG_MONREADER is not set 430# CONFIG_MONREADER is not set
431CONFIG_MONWRITER=m
431 432
432# 433#
433# Cryptographic devices 434# Cryptographic devices
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h
index ea5567be00fc..f3dbd91965c6 100644
--- a/arch/s390/hypfs/hypfs.h
+++ b/arch/s390/hypfs/hypfs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/hypfs.h 2 * arch/s390/hypfs/hypfs.h
3 * Hypervisor filesystem for Linux on s390. 3 * Hypervisor filesystem for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2006 5 * Copyright (C) IBM Corp. 2006
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 1785bce2b919..75144efbb92b 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/hypfs_diag.c 2 * arch/s390/hypfs/hypfs_diag.c
3 * Hypervisor filesystem for Linux on s390. Diag 204 and 224 3 * Hypervisor filesystem for Linux on s390. Diag 204 and 224
4 * implementation. 4 * implementation.
5 * 5 *
@@ -432,12 +432,14 @@ static int diag204_probe(void)
432 432
433 buf = diag204_get_buffer(INFO_EXT, &pages); 433 buf = diag204_get_buffer(INFO_EXT, &pages);
434 if (!IS_ERR(buf)) { 434 if (!IS_ERR(buf)) {
435 if (diag204(SUBC_STIB7 | INFO_EXT, pages, buf) >= 0) { 435 if (diag204((unsigned long)SUBC_STIB7 |
436 (unsigned long)INFO_EXT, pages, buf) >= 0) {
436 diag204_store_sc = SUBC_STIB7; 437 diag204_store_sc = SUBC_STIB7;
437 diag204_info_type = INFO_EXT; 438 diag204_info_type = INFO_EXT;
438 goto out; 439 goto out;
439 } 440 }
440 if (diag204(SUBC_STIB6 | INFO_EXT, pages, buf) >= 0) { 441 if (diag204((unsigned long)SUBC_STIB6 |
442 (unsigned long)INFO_EXT, pages, buf) >= 0) {
441 diag204_store_sc = SUBC_STIB7; 443 diag204_store_sc = SUBC_STIB7;
442 diag204_info_type = INFO_EXT; 444 diag204_info_type = INFO_EXT;
443 goto out; 445 goto out;
@@ -452,7 +454,8 @@ static int diag204_probe(void)
452 rc = PTR_ERR(buf); 454 rc = PTR_ERR(buf);
453 goto fail_alloc; 455 goto fail_alloc;
454 } 456 }
455 if (diag204(SUBC_STIB4 | INFO_SIMPLE, pages, buf) >= 0) { 457 if (diag204((unsigned long)SUBC_STIB4 |
458 (unsigned long)INFO_SIMPLE, pages, buf) >= 0) {
456 diag204_store_sc = SUBC_STIB4; 459 diag204_store_sc = SUBC_STIB4;
457 diag204_info_type = INFO_SIMPLE; 460 diag204_info_type = INFO_SIMPLE;
458 goto out; 461 goto out;
@@ -476,7 +479,8 @@ static void *diag204_store(void)
476 buf = diag204_get_buffer(diag204_info_type, &pages); 479 buf = diag204_get_buffer(diag204_info_type, &pages);
477 if (IS_ERR(buf)) 480 if (IS_ERR(buf))
478 goto out; 481 goto out;
479 if (diag204(diag204_store_sc | diag204_info_type, pages, buf) < 0) 482 if (diag204((unsigned long)diag204_store_sc |
483 (unsigned long)diag204_info_type, pages, buf) < 0)
480 return ERR_PTR(-ENOSYS); 484 return ERR_PTR(-ENOSYS);
481out: 485out:
482 return buf; 486 return buf;
@@ -531,7 +535,7 @@ __init int hypfs_diag_init(void)
531 return rc; 535 return rc;
532} 536}
533 537
534__exit void hypfs_diag_exit(void) 538void hypfs_diag_exit(void)
535{ 539{
536 diag224_delete_name_table(); 540 diag224_delete_name_table();
537 diag204_free_buffer(); 541 diag204_free_buffer();
diff --git a/arch/s390/hypfs/hypfs_diag.h b/arch/s390/hypfs/hypfs_diag.h
index 793dea6b9bb6..256b384aebe1 100644
--- a/arch/s390/hypfs/hypfs_diag.h
+++ b/arch/s390/hypfs/hypfs_diag.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/hypfs_diag.h 2 * arch/s390/hypfs_diag.h
3 * Hypervisor filesystem for Linux on s390. 3 * Hypervisor filesystem for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2006 5 * Copyright (C) IBM Corp. 2006
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 18c091925ea5..bdade5f2e325 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * fs/hypfs/inode.c 2 * arch/s390/hypfs/inode.c
3 * Hypervisor filesystem for Linux on s390. 3 * Hypervisor filesystem for Linux on s390.
4 * 4 *
5 * Copyright (C) IBM Corp. 2006 5 * Copyright (C) IBM Corp. 2006
@@ -312,10 +312,12 @@ static void hypfs_kill_super(struct super_block *sb)
312{ 312{
313 struct hypfs_sb_info *sb_info = sb->s_fs_info; 313 struct hypfs_sb_info *sb_info = sb->s_fs_info;
314 314
315 hypfs_delete_tree(sb->s_root); 315 if (sb->s_root) {
316 hypfs_remove(sb_info->update_file); 316 hypfs_delete_tree(sb->s_root);
317 kfree(sb->s_fs_info); 317 hypfs_remove(sb_info->update_file);
318 sb->s_fs_info = NULL; 318 kfree(sb->s_fs_info);
319 sb->s_fs_info = NULL;
320 }
319 kill_litter_super(sb); 321 kill_litter_super(sb);
320} 322}
321 323
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 9a33ed6ca696..aa978978d3d1 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional
6 6
7obj-y := bitmap.o traps.o time.o process.o \ 7obj-y := bitmap.o traps.o time.o process.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o 9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o
10 10
11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) 11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) 12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
@@ -24,6 +24,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
24 24
25obj-$(CONFIG_VIRT_TIMER) += vtime.o 25obj-$(CONFIG_VIRT_TIMER) += vtime.o
26obj-$(CONFIG_STACKTRACE) += stacktrace.o 26obj-$(CONFIG_STACKTRACE) += stacktrace.o
27obj-$(CONFIG_KPROBES) += kprobes.o
27 28
28# Kexec part 29# Kexec part
29S390_KEXEC_OBJS := machine_kexec.o crash.o 30S390_KEXEC_OBJS := machine_kexec.o crash.o
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 5b5799ac8f83..0c712b78a7e8 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -505,6 +505,8 @@ pgm_no_vtime2:
505 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 505 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
506 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 506 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
507 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 507 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
508 tm SP_PSW+1(%r15),0x01 # kernel per event ?
509 bz BASED(kernel_per)
508 l %r3,__LC_PGM_ILC # load program interruption code 510 l %r3,__LC_PGM_ILC # load program interruption code
509 la %r8,0x7f 511 la %r8,0x7f
510 nr %r8,%r3 # clear per-event-bit and ilc 512 nr %r8,%r3 # clear per-event-bit and ilc
@@ -536,6 +538,16 @@ pgm_no_vtime3:
536 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 538 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
537 b BASED(sysc_do_svc) 539 b BASED(sysc_do_svc)
538 540
541#
542# per was called from kernel, must be kprobes
543#
544kernel_per:
545 mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check
546 la %r2,SP_PTREGS(%r15) # address of register-save area
547 l %r1,BASED(.Lhandle_per) # load adr. of per handler
548 la %r14,BASED(sysc_leave) # load adr. of system return
549 br %r1 # branch to do_single_step
550
539/* 551/*
540 * IO interrupt handler routine 552 * IO interrupt handler routine
541 */ 553 */
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 56f5f613b868..29bbfbab7332 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -518,6 +518,8 @@ pgm_no_vtime2:
518#endif 518#endif
519 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 519 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
520 lg %r1,__TI_task(%r9) 520 lg %r1,__TI_task(%r9)
521 tm SP_PSW+1(%r15),0x01 # kernel per event ?
522 jz kernel_per
521 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID 523 mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
522 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS 524 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
523 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 525 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
@@ -553,6 +555,16 @@ pgm_no_vtime3:
553 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 555 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
554 j sysc_do_svc 556 j sysc_do_svc
555 557
558#
559# per was called from kernel, must be kprobes
560#
561kernel_per:
562 lhi %r0,__LC_PGM_OLD_PSW
563 sth %r0,SP_TRAP(%r15) # set trap indication to pgm check
564 la %r2,SP_PTREGS(%r15) # address of register-save area
565 larl %r14,sysc_leave # load adr. of system ret, no work
566 jg do_single_step # branch to do_single_step
567
556/* 568/*
557 * IO interrupt handler routine 569 * IO interrupt handler routine
558 */ 570 */
@@ -815,7 +827,7 @@ restart_go:
815 */ 827 */
816stack_overflow: 828stack_overflow:
817 lg %r15,__LC_PANIC_STACK # change to panic stack 829 lg %r15,__LC_PANIC_STACK # change to panic stack
818 aghi %r1,-SP_SIZE 830 aghi %r15,-SP_SIZE
819 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 831 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
820 stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 832 stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
821 la %r1,__LC_SAVE_AREA 833 la %r1,__LC_SAVE_AREA
@@ -823,7 +835,7 @@ stack_overflow:
823 je 0f 835 je 0f
824 chi %r12,__LC_PGM_OLD_PSW 836 chi %r12,__LC_PGM_OLD_PSW
825 je 0f 837 je 0f
826 la %r1,__LC_SAVE_AREA+16 838 la %r1,__LC_SAVE_AREA+32
8270: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack 8390: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack
828 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain 840 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
829 la %r2,SP_PTREGS(%r15) # load pt_regs 841 la %r2,SP_PTREGS(%r15) # load pt_regs
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index adad8863ee2f..0f1db268a8a9 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -272,7 +272,7 @@ iplstart:
272# load parameter file from ipl device 272# load parameter file from ipl device
273# 273#
274.Lagain1: 274.Lagain1:
275 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp 275 l %r2,.Linitrd # ramdisk loc. is temp
276 bas %r14,.Lloader # load parameter file 276 bas %r14,.Lloader # load parameter file
277 ltr %r2,%r2 # got anything ? 277 ltr %r2,%r2 # got anything ?
278 bz .Lnopf 278 bz .Lnopf
@@ -280,7 +280,7 @@ iplstart:
280 bnh .Lnotrunc 280 bnh .Lnotrunc
281 la %r2,895 281 la %r2,895
282.Lnotrunc: 282.Lnotrunc:
283 l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) 283 l %r4,.Linitrd
284 clc 0(3,%r4),.L_hdr # if it is HDRx 284 clc 0(3,%r4),.L_hdr # if it is HDRx
285 bz .Lagain1 # skip dataset header 285 bz .Lagain1 # skip dataset header
286 clc 0(3,%r4),.L_eof # if it is EOFx 286 clc 0(3,%r4),.L_eof # if it is EOFx
@@ -323,14 +323,15 @@ iplstart:
323# load ramdisk from ipl device 323# load ramdisk from ipl device
324# 324#
325.Lagain2: 325.Lagain2:
326 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk 326 l %r2,.Linitrd # addr of ramdisk
327 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
327 bas %r14,.Lloader # load ramdisk 328 bas %r14,.Lloader # load ramdisk
328 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk 329 st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
329 ltr %r2,%r2 330 ltr %r2,%r2
330 bnz .Lrdcont 331 bnz .Lrdcont
331 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found 332 st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
332.Lrdcont: 333.Lrdcont:
333 l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) 334 l %r2,.Linitrd
334 335
335 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx 336 clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
336 bz .Lagain2 337 bz .Lagain2
@@ -379,6 +380,7 @@ iplstart:
379 l %r1,.Lstartup 380 l %r1,.Lstartup
380 br %r1 381 br %r1
381 382
383.Linitrd:.long _end + 0x400000 # default address of initrd
382.Lparm: .long PARMAREA 384.Lparm: .long PARMAREA
383.Lstartup: .long startup 385.Lstartup: .long startup
384.Lcvtab:.long _ebcasc # ebcdic to ascii table 386.Lcvtab:.long _ebcasc # ebcdic to ascii table
@@ -479,65 +481,6 @@ start:
479 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 481 .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7
480 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff 482 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
481 483
482.macro GET_IPL_DEVICE
483.Lget_ipl_device:
484 l %r1,0xb8 # get sid
485 sll %r1,15 # test if subchannel is enabled
486 srl %r1,31
487 ltr %r1,%r1
488 bz 2f-.LPG1(%r13) # subchannel disabled
489 l %r1,0xb8
490 la %r5,.Lipl_schib-.LPG1(%r13)
491 stsch 0(%r5) # get schib of subchannel
492 bnz 2f-.LPG1(%r13) # schib not available
493 tm 5(%r5),0x01 # devno valid?
494 bno 2f-.LPG1(%r13)
495 la %r6,ipl_parameter_flags-.LPG1(%r13)
496 oi 3(%r6),0x01 # set flag
497 la %r2,ipl_devno-.LPG1(%r13)
498 mvc 0(2,%r2),6(%r5) # store devno
499 tm 4(%r5),0x80 # qdio capable device?
500 bno 2f-.LPG1(%r13)
501 oi 3(%r6),0x02 # set flag
502
503 # copy ipl parameters
504
505 lhi %r0,4096
506 l %r2,20(%r0) # get address of parameter list
507 lhi %r3,IPL_PARMBLOCK_ORIGIN
508 st %r3,20(%r0)
509 lhi %r4,1
510 cr %r2,%r3 # start parameters < destination ?
511 jl 0f
512 lhi %r1,1 # copy direction is upwards
513 j 1f
5140: lhi %r1,-1 # copy direction is downwards
515 ar %r2,%r0
516 ar %r3,%r0
517 ar %r2,%r1
518 ar %r3,%r1
5191: mvc 0(1,%r3),0(%r2) # finally copy ipl parameters
520 ar %r3,%r1
521 ar %r2,%r1
522 sr %r0,%r4
523 jne 1b
524 b 2f-.LPG1(%r13)
525
526 .align 4
527.Lipl_schib:
528 .rept 13
529 .long 0
530 .endr
531
532 .globl ipl_parameter_flags
533ipl_parameter_flags:
534 .long 0
535 .globl ipl_devno
536ipl_devno:
537 .word 0
5382:
539.endm
540
541#ifdef CONFIG_64BIT 484#ifdef CONFIG_64BIT
542#include "head64.S" 485#include "head64.S"
543#else 486#else
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index a4dc61f3285e..1fa9fa1ca740 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base
26# 26#
27 .org PARMAREA 27 .org PARMAREA
28 .long 0,0 # IPL_DEVICE 28 .long 0,0 # IPL_DEVICE
29 .long 0,RAMDISK_ORIGIN # INITRD_START 29 .long 0,0 # INITRD_START
30 .long 0,RAMDISK_SIZE # INITRD_SIZE 30 .long 0,0 # INITRD_SIZE
31 31
32 .org COMMAND_LINE 32 .org COMMAND_LINE
33 .byte "root=/dev/ram0 ro" 33 .byte "root=/dev/ram0 ro"
@@ -37,12 +37,23 @@ startup:basr %r13,0 # get base
37 37
38startup_continue: 38startup_continue:
39 basr %r13,0 # get base 39 basr %r13,0 # get base
40.LPG1: GET_IPL_DEVICE 40.LPG1: mvi __LC_AR_MODE_ID,0 # set ESA flag (mode 0)
41 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 41 lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
42 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area 42 l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
43 # move IPL device to lowcore 43 # move IPL device to lowcore
44 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) 44 mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
45#
46# Setup stack
47#
48 l %r15,.Linittu-.LPG1(%r13)
49 mvc __LC_CURRENT(4),__TI_task(%r15)
50 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
51 st %r15,__LC_KERNEL_STACK # set end of kernel stack
52 ahi %r15,-96
53 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
45 54
55 l %r14,.Lipl_save_parameters-.LPG1(%r13)
56 basr %r14,%r14
46# 57#
47# clear bss memory 58# clear bss memory
48# 59#
@@ -114,6 +125,10 @@ startup_continue:
114 b .Lfchunk-.LPG1(%r13) 125 b .Lfchunk-.LPG1(%r13)
115 126
116 .align 4 127 .align 4
128.Lipl_save_parameters:
129 .long ipl_save_parameters
130.Linittu:
131 .long init_thread_union
117.Lpmask: 132.Lpmask:
118 .byte 0 133 .byte 0
119.align 8 134.align 8
@@ -273,7 +288,23 @@ startup_continue:
273.Lbss_end: .long _end 288.Lbss_end: .long _end
274.Lparmaddr: .long PARMAREA 289.Lparmaddr: .long PARMAREA
275.Lsccbaddr: .long .Lsccb 290.Lsccbaddr: .long .Lsccb
291
292 .globl ipl_schib
293ipl_schib:
294 .rept 13
295 .long 0
296 .endr
297
298 .globl ipl_flags
299ipl_flags:
300 .long 0
301 .globl ipl_devno
302ipl_devno:
303 .word 0
304
276 .org 0x12000 305 .org 0x12000
306.globl s390_readinfo_sccb
307s390_readinfo_sccb:
277.Lsccb: 308.Lsccb:
278 .hword 0x1000 # length, one page 309 .hword 0x1000 # length, one page
279 .byte 0x00,0x00,0x00 310 .byte 0x00,0x00,0x00
@@ -302,16 +333,6 @@ startup_continue:
302 .globl _stext 333 .globl _stext
303_stext: basr %r13,0 # get base 334_stext: basr %r13,0 # get base
304.LPG3: 335.LPG3:
305#
306# Setup stack
307#
308 l %r15,.Linittu-.LPG3(%r13)
309 mvc __LC_CURRENT(4),__TI_task(%r15)
310 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
311 st %r15,__LC_KERNEL_STACK # set end of kernel stack
312 ahi %r15,-96
313 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
314
315# check control registers 336# check control registers
316 stctl %c0,%c15,0(%r15) 337 stctl %c0,%c15,0(%r15)
317 oi 2(%r15),0x40 # enable sigp emergency signal 338 oi 2(%r15),0x40 # enable sigp emergency signal
@@ -330,6 +351,5 @@ _stext: basr %r13,0 # get base
330# 351#
331 .align 8 352 .align 8
332.Ldw: .long 0x000a0000,0x00000000 353.Ldw: .long 0x000a0000,0x00000000
333.Linittu:.long init_thread_union
334.Lstart:.long start_kernel 354.Lstart:.long start_kernel
335.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 355.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 9d80c5b1ef95..a8bdd96494c7 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base
26# 26#
27 .org PARMAREA 27 .org PARMAREA
28 .quad 0 # IPL_DEVICE 28 .quad 0 # IPL_DEVICE
29 .quad RAMDISK_ORIGIN # INITRD_START 29 .quad 0 # INITRD_START
30 .quad RAMDISK_SIZE # INITRD_SIZE 30 .quad 0 # INITRD_SIZE
31 31
32 .org COMMAND_LINE 32 .org COMMAND_LINE
33 .byte "root=/dev/ram0 ro" 33 .byte "root=/dev/ram0 ro"
@@ -39,8 +39,8 @@ startup_continue:
39 basr %r13,0 # get base 39 basr %r13,0 # get base
40.LPG1: sll %r13,1 # remove high order bit 40.LPG1: sll %r13,1 # remove high order bit
41 srl %r13,1 41 srl %r13,1
42 GET_IPL_DEVICE
43 lhi %r1,1 # mode 1 = esame 42 lhi %r1,1 # mode 1 = esame
43 mvi __LC_AR_MODE_ID,1 # set esame flag
44 slr %r0,%r0 # set cpuid to zero 44 slr %r0,%r0 # set cpuid to zero
45 sigp %r1,%r0,0x12 # switch to esame mode 45 sigp %r1,%r0,0x12 # switch to esame mode
46 sam64 # switch to 64 bit mode 46 sam64 # switch to 64 bit mode
@@ -48,7 +48,18 @@ startup_continue:
48 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area 48 lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area
49 # move IPL device to lowcore 49 # move IPL device to lowcore
50 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) 50 mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
51#
52# Setup stack
53#
54 larl %r15,init_thread_union
55 lg %r14,__TI_task(%r15) # cache current in lowcore
56 stg %r14,__LC_CURRENT
57 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
58 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
59 aghi %r15,-160
60 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
51 61
62 brasl %r14,ipl_save_parameters
52# 63#
53# clear bss memory 64# clear bss memory
54# 65#
@@ -239,6 +250,19 @@ startup_continue:
239 oi 7(%r12),0x80 # set IDTE flag 250 oi 7(%r12),0x80 # set IDTE flag
2400: 2510:
241 252
253#
254# find out if we have the MVCOS instruction
255#
256 la %r1,0f-.LPG1(%r13) # set program check address
257 stg %r1,__LC_PGM_NEW_PSW+8
258 .short 0xc800 # mvcos 0(%r0),0(%r0),%r0
259 .short 0x0000
260 .short 0x0000
2610: tm 0x8f,0x13 # special-operation exception?
262 bno 1f-.LPG1(%r13) # if yes, MVCOS is present
263 oi 6(%r12),2 # set MVCOS flag
2641:
265
242 lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, 266 lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space,
243 # virtual and never return ... 267 # virtual and never return ...
244 .align 16 268 .align 16
@@ -268,7 +292,22 @@ startup_continue:
268.Lparmaddr: 292.Lparmaddr:
269 .quad PARMAREA 293 .quad PARMAREA
270 294
295 .globl ipl_schib
296ipl_schib:
297 .rept 13
298 .long 0
299 .endr
300
301 .globl ipl_flags
302ipl_flags:
303 .long 0
304 .globl ipl_devno
305ipl_devno:
306 .word 0
307
271 .org 0x12000 308 .org 0x12000
309.globl s390_readinfo_sccb
310s390_readinfo_sccb:
272.Lsccb: 311.Lsccb:
273 .hword 0x1000 # length, one page 312 .hword 0x1000 # length, one page
274 .byte 0x00,0x00,0x00 313 .byte 0x00,0x00,0x00
@@ -297,24 +336,12 @@ startup_continue:
297 .globl _stext 336 .globl _stext
298_stext: basr %r13,0 # get base 337_stext: basr %r13,0 # get base
299.LPG3: 338.LPG3:
300#
301# Setup stack
302#
303 larl %r15,init_thread_union
304 lg %r14,__TI_task(%r15) # cache current in lowcore
305 stg %r14,__LC_CURRENT
306 aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
307 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
308 aghi %r15,-160
309 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
310
311# check control registers 339# check control registers
312 stctg %c0,%c15,0(%r15) 340 stctg %c0,%c15,0(%r15)
313 oi 6(%r15),0x40 # enable sigp emergency signal 341 oi 6(%r15),0x40 # enable sigp emergency signal
314 oi 4(%r15),0x10 # switch on low address proctection 342 oi 4(%r15),0x10 # switch on low address proctection
315 lctlg %c0,%c15,0(%r15) 343 lctlg %c0,%c15,0(%r15)
316 344
317#
318 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess 345 lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
319 brasl %r14,start_kernel # go to C code 346 brasl %r14,start_kernel # go to C code
320# 347#
@@ -322,7 +349,7 @@ _stext: basr %r13,0 # get base
322# 349#
323 basr %r13,0 350 basr %r13,0
324 lpswe .Ldw-.(%r13) # load disabled wait psw 351 lpswe .Ldw-.(%r13) # load disabled wait psw
325# 352
326 .align 8 353 .align 8
327.Ldw: .quad 0x0002000180000000,0x0000000000000000 354.Ldw: .quad 0x0002000180000000,0x0000000000000000
328.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 355.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
new file mode 100644
index 000000000000..6555cc48e28f
--- /dev/null
+++ b/arch/s390/kernel/ipl.c
@@ -0,0 +1,942 @@
1/*
2 * arch/s390/kernel/ipl.c
3 * ipl/reipl/dump support for Linux on s390.
4 *
5 * Copyright (C) IBM Corp. 2005,2006
6 * Author(s): Michael Holzheu <holzheu@de.ibm.com>
7 * Heiko Carstens <heiko.carstens@de.ibm.com>
8 * Volker Sameske <sameske@de.ibm.com>
9 */
10
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/device.h>
14#include <linux/delay.h>
15#include <linux/reboot.h>
16#include <asm/smp.h>
17#include <asm/setup.h>
18#include <asm/cpcmd.h>
19#include <asm/cio.h>
20
21#define IPL_PARM_BLOCK_VERSION 0
22
23enum ipl_type {
24 IPL_TYPE_NONE = 1,
25 IPL_TYPE_UNKNOWN = 2,
26 IPL_TYPE_CCW = 4,
27 IPL_TYPE_FCP = 8,
28};
29
30#define IPL_NONE_STR "none"
31#define IPL_UNKNOWN_STR "unknown"
32#define IPL_CCW_STR "ccw"
33#define IPL_FCP_STR "fcp"
34
35static char *ipl_type_str(enum ipl_type type)
36{
37 switch (type) {
38 case IPL_TYPE_NONE:
39 return IPL_NONE_STR;
40 case IPL_TYPE_CCW:
41 return IPL_CCW_STR;
42 case IPL_TYPE_FCP:
43 return IPL_FCP_STR;
44 case IPL_TYPE_UNKNOWN:
45 default:
46 return IPL_UNKNOWN_STR;
47 }
48}
49
50enum ipl_method {
51 IPL_METHOD_NONE,
52 IPL_METHOD_CCW_CIO,
53 IPL_METHOD_CCW_DIAG,
54 IPL_METHOD_CCW_VM,
55 IPL_METHOD_FCP_RO_DIAG,
56 IPL_METHOD_FCP_RW_DIAG,
57 IPL_METHOD_FCP_RO_VM,
58};
59
60enum shutdown_action {
61 SHUTDOWN_REIPL,
62 SHUTDOWN_DUMP,
63 SHUTDOWN_STOP,
64};
65
66#define SHUTDOWN_REIPL_STR "reipl"
67#define SHUTDOWN_DUMP_STR "dump"
68#define SHUTDOWN_STOP_STR "stop"
69
70static char *shutdown_action_str(enum shutdown_action action)
71{
72 switch (action) {
73 case SHUTDOWN_REIPL:
74 return SHUTDOWN_REIPL_STR;
75 case SHUTDOWN_DUMP:
76 return SHUTDOWN_DUMP_STR;
77 case SHUTDOWN_STOP:
78 return SHUTDOWN_STOP_STR;
79 default:
80 BUG();
81 }
82}
83
84enum diag308_subcode {
85 DIAG308_IPL = 3,
86 DIAG308_DUMP = 4,
87 DIAG308_SET = 5,
88 DIAG308_STORE = 6,
89};
90
91enum diag308_ipl_type {
92 DIAG308_IPL_TYPE_FCP = 0,
93 DIAG308_IPL_TYPE_CCW = 2,
94};
95
96enum diag308_opt {
97 DIAG308_IPL_OPT_IPL = 0x10,
98 DIAG308_IPL_OPT_DUMP = 0x20,
99};
100
101enum diag308_rc {
102 DIAG308_RC_OK = 1,
103};
104
105static int diag308_set_works = 0;
106
107static int reipl_capabilities = IPL_TYPE_UNKNOWN;
108static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
109static enum ipl_method reipl_method = IPL_METHOD_NONE;
110static struct ipl_parameter_block *reipl_block_fcp;
111static struct ipl_parameter_block *reipl_block_ccw;
112
113static int dump_capabilities = IPL_TYPE_NONE;
114static enum ipl_type dump_type = IPL_TYPE_NONE;
115static enum ipl_method dump_method = IPL_METHOD_NONE;
116static struct ipl_parameter_block *dump_block_fcp;
117static struct ipl_parameter_block *dump_block_ccw;
118
119static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
120
121static int diag308(unsigned long subcode, void *addr)
122{
123 register unsigned long _addr asm("0") = (unsigned long)addr;
124 register unsigned long _rc asm("1") = 0;
125
126 asm volatile (
127 " diag %0,%2,0x308\n"
128 "0: \n"
129 ".section __ex_table,\"a\"\n"
130#ifdef CONFIG_64BIT
131 " .align 8\n"
132 " .quad 0b, 0b\n"
133#else
134 " .align 4\n"
135 " .long 0b, 0b\n"
136#endif
137 ".previous\n"
138 : "+d" (_addr), "+d" (_rc)
139 : "d" (subcode) : "cc", "memory" );
140
141 return _rc;
142}
143
144/* SYSFS */
145
146#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
147static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
148 char *page) \
149{ \
150 return sprintf(page, _format, _value); \
151} \
152static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
153 __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
154
155#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \
156static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
157 char *page) \
158{ \
159 return sprintf(page, _fmt_out, \
160 (unsigned long long) _value); \
161} \
162static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
163 const char *buf, size_t len) \
164{ \
165 unsigned long long value; \
166 if (sscanf(buf, _fmt_in, &value) != 1) \
167 return -EINVAL; \
168 _value = value; \
169 return len; \
170} \
171static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
172 __ATTR(_name,(S_IRUGO | S_IWUSR), \
173 sys_##_prefix##_##_name##_show, \
174 sys_##_prefix##_##_name##_store);
175
176static void make_attrs_ro(struct attribute **attrs)
177{
178 while (*attrs) {
179 (*attrs)->mode = S_IRUGO;
180 attrs++;
181 }
182}
183
184/*
185 * ipl section
186 */
187
188static enum ipl_type ipl_get_type(void)
189{
190 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
191
192 if (!(ipl_flags & IPL_DEVNO_VALID))
193 return IPL_TYPE_UNKNOWN;
194 if (!(ipl_flags & IPL_PARMBLOCK_VALID))
195 return IPL_TYPE_CCW;
196 if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
197 return IPL_TYPE_UNKNOWN;
198 if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
199 return IPL_TYPE_UNKNOWN;
200 return IPL_TYPE_FCP;
201}
202
203static ssize_t ipl_type_show(struct subsystem *subsys, char *page)
204{
205 return sprintf(page, "%s\n", ipl_type_str(ipl_get_type()));
206}
207
208static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
209
210static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page)
211{
212 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
213
214 switch (ipl_get_type()) {
215 case IPL_TYPE_CCW:
216 return sprintf(page, "0.0.%04x\n", ipl_devno);
217 case IPL_TYPE_FCP:
218 return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
219 default:
220 return 0;
221 }
222}
223
224static struct subsys_attribute sys_ipl_device_attr =
225 __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
226
227static ssize_t ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off,
228 size_t count)
229{
230 unsigned int size = IPL_PARMBLOCK_SIZE;
231
232 if (off > size)
233 return 0;
234 if (off + count > size)
235 count = size - off;
236 memcpy(buf, (void *)IPL_PARMBLOCK_START + off, count);
237 return count;
238}
239
240static struct bin_attribute ipl_parameter_attr = {
241 .attr = {
242 .name = "binary_parameter",
243 .mode = S_IRUGO,
244 .owner = THIS_MODULE,
245 },
246 .size = PAGE_SIZE,
247 .read = &ipl_parameter_read,
248};
249
250static ssize_t ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off,
251 size_t count)
252{
253 unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
254 void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
255
256 if (off > size)
257 return 0;
258 if (off + count > size)
259 count = size - off;
260 memcpy(buf, scp_data + off, count);
261 return count;
262}
263
264static struct bin_attribute ipl_scp_data_attr = {
265 .attr = {
266 .name = "scp_data",
267 .mode = S_IRUGO,
268 .owner = THIS_MODULE,
269 },
270 .size = PAGE_SIZE,
271 .read = &ipl_scp_data_read,
272};
273
274/* FCP ipl device attributes */
275
276DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long)
277 IPL_PARMBLOCK_START->ipl_info.fcp.wwpn);
278DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long)
279 IPL_PARMBLOCK_START->ipl_info.fcp.lun);
280DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
281 IPL_PARMBLOCK_START->ipl_info.fcp.bootprog);
282DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
283 IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
284
285static struct attribute *ipl_fcp_attrs[] = {
286 &sys_ipl_type_attr.attr,
287 &sys_ipl_device_attr.attr,
288 &sys_ipl_fcp_wwpn_attr.attr,
289 &sys_ipl_fcp_lun_attr.attr,
290 &sys_ipl_fcp_bootprog_attr.attr,
291 &sys_ipl_fcp_br_lba_attr.attr,
292 NULL,
293};
294
295static struct attribute_group ipl_fcp_attr_group = {
296 .attrs = ipl_fcp_attrs,
297};
298
299/* CCW ipl device attributes */
300
301static struct attribute *ipl_ccw_attrs[] = {
302 &sys_ipl_type_attr.attr,
303 &sys_ipl_device_attr.attr,
304 NULL,
305};
306
307static struct attribute_group ipl_ccw_attr_group = {
308 .attrs = ipl_ccw_attrs,
309};
310
311/* UNKNOWN ipl device attributes */
312
313static struct attribute *ipl_unknown_attrs[] = {
314 &sys_ipl_type_attr.attr,
315 NULL,
316};
317
318static struct attribute_group ipl_unknown_attr_group = {
319 .attrs = ipl_unknown_attrs,
320};
321
322static decl_subsys(ipl, NULL, NULL);
323
324/*
325 * reipl section
326 */
327
328/* FCP reipl device attributes */
329
330DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n",
331 reipl_block_fcp->ipl_info.fcp.wwpn);
332DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n",
333 reipl_block_fcp->ipl_info.fcp.lun);
334DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
335 reipl_block_fcp->ipl_info.fcp.bootprog);
336DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
337 reipl_block_fcp->ipl_info.fcp.br_lba);
338DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
339 reipl_block_fcp->ipl_info.fcp.devno);
340
341static struct attribute *reipl_fcp_attrs[] = {
342 &sys_reipl_fcp_device_attr.attr,
343 &sys_reipl_fcp_wwpn_attr.attr,
344 &sys_reipl_fcp_lun_attr.attr,
345 &sys_reipl_fcp_bootprog_attr.attr,
346 &sys_reipl_fcp_br_lba_attr.attr,
347 NULL,
348};
349
350static struct attribute_group reipl_fcp_attr_group = {
351 .name = IPL_FCP_STR,
352 .attrs = reipl_fcp_attrs,
353};
354
355/* CCW reipl device attributes */
356
357DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
358 reipl_block_ccw->ipl_info.ccw.devno);
359
360static struct attribute *reipl_ccw_attrs[] = {
361 &sys_reipl_ccw_device_attr.attr,
362 NULL,
363};
364
365static struct attribute_group reipl_ccw_attr_group = {
366 .name = IPL_CCW_STR,
367 .attrs = reipl_ccw_attrs,
368};
369
370/* reipl type */
371
372static int reipl_set_type(enum ipl_type type)
373{
374 if (!(reipl_capabilities & type))
375 return -EINVAL;
376
377 switch(type) {
378 case IPL_TYPE_CCW:
379 if (MACHINE_IS_VM)
380 reipl_method = IPL_METHOD_CCW_VM;
381 else
382 reipl_method = IPL_METHOD_CCW_CIO;
383 break;
384 case IPL_TYPE_FCP:
385 if (diag308_set_works)
386 reipl_method = IPL_METHOD_FCP_RW_DIAG;
387 else if (MACHINE_IS_VM)
388 reipl_method = IPL_METHOD_FCP_RO_VM;
389 else
390 reipl_method = IPL_METHOD_FCP_RO_DIAG;
391 break;
392 default:
393 reipl_method = IPL_METHOD_NONE;
394 }
395 reipl_type = type;
396 return 0;
397}
398
399static ssize_t reipl_type_show(struct subsystem *subsys, char *page)
400{
401 return sprintf(page, "%s\n", ipl_type_str(reipl_type));
402}
403
404static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf,
405 size_t len)
406{
407 int rc = -EINVAL;
408
409 if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
410 rc = reipl_set_type(IPL_TYPE_CCW);
411 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
412 rc = reipl_set_type(IPL_TYPE_FCP);
413 return (rc != 0) ? rc : len;
414}
415
416static struct subsys_attribute reipl_type_attr =
417 __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
418
419static decl_subsys(reipl, NULL, NULL);
420
421/*
422 * dump section
423 */
424
425/* FCP dump device attributes */
426
427DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
428 dump_block_fcp->ipl_info.fcp.wwpn);
429DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
430 dump_block_fcp->ipl_info.fcp.lun);
431DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
432 dump_block_fcp->ipl_info.fcp.bootprog);
433DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
434 dump_block_fcp->ipl_info.fcp.br_lba);
435DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
436 dump_block_fcp->ipl_info.fcp.devno);
437
438static struct attribute *dump_fcp_attrs[] = {
439 &sys_dump_fcp_device_attr.attr,
440 &sys_dump_fcp_wwpn_attr.attr,
441 &sys_dump_fcp_lun_attr.attr,
442 &sys_dump_fcp_bootprog_attr.attr,
443 &sys_dump_fcp_br_lba_attr.attr,
444 NULL,
445};
446
447static struct attribute_group dump_fcp_attr_group = {
448 .name = IPL_FCP_STR,
449 .attrs = dump_fcp_attrs,
450};
451
452/* CCW dump device attributes */
453
454DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
455 dump_block_ccw->ipl_info.ccw.devno);
456
457static struct attribute *dump_ccw_attrs[] = {
458 &sys_dump_ccw_device_attr.attr,
459 NULL,
460};
461
462static struct attribute_group dump_ccw_attr_group = {
463 .name = IPL_CCW_STR,
464 .attrs = dump_ccw_attrs,
465};
466
467/* dump type */
468
469static int dump_set_type(enum ipl_type type)
470{
471 if (!(dump_capabilities & type))
472 return -EINVAL;
473 switch(type) {
474 case IPL_TYPE_CCW:
475 if (MACHINE_IS_VM)
476 dump_method = IPL_METHOD_CCW_VM;
477 else
478 dump_method = IPL_METHOD_CCW_CIO;
479 break;
480 case IPL_TYPE_FCP:
481 dump_method = IPL_METHOD_FCP_RW_DIAG;
482 break;
483 default:
484 dump_method = IPL_METHOD_NONE;
485 }
486 dump_type = type;
487 return 0;
488}
489
490static ssize_t dump_type_show(struct subsystem *subsys, char *page)
491{
492 return sprintf(page, "%s\n", ipl_type_str(dump_type));
493}
494
495static ssize_t dump_type_store(struct subsystem *subsys, const char *buf,
496 size_t len)
497{
498 int rc = -EINVAL;
499
500 if (strncmp(buf, IPL_NONE_STR, strlen(IPL_NONE_STR)) == 0)
501 rc = dump_set_type(IPL_TYPE_NONE);
502 else if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
503 rc = dump_set_type(IPL_TYPE_CCW);
504 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
505 rc = dump_set_type(IPL_TYPE_FCP);
506 return (rc != 0) ? rc : len;
507}
508
509static struct subsys_attribute dump_type_attr =
510 __ATTR(dump_type, 0644, dump_type_show, dump_type_store);
511
512static decl_subsys(dump, NULL, NULL);
513
514#ifdef CONFIG_SMP
515static void dump_smp_stop_all(void)
516{
517 int cpu;
518 preempt_disable();
519 for_each_online_cpu(cpu) {
520 if (cpu == smp_processor_id())
521 continue;
522 while (signal_processor(cpu, sigp_stop) == sigp_busy)
523 udelay(10);
524 }
525 preempt_enable();
526}
527#else
528#define dump_smp_stop_all() do { } while (0)
529#endif
530
531/*
532 * Shutdown actions section
533 */
534
535static decl_subsys(shutdown_actions, NULL, NULL);
536
537/* on panic */
538
539static ssize_t on_panic_show(struct subsystem *subsys, char *page)
540{
541 return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
542}
543
544static ssize_t on_panic_store(struct subsystem *subsys, const char *buf,
545 size_t len)
546{
547 if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
548 on_panic_action = SHUTDOWN_REIPL;
549 else if (strncmp(buf, SHUTDOWN_DUMP_STR,
550 strlen(SHUTDOWN_DUMP_STR)) == 0)
551 on_panic_action = SHUTDOWN_DUMP;
552 else if (strncmp(buf, SHUTDOWN_STOP_STR,
553 strlen(SHUTDOWN_STOP_STR)) == 0)
554 on_panic_action = SHUTDOWN_STOP;
555 else
556 return -EINVAL;
557
558 return len;
559}
560
561static struct subsys_attribute on_panic_attr =
562 __ATTR(on_panic, 0644, on_panic_show, on_panic_store);
563
564static void print_fcp_block(struct ipl_parameter_block *fcp_block)
565{
566 printk(KERN_EMERG "wwpn: %016llx\n",
567 (unsigned long long)fcp_block->ipl_info.fcp.wwpn);
568 printk(KERN_EMERG "lun: %016llx\n",
569 (unsigned long long)fcp_block->ipl_info.fcp.lun);
570 printk(KERN_EMERG "bootprog: %lld\n",
571 (unsigned long long)fcp_block->ipl_info.fcp.bootprog);
572 printk(KERN_EMERG "br_lba: %lld\n",
573 (unsigned long long)fcp_block->ipl_info.fcp.br_lba);
574 printk(KERN_EMERG "device: %llx\n",
575 (unsigned long long)fcp_block->ipl_info.fcp.devno);
576 printk(KERN_EMERG "opt: %x\n", fcp_block->ipl_info.fcp.opt);
577}
578
579void do_reipl(void)
580{
581 struct ccw_dev_id devid;
582 static char buf[100];
583
584 switch (reipl_type) {
585 case IPL_TYPE_CCW:
586 printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n",
587 reipl_block_ccw->ipl_info.ccw.devno);
588 break;
589 case IPL_TYPE_FCP:
590 printk(KERN_EMERG "reboot on fcp device:\n");
591 print_fcp_block(reipl_block_fcp);
592 break;
593 default:
594 break;
595 }
596
597 switch (reipl_method) {
598 case IPL_METHOD_CCW_CIO:
599 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
600 devid.ssid = 0;
601 reipl_ccw_dev(&devid);
602 break;
603 case IPL_METHOD_CCW_VM:
604 sprintf(buf, "IPL %X", reipl_block_ccw->ipl_info.ccw.devno);
605 cpcmd(buf, NULL, 0, NULL);
606 break;
607 case IPL_METHOD_CCW_DIAG:
608 diag308(DIAG308_SET, reipl_block_ccw);
609 diag308(DIAG308_IPL, NULL);
610 break;
611 case IPL_METHOD_FCP_RW_DIAG:
612 diag308(DIAG308_SET, reipl_block_fcp);
613 diag308(DIAG308_IPL, NULL);
614 break;
615 case IPL_METHOD_FCP_RO_DIAG:
616 diag308(DIAG308_IPL, NULL);
617 break;
618 case IPL_METHOD_FCP_RO_VM:
619 cpcmd("IPL", NULL, 0, NULL);
620 break;
621 case IPL_METHOD_NONE:
622 default:
623 if (MACHINE_IS_VM)
624 cpcmd("IPL", NULL, 0, NULL);
625 diag308(DIAG308_IPL, NULL);
626 break;
627 }
628 panic("reipl failed!\n");
629}
630
631static void do_dump(void)
632{
633 struct ccw_dev_id devid;
634 static char buf[100];
635
636 switch (dump_type) {
637 case IPL_TYPE_CCW:
638 printk(KERN_EMERG "Automatic dump on ccw device: 0.0.%04x\n",
639 dump_block_ccw->ipl_info.ccw.devno);
640 break;
641 case IPL_TYPE_FCP:
642 printk(KERN_EMERG "Automatic dump on fcp device:\n");
643 print_fcp_block(dump_block_fcp);
644 break;
645 default:
646 return;
647 }
648
649 switch (dump_method) {
650 case IPL_METHOD_CCW_CIO:
651 dump_smp_stop_all();
652 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
653 devid.ssid = 0;
654 reipl_ccw_dev(&devid);
655 break;
656 case IPL_METHOD_CCW_VM:
657 dump_smp_stop_all();
658 sprintf(buf, "STORE STATUS");
659 cpcmd(buf, NULL, 0, NULL);
660 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
661 cpcmd(buf, NULL, 0, NULL);
662 break;
663 case IPL_METHOD_CCW_DIAG:
664 diag308(DIAG308_SET, dump_block_ccw);
665 diag308(DIAG308_DUMP, NULL);
666 break;
667 case IPL_METHOD_FCP_RW_DIAG:
668 diag308(DIAG308_SET, dump_block_fcp);
669 diag308(DIAG308_DUMP, NULL);
670 break;
671 case IPL_METHOD_NONE:
672 default:
673 return;
674 }
675 printk(KERN_EMERG "Dump failed!\n");
676}
677
678/* init functions */
679
680static int __init ipl_register_fcp_files(void)
681{
682 int rc;
683
684 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
685 &ipl_fcp_attr_group);
686 if (rc)
687 goto out;
688 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
689 &ipl_parameter_attr);
690 if (rc)
691 goto out_ipl_parm;
692 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
693 &ipl_scp_data_attr);
694 if (!rc)
695 goto out;
696
697 sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
698
699out_ipl_parm:
700 sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
701out:
702 return rc;
703}
704
705static int __init ipl_init(void)
706{
707 int rc;
708
709 rc = firmware_register(&ipl_subsys);
710 if (rc)
711 return rc;
712 switch (ipl_get_type()) {
713 case IPL_TYPE_CCW:
714 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
715 &ipl_ccw_attr_group);
716 break;
717 case IPL_TYPE_FCP:
718 rc = ipl_register_fcp_files();
719 break;
720 default:
721 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
722 &ipl_unknown_attr_group);
723 break;
724 }
725 if (rc)
726 firmware_unregister(&ipl_subsys);
727 return rc;
728}
729
730static void __init reipl_probe(void)
731{
732 void *buffer;
733
734 buffer = (void *) get_zeroed_page(GFP_KERNEL);
735 if (!buffer)
736 return;
737 if (diag308(DIAG308_STORE, buffer) == DIAG308_RC_OK)
738 diag308_set_works = 1;
739 free_page((unsigned long)buffer);
740}
741
742static int __init reipl_ccw_init(void)
743{
744 int rc;
745
746 reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
747 if (!reipl_block_ccw)
748 return -ENOMEM;
749 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_ccw_attr_group);
750 if (rc) {
751 free_page((unsigned long)reipl_block_ccw);
752 return rc;
753 }
754 reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
755 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
756 reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
757 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
758 if (ipl_get_type() == IPL_TYPE_CCW)
759 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
760 reipl_capabilities |= IPL_TYPE_CCW;
761 return 0;
762}
763
764static int __init reipl_fcp_init(void)
765{
766 int rc;
767
768 if ((!diag308_set_works) && (ipl_get_type() != IPL_TYPE_FCP))
769 return 0;
770 if ((!diag308_set_works) && (ipl_get_type() == IPL_TYPE_FCP))
771 make_attrs_ro(reipl_fcp_attrs);
772
773 reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
774 if (!reipl_block_fcp)
775 return -ENOMEM;
776 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_fcp_attr_group);
777 if (rc) {
778 free_page((unsigned long)reipl_block_fcp);
779 return rc;
780 }
781 if (ipl_get_type() == IPL_TYPE_FCP) {
782 memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
783 } else {
784 reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
785 reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
786 reipl_block_fcp->hdr.blk0_len =
787 sizeof(reipl_block_fcp->ipl_info.fcp);
788 reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
789 reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
790 }
791 reipl_capabilities |= IPL_TYPE_FCP;
792 return 0;
793}
794
795static int __init reipl_init(void)
796{
797 int rc;
798
799 rc = firmware_register(&reipl_subsys);
800 if (rc)
801 return rc;
802 rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
803 if (rc) {
804 firmware_unregister(&reipl_subsys);
805 return rc;
806 }
807 rc = reipl_ccw_init();
808 if (rc)
809 return rc;
810 rc = reipl_fcp_init();
811 if (rc)
812 return rc;
813 rc = reipl_set_type(ipl_get_type());
814 if (rc)
815 return rc;
816 return 0;
817}
818
819static int __init dump_ccw_init(void)
820{
821 int rc;
822
823 dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
824 if (!dump_block_ccw)
825 return -ENOMEM;
826 rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_ccw_attr_group);
827 if (rc) {
828 free_page((unsigned long)dump_block_ccw);
829 return rc;
830 }
831 dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
832 dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
833 dump_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
834 dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
835 dump_capabilities |= IPL_TYPE_CCW;
836 return 0;
837}
838
839extern char s390_readinfo_sccb[];
840
841static int __init dump_fcp_init(void)
842{
843 int rc;
844
845 if(!(s390_readinfo_sccb[91] & 0x2))
846 return 0; /* LDIPL DUMP is not installed */
847 if (!diag308_set_works)
848 return 0;
849 dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
850 if (!dump_block_fcp)
851 return -ENOMEM;
852 rc = sysfs_create_group(&dump_subsys.kset.kobj, &dump_fcp_attr_group);
853 if (rc) {
854 free_page((unsigned long)dump_block_fcp);
855 return rc;
856 }
857 dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
858 dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
859 dump_block_fcp->hdr.blk0_len = sizeof(dump_block_fcp->ipl_info.fcp);
860 dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
861 dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
862 dump_capabilities |= IPL_TYPE_FCP;
863 return 0;
864}
865
866#define SHUTDOWN_ON_PANIC_PRIO 0
867
868static int shutdown_on_panic_notify(struct notifier_block *self,
869 unsigned long event, void *data)
870{
871 if (on_panic_action == SHUTDOWN_DUMP)
872 do_dump();
873 else if (on_panic_action == SHUTDOWN_REIPL)
874 do_reipl();
875 return NOTIFY_OK;
876}
877
878static struct notifier_block shutdown_on_panic_nb = {
879 .notifier_call = shutdown_on_panic_notify,
880 .priority = SHUTDOWN_ON_PANIC_PRIO
881};
882
883static int __init dump_init(void)
884{
885 int rc;
886
887 rc = firmware_register(&dump_subsys);
888 if (rc)
889 return rc;
890 rc = subsys_create_file(&dump_subsys, &dump_type_attr);
891 if (rc) {
892 firmware_unregister(&dump_subsys);
893 return rc;
894 }
895 rc = dump_ccw_init();
896 if (rc)
897 return rc;
898 rc = dump_fcp_init();
899 if (rc)
900 return rc;
901 dump_set_type(IPL_TYPE_NONE);
902 return 0;
903}
904
905static int __init shutdown_actions_init(void)
906{
907 int rc;
908
909 rc = firmware_register(&shutdown_actions_subsys);
910 if (rc)
911 return rc;
912 rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
913 if (rc) {
914 firmware_unregister(&shutdown_actions_subsys);
915 return rc;
916 }
917 atomic_notifier_chain_register(&panic_notifier_list,
918 &shutdown_on_panic_nb);
919 return 0;
920}
921
922static int __init s390_ipl_init(void)
923{
924 int rc;
925
926 reipl_probe();
927 rc = ipl_init();
928 if (rc)
929 return rc;
930 rc = reipl_init();
931 if (rc)
932 return rc;
933 rc = dump_init();
934 if (rc)
935 return rc;
936 rc = shutdown_actions_init();
937 if (rc)
938 return rc;
939 return 0;
940}
941
942__initcall(s390_ipl_init);
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
new file mode 100644
index 000000000000..ca28fb0b3790
--- /dev/null
+++ b/arch/s390/kernel/kprobes.c
@@ -0,0 +1,657 @@
1/*
2 * Kernel Probes (KProbes)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) IBM Corporation, 2002, 2006
19 *
20 * s390 port, used ppc64 as template. Mike Grundy <grundym@us.ibm.com>
21 */
22
23#include <linux/config.h>
24#include <linux/kprobes.h>
25#include <linux/ptrace.h>
26#include <linux/preempt.h>
27#include <linux/stop_machine.h>
28#include <asm/cacheflush.h>
29#include <asm/kdebug.h>
30#include <asm/sections.h>
31#include <asm/uaccess.h>
32#include <linux/module.h>
33
34DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
35DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
36
37int __kprobes arch_prepare_kprobe(struct kprobe *p)
38{
39 /* Make sure the probe isn't going on a difficult instruction */
40 if (is_prohibited_opcode((kprobe_opcode_t *) p->addr))
41 return -EINVAL;
42
43 if ((unsigned long)p->addr & 0x01) {
44 printk("Attempt to register kprobe at an unaligned address\n");
45 return -EINVAL;
46 }
47
48 /* Use the get_insn_slot() facility for correctness */
49 if (!(p->ainsn.insn = get_insn_slot()))
50 return -ENOMEM;
51
52 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
53
54 get_instruction_type(&p->ainsn);
55 p->opcode = *p->addr;
56 return 0;
57}
58
59int __kprobes is_prohibited_opcode(kprobe_opcode_t *instruction)
60{
61 switch (*(__u8 *) instruction) {
62 case 0x0c: /* bassm */
63 case 0x0b: /* bsm */
64 case 0x83: /* diag */
65 case 0x44: /* ex */
66 return -EINVAL;
67 }
68 switch (*(__u16 *) instruction) {
69 case 0x0101: /* pr */
70 case 0xb25a: /* bsa */
71 case 0xb240: /* bakr */
72 case 0xb258: /* bsg */
73 case 0xb218: /* pc */
74 case 0xb228: /* pt */
75 return -EINVAL;
76 }
77 return 0;
78}
79
80void __kprobes get_instruction_type(struct arch_specific_insn *ainsn)
81{
82 /* default fixup method */
83 ainsn->fixup = FIXUP_PSW_NORMAL;
84
85 /* save r1 operand */
86 ainsn->reg = (*ainsn->insn & 0xf0) >> 4;
87
88 /* save the instruction length (pop 5-5) in bytes */
89 switch (*(__u8 *) (ainsn->insn) >> 4) {
90 case 0:
91 ainsn->ilen = 2;
92 break;
93 case 1:
94 case 2:
95 ainsn->ilen = 4;
96 break;
97 case 3:
98 ainsn->ilen = 6;
99 break;
100 }
101
102 switch (*(__u8 *) ainsn->insn) {
103 case 0x05: /* balr */
104 case 0x0d: /* basr */
105 ainsn->fixup = FIXUP_RETURN_REGISTER;
106 /* if r2 = 0, no branch will be taken */
107 if ((*ainsn->insn & 0x0f) == 0)
108 ainsn->fixup |= FIXUP_BRANCH_NOT_TAKEN;
109 break;
110 case 0x06: /* bctr */
111 case 0x07: /* bcr */
112 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
113 break;
114 case 0x45: /* bal */
115 case 0x4d: /* bas */
116 ainsn->fixup = FIXUP_RETURN_REGISTER;
117 break;
118 case 0x47: /* bc */
119 case 0x46: /* bct */
120 case 0x86: /* bxh */
121 case 0x87: /* bxle */
122 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
123 break;
124 case 0x82: /* lpsw */
125 ainsn->fixup = FIXUP_NOT_REQUIRED;
126 break;
127 case 0xb2: /* lpswe */
128 if (*(((__u8 *) ainsn->insn) + 1) == 0xb2) {
129 ainsn->fixup = FIXUP_NOT_REQUIRED;
130 }
131 break;
132 case 0xa7: /* bras */
133 if ((*ainsn->insn & 0x0f) == 0x05) {
134 ainsn->fixup |= FIXUP_RETURN_REGISTER;
135 }
136 break;
137 case 0xc0:
138 if ((*ainsn->insn & 0x0f) == 0x00 /* larl */
139 || (*ainsn->insn & 0x0f) == 0x05) /* brasl */
140 ainsn->fixup |= FIXUP_RETURN_REGISTER;
141 break;
142 case 0xeb:
143 if (*(((__u8 *) ainsn->insn) + 5 ) == 0x44 || /* bxhg */
144 *(((__u8 *) ainsn->insn) + 5) == 0x45) {/* bxleg */
145 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
146 }
147 break;
148 case 0xe3: /* bctg */
149 if (*(((__u8 *) ainsn->insn) + 5) == 0x46) {
150 ainsn->fixup = FIXUP_BRANCH_NOT_TAKEN;
151 }
152 break;
153 }
154}
155
156static int __kprobes swap_instruction(void *aref)
157{
158 struct ins_replace_args *args = aref;
159 int err = -EFAULT;
160
161 asm volatile(
162 "0: mvc 0(2,%2),0(%3)\n"
163 "1: la %0,0\n"
164 "2:\n"
165 EX_TABLE(0b,2b)
166 : "+d" (err), "=m" (*args->ptr)
167 : "a" (args->ptr), "a" (&args->new), "m" (args->new));
168 return err;
169}
170
171void __kprobes arch_arm_kprobe(struct kprobe *p)
172{
173 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
174 unsigned long status = kcb->kprobe_status;
175 struct ins_replace_args args;
176
177 args.ptr = p->addr;
178 args.old = p->opcode;
179 args.new = BREAKPOINT_INSTRUCTION;
180
181 kcb->kprobe_status = KPROBE_SWAP_INST;
182 stop_machine_run(swap_instruction, &args, NR_CPUS);
183 kcb->kprobe_status = status;
184}
185
186void __kprobes arch_disarm_kprobe(struct kprobe *p)
187{
188 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
189 unsigned long status = kcb->kprobe_status;
190 struct ins_replace_args args;
191
192 args.ptr = p->addr;
193 args.old = BREAKPOINT_INSTRUCTION;
194 args.new = p->opcode;
195
196 kcb->kprobe_status = KPROBE_SWAP_INST;
197 stop_machine_run(swap_instruction, &args, NR_CPUS);
198 kcb->kprobe_status = status;
199}
200
201void __kprobes arch_remove_kprobe(struct kprobe *p)
202{
203 mutex_lock(&kprobe_mutex);
204 free_insn_slot(p->ainsn.insn);
205 mutex_unlock(&kprobe_mutex);
206}
207
208static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
209{
210 per_cr_bits kprobe_per_regs[1];
211
212 memset(kprobe_per_regs, 0, sizeof(per_cr_bits));
213 regs->psw.addr = (unsigned long)p->ainsn.insn | PSW_ADDR_AMODE;
214
215 /* Set up the per control reg info, will pass to lctl */
216 kprobe_per_regs[0].em_instruction_fetch = 1;
217 kprobe_per_regs[0].starting_addr = (unsigned long)p->ainsn.insn;
218 kprobe_per_regs[0].ending_addr = (unsigned long)p->ainsn.insn + 1;
219
220 /* Set the PER control regs, turns on single step for this address */
221 __ctl_load(kprobe_per_regs, 9, 11);
222 regs->psw.mask |= PSW_MASK_PER;
223 regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
224}
225
226static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
227{
228 kcb->prev_kprobe.kp = kprobe_running();
229 kcb->prev_kprobe.status = kcb->kprobe_status;
230 kcb->prev_kprobe.kprobe_saved_imask = kcb->kprobe_saved_imask;
231 memcpy(kcb->prev_kprobe.kprobe_saved_ctl, kcb->kprobe_saved_ctl,
232 sizeof(kcb->kprobe_saved_ctl));
233}
234
235static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
236{
237 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
238 kcb->kprobe_status = kcb->prev_kprobe.status;
239 kcb->kprobe_saved_imask = kcb->prev_kprobe.kprobe_saved_imask;
240 memcpy(kcb->kprobe_saved_ctl, kcb->prev_kprobe.kprobe_saved_ctl,
241 sizeof(kcb->kprobe_saved_ctl));
242}
243
244static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
245 struct kprobe_ctlblk *kcb)
246{
247 __get_cpu_var(current_kprobe) = p;
248 /* Save the interrupt and per flags */
249 kcb->kprobe_saved_imask = regs->psw.mask &
250 (PSW_MASK_PER | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK);
251 /* Save the control regs that govern PER */
252 __ctl_store(kcb->kprobe_saved_ctl, 9, 11);
253}
254
255/* Called with kretprobe_lock held */
256void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
257 struct pt_regs *regs)
258{
259 struct kretprobe_instance *ri;
260
261 if ((ri = get_free_rp_inst(rp)) != NULL) {
262 ri->rp = rp;
263 ri->task = current;
264 ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
265
266 /* Replace the return addr with trampoline addr */
267 regs->gprs[14] = (unsigned long)&kretprobe_trampoline;
268
269 add_rp_inst(ri);
270 } else {
271 rp->nmissed++;
272 }
273}
274
275static int __kprobes kprobe_handler(struct pt_regs *regs)
276{
277 struct kprobe *p;
278 int ret = 0;
279 unsigned long *addr = (unsigned long *)
280 ((regs->psw.addr & PSW_ADDR_INSN) - 2);
281 struct kprobe_ctlblk *kcb;
282
283 /*
284 * We don't want to be preempted for the entire
285 * duration of kprobe processing
286 */
287 preempt_disable();
288 kcb = get_kprobe_ctlblk();
289
290 /* Check we're not actually recursing */
291 if (kprobe_running()) {
292 p = get_kprobe(addr);
293 if (p) {
294 if (kcb->kprobe_status == KPROBE_HIT_SS &&
295 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
296 regs->psw.mask &= ~PSW_MASK_PER;
297 regs->psw.mask |= kcb->kprobe_saved_imask;
298 goto no_kprobe;
299 }
300 /* We have reentered the kprobe_handler(), since
301 * another probe was hit while within the handler.
302 * We here save the original kprobes variables and
303 * just single step on the instruction of the new probe
304 * without calling any user handlers.
305 */
306 save_previous_kprobe(kcb);
307 set_current_kprobe(p, regs, kcb);
308 kprobes_inc_nmissed_count(p);
309 prepare_singlestep(p, regs);
310 kcb->kprobe_status = KPROBE_REENTER;
311 return 1;
312 } else {
313 p = __get_cpu_var(current_kprobe);
314 if (p->break_handler && p->break_handler(p, regs)) {
315 goto ss_probe;
316 }
317 }
318 goto no_kprobe;
319 }
320
321 p = get_kprobe(addr);
322 if (!p) {
323 if (*addr != BREAKPOINT_INSTRUCTION) {
324 /*
325 * The breakpoint instruction was removed right
326 * after we hit it. Another cpu has removed
327 * either a probepoint or a debugger breakpoint
328 * at this address. In either case, no further
329 * handling of this interrupt is appropriate.
330 *
331 */
332 ret = 1;
333 }
334 /* Not one of ours: let kernel handle it */
335 goto no_kprobe;
336 }
337
338 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
339 set_current_kprobe(p, regs, kcb);
340 if (p->pre_handler && p->pre_handler(p, regs))
341 /* handler has already set things up, so skip ss setup */
342 return 1;
343
344ss_probe:
345 prepare_singlestep(p, regs);
346 kcb->kprobe_status = KPROBE_HIT_SS;
347 return 1;
348
349no_kprobe:
350 preempt_enable_no_resched();
351 return ret;
352}
353
354/*
355 * Function return probe trampoline:
356 * - init_kprobes() establishes a probepoint here
357 * - When the probed function returns, this probe
358 * causes the handlers to fire
359 */
360void __kprobes kretprobe_trampoline_holder(void)
361{
362 asm volatile(".global kretprobe_trampoline\n"
363 "kretprobe_trampoline: bcr 0,0\n");
364}
365
366/*
367 * Called when the probe at kretprobe trampoline is hit
368 */
369int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
370{
371 struct kretprobe_instance *ri = NULL;
372 struct hlist_head *head;
373 struct hlist_node *node, *tmp;
374 unsigned long flags, orig_ret_address = 0;
375 unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
376
377 spin_lock_irqsave(&kretprobe_lock, flags);
378 head = kretprobe_inst_table_head(current);
379
380 /*
381 * It is possible to have multiple instances associated with a given
382 * task either because an multiple functions in the call path
383 * have a return probe installed on them, and/or more then one return
384 * return probe was registered for a target function.
385 *
386 * We can handle this because:
387 * - instances are always inserted at the head of the list
388 * - when multiple return probes are registered for the same
389 * function, the first instance's ret_addr will point to the
390 * real return address, and all the rest will point to
391 * kretprobe_trampoline
392 */
393 hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
394 if (ri->task != current)
395 /* another task is sharing our hash bucket */
396 continue;
397
398 if (ri->rp && ri->rp->handler)
399 ri->rp->handler(ri, regs);
400
401 orig_ret_address = (unsigned long)ri->ret_addr;
402 recycle_rp_inst(ri);
403
404 if (orig_ret_address != trampoline_address) {
405 /*
406 * This is the real return address. Any other
407 * instances associated with this task are for
408 * other calls deeper on the call stack
409 */
410 break;
411 }
412 }
413 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
414 regs->psw.addr = orig_ret_address | PSW_ADDR_AMODE;
415
416 reset_current_kprobe();
417 spin_unlock_irqrestore(&kretprobe_lock, flags);
418 preempt_enable_no_resched();
419
420 /*
421 * By returning a non-zero value, we are telling
422 * kprobe_handler() that we don't want the post_handler
423 * to run (and have re-enabled preemption)
424 */
425 return 1;
426}
427
428/*
429 * Called after single-stepping. p->addr is the address of the
430 * instruction whose first byte has been replaced by the "breakpoint"
431 * instruction. To avoid the SMP problems that can occur when we
432 * temporarily put back the original opcode to single-step, we
433 * single-stepped a copy of the instruction. The address of this
434 * copy is p->ainsn.insn.
435 */
436static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
437{
438 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
439
440 regs->psw.addr &= PSW_ADDR_INSN;
441
442 if (p->ainsn.fixup & FIXUP_PSW_NORMAL)
443 regs->psw.addr = (unsigned long)p->addr +
444 ((unsigned long)regs->psw.addr -
445 (unsigned long)p->ainsn.insn);
446
447 if (p->ainsn.fixup & FIXUP_BRANCH_NOT_TAKEN)
448 if ((unsigned long)regs->psw.addr -
449 (unsigned long)p->ainsn.insn == p->ainsn.ilen)
450 regs->psw.addr = (unsigned long)p->addr + p->ainsn.ilen;
451
452 if (p->ainsn.fixup & FIXUP_RETURN_REGISTER)
453 regs->gprs[p->ainsn.reg] = ((unsigned long)p->addr +
454 (regs->gprs[p->ainsn.reg] -
455 (unsigned long)p->ainsn.insn))
456 | PSW_ADDR_AMODE;
457
458 regs->psw.addr |= PSW_ADDR_AMODE;
459 /* turn off PER mode */
460 regs->psw.mask &= ~PSW_MASK_PER;
461 /* Restore the original per control regs */
462 __ctl_load(kcb->kprobe_saved_ctl, 9, 11);
463 regs->psw.mask |= kcb->kprobe_saved_imask;
464}
465
466static int __kprobes post_kprobe_handler(struct pt_regs *regs)
467{
468 struct kprobe *cur = kprobe_running();
469 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
470
471 if (!cur)
472 return 0;
473
474 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
475 kcb->kprobe_status = KPROBE_HIT_SSDONE;
476 cur->post_handler(cur, regs, 0);
477 }
478
479 resume_execution(cur, regs);
480
481 /*Restore back the original saved kprobes variables and continue. */
482 if (kcb->kprobe_status == KPROBE_REENTER) {
483 restore_previous_kprobe(kcb);
484 goto out;
485 }
486 reset_current_kprobe();
487out:
488 preempt_enable_no_resched();
489
490 /*
491 * if somebody else is singlestepping across a probe point, psw mask
492 * will have PER set, in which case, continue the remaining processing
493 * of do_single_step, as if this is not a probe hit.
494 */
495 if (regs->psw.mask & PSW_MASK_PER) {
496 return 0;
497 }
498
499 return 1;
500}
501
502static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
503{
504 struct kprobe *cur = kprobe_running();
505 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
506 const struct exception_table_entry *entry;
507
508 switch(kcb->kprobe_status) {
509 case KPROBE_SWAP_INST:
510 /* We are here because the instruction replacement failed */
511 return 0;
512 case KPROBE_HIT_SS:
513 case KPROBE_REENTER:
514 /*
515 * We are here because the instruction being single
516 * stepped caused a page fault. We reset the current
517 * kprobe and the nip points back to the probe address
518 * and allow the page fault handler to continue as a
519 * normal page fault.
520 */
521 regs->psw.addr = (unsigned long)cur->addr | PSW_ADDR_AMODE;
522 regs->psw.mask &= ~PSW_MASK_PER;
523 regs->psw.mask |= kcb->kprobe_saved_imask;
524 if (kcb->kprobe_status == KPROBE_REENTER)
525 restore_previous_kprobe(kcb);
526 else
527 reset_current_kprobe();
528 preempt_enable_no_resched();
529 break;
530 case KPROBE_HIT_ACTIVE:
531 case KPROBE_HIT_SSDONE:
532 /*
533 * We increment the nmissed count for accounting,
534 * we can also use npre/npostfault count for accouting
535 * these specific fault cases.
536 */
537 kprobes_inc_nmissed_count(cur);
538
539 /*
540 * We come here because instructions in the pre/post
541 * handler caused the page_fault, this could happen
542 * if handler tries to access user space by
543 * copy_from_user(), get_user() etc. Let the
544 * user-specified handler try to fix it first.
545 */
546 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
547 return 1;
548
549 /*
550 * In case the user-specified fault handler returned
551 * zero, try to fix up.
552 */
553 entry = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
554 if (entry) {
555 regs->psw.addr = entry->fixup | PSW_ADDR_AMODE;
556 return 1;
557 }
558
559 /*
560 * fixup_exception() could not handle it,
561 * Let do_page_fault() fix it.
562 */
563 break;
564 default:
565 break;
566 }
567 return 0;
568}
569
570/*
571 * Wrapper routine to for handling exceptions.
572 */
573int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
574 unsigned long val, void *data)
575{
576 struct die_args *args = (struct die_args *)data;
577 int ret = NOTIFY_DONE;
578
579 switch (val) {
580 case DIE_BPT:
581 if (kprobe_handler(args->regs))
582 ret = NOTIFY_STOP;
583 break;
584 case DIE_SSTEP:
585 if (post_kprobe_handler(args->regs))
586 ret = NOTIFY_STOP;
587 break;
588 case DIE_TRAP:
589 case DIE_PAGE_FAULT:
590 /* kprobe_running() needs smp_processor_id() */
591 preempt_disable();
592 if (kprobe_running() &&
593 kprobe_fault_handler(args->regs, args->trapnr))
594 ret = NOTIFY_STOP;
595 preempt_enable();
596 break;
597 default:
598 break;
599 }
600 return ret;
601}
602
603int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
604{
605 struct jprobe *jp = container_of(p, struct jprobe, kp);
606 unsigned long addr;
607 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
608
609 memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
610
611 /* setup return addr to the jprobe handler routine */
612 regs->psw.addr = (unsigned long)(jp->entry) | PSW_ADDR_AMODE;
613
614 /* r14 is the function return address */
615 kcb->jprobe_saved_r14 = (unsigned long)regs->gprs[14];
616 /* r15 is the stack pointer */
617 kcb->jprobe_saved_r15 = (unsigned long)regs->gprs[15];
618 addr = (unsigned long)kcb->jprobe_saved_r15;
619
620 memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
621 MIN_STACK_SIZE(addr));
622 return 1;
623}
624
625void __kprobes jprobe_return(void)
626{
627 asm volatile(".word 0x0002");
628}
629
630void __kprobes jprobe_return_end(void)
631{
632 asm volatile("bcr 0,0");
633}
634
635int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
636{
637 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
638 unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_r15);
639
640 /* Put the regs back */
641 memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
642 /* put the stack back */
643 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
644 MIN_STACK_SIZE(stack_addr));
645 preempt_enable_no_resched();
646 return 1;
647}
648
649static struct kprobe trampoline_p = {
650 .addr = (kprobe_opcode_t *) & kretprobe_trampoline,
651 .pre_handler = trampoline_probe_handler
652};
653
654int __init arch_init_kprobes(void)
655{
656 return register_kprobe(&trampoline_p);
657}
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 658e5ac484f9..4562cdbce8eb 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -8,13 +8,30 @@
8 8
9#include <asm/lowcore.h> 9#include <asm/lowcore.h>
10 10
11 .globl do_reipl 11 .globl do_reipl_asm
12do_reipl: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13) 13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13)
14.Lpg1: lctl %c6,%c6,.Lall-.Lpg0(%r13) 14
15 stctl %c0,%c0,.Lctlsave-.Lpg0(%r13) 15 # switch off lowcore protection
16 ni .Lctlsave-.Lpg0(%r13),0xef 16
17 lctl %c0,%c0,.Lctlsave-.Lpg0(%r13) 17.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
18 stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13)
19 ni .Lctlsave1-.Lpg0(%r13),0xef
20 lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
21
22 # do store status of all registers
23
24 stm %r0,%r15,__LC_GPREGS_SAVE_AREA
25 stctl %c0,%c15,__LC_CREGS_SAVE_AREA
26 mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13)
27 stam %a0,%a15,__LC_AREGS_SAVE_AREA
28 stpx __LC_PREFIX_SAVE_AREA
29 stckc .Lclkcmp-.Lpg0(%r13)
30 mvc __LC_CLOCK_COMP_SAVE_AREA(8),.Lclkcmp-.Lpg0(%r13)
31 stpt __LC_CPU_TIMER_SAVE_AREA
32 st %r13, __LC_PSW_SAVE_AREA+4
33
34 lctl %c6,%c6,.Lall-.Lpg0(%r13)
18 lr %r1,%r2 35 lr %r1,%r2
19 mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13) 36 mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13)
20 stsch .Lschib-.Lpg0(%r13) 37 stsch .Lschib-.Lpg0(%r13)
@@ -46,9 +63,11 @@ do_reipl: basr %r13,0
46.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) 63.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13)
47 lpsw .Ldispsw-.Lpg0(%r13) 64 lpsw .Ldispsw-.Lpg0(%r13)
48 .align 8 65 .align 8
66.Lclkcmp: .quad 0x0000000000000000
49.Lall: .long 0xff000000 67.Lall: .long 0xff000000
50.Lnull: .long 0x00000000 68.Lnull: .long 0x00000000
51.Lctlsave: .long 0x00000000 69.Lctlsave1: .long 0x00000000
70.Lctlsave2: .long 0x00000000
52 .align 8 71 .align 8
53.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 72.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1
54.Lpcnew: .long 0x00080000,0x80000000+.Lecs 73.Lpcnew: .long 0x00080000,0x80000000+.Lecs
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 4d090d60f3ef..95bd1e234f63 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -8,13 +8,30 @@
8 */ 8 */
9 9
10#include <asm/lowcore.h> 10#include <asm/lowcore.h>
11 .globl do_reipl 11 .globl do_reipl_asm
12do_reipl: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) 13
14 # do store status of all registers
15
16.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13)
17 lghi %r1,0x1000
18 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
19 lg %r0,.Lregsave-.Lpg0(%r13)
20 stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
21 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
22 stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
23 stpx __LC_PREFIX_SAVE_AREA-0x1000(%r1)
24 stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
25 stckc .Lclkcmp-.Lpg0(%r13)
26 mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
27 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
28 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
29
30 lpswe .Lnewpsw-.Lpg0(%r13)
14.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13) 31.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
15 stctg %c0,%c0,.Lctlsave-.Lpg0(%r13) 32 stctg %c0,%c0,.Lregsave-.Lpg0(%r13)
16 ni .Lctlsave+4-.Lpg0(%r13),0xef 33 ni .Lregsave+4-.Lpg0(%r13),0xef
17 lctlg %c0,%c0,.Lctlsave-.Lpg0(%r13) 34 lctlg %c0,%c0,.Lregsave-.Lpg0(%r13)
18 lgr %r1,%r2 35 lgr %r1,%r2
19 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) 36 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
20 stsch .Lschib-.Lpg0(%r13) 37 stsch .Lschib-.Lpg0(%r13)
@@ -50,8 +67,9 @@ do_reipl: basr %r13,0
50 st %r14,.Ldispsw+12-.Lpg0(%r13) 67 st %r14,.Ldispsw+12-.Lpg0(%r13)
51 lpswe .Ldispsw-.Lpg0(%r13) 68 lpswe .Ldispsw-.Lpg0(%r13)
52 .align 8 69 .align 8
70.Lclkcmp: .quad 0x0000000000000000
53.Lall: .quad 0x00000000ff000000 71.Lall: .quad 0x00000000ff000000
54.Lctlsave: .quad 0x0000000000000000 72.Lregsave: .quad 0x0000000000000000
55.Lnull: .long 0x0000000000000000 73.Lnull: .long 0x0000000000000000
56 .align 16 74 .align 16
57/* 75/*
@@ -92,5 +110,3 @@ do_reipl: basr %r13,0
92 .long 0x00000000,0x00000000 110 .long 0x00000000,0x00000000
93 .long 0x00000000,0x00000000 111 .long 0x00000000,0x00000000
94 112
95
96
diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c
deleted file mode 100644
index 1f33951ba439..000000000000
--- a/arch/s390/kernel/reipl_diag.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * This file contains the implementation of the
3 * Linux re-IPL support
4 *
5 * (C) Copyright IBM Corp. 2005
6 *
7 * Author(s): Volker Sameske (sameske@de.ibm.com)
8 *
9 */
10
11#include <linux/kernel.h>
12
13static unsigned int reipl_diag_rc1;
14static unsigned int reipl_diag_rc2;
15
16/*
17 * re-IPL the system using the last used IPL parameters
18 */
19void reipl_diag(void)
20{
21 asm volatile (
22 " la %%r4,0\n"
23 " la %%r5,0\n"
24 " diag %%r4,%2,0x308\n"
25 "0:\n"
26 " st %%r4,%0\n"
27 " st %%r5,%1\n"
28 ".section __ex_table,\"a\"\n"
29#ifdef CONFIG_64BIT
30 " .align 8\n"
31 " .quad 0b, 0b\n"
32#else
33 " .align 4\n"
34 " .long 0b, 0b\n"
35#endif
36 ".previous\n"
37 : "=m" (reipl_diag_rc1), "=m" (reipl_diag_rc2)
38 : "d" (3) : "cc", "4", "5" );
39}
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index c73a45467fa4..9f19e833a562 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -25,12 +25,6 @@ EXPORT_SYMBOL(_oi_bitmap);
25EXPORT_SYMBOL(_ni_bitmap); 25EXPORT_SYMBOL(_ni_bitmap);
26EXPORT_SYMBOL(_zb_findmap); 26EXPORT_SYMBOL(_zb_findmap);
27EXPORT_SYMBOL(_sb_findmap); 27EXPORT_SYMBOL(_sb_findmap);
28EXPORT_SYMBOL(__copy_from_user_asm);
29EXPORT_SYMBOL(__copy_to_user_asm);
30EXPORT_SYMBOL(__copy_in_user_asm);
31EXPORT_SYMBOL(__clear_user_asm);
32EXPORT_SYMBOL(__strncpy_from_user_asm);
33EXPORT_SYMBOL(__strnlen_user_asm);
34EXPORT_SYMBOL(diag10); 28EXPORT_SYMBOL(diag10);
35 29
36/* 30/*
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c902f059c7aa..e3d9325f6022 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -37,6 +37,7 @@
37#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <linux/notifier.h> 39#include <linux/notifier.h>
40#include <linux/pfn.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/system.h> 43#include <asm/system.h>
@@ -50,6 +51,12 @@
50#include <asm/sections.h> 51#include <asm/sections.h>
51 52
52/* 53/*
54 * User copy operations.
55 */
56struct uaccess_ops uaccess;
57EXPORT_SYMBOL_GPL(uaccess);
58
59/*
53 * Machine setup.. 60 * Machine setup..
54 */ 61 */
55unsigned int console_mode = 0; 62unsigned int console_mode = 0;
@@ -284,16 +291,9 @@ void (*_machine_power_off)(void) = machine_power_off_smp;
284/* 291/*
285 * Reboot, halt and power_off routines for non SMP. 292 * Reboot, halt and power_off routines for non SMP.
286 */ 293 */
287extern void reipl(unsigned long devno);
288extern void reipl_diag(void);
289static void do_machine_restart_nonsmp(char * __unused) 294static void do_machine_restart_nonsmp(char * __unused)
290{ 295{
291 reipl_diag(); 296 do_reipl();
292
293 if (MACHINE_IS_VM)
294 cpcmd ("IPL", NULL, 0, NULL);
295 else
296 reipl (0x10000 | S390_lowcore.ipl_device);
297} 297}
298 298
299static void do_machine_halt_nonsmp(void) 299static void do_machine_halt_nonsmp(void)
@@ -501,13 +501,47 @@ setup_memory(void)
501 * partially used pages are not usable - thus 501 * partially used pages are not usable - thus
502 * we are rounding upwards: 502 * we are rounding upwards:
503 */ 503 */
504 start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; 504 start_pfn = PFN_UP(__pa(&_end));
505 end_pfn = max_pfn = memory_end >> PAGE_SHIFT; 505 end_pfn = max_pfn = PFN_DOWN(memory_end);
506 506
507 /* Initialize storage key for kernel pages */ 507 /* Initialize storage key for kernel pages */
508 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++) 508 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
509 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); 509 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
510 510
511#ifdef CONFIG_BLK_DEV_INITRD
512 /*
513 * Move the initrd in case the bitmap of the bootmem allocater
514 * would overwrite it.
515 */
516
517 if (INITRD_START && INITRD_SIZE) {
518 unsigned long bmap_size;
519 unsigned long start;
520
521 bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1);
522 bmap_size = PFN_PHYS(bmap_size);
523
524 if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
525 start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
526
527 if (start + INITRD_SIZE > memory_end) {
528 printk("initrd extends beyond end of memory "
529 "(0x%08lx > 0x%08lx)\n"
530 "disabling initrd\n",
531 start + INITRD_SIZE, memory_end);
532 INITRD_START = INITRD_SIZE = 0;
533 } else {
534 printk("Moving initrd (0x%08lx -> 0x%08lx, "
535 "size: %ld)\n",
536 INITRD_START, start, INITRD_SIZE);
537 memmove((void *) start, (void *) INITRD_START,
538 INITRD_SIZE);
539 INITRD_START = start;
540 }
541 }
542 }
543#endif
544
511 /* 545 /*
512 * Initialize the boot-time allocator (with low memory only): 546 * Initialize the boot-time allocator (with low memory only):
513 */ 547 */
@@ -559,7 +593,7 @@ setup_memory(void)
559 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); 593 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
560 594
561#ifdef CONFIG_BLK_DEV_INITRD 595#ifdef CONFIG_BLK_DEV_INITRD
562 if (INITRD_START) { 596 if (INITRD_START && INITRD_SIZE) {
563 if (INITRD_START + INITRD_SIZE <= memory_end) { 597 if (INITRD_START + INITRD_SIZE <= memory_end) {
564 reserve_bootmem(INITRD_START, INITRD_SIZE); 598 reserve_bootmem(INITRD_START, INITRD_SIZE);
565 initrd_start = INITRD_START; 599 initrd_start = INITRD_START;
@@ -613,6 +647,11 @@ setup_arch(char **cmdline_p)
613 647
614 memory_end = memory_size; 648 memory_end = memory_size;
615 649
650 if (MACHINE_HAS_MVCOS)
651 memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
652 else
653 memcpy(&uaccess, &uaccess_std, sizeof(uaccess));
654
616 parse_early_param(); 655 parse_early_param();
617 656
618#ifndef CONFIG_64BIT 657#ifndef CONFIG_64BIT
@@ -720,214 +759,3 @@ struct seq_operations cpuinfo_op = {
720 .show = show_cpuinfo, 759 .show = show_cpuinfo,
721}; 760};
722 761
723#define DEFINE_IPL_ATTR(_name, _format, _value) \
724static ssize_t ipl_##_name##_show(struct subsystem *subsys, \
725 char *page) \
726{ \
727 return sprintf(page, _format, _value); \
728} \
729static struct subsys_attribute ipl_##_name##_attr = \
730 __ATTR(_name, S_IRUGO, ipl_##_name##_show, NULL);
731
732DEFINE_IPL_ATTR(wwpn, "0x%016llx\n", (unsigned long long)
733 IPL_PARMBLOCK_START->fcp.wwpn);
734DEFINE_IPL_ATTR(lun, "0x%016llx\n", (unsigned long long)
735 IPL_PARMBLOCK_START->fcp.lun);
736DEFINE_IPL_ATTR(bootprog, "%lld\n", (unsigned long long)
737 IPL_PARMBLOCK_START->fcp.bootprog);
738DEFINE_IPL_ATTR(br_lba, "%lld\n", (unsigned long long)
739 IPL_PARMBLOCK_START->fcp.br_lba);
740
741enum ipl_type_type {
742 ipl_type_unknown,
743 ipl_type_ccw,
744 ipl_type_fcp,
745};
746
747static enum ipl_type_type
748get_ipl_type(void)
749{
750 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
751
752 if (!IPL_DEVNO_VALID)
753 return ipl_type_unknown;
754 if (!IPL_PARMBLOCK_VALID)
755 return ipl_type_ccw;
756 if (ipl->hdr.header.version > IPL_MAX_SUPPORTED_VERSION)
757 return ipl_type_unknown;
758 if (ipl->fcp.pbt != IPL_TYPE_FCP)
759 return ipl_type_unknown;
760 return ipl_type_fcp;
761}
762
763static ssize_t
764ipl_type_show(struct subsystem *subsys, char *page)
765{
766 switch (get_ipl_type()) {
767 case ipl_type_ccw:
768 return sprintf(page, "ccw\n");
769 case ipl_type_fcp:
770 return sprintf(page, "fcp\n");
771 default:
772 return sprintf(page, "unknown\n");
773 }
774}
775
776static struct subsys_attribute ipl_type_attr = __ATTR_RO(ipl_type);
777
778static ssize_t
779ipl_device_show(struct subsystem *subsys, char *page)
780{
781 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
782
783 switch (get_ipl_type()) {
784 case ipl_type_ccw:
785 return sprintf(page, "0.0.%04x\n", ipl_devno);
786 case ipl_type_fcp:
787 return sprintf(page, "0.0.%04x\n", ipl->fcp.devno);
788 default:
789 return 0;
790 }
791}
792
793static struct subsys_attribute ipl_device_attr =
794 __ATTR(device, S_IRUGO, ipl_device_show, NULL);
795
796static struct attribute *ipl_fcp_attrs[] = {
797 &ipl_type_attr.attr,
798 &ipl_device_attr.attr,
799 &ipl_wwpn_attr.attr,
800 &ipl_lun_attr.attr,
801 &ipl_bootprog_attr.attr,
802 &ipl_br_lba_attr.attr,
803 NULL,
804};
805
806static struct attribute_group ipl_fcp_attr_group = {
807 .attrs = ipl_fcp_attrs,
808};
809
810static struct attribute *ipl_ccw_attrs[] = {
811 &ipl_type_attr.attr,
812 &ipl_device_attr.attr,
813 NULL,
814};
815
816static struct attribute_group ipl_ccw_attr_group = {
817 .attrs = ipl_ccw_attrs,
818};
819
820static struct attribute *ipl_unknown_attrs[] = {
821 &ipl_type_attr.attr,
822 NULL,
823};
824
825static struct attribute_group ipl_unknown_attr_group = {
826 .attrs = ipl_unknown_attrs,
827};
828
829static ssize_t
830ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
831{
832 unsigned int size = IPL_PARMBLOCK_SIZE;
833
834 if (off > size)
835 return 0;
836 if (off + count > size)
837 count = size - off;
838
839 memcpy(buf, (void *) IPL_PARMBLOCK_START + off, count);
840 return count;
841}
842
843static struct bin_attribute ipl_parameter_attr = {
844 .attr = {
845 .name = "binary_parameter",
846 .mode = S_IRUGO,
847 .owner = THIS_MODULE,
848 },
849 .size = PAGE_SIZE,
850 .read = &ipl_parameter_read,
851};
852
853static ssize_t
854ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
855{
856 unsigned int size = IPL_PARMBLOCK_START->fcp.scp_data_len;
857 void *scp_data = &IPL_PARMBLOCK_START->fcp.scp_data;
858
859 if (off > size)
860 return 0;
861 if (off + count > size)
862 count = size - off;
863
864 memcpy(buf, scp_data + off, count);
865 return count;
866}
867
868static struct bin_attribute ipl_scp_data_attr = {
869 .attr = {
870 .name = "scp_data",
871 .mode = S_IRUGO,
872 .owner = THIS_MODULE,
873 },
874 .size = PAGE_SIZE,
875 .read = &ipl_scp_data_read,
876};
877
878static decl_subsys(ipl, NULL, NULL);
879
880static int ipl_register_fcp_files(void)
881{
882 int rc;
883
884 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
885 &ipl_fcp_attr_group);
886 if (rc)
887 goto out;
888 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
889 &ipl_parameter_attr);
890 if (rc)
891 goto out_ipl_parm;
892 rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj,
893 &ipl_scp_data_attr);
894 if (!rc)
895 goto out;
896
897 sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr);
898
899out_ipl_parm:
900 sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group);
901out:
902 return rc;
903}
904
905static int __init
906ipl_device_sysfs_register(void) {
907 int rc;
908
909 rc = firmware_register(&ipl_subsys);
910 if (rc)
911 goto out;
912
913 switch (get_ipl_type()) {
914 case ipl_type_ccw:
915 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
916 &ipl_ccw_attr_group);
917 break;
918 case ipl_type_fcp:
919 rc = ipl_register_fcp_files();
920 break;
921 default:
922 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
923 &ipl_unknown_attr_group);
924 break;
925 }
926
927 if (rc)
928 firmware_unregister(&ipl_subsys);
929out:
930 return rc;
931}
932
933__initcall(ipl_device_sysfs_register);
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index a887b686f279..642095ec7c07 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -114,29 +114,26 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
114static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) 114static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
115{ 115{
116 unsigned long old_mask = regs->psw.mask; 116 unsigned long old_mask = regs->psw.mask;
117 int err; 117 _sigregs user_sregs;
118 118
119 save_access_regs(current->thread.acrs); 119 save_access_regs(current->thread.acrs);
120 120
121 /* Copy a 'clean' PSW mask to the user to avoid leaking 121 /* Copy a 'clean' PSW mask to the user to avoid leaking
122 information about whether PER is currently on. */ 122 information about whether PER is currently on. */
123 regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask); 123 regs->psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask);
124 err = __copy_to_user(&sregs->regs.psw, &regs->psw, 124 memcpy(&user_sregs.regs.psw, &regs->psw, sizeof(sregs->regs.psw) +
125 sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs)); 125 sizeof(sregs->regs.gprs));
126 regs->psw.mask = old_mask; 126 regs->psw.mask = old_mask;
127 if (err != 0) 127 memcpy(&user_sregs.regs.acrs, current->thread.acrs,
128 return err; 128 sizeof(sregs->regs.acrs));
129 err = __copy_to_user(&sregs->regs.acrs, current->thread.acrs,
130 sizeof(sregs->regs.acrs));
131 if (err != 0)
132 return err;
133 /* 129 /*
134 * We have to store the fp registers to current->thread.fp_regs 130 * We have to store the fp registers to current->thread.fp_regs
135 * to merge them with the emulated registers. 131 * to merge them with the emulated registers.
136 */ 132 */
137 save_fp_regs(&current->thread.fp_regs); 133 save_fp_regs(&current->thread.fp_regs);
138 return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs, 134 memcpy(&user_sregs.fpregs, &current->thread.fp_regs,
139 sizeof(s390_fp_regs)); 135 sizeof(s390_fp_regs));
136 return __copy_to_user(sregs, &user_sregs, sizeof(_sigregs));
140} 137}
141 138
142/* Returns positive number on error */ 139/* Returns positive number on error */
@@ -144,27 +141,25 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
144{ 141{
145 unsigned long old_mask = regs->psw.mask; 142 unsigned long old_mask = regs->psw.mask;
146 int err; 143 int err;
144 _sigregs user_sregs;
147 145
148 /* Alwys make any pending restarted system call return -EINTR */ 146 /* Alwys make any pending restarted system call return -EINTR */
149 current_thread_info()->restart_block.fn = do_no_restart_syscall; 147 current_thread_info()->restart_block.fn = do_no_restart_syscall;
150 148
151 err = __copy_from_user(&regs->psw, &sregs->regs.psw, 149 err = __copy_from_user(&user_sregs, sregs, sizeof(_sigregs));
152 sizeof(sregs->regs.psw)+sizeof(sregs->regs.gprs));
153 regs->psw.mask = PSW_MASK_MERGE(old_mask, regs->psw.mask); 150 regs->psw.mask = PSW_MASK_MERGE(old_mask, regs->psw.mask);
154 regs->psw.addr |= PSW_ADDR_AMODE; 151 regs->psw.addr |= PSW_ADDR_AMODE;
155 if (err) 152 if (err)
156 return err; 153 return err;
157 err = __copy_from_user(&current->thread.acrs, &sregs->regs.acrs, 154 memcpy(&regs->psw, &user_sregs.regs.psw, sizeof(sregs->regs.psw) +
158 sizeof(sregs->regs.acrs)); 155 sizeof(sregs->regs.gprs));
159 if (err) 156 memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
160 return err; 157 sizeof(sregs->regs.acrs));
161 restore_access_regs(current->thread.acrs); 158 restore_access_regs(current->thread.acrs);
162 159
163 err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs, 160 memcpy(&current->thread.fp_regs, &user_sregs.fpregs,
164 sizeof(s390_fp_regs)); 161 sizeof(s390_fp_regs));
165 current->thread.fp_regs.fpc &= FPC_VALID_MASK; 162 current->thread.fp_regs.fpc &= FPC_VALID_MASK;
166 if (err)
167 return err;
168 163
169 restore_fp_regs(&current->thread.fp_regs); 164 restore_fp_regs(&current->thread.fp_regs);
170 regs->trap = -1; /* disable syscall checks */ 165 regs->trap = -1; /* disable syscall checks */
@@ -457,6 +452,7 @@ void do_signal(struct pt_regs *regs)
457 case -ERESTART_RESTARTBLOCK: 452 case -ERESTART_RESTARTBLOCK:
458 regs->gprs[2] = -EINTR; 453 regs->gprs[2] = -EINTR;
459 } 454 }
455 regs->trap = -1; /* Don't deal with this again. */
460 } 456 }
461 457
462 /* Get signal to deliver. When running under ptrace, at this point 458 /* Get signal to deliver. When running under ptrace, at this point
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8e03219eea76..b2e6f4c8d382 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -59,9 +59,6 @@ static struct task_struct *current_set[NR_CPUS];
59extern char vmhalt_cmd[]; 59extern char vmhalt_cmd[];
60extern char vmpoff_cmd[]; 60extern char vmpoff_cmd[];
61 61
62extern void reipl(unsigned long devno);
63extern void reipl_diag(void);
64
65static void smp_ext_bitcall(int, ec_bit_sig); 62static void smp_ext_bitcall(int, ec_bit_sig);
66static void smp_ext_bitcall_others(ec_bit_sig); 63static void smp_ext_bitcall_others(ec_bit_sig);
67 64
@@ -279,12 +276,7 @@ static void do_machine_restart(void * __unused)
279 * interrupted by an external interrupt and s390irq 276 * interrupted by an external interrupt and s390irq
280 * locks are always held disabled). 277 * locks are always held disabled).
281 */ 278 */
282 reipl_diag(); 279 do_reipl();
283
284 if (MACHINE_IS_VM)
285 cpcmd ("IPL", NULL, 0, NULL);
286 else
287 reipl (0x10000 | S390_lowcore.ipl_device);
288} 280}
289 281
290void machine_restart_smp(char * __unused) 282void machine_restart_smp(char * __unused)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index bde1d1d59858..c4982c963424 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -29,6 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/kallsyms.h> 30#include <linux/kallsyms.h>
31#include <linux/reboot.h> 31#include <linux/reboot.h>
32#include <linux/kprobes.h>
32 33
33#include <asm/system.h> 34#include <asm/system.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -39,6 +40,7 @@
39#include <asm/s390_ext.h> 40#include <asm/s390_ext.h>
40#include <asm/lowcore.h> 41#include <asm/lowcore.h>
41#include <asm/debug.h> 42#include <asm/debug.h>
43#include <asm/kdebug.h>
42 44
43/* Called from entry.S only */ 45/* Called from entry.S only */
44extern void handle_per_exception(struct pt_regs *regs); 46extern void handle_per_exception(struct pt_regs *regs);
@@ -74,6 +76,20 @@ static int kstack_depth_to_print = 12;
74static int kstack_depth_to_print = 20; 76static int kstack_depth_to_print = 20;
75#endif /* CONFIG_64BIT */ 77#endif /* CONFIG_64BIT */
76 78
79ATOMIC_NOTIFIER_HEAD(s390die_chain);
80
81int register_die_notifier(struct notifier_block *nb)
82{
83 return atomic_notifier_chain_register(&s390die_chain, nb);
84}
85EXPORT_SYMBOL(register_die_notifier);
86
87int unregister_die_notifier(struct notifier_block *nb)
88{
89 return atomic_notifier_chain_unregister(&s390die_chain, nb);
90}
91EXPORT_SYMBOL(unregister_die_notifier);
92
77/* 93/*
78 * For show_trace we have tree different stack to consider: 94 * For show_trace we have tree different stack to consider:
79 * - the panic stack which is used if the kernel stack has overflown 95 * - the panic stack which is used if the kernel stack has overflown
@@ -305,8 +321,9 @@ report_user_fault(long interruption_code, struct pt_regs *regs)
305#endif 321#endif
306} 322}
307 323
308static void inline do_trap(long interruption_code, int signr, char *str, 324static void __kprobes inline do_trap(long interruption_code, int signr,
309 struct pt_regs *regs, siginfo_t *info) 325 char *str, struct pt_regs *regs,
326 siginfo_t *info)
310{ 327{
311 /* 328 /*
312 * We got all needed information from the lowcore and can 329 * We got all needed information from the lowcore and can
@@ -315,6 +332,10 @@ static void inline do_trap(long interruption_code, int signr, char *str,
315 if (regs->psw.mask & PSW_MASK_PSTATE) 332 if (regs->psw.mask & PSW_MASK_PSTATE)
316 local_irq_enable(); 333 local_irq_enable();
317 334
335 if (notify_die(DIE_TRAP, str, regs, interruption_code,
336 interruption_code, signr) == NOTIFY_STOP)
337 return;
338
318 if (regs->psw.mask & PSW_MASK_PSTATE) { 339 if (regs->psw.mask & PSW_MASK_PSTATE) {
319 struct task_struct *tsk = current; 340 struct task_struct *tsk = current;
320 341
@@ -336,8 +357,12 @@ static inline void __user *get_check_address(struct pt_regs *regs)
336 return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN); 357 return (void __user *)((regs->psw.addr-S390_lowcore.pgm_ilc) & PSW_ADDR_INSN);
337} 358}
338 359
339void do_single_step(struct pt_regs *regs) 360void __kprobes do_single_step(struct pt_regs *regs)
340{ 361{
362 if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0,
363 SIGTRAP) == NOTIFY_STOP){
364 return;
365 }
341 if ((current->ptrace & PT_PTRACED) != 0) 366 if ((current->ptrace & PT_PTRACED) != 0)
342 force_sig(SIGTRAP, current); 367 force_sig(SIGTRAP, current);
343} 368}
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index ff5f7bb34f75..af9e69a03011 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -24,6 +24,7 @@ SECTIONS
24 *(.text) 24 *(.text)
25 SCHED_TEXT 25 SCHED_TEXT
26 LOCK_TEXT 26 LOCK_TEXT
27 KPROBES_TEXT
27 *(.fixup) 28 *(.fixup)
28 *(.gnu.warning) 29 *(.gnu.warning)
29 } = 0x0700 30 } = 0x0700
@@ -117,7 +118,7 @@ SECTIONS
117 118
118 /* Sections to be discarded */ 119 /* Sections to be discarded */
119 /DISCARD/ : { 120 /DISCARD/ : {
120 *(.exitcall.exit) 121 *(.exit.text) *(.exit.data) *(.exitcall.exit)
121 } 122 }
122 123
123 /* Stabs debugging sections. */ 124 /* Stabs debugging sections. */
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index e05d087a6eae..c42ffedfdb49 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,6 +4,6 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y += delay.o string.o 7lib-y += delay.o string.o uaccess_std.o
8lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o) 8lib-$(CONFIG_64BIT) += uaccess_mvcos.o
9lib-$(CONFIG_SMP) += spinlock.o 9lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/lib/uaccess.S b/arch/s390/lib/uaccess.S
deleted file mode 100644
index 837275284d9f..000000000000
--- a/arch/s390/lib/uaccess.S
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * arch/s390/lib/uaccess.S
3 * __copy_{from|to}_user functions.
4 *
5 * s390
6 * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *
9 * These functions have standard call interface
10 */
11
12#include <linux/errno.h>
13#include <asm/lowcore.h>
14#include <asm/asm-offsets.h>
15
16 .text
17 .align 4
18 .globl __copy_from_user_asm
19 # %r2 = to, %r3 = n, %r4 = from
20__copy_from_user_asm:
21 slr %r0,%r0
220: mvcp 0(%r3,%r2),0(%r4),%r0
23 jnz 1f
24 slr %r2,%r2
25 br %r14
261: la %r2,256(%r2)
27 la %r4,256(%r4)
28 ahi %r3,-256
292: mvcp 0(%r3,%r2),0(%r4),%r0
30 jnz 1b
313: slr %r2,%r2
32 br %r14
334: lhi %r0,-4096
34 lr %r5,%r4
35 slr %r5,%r0
36 nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
37 slr %r5,%r4 # %r5 = #bytes to next user page boundary
38 clr %r3,%r5 # copy crosses next page boundary ?
39 jnh 6f # no, the current page faulted
40 # move with the reduced length which is < 256
415: mvcp 0(%r5,%r2),0(%r4),%r0
42 slr %r3,%r5
436: lr %r2,%r3
44 br %r14
45 .section __ex_table,"a"
46 .long 0b,4b
47 .long 2b,4b
48 .long 5b,6b
49 .previous
50
51 .align 4
52 .text
53 .globl __copy_to_user_asm
54 # %r2 = from, %r3 = n, %r4 = to
55__copy_to_user_asm:
56 slr %r0,%r0
570: mvcs 0(%r3,%r4),0(%r2),%r0
58 jnz 1f
59 slr %r2,%r2
60 br %r14
611: la %r2,256(%r2)
62 la %r4,256(%r4)
63 ahi %r3,-256
642: mvcs 0(%r3,%r4),0(%r2),%r0
65 jnz 1b
663: slr %r2,%r2
67 br %r14
684: lhi %r0,-4096
69 lr %r5,%r4
70 slr %r5,%r0
71 nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
72 slr %r5,%r4 # %r5 = #bytes to next user page boundary
73 clr %r3,%r5 # copy crosses next page boundary ?
74 jnh 6f # no, the current page faulted
75 # move with the reduced length which is < 256
765: mvcs 0(%r5,%r4),0(%r2),%r0
77 slr %r3,%r5
786: lr %r2,%r3
79 br %r14
80 .section __ex_table,"a"
81 .long 0b,4b
82 .long 2b,4b
83 .long 5b,6b
84 .previous
85
86 .align 4
87 .text
88 .globl __copy_in_user_asm
89 # %r2 = from, %r3 = n, %r4 = to
90__copy_in_user_asm:
91 ahi %r3,-1
92 jo 6f
93 sacf 256
94 bras %r1,4f
950: ahi %r3,257
961: mvc 0(1,%r4),0(%r2)
97 la %r2,1(%r2)
98 la %r4,1(%r4)
99 ahi %r3,-1
100 jnz 1b
1012: lr %r2,%r3
102 br %r14
1033: mvc 0(256,%r4),0(%r2)
104 la %r2,256(%r2)
105 la %r4,256(%r4)
1064: ahi %r3,-256
107 jnm 3b
1085: ex %r3,4(%r1)
109 sacf 0
1106: slr %r2,%r2
111 br %r14
112 .section __ex_table,"a"
113 .long 1b,2b
114 .long 3b,0b
115 .long 5b,0b
116 .previous
117
118 .align 4
119 .text
120 .globl __clear_user_asm
121 # %r2 = to, %r3 = n
122__clear_user_asm:
123 bras %r5,0f
124 .long empty_zero_page
1250: l %r5,0(%r5)
126 slr %r0,%r0
1271: mvcs 0(%r3,%r2),0(%r5),%r0
128 jnz 2f
129 slr %r2,%r2
130 br %r14
1312: la %r2,256(%r2)
132 ahi %r3,-256
1333: mvcs 0(%r3,%r2),0(%r5),%r0
134 jnz 2b
1354: slr %r2,%r2
136 br %r14
1375: lhi %r0,-4096
138 lr %r4,%r2
139 slr %r4,%r0
140 nr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
141 slr %r4,%r2 # %r4 = #bytes to next user page boundary
142 clr %r3,%r4 # clear crosses next page boundary ?
143 jnh 7f # no, the current page faulted
144 # clear with the reduced length which is < 256
1456: mvcs 0(%r4,%r2),0(%r5),%r0
146 slr %r3,%r4
1477: lr %r2,%r3
148 br %r14
149 .section __ex_table,"a"
150 .long 1b,5b
151 .long 3b,5b
152 .long 6b,7b
153 .previous
154
155 .align 4
156 .text
157 .globl __strncpy_from_user_asm
158 # %r2 = count, %r3 = dst, %r4 = src
159__strncpy_from_user_asm:
160 lhi %r0,0
161 lr %r1,%r4
162 la %r4,0(%r4) # clear high order bit from %r4
163 la %r2,0(%r2,%r4) # %r2 points to first byte after string
164 sacf 256
1650: srst %r2,%r1
166 jo 0b
167 sacf 0
168 lr %r1,%r2
169 jh 1f # \0 found in string ?
170 ahi %r1,1 # include \0 in copy
1711: slr %r1,%r4 # %r1 = copy length (without \0)
172 slr %r2,%r4 # %r2 = return length (including \0)
1732: mvcp 0(%r1,%r3),0(%r4),%r0
174 jnz 3f
175 br %r14
1763: la %r3,256(%r3)
177 la %r4,256(%r4)
178 ahi %r1,-256
179 mvcp 0(%r1,%r3),0(%r4),%r0
180 jnz 3b
181 br %r14
1824: sacf 0
183 lhi %r2,-EFAULT
184 br %r14
185 .section __ex_table,"a"
186 .long 0b,4b
187 .previous
188
189 .align 4
190 .text
191 .globl __strnlen_user_asm
192 # %r2 = count, %r3 = src
193__strnlen_user_asm:
194 lhi %r0,0
195 lr %r1,%r3
196 la %r3,0(%r3) # clear high order bit from %r4
197 la %r2,0(%r2,%r3) # %r2 points to first byte after string
198 sacf 256
1990: srst %r2,%r1
200 jo 0b
201 sacf 0
202 ahi %r2,1 # strnlen_user result includes the \0
203 # or return count+1 if \0 not found
204 slr %r2,%r3
205 br %r14
2062: sacf 0
207 slr %r2,%r2 # return 0 on exception
208 br %r14
209 .section __ex_table,"a"
210 .long 0b,2b
211 .previous
diff --git a/arch/s390/lib/uaccess64.S b/arch/s390/lib/uaccess64.S
deleted file mode 100644
index 1f755be22f92..000000000000
--- a/arch/s390/lib/uaccess64.S
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * arch/s390x/lib/uaccess.S
3 * __copy_{from|to}_user functions.
4 *
5 * s390
6 * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8 *
9 * These functions have standard call interface
10 */
11
12#include <linux/errno.h>
13#include <asm/lowcore.h>
14#include <asm/asm-offsets.h>
15
16 .text
17 .align 4
18 .globl __copy_from_user_asm
19 # %r2 = to, %r3 = n, %r4 = from
20__copy_from_user_asm:
21 slgr %r0,%r0
220: mvcp 0(%r3,%r2),0(%r4),%r0
23 jnz 1f
24 slgr %r2,%r2
25 br %r14
261: la %r2,256(%r2)
27 la %r4,256(%r4)
28 aghi %r3,-256
292: mvcp 0(%r3,%r2),0(%r4),%r0
30 jnz 1b
313: slgr %r2,%r2
32 br %r14
334: lghi %r0,-4096
34 lgr %r5,%r4
35 slgr %r5,%r0
36 ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
37 slgr %r5,%r4 # %r5 = #bytes to next user page boundary
38 clgr %r3,%r5 # copy crosses next page boundary ?
39 jnh 6f # no, the current page faulted
40 # move with the reduced length which is < 256
415: mvcp 0(%r5,%r2),0(%r4),%r0
42 slgr %r3,%r5
436: lgr %r2,%r3
44 br %r14
45 .section __ex_table,"a"
46 .quad 0b,4b
47 .quad 2b,4b
48 .quad 5b,6b
49 .previous
50
51 .align 4
52 .text
53 .globl __copy_to_user_asm
54 # %r2 = from, %r3 = n, %r4 = to
55__copy_to_user_asm:
56 slgr %r0,%r0
570: mvcs 0(%r3,%r4),0(%r2),%r0
58 jnz 1f
59 slgr %r2,%r2
60 br %r14
611: la %r2,256(%r2)
62 la %r4,256(%r4)
63 aghi %r3,-256
642: mvcs 0(%r3,%r4),0(%r2),%r0
65 jnz 1b
663: slgr %r2,%r2
67 br %r14
684: lghi %r0,-4096
69 lgr %r5,%r4
70 slgr %r5,%r0
71 ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
72 slgr %r5,%r4 # %r5 = #bytes to next user page boundary
73 clgr %r3,%r5 # copy crosses next page boundary ?
74 jnh 6f # no, the current page faulted
75 # move with the reduced length which is < 256
765: mvcs 0(%r5,%r4),0(%r2),%r0
77 slgr %r3,%r5
786: lgr %r2,%r3
79 br %r14
80 .section __ex_table,"a"
81 .quad 0b,4b
82 .quad 2b,4b
83 .quad 5b,6b
84 .previous
85
86 .align 4
87 .text
88 .globl __copy_in_user_asm
89 # %r2 = from, %r3 = n, %r4 = to
90__copy_in_user_asm:
91 aghi %r3,-1
92 jo 6f
93 sacf 256
94 bras %r1,4f
950: aghi %r3,257
961: mvc 0(1,%r4),0(%r2)
97 la %r2,1(%r2)
98 la %r4,1(%r4)
99 aghi %r3,-1
100 jnz 1b
1012: lgr %r2,%r3
102 br %r14
1033: mvc 0(256,%r4),0(%r2)
104 la %r2,256(%r2)
105 la %r4,256(%r4)
1064: aghi %r3,-256
107 jnm 3b
1085: ex %r3,4(%r1)
109 sacf 0
1106: slgr %r2,%r2
111 br 14
112 .section __ex_table,"a"
113 .quad 1b,2b
114 .quad 3b,0b
115 .quad 5b,0b
116 .previous
117
118 .align 4
119 .text
120 .globl __clear_user_asm
121 # %r2 = to, %r3 = n
122__clear_user_asm:
123 slgr %r0,%r0
124 larl %r5,empty_zero_page
1251: mvcs 0(%r3,%r2),0(%r5),%r0
126 jnz 2f
127 slgr %r2,%r2
128 br %r14
1292: la %r2,256(%r2)
130 aghi %r3,-256
1313: mvcs 0(%r3,%r2),0(%r5),%r0
132 jnz 2b
1334: slgr %r2,%r2
134 br %r14
1355: lghi %r0,-4096
136 lgr %r4,%r2
137 slgr %r4,%r0
138 ngr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
139 slgr %r4,%r2 # %r4 = #bytes to next user page boundary
140 clgr %r3,%r4 # clear crosses next page boundary ?
141 jnh 7f # no, the current page faulted
142 # clear with the reduced length which is < 256
1436: mvcs 0(%r4,%r2),0(%r5),%r0
144 slgr %r3,%r4
1457: lgr %r2,%r3
146 br %r14
147 .section __ex_table,"a"
148 .quad 1b,5b
149 .quad 3b,5b
150 .quad 6b,7b
151 .previous
152
153 .align 4
154 .text
155 .globl __strncpy_from_user_asm
156 # %r2 = count, %r3 = dst, %r4 = src
157__strncpy_from_user_asm:
158 lghi %r0,0
159 lgr %r1,%r4
160 la %r2,0(%r2,%r4) # %r2 points to first byte after string
161 sacf 256
1620: srst %r2,%r1
163 jo 0b
164 sacf 0
165 lgr %r1,%r2
166 jh 1f # \0 found in string ?
167 aghi %r1,1 # include \0 in copy
1681: slgr %r1,%r4 # %r1 = copy length (without \0)
169 slgr %r2,%r4 # %r2 = return length (including \0)
1702: mvcp 0(%r1,%r3),0(%r4),%r0
171 jnz 3f
172 br %r14
1733: la %r3,256(%r3)
174 la %r4,256(%r4)
175 aghi %r1,-256
176 mvcp 0(%r1,%r3),0(%r4),%r0
177 jnz 3b
178 br %r14
1794: sacf 0
180 lghi %r2,-EFAULT
181 br %r14
182 .section __ex_table,"a"
183 .quad 0b,4b
184 .previous
185
186 .align 4
187 .text
188 .globl __strnlen_user_asm
189 # %r2 = count, %r3 = src
190__strnlen_user_asm:
191 lghi %r0,0
192 lgr %r1,%r3
193 la %r2,0(%r2,%r3) # %r2 points to first byte after string
194 sacf 256
1950: srst %r2,%r1
196 jo 0b
197 sacf 0
198 aghi %r2,1 # strnlen_user result includes the \0
199 # or return count+1 if \0 not found
200 slgr %r2,%r3
201 br %r14
2022: sacf 0
203 slgr %r2,%r2 # return 0 on exception
204 br %r14
205 .section __ex_table,"a"
206 .quad 0b,2b
207 .previous
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
new file mode 100644
index 000000000000..86c96d6c191a
--- /dev/null
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -0,0 +1,156 @@
1/*
2 * arch/s390/lib/uaccess_mvcos.c
3 *
4 * Optimized user space space access functions based on mvcos.
5 *
6 * Copyright (C) IBM Corp. 2006
7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8 * Gerald Schaefer (gerald.schaefer@de.ibm.com)
9 */
10
11#include <linux/errno.h>
12#include <linux/mm.h>
13#include <asm/uaccess.h>
14#include <asm/futex.h>
15
16#ifndef __s390x__
17#define AHI "ahi"
18#define ALR "alr"
19#define CLR "clr"
20#define LHI "lhi"
21#define SLR "slr"
22#else
23#define AHI "aghi"
24#define ALR "algr"
25#define CLR "clgr"
26#define LHI "lghi"
27#define SLR "slgr"
28#endif
29
30size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
31{
32 register unsigned long reg0 asm("0") = 0x81UL;
33 unsigned long tmp1, tmp2;
34
35 tmp1 = -4096UL;
36 asm volatile(
37 "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
38 " jz 4f\n"
39 "1:"ALR" %0,%3\n"
40 " "SLR" %1,%3\n"
41 " "SLR" %2,%3\n"
42 " j 0b\n"
43 "2: la %4,4095(%1)\n"/* %4 = ptr + 4095 */
44 " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */
45 " "SLR" %4,%1\n"
46 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
47 " jnh 5f\n"
48 "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n"
49 " "SLR" %0,%4\n"
50 " j 5f\n"
51 "4:"SLR" %0,%0\n"
52 "5: \n"
53 EX_TABLE(0b,2b) EX_TABLE(3b,5b)
54 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
55 : "d" (reg0) : "cc", "memory");
56 return size;
57}
58
59size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
60{
61 register unsigned long reg0 asm("0") = 0x810000UL;
62 unsigned long tmp1, tmp2;
63
64 tmp1 = -4096UL;
65 asm volatile(
66 "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
67 " jz 4f\n"
68 "1:"ALR" %0,%3\n"
69 " "SLR" %1,%3\n"
70 " "SLR" %2,%3\n"
71 " j 0b\n"
72 "2: la %4,4095(%1)\n"/* %4 = ptr + 4095 */
73 " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */
74 " "SLR" %4,%1\n"
75 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
76 " jnh 5f\n"
77 "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n"
78 " "SLR" %0,%4\n"
79 " j 5f\n"
80 "4:"SLR" %0,%0\n"
81 "5: \n"
82 EX_TABLE(0b,2b) EX_TABLE(3b,5b)
83 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
84 : "d" (reg0) : "cc", "memory");
85 return size;
86}
87
88size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from)
89{
90 register unsigned long reg0 asm("0") = 0x810081UL;
91 unsigned long tmp1, tmp2;
92
93 tmp1 = -4096UL;
94 /* FIXME: copy with reduced length. */
95 asm volatile(
96 "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
97 " jz 2f\n"
98 "1:"ALR" %0,%3\n"
99 " "SLR" %1,%3\n"
100 " "SLR" %2,%3\n"
101 " j 0b\n"
102 "2:"SLR" %0,%0\n"
103 "3: \n"
104 EX_TABLE(0b,3b)
105 : "+a" (size), "+a" (to), "+a" (from), "+a" (tmp1), "=a" (tmp2)
106 : "d" (reg0) : "cc", "memory");
107 return size;
108}
109
110size_t clear_user_mvcos(size_t size, void __user *to)
111{
112 register unsigned long reg0 asm("0") = 0x810000UL;
113 unsigned long tmp1, tmp2;
114
115 tmp1 = -4096UL;
116 asm volatile(
117 "0: .insn ss,0xc80000000000,0(%0,%1),0(%4),0\n"
118 " jz 4f\n"
119 "1:"ALR" %0,%2\n"
120 " "SLR" %1,%2\n"
121 " j 0b\n"
122 "2: la %3,4095(%1)\n"/* %4 = to + 4095 */
123 " nr %3,%2\n" /* %4 = (to + 4095) & -4096 */
124 " "SLR" %3,%1\n"
125 " "CLR" %0,%3\n" /* copy crosses next page boundary? */
126 " jnh 5f\n"
127 "3: .insn ss,0xc80000000000,0(%3,%1),0(%4),0\n"
128 " "SLR" %0,%3\n"
129 " j 5f\n"
130 "4:"SLR" %0,%0\n"
131 "5: \n"
132 EX_TABLE(0b,2b) EX_TABLE(3b,5b)
133 : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
134 : "a" (empty_zero_page), "d" (reg0) : "cc", "memory");
135 return size;
136}
137
138extern size_t copy_from_user_std_small(size_t, const void __user *, void *);
139extern size_t copy_to_user_std_small(size_t, void __user *, const void *);
140extern size_t strnlen_user_std(size_t, const char __user *);
141extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
142extern int futex_atomic_op(int, int __user *, int, int *);
143extern int futex_atomic_cmpxchg(int __user *, int, int);
144
145struct uaccess_ops uaccess_mvcos = {
146 .copy_from_user = copy_from_user_mvcos,
147 .copy_from_user_small = copy_from_user_std_small,
148 .copy_to_user = copy_to_user_mvcos,
149 .copy_to_user_small = copy_to_user_std_small,
150 .copy_in_user = copy_in_user_mvcos,
151 .clear_user = clear_user_mvcos,
152 .strnlen_user = strnlen_user_std,
153 .strncpy_from_user = strncpy_from_user_std,
154 .futex_atomic_op = futex_atomic_op,
155 .futex_atomic_cmpxchg = futex_atomic_cmpxchg,
156};
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
new file mode 100644
index 000000000000..9a4d4a29ea79
--- /dev/null
+++ b/arch/s390/lib/uaccess_std.c
@@ -0,0 +1,340 @@
1/*
2 * arch/s390/lib/uaccess_std.c
3 *
4 * Standard user space access functions based on mvcp/mvcs and doing
5 * interesting things in the secondary space mode.
6 *
7 * Copyright (C) IBM Corp. 2006
8 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
9 * Gerald Schaefer (gerald.schaefer@de.ibm.com)
10 */
11
12#include <linux/errno.h>
13#include <linux/mm.h>
14#include <asm/uaccess.h>
15#include <asm/futex.h>
16
17#ifndef __s390x__
18#define AHI "ahi"
19#define ALR "alr"
20#define CLR "clr"
21#define LHI "lhi"
22#define SLR "slr"
23#else
24#define AHI "aghi"
25#define ALR "algr"
26#define CLR "clgr"
27#define LHI "lghi"
28#define SLR "slgr"
29#endif
30
31size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
32{
33 unsigned long tmp1, tmp2;
34
35 tmp1 = -256UL;
36 asm volatile(
37 "0: mvcp 0(%0,%2),0(%1),%3\n"
38 " jz 5f\n"
39 "1:"ALR" %0,%3\n"
40 " la %1,256(%1)\n"
41 " la %2,256(%2)\n"
42 "2: mvcp 0(%0,%2),0(%1),%3\n"
43 " jnz 1b\n"
44 " j 5f\n"
45 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
46 " "LHI" %3,-4096\n"
47 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
48 " "SLR" %4,%1\n"
49 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
50 " jnh 6f\n"
51 "4: mvcp 0(%4,%2),0(%1),%3\n"
52 " "SLR" %0,%4\n"
53 " j 6f\n"
54 "5:"SLR" %0,%0\n"
55 "6: \n"
56 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
57 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
58 : : "cc", "memory");
59 return size;
60}
61
62size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x)
63{
64 unsigned long tmp1, tmp2;
65
66 tmp1 = 0UL;
67 asm volatile(
68 "0: mvcp 0(%0,%2),0(%1),%3\n"
69 " "SLR" %0,%0\n"
70 " j 3f\n"
71 "1: la %4,255(%1)\n" /* %4 = ptr + 255 */
72 " "LHI" %3,-4096\n"
73 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
74 " "SLR" %4,%1\n"
75 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
76 " jnh 3f\n"
77 "2: mvcp 0(%4,%2),0(%1),%3\n"
78 " "SLR" %0,%4\n"
79 "3:\n"
80 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
81 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
82 : : "cc", "memory");
83 return size;
84}
85
86size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
87{
88 unsigned long tmp1, tmp2;
89
90 tmp1 = -256UL;
91 asm volatile(
92 "0: mvcs 0(%0,%1),0(%2),%3\n"
93 " jz 5f\n"
94 "1:"ALR" %0,%3\n"
95 " la %1,256(%1)\n"
96 " la %2,256(%2)\n"
97 "2: mvcs 0(%0,%1),0(%2),%3\n"
98 " jnz 1b\n"
99 " j 5f\n"
100 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
101 " "LHI" %3,-4096\n"
102 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
103 " "SLR" %4,%1\n"
104 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
105 " jnh 6f\n"
106 "4: mvcs 0(%4,%1),0(%2),%3\n"
107 " "SLR" %0,%4\n"
108 " j 6f\n"
109 "5:"SLR" %0,%0\n"
110 "6: \n"
111 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
112 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
113 : : "cc", "memory");
114 return size;
115}
116
117size_t copy_to_user_std_small(size_t size, void __user *ptr, const void *x)
118{
119 unsigned long tmp1, tmp2;
120
121 tmp1 = 0UL;
122 asm volatile(
123 "0: mvcs 0(%0,%1),0(%2),%3\n"
124 " "SLR" %0,%0\n"
125 " j 3f\n"
126 "1: la %4,255(%1)\n" /* ptr + 255 */
127 " "LHI" %3,-4096\n"
128 " nr %4,%3\n" /* (ptr + 255) & -4096UL */
129 " "SLR" %4,%1\n"
130 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
131 " jnh 3f\n"
132 "2: mvcs 0(%4,%1),0(%2),%3\n"
133 " "SLR" %0,%4\n"
134 "3:\n"
135 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
136 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
137 : : "cc", "memory");
138 return size;
139}
140
141size_t copy_in_user_std(size_t size, void __user *to, const void __user *from)
142{
143 unsigned long tmp1;
144
145 asm volatile(
146 " "AHI" %0,-1\n"
147 " jo 5f\n"
148 " sacf 256\n"
149 " bras %3,3f\n"
150 "0:"AHI" %0,257\n"
151 "1: mvc 0(1,%1),0(%2)\n"
152 " la %1,1(%1)\n"
153 " la %2,1(%2)\n"
154 " "AHI" %0,-1\n"
155 " jnz 1b\n"
156 " j 5f\n"
157 "2: mvc 0(256,%1),0(%2)\n"
158 " la %1,256(%1)\n"
159 " la %2,256(%2)\n"
160 "3:"AHI" %0,-256\n"
161 " jnm 2b\n"
162 "4: ex %0,1b-0b(%3)\n"
163 " sacf 0\n"
164 "5: "SLR" %0,%0\n"
165 "6:\n"
166 EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
167 : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
168 : : "cc", "memory");
169 return size;
170}
171
172size_t clear_user_std(size_t size, void __user *to)
173{
174 unsigned long tmp1, tmp2;
175
176 asm volatile(
177 " "AHI" %0,-1\n"
178 " jo 5f\n"
179 " sacf 256\n"
180 " bras %3,3f\n"
181 " xc 0(1,%1),0(%1)\n"
182 "0:"AHI" %0,257\n"
183 " la %2,255(%1)\n" /* %2 = ptr + 255 */
184 " srl %2,12\n"
185 " sll %2,12\n" /* %2 = (ptr + 255) & -4096 */
186 " "SLR" %2,%1\n"
187 " "CLR" %0,%2\n" /* clear crosses next page boundary? */
188 " jnh 5f\n"
189 " "AHI" %2,-1\n"
190 "1: ex %2,0(%3)\n"
191 " "AHI" %2,1\n"
192 " "SLR" %0,%2\n"
193 " j 5f\n"
194 "2: xc 0(256,%1),0(%1)\n"
195 " la %1,256(%1)\n"
196 "3:"AHI" %0,-256\n"
197 " jnm 2b\n"
198 "4: ex %0,0(%3)\n"
199 " sacf 0\n"
200 "5: "SLR" %0,%0\n"
201 "6:\n"
202 EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
203 : "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2)
204 : : "cc", "memory");
205 return size;
206}
207
208size_t strnlen_user_std(size_t size, const char __user *src)
209{
210 register unsigned long reg0 asm("0") = 0UL;
211 unsigned long tmp1, tmp2;
212
213 asm volatile(
214 " la %2,0(%1)\n"
215 " la %3,0(%0,%1)\n"
216 " "SLR" %0,%0\n"
217 " sacf 256\n"
218 "0: srst %3,%2\n"
219 " jo 0b\n"
220 " la %0,1(%3)\n" /* strnlen_user results includes \0 */
221 " "SLR" %0,%1\n"
222 "1: sacf 0\n"
223 EX_TABLE(0b,1b)
224 : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
225 : "d" (reg0) : "cc", "memory");
226 return size;
227}
228
229size_t strncpy_from_user_std(size_t size, const char __user *src, char *dst)
230{
231 register unsigned long reg0 asm("0") = 0UL;
232 unsigned long tmp1, tmp2;
233
234 asm volatile(
235 " la %3,0(%1)\n"
236 " la %4,0(%0,%1)\n"
237 " sacf 256\n"
238 "0: srst %4,%3\n"
239 " jo 0b\n"
240 " sacf 0\n"
241 " la %0,0(%4)\n"
242 " jh 1f\n" /* found \0 in string ? */
243 " "AHI" %4,1\n" /* include \0 in copy */
244 "1:"SLR" %0,%1\n" /* %0 = return length (without \0) */
245 " "SLR" %4,%1\n" /* %4 = copy length (including \0) */
246 "2: mvcp 0(%4,%2),0(%1),%5\n"
247 " jz 9f\n"
248 "3:"AHI" %4,-256\n"
249 " la %1,256(%1)\n"
250 " la %2,256(%2)\n"
251 "4: mvcp 0(%4,%2),0(%1),%5\n"
252 " jnz 3b\n"
253 " j 9f\n"
254 "7: sacf 0\n"
255 "8:"LHI" %0,%6\n"
256 "9:\n"
257 EX_TABLE(0b,7b) EX_TABLE(2b,8b) EX_TABLE(4b,8b)
258 : "+a" (size), "+a" (src), "+d" (dst), "=a" (tmp1), "=a" (tmp2)
259 : "d" (reg0), "K" (-EFAULT) : "cc", "memory");
260 return size;
261}
262
263#define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \
264 asm volatile( \
265 " sacf 256\n" \
266 "0: l %1,0(%6)\n" \
267 "1:"insn \
268 "2: cs %1,%2,0(%6)\n" \
269 "3: jl 1b\n" \
270 " lhi %0,0\n" \
271 "4: sacf 0\n" \
272 EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \
273 : "=d" (ret), "=&d" (oldval), "=&d" (newval), \
274 "=m" (*uaddr) \
275 : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \
276 "m" (*uaddr) : "cc");
277
278int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old)
279{
280 int oldval = 0, newval, ret;
281
282 inc_preempt_count();
283
284 switch (op) {
285 case FUTEX_OP_SET:
286 __futex_atomic_op("lr %2,%5\n",
287 ret, oldval, newval, uaddr, oparg);
288 break;
289 case FUTEX_OP_ADD:
290 __futex_atomic_op("lr %2,%1\nar %2,%5\n",
291 ret, oldval, newval, uaddr, oparg);
292 break;
293 case FUTEX_OP_OR:
294 __futex_atomic_op("lr %2,%1\nor %2,%5\n",
295 ret, oldval, newval, uaddr, oparg);
296 break;
297 case FUTEX_OP_ANDN:
298 __futex_atomic_op("lr %2,%1\nnr %2,%5\n",
299 ret, oldval, newval, uaddr, oparg);
300 break;
301 case FUTEX_OP_XOR:
302 __futex_atomic_op("lr %2,%1\nxr %2,%5\n",
303 ret, oldval, newval, uaddr, oparg);
304 break;
305 default:
306 ret = -ENOSYS;
307 }
308 dec_preempt_count();
309 *old = oldval;
310 return ret;
311}
312
313int futex_atomic_cmpxchg(int __user *uaddr, int oldval, int newval)
314{
315 int ret;
316
317 asm volatile(
318 " sacf 256\n"
319 " cs %1,%4,0(%5)\n"
320 "0: lr %0,%1\n"
321 "1: sacf 0\n"
322 EX_TABLE(0b,1b)
323 : "=d" (ret), "+d" (oldval), "=m" (*uaddr)
324 : "0" (-EFAULT), "d" (newval), "a" (uaddr), "m" (*uaddr)
325 : "cc", "memory" );
326 return ret;
327}
328
329struct uaccess_ops uaccess_std = {
330 .copy_from_user = copy_from_user_std,
331 .copy_from_user_small = copy_from_user_std_small,
332 .copy_to_user = copy_to_user_std,
333 .copy_to_user_small = copy_to_user_std_small,
334 .copy_in_user = copy_in_user_std,
335 .clear_user = clear_user_std,
336 .strnlen_user = strnlen_user_std,
337 .strncpy_from_user = strncpy_from_user_std,
338 .futex_atomic_op = futex_atomic_op,
339 .futex_atomic_cmpxchg = futex_atomic_cmpxchg,
340};
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index ceea51cff03b..786a44dba5bf 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -53,22 +53,6 @@ static void cmm_timer_fn(unsigned long);
53static void cmm_set_timer(void); 53static void cmm_set_timer(void);
54 54
55static long 55static long
56cmm_strtoul(const char *cp, char **endp)
57{
58 unsigned int base = 10;
59
60 if (*cp == '0') {
61 base = 8;
62 cp++;
63 if ((*cp == 'x' || *cp == 'X') && isxdigit(cp[1])) {
64 base = 16;
65 cp++;
66 }
67 }
68 return simple_strtoul(cp, endp, base);
69}
70
71static long
72cmm_alloc_pages(long pages, long *counter, struct cmm_page_array **list) 56cmm_alloc_pages(long pages, long *counter, struct cmm_page_array **list)
73{ 57{
74 struct cmm_page_array *pa; 58 struct cmm_page_array *pa;
@@ -276,7 +260,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
276 return -EFAULT; 260 return -EFAULT;
277 buf[sizeof(buf) - 1] = '\0'; 261 buf[sizeof(buf) - 1] = '\0';
278 cmm_skip_blanks(buf, &p); 262 cmm_skip_blanks(buf, &p);
279 pages = cmm_strtoul(p, &p); 263 pages = simple_strtoul(p, &p, 0);
280 if (ctl == &cmm_table[0]) 264 if (ctl == &cmm_table[0])
281 cmm_set_pages(pages); 265 cmm_set_pages(pages);
282 else 266 else
@@ -317,9 +301,9 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
317 return -EFAULT; 301 return -EFAULT;
318 buf[sizeof(buf) - 1] = '\0'; 302 buf[sizeof(buf) - 1] = '\0';
319 cmm_skip_blanks(buf, &p); 303 cmm_skip_blanks(buf, &p);
320 pages = cmm_strtoul(p, &p); 304 pages = simple_strtoul(p, &p, 0);
321 cmm_skip_blanks(p, &p); 305 cmm_skip_blanks(p, &p);
322 seconds = cmm_strtoul(p, &p); 306 seconds = simple_strtoul(p, &p, 0);
323 cmm_set_timeout(pages, seconds); 307 cmm_set_timeout(pages, seconds);
324 } else { 308 } else {
325 len = sprintf(buf, "%ld %ld\n", 309 len = sprintf(buf, "%ld %ld\n",
@@ -382,24 +366,24 @@ cmm_smsg_target(char *from, char *msg)
382 if (strncmp(msg, "SHRINK", 6) == 0) { 366 if (strncmp(msg, "SHRINK", 6) == 0) {
383 if (!cmm_skip_blanks(msg + 6, &msg)) 367 if (!cmm_skip_blanks(msg + 6, &msg))
384 return; 368 return;
385 pages = cmm_strtoul(msg, &msg); 369 pages = simple_strtoul(msg, &msg, 0);
386 cmm_skip_blanks(msg, &msg); 370 cmm_skip_blanks(msg, &msg);
387 if (*msg == '\0') 371 if (*msg == '\0')
388 cmm_set_pages(pages); 372 cmm_set_pages(pages);
389 } else if (strncmp(msg, "RELEASE", 7) == 0) { 373 } else if (strncmp(msg, "RELEASE", 7) == 0) {
390 if (!cmm_skip_blanks(msg + 7, &msg)) 374 if (!cmm_skip_blanks(msg + 7, &msg))
391 return; 375 return;
392 pages = cmm_strtoul(msg, &msg); 376 pages = simple_strtoul(msg, &msg, 0);
393 cmm_skip_blanks(msg, &msg); 377 cmm_skip_blanks(msg, &msg);
394 if (*msg == '\0') 378 if (*msg == '\0')
395 cmm_add_timed_pages(pages); 379 cmm_add_timed_pages(pages);
396 } else if (strncmp(msg, "REUSE", 5) == 0) { 380 } else if (strncmp(msg, "REUSE", 5) == 0) {
397 if (!cmm_skip_blanks(msg + 5, &msg)) 381 if (!cmm_skip_blanks(msg + 5, &msg))
398 return; 382 return;
399 pages = cmm_strtoul(msg, &msg); 383 pages = simple_strtoul(msg, &msg, 0);
400 if (!cmm_skip_blanks(msg, &msg)) 384 if (!cmm_skip_blanks(msg, &msg))
401 return; 385 return;
402 seconds = cmm_strtoul(msg, &msg); 386 seconds = simple_strtoul(msg, &msg, 0);
403 cmm_skip_blanks(msg, &msg); 387 cmm_skip_blanks(msg, &msg);
404 if (*msg == '\0') 388 if (*msg == '\0')
405 cmm_set_timeout(pages, seconds); 389 cmm_set_timeout(pages, seconds);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 7cd82575813d..44f0cda7e72e 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -25,10 +25,12 @@
25#include <linux/console.h> 25#include <linux/console.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/hardirq.h> 27#include <linux/hardirq.h>
28#include <linux/kprobes.h>
28 29
29#include <asm/system.h> 30#include <asm/system.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/pgtable.h> 32#include <asm/pgtable.h>
33#include <asm/kdebug.h>
32 34
33#ifndef CONFIG_64BIT 35#ifndef CONFIG_64BIT
34#define __FAIL_ADDR_MASK 0x7ffff000 36#define __FAIL_ADDR_MASK 0x7ffff000
@@ -48,6 +50,38 @@ extern int sysctl_userprocess_debug;
48 50
49extern void die(const char *,struct pt_regs *,long); 51extern void die(const char *,struct pt_regs *,long);
50 52
53#ifdef CONFIG_KPROBES
54ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
55int register_page_fault_notifier(struct notifier_block *nb)
56{
57 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
58}
59
60int unregister_page_fault_notifier(struct notifier_block *nb)
61{
62 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
63}
64
65static inline int notify_page_fault(enum die_val val, const char *str,
66 struct pt_regs *regs, long err, int trap, int sig)
67{
68 struct die_args args = {
69 .regs = regs,
70 .str = str,
71 .err = err,
72 .trapnr = trap,
73 .signr = sig
74 };
75 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
76}
77#else
78static inline int notify_page_fault(enum die_val val, const char *str,
79 struct pt_regs *regs, long err, int trap, int sig)
80{
81 return NOTIFY_DONE;
82}
83#endif
84
51extern spinlock_t timerlist_lock; 85extern spinlock_t timerlist_lock;
52 86
53/* 87/*
@@ -159,7 +193,7 @@ static void do_sigsegv(struct pt_regs *regs, unsigned long error_code,
159 * 11 Page translation -> Not present (nullification) 193 * 11 Page translation -> Not present (nullification)
160 * 3b Region third trans. -> Not present (nullification) 194 * 3b Region third trans. -> Not present (nullification)
161 */ 195 */
162static inline void 196static inline void __kprobes
163do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) 197do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
164{ 198{
165 struct task_struct *tsk; 199 struct task_struct *tsk;
@@ -173,6 +207,10 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection)
173 tsk = current; 207 tsk = current;
174 mm = tsk->mm; 208 mm = tsk->mm;
175 209
210 if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
211 SIGSEGV) == NOTIFY_STOP)
212 return;
213
176 /* 214 /*
177 * Check for low-address protection. This needs to be treated 215 * Check for low-address protection. This needs to be treated
178 * as a special case because the translation exception code 216 * as a special case because the translation exception code
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 6e6b6de77770..cfd9b8f7a523 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -108,16 +108,23 @@ void __init paging_init(void)
108 unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; 108 unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
109 static const int ssm_mask = 0x04000000L; 109 static const int ssm_mask = 0x04000000L;
110 unsigned long ro_start_pfn, ro_end_pfn; 110 unsigned long ro_start_pfn, ro_end_pfn;
111 unsigned long zones_size[MAX_NR_ZONES];
111 112
112 ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); 113 ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata);
113 ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); 114 ro_end_pfn = PFN_UP((unsigned long)&__end_rodata);
114 115
116 memset(zones_size, 0, sizeof(zones_size));
117 zones_size[ZONE_DMA] = max_low_pfn;
118 free_area_init_node(0, &contig_page_data, zones_size,
119 __pa(PAGE_OFFSET) >> PAGE_SHIFT,
120 zholes_size);
121
115 /* unmap whole virtual address space */ 122 /* unmap whole virtual address space */
116 123
117 pg_dir = swapper_pg_dir; 124 pg_dir = swapper_pg_dir;
118 125
119 for (i=0;i<KERNEL_PGD_PTRS;i++) 126 for (i = 0; i < PTRS_PER_PGD; i++)
120 pmd_clear((pmd_t*)pg_dir++); 127 pmd_clear((pmd_t *) pg_dir++);
121 128
122 /* 129 /*
123 * map whole physical memory to virtual memory (identity mapping) 130 * map whole physical memory to virtual memory (identity mapping)
@@ -131,10 +138,7 @@ void __init paging_init(void)
131 */ 138 */
132 pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); 139 pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
133 140
134 pg_dir->pgd0 = (_PAGE_TABLE | __pa(pg_table)); 141 pmd_populate_kernel(&init_mm, (pmd_t *) pg_dir, pg_table);
135 pg_dir->pgd1 = (_PAGE_TABLE | (__pa(pg_table)+1024));
136 pg_dir->pgd2 = (_PAGE_TABLE | (__pa(pg_table)+2048));
137 pg_dir->pgd3 = (_PAGE_TABLE | (__pa(pg_table)+3072));
138 pg_dir++; 142 pg_dir++;
139 143
140 for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { 144 for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
@@ -143,8 +147,8 @@ void __init paging_init(void)
143 else 147 else
144 pte = pfn_pte(pfn, PAGE_KERNEL); 148 pte = pfn_pte(pfn, PAGE_KERNEL);
145 if (pfn >= max_low_pfn) 149 if (pfn >= max_low_pfn)
146 pte_clear(&init_mm, 0, &pte); 150 pte_val(pte) = _PAGE_TYPE_EMPTY;
147 set_pte(pg_table, pte); 151 set_pte(pg_table, pte);
148 pfn++; 152 pfn++;
149 } 153 }
150 } 154 }
@@ -159,16 +163,6 @@ void __init paging_init(void)
159 : : "m" (pgdir_k), "m" (ssm_mask)); 163 : : "m" (pgdir_k), "m" (ssm_mask));
160 164
161 local_flush_tlb(); 165 local_flush_tlb();
162
163 {
164 unsigned long zones_size[MAX_NR_ZONES];
165
166 memset(zones_size, 0, sizeof(zones_size));
167 zones_size[ZONE_DMA] = max_low_pfn;
168 free_area_init_node(0, &contig_page_data, zones_size,
169 __pa(PAGE_OFFSET) >> PAGE_SHIFT,
170 zholes_size);
171 }
172 return; 166 return;
173} 167}
174 168
@@ -236,10 +230,8 @@ void __init paging_init(void)
236 pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); 230 pte = pfn_pte(pfn, __pgprot(_PAGE_RO));
237 else 231 else
238 pte = pfn_pte(pfn, PAGE_KERNEL); 232 pte = pfn_pte(pfn, PAGE_KERNEL);
239 if (pfn >= max_low_pfn) { 233 if (pfn >= max_low_pfn)
240 pte_clear(&init_mm, 0, &pte); 234 pte_val(pte) = _PAGE_TYPE_EMPTY;
241 continue;
242 }
243 set_pte(pt_dir, pte); 235 set_pte(pt_dir, pte);
244 pfn++; 236 pfn++;
245 } 237 }
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 22dc9c21201d..f2031314cb2b 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -26,6 +26,7 @@
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/mmu_context.h> 27#include <asm/mmu_context.h>
28#include <asm/elf.h> 28#include <asm/elf.h>
29#include <asm/ubc.h>
29 30
30static int hlt_counter=0; 31static int hlt_counter=0;
31 32
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index 81c0cbd96ff0..75ac24d229b1 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -277,7 +277,7 @@ void __init ebus_init(void)
277 struct pci_dev *pdev; 277 struct pci_dev *pdev;
278 struct pcidev_cookie *cookie; 278 struct pcidev_cookie *cookie;
279 struct device_node *dp; 279 struct device_node *dp;
280 unsigned long addr, *base; 280 struct resource *p;
281 unsigned short pci_command; 281 unsigned short pci_command;
282 int len, reg, nreg; 282 int len, reg, nreg;
283 int num_ebus = 0; 283 int num_ebus = 0;
@@ -321,13 +321,12 @@ void __init ebus_init(void)
321 } 321 }
322 nreg = len / sizeof(struct linux_prom_pci_registers); 322 nreg = len / sizeof(struct linux_prom_pci_registers);
323 323
324 base = &ebus->self->resource[0].start; 324 p = &ebus->self->resource[0];
325 for (reg = 0; reg < nreg; reg++) { 325 for (reg = 0; reg < nreg; reg++) {
326 if (!(regs[reg].which_io & 0x03000000)) 326 if (!(regs[reg].which_io & 0x03000000))
327 continue; 327 continue;
328 328
329 addr = regs[reg].phys_lo; 329 (p++)->start = regs[reg].phys_lo;
330 *base++ = addr;
331 } 330 }
332 331
333 ebus->ofdev.node = dp; 332 ebus->ofdev.node = dp;
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 8654b446ac9e..d33f8a07ccac 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -508,6 +508,7 @@ void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *s
508 508
509void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) 509void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
510{ 510{
511#ifndef CONFIG_SUN4
511 struct device_node *parent = dp->parent; 512 struct device_node *parent = dp->parent;
512 513
513 if (sparc_cpu_model != sun4d && 514 if (sparc_cpu_model != sun4d &&
@@ -524,6 +525,7 @@ void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
524 525
525 iounit_init(dp->node, parent->node, sbus); 526 iounit_init(dp->node, parent->node, sbus);
526 } 527 }
528#endif
527} 529}
528 530
529void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) 531void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 43d9229fca07..51cf6027b701 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18-rc2 3# Linux kernel version: 2.6.18
4# Fri Jul 21 14:19:24 2006 4# Sat Sep 23 18:32:19 2006
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -9,6 +9,7 @@ CONFIG_64BIT=y
9CONFIG_MMU=y 9CONFIG_MMU=y
10CONFIG_TIME_INTERPOLATION=y 10CONFIG_TIME_INTERPOLATION=y
11CONFIG_ARCH_MAY_HAVE_PC_FDC=y 11CONFIG_ARCH_MAY_HAVE_PC_FDC=y
12CONFIG_AUDIT_ARCH=y
12CONFIG_SPARC64_PAGE_SIZE_8KB=y 13CONFIG_SPARC64_PAGE_SIZE_8KB=y
13# CONFIG_SPARC64_PAGE_SIZE_64KB is not set 14# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
14# CONFIG_SPARC64_PAGE_SIZE_512KB is not set 15# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
@@ -37,14 +38,14 @@ CONFIG_SYSVIPC=y
37CONFIG_POSIX_MQUEUE=y 38CONFIG_POSIX_MQUEUE=y
38# CONFIG_BSD_PROCESS_ACCT is not set 39# CONFIG_BSD_PROCESS_ACCT is not set
39# CONFIG_TASKSTATS is not set 40# CONFIG_TASKSTATS is not set
40CONFIG_SYSCTL=y
41# CONFIG_AUDIT is not set 41# CONFIG_AUDIT is not set
42# CONFIG_IKCONFIG is not set 42# CONFIG_IKCONFIG is not set
43CONFIG_RELAY=y 43CONFIG_RELAY=y
44CONFIG_INITRAMFS_SOURCE="" 44CONFIG_INITRAMFS_SOURCE=""
45CONFIG_UID16=y
46CONFIG_CC_OPTIMIZE_FOR_SIZE=y 45CONFIG_CC_OPTIMIZE_FOR_SIZE=y
47# CONFIG_EMBEDDED is not set 46# CONFIG_EMBEDDED is not set
47CONFIG_UID16=y
48CONFIG_SYSCTL=y
48CONFIG_KALLSYMS=y 49CONFIG_KALLSYMS=y
49# CONFIG_KALLSYMS_ALL is not set 50# CONFIG_KALLSYMS_ALL is not set
50# CONFIG_KALLSYMS_EXTRA_PASS is not set 51# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -53,12 +54,12 @@ CONFIG_PRINTK=y
53CONFIG_BUG=y 54CONFIG_BUG=y
54CONFIG_ELF_CORE=y 55CONFIG_ELF_CORE=y
55CONFIG_BASE_FULL=y 56CONFIG_BASE_FULL=y
56CONFIG_RT_MUTEXES=y
57CONFIG_FUTEX=y 57CONFIG_FUTEX=y
58CONFIG_EPOLL=y 58CONFIG_EPOLL=y
59CONFIG_SHMEM=y 59CONFIG_SHMEM=y
60CONFIG_SLAB=y 60CONFIG_SLAB=y
61CONFIG_VM_EVENT_COUNTERS=y 61CONFIG_VM_EVENT_COUNTERS=y
62CONFIG_RT_MUTEXES=y
62# CONFIG_TINY_SHMEM is not set 63# CONFIG_TINY_SHMEM is not set
63CONFIG_BASE_SMALL=0 64CONFIG_BASE_SMALL=0
64# CONFIG_SLOB is not set 65# CONFIG_SLOB is not set
@@ -169,6 +170,7 @@ CONFIG_PACKET_MMAP=y
169CONFIG_UNIX=y 170CONFIG_UNIX=y
170CONFIG_XFRM=y 171CONFIG_XFRM=y
171CONFIG_XFRM_USER=m 172CONFIG_XFRM_USER=m
173# CONFIG_XFRM_SUB_POLICY is not set
172CONFIG_NET_KEY=m 174CONFIG_NET_KEY=m
173CONFIG_INET=y 175CONFIG_INET=y
174CONFIG_IP_MULTICAST=y 176CONFIG_IP_MULTICAST=y
@@ -214,11 +216,15 @@ CONFIG_IPV6_ROUTE_INFO=y
214CONFIG_INET6_AH=m 216CONFIG_INET6_AH=m
215CONFIG_INET6_ESP=m 217CONFIG_INET6_ESP=m
216CONFIG_INET6_IPCOMP=m 218CONFIG_INET6_IPCOMP=m
219# CONFIG_IPV6_MIP6 is not set
217CONFIG_INET6_XFRM_TUNNEL=m 220CONFIG_INET6_XFRM_TUNNEL=m
218CONFIG_INET6_TUNNEL=m 221CONFIG_INET6_TUNNEL=m
219CONFIG_INET6_XFRM_MODE_TRANSPORT=m 222CONFIG_INET6_XFRM_MODE_TRANSPORT=m
220CONFIG_INET6_XFRM_MODE_TUNNEL=m 223CONFIG_INET6_XFRM_MODE_TUNNEL=m
224# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
221CONFIG_IPV6_TUNNEL=m 225CONFIG_IPV6_TUNNEL=m
226# CONFIG_IPV6_SUBTREES is not set
227# CONFIG_IPV6_MULTIPLE_TABLES is not set
222# CONFIG_NETWORK_SECMARK is not set 228# CONFIG_NETWORK_SECMARK is not set
223# CONFIG_NETFILTER is not set 229# CONFIG_NETFILTER is not set
224 230
@@ -233,6 +239,7 @@ CONFIG_IP_DCCP_ACKVEC=y
233# DCCP CCIDs Configuration (EXPERIMENTAL) 239# DCCP CCIDs Configuration (EXPERIMENTAL)
234# 240#
235CONFIG_IP_DCCP_CCID2=m 241CONFIG_IP_DCCP_CCID2=m
242# CONFIG_IP_DCCP_CCID2_DEBUG is not set
236CONFIG_IP_DCCP_CCID3=m 243CONFIG_IP_DCCP_CCID3=m
237CONFIG_IP_DCCP_TFRC_LIB=m 244CONFIG_IP_DCCP_TFRC_LIB=m
238 245
@@ -259,7 +266,6 @@ CONFIG_VLAN_8021Q=m
259# CONFIG_ATALK is not set 266# CONFIG_ATALK is not set
260# CONFIG_X25 is not set 267# CONFIG_X25 is not set
261# CONFIG_LAPB is not set 268# CONFIG_LAPB is not set
262# CONFIG_NET_DIVERT is not set
263# CONFIG_ECONET is not set 269# CONFIG_ECONET is not set
264# CONFIG_WAN_ROUTER is not set 270# CONFIG_WAN_ROUTER is not set
265 271
@@ -1386,6 +1392,10 @@ CONFIG_KEYS=y
1386# Cryptographic options 1392# Cryptographic options
1387# 1393#
1388CONFIG_CRYPTO=y 1394CONFIG_CRYPTO=y
1395CONFIG_CRYPTO_ALGAPI=y
1396CONFIG_CRYPTO_BLKCIPHER=y
1397CONFIG_CRYPTO_HASH=y
1398CONFIG_CRYPTO_MANAGER=m
1389CONFIG_CRYPTO_HMAC=y 1399CONFIG_CRYPTO_HMAC=y
1390CONFIG_CRYPTO_NULL=m 1400CONFIG_CRYPTO_NULL=m
1391CONFIG_CRYPTO_MD4=y 1401CONFIG_CRYPTO_MD4=y
@@ -1395,9 +1405,12 @@ CONFIG_CRYPTO_SHA256=m
1395CONFIG_CRYPTO_SHA512=m 1405CONFIG_CRYPTO_SHA512=m
1396CONFIG_CRYPTO_WP512=m 1406CONFIG_CRYPTO_WP512=m
1397CONFIG_CRYPTO_TGR192=m 1407CONFIG_CRYPTO_TGR192=m
1408CONFIG_CRYPTO_ECB=m
1409CONFIG_CRYPTO_CBC=y
1398CONFIG_CRYPTO_DES=y 1410CONFIG_CRYPTO_DES=y
1399CONFIG_CRYPTO_BLOWFISH=m 1411CONFIG_CRYPTO_BLOWFISH=m
1400CONFIG_CRYPTO_TWOFISH=m 1412CONFIG_CRYPTO_TWOFISH=m
1413CONFIG_CRYPTO_TWOFISH_COMMON=m
1401CONFIG_CRYPTO_SERPENT=m 1414CONFIG_CRYPTO_SERPENT=m
1402CONFIG_CRYPTO_AES=m 1415CONFIG_CRYPTO_AES=m
1403CONFIG_CRYPTO_CAST5=m 1416CONFIG_CRYPTO_CAST5=m
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 094d3e35be18..b0b4feeec098 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -983,7 +983,7 @@ static struct time_interpolator sparc64_cpu_interpolator = {
983}; 983};
984 984
985/* The quotient formula is taken from the IA64 port. */ 985/* The quotient formula is taken from the IA64 port. */
986#define SPARC64_NSEC_PER_CYC_SHIFT 30UL 986#define SPARC64_NSEC_PER_CYC_SHIFT 10UL
987void __init time_init(void) 987void __init time_init(void)
988{ 988{
989 unsigned long clock = sparc64_init_timers(); 989 unsigned long clock = sparc64_init_timers();
diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile
index 426d20f4b72e..15b538a8b7f7 100644
--- a/arch/x86_64/crypto/Makefile
+++ b/arch/x86_64/crypto/Makefile
@@ -5,5 +5,8 @@
5# 5#
6 6
7obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o 7obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
8obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
8 9
9aes-x86_64-y := aes-x86_64-asm.o aes.o 10aes-x86_64-y := aes-x86_64-asm.o aes.o
11twofish-x86_64-y := twofish-x86_64-asm.o twofish.o
12
diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c
index 68866fab37aa..5cdb13ea5cc2 100644
--- a/arch/x86_64/crypto/aes.c
+++ b/arch/x86_64/crypto/aes.c
@@ -228,13 +228,14 @@ static void __init gen_tabs(void)
228} 228}
229 229
230static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, 230static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
231 unsigned int key_len, u32 *flags) 231 unsigned int key_len)
232{ 232{
233 struct aes_ctx *ctx = crypto_tfm_ctx(tfm); 233 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
234 const __le32 *key = (const __le32 *)in_key; 234 const __le32 *key = (const __le32 *)in_key;
235 u32 *flags = &tfm->crt_flags;
235 u32 i, j, t, u, v, w; 236 u32 i, j, t, u, v, w;
236 237
237 if (key_len != 16 && key_len != 24 && key_len != 32) { 238 if (key_len % 8) {
238 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 239 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
239 return -EINVAL; 240 return -EINVAL;
240 } 241 }
diff --git a/arch/x86_64/crypto/twofish-x86_64-asm.S b/arch/x86_64/crypto/twofish-x86_64-asm.S
new file mode 100644
index 000000000000..35974a586615
--- /dev/null
+++ b/arch/x86_64/crypto/twofish-x86_64-asm.S
@@ -0,0 +1,324 @@
1/***************************************************************************
2* Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
3* *
4* This program is free software; you can redistribute it and/or modify *
5* it under the terms of the GNU General Public License as published by *
6* the Free Software Foundation; either version 2 of the License, or *
7* (at your option) any later version. *
8* *
9* This program is distributed in the hope that it will be useful, *
10* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12* GNU General Public License for more details. *
13* *
14* You should have received a copy of the GNU General Public License *
15* along with this program; if not, write to the *
16* Free Software Foundation, Inc., *
17* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18***************************************************************************/
19
20.file "twofish-x86_64-asm.S"
21.text
22
23#include <asm/asm-offsets.h>
24
25#define a_offset 0
26#define b_offset 4
27#define c_offset 8
28#define d_offset 12
29
30/* Structure of the crypto context struct*/
31
32#define s0 0 /* S0 Array 256 Words each */
33#define s1 1024 /* S1 Array */
34#define s2 2048 /* S2 Array */
35#define s3 3072 /* S3 Array */
36#define w 4096 /* 8 whitening keys (word) */
37#define k 4128 /* key 1-32 ( word ) */
38
39/* define a few register aliases to allow macro substitution */
40
41#define R0 %rax
42#define R0D %eax
43#define R0B %al
44#define R0H %ah
45
46#define R1 %rbx
47#define R1D %ebx
48#define R1B %bl
49#define R1H %bh
50
51#define R2 %rcx
52#define R2D %ecx
53#define R2B %cl
54#define R2H %ch
55
56#define R3 %rdx
57#define R3D %edx
58#define R3B %dl
59#define R3H %dh
60
61
62/* performs input whitening */
63#define input_whitening(src,context,offset)\
64 xor w+offset(context), src;
65
66/* performs input whitening */
67#define output_whitening(src,context,offset)\
68 xor w+16+offset(context), src;
69
70
71/*
72 * a input register containing a (rotated 16)
73 * b input register containing b
74 * c input register containing c
75 * d input register containing d (already rol $1)
76 * operations on a and b are interleaved to increase performance
77 */
78#define encrypt_round(a,b,c,d,round)\
79 movzx b ## B, %edi;\
80 mov s1(%r11,%rdi,4),%r8d;\
81 movzx a ## B, %edi;\
82 mov s2(%r11,%rdi,4),%r9d;\
83 movzx b ## H, %edi;\
84 ror $16, b ## D;\
85 xor s2(%r11,%rdi,4),%r8d;\
86 movzx a ## H, %edi;\
87 ror $16, a ## D;\
88 xor s3(%r11,%rdi,4),%r9d;\
89 movzx b ## B, %edi;\
90 xor s3(%r11,%rdi,4),%r8d;\
91 movzx a ## B, %edi;\
92 xor (%r11,%rdi,4), %r9d;\
93 movzx b ## H, %edi;\
94 ror $15, b ## D;\
95 xor (%r11,%rdi,4), %r8d;\
96 movzx a ## H, %edi;\
97 xor s1(%r11,%rdi,4),%r9d;\
98 add %r8d, %r9d;\
99 add %r9d, %r8d;\
100 add k+round(%r11), %r9d;\
101 xor %r9d, c ## D;\
102 rol $15, c ## D;\
103 add k+4+round(%r11),%r8d;\
104 xor %r8d, d ## D;
105
106/*
107 * a input register containing a(rotated 16)
108 * b input register containing b
109 * c input register containing c
110 * d input register containing d (already rol $1)
111 * operations on a and b are interleaved to increase performance
112 * during the round a and b are prepared for the output whitening
113 */
114#define encrypt_last_round(a,b,c,d,round)\
115 mov b ## D, %r10d;\
116 shl $32, %r10;\
117 movzx b ## B, %edi;\
118 mov s1(%r11,%rdi,4),%r8d;\
119 movzx a ## B, %edi;\
120 mov s2(%r11,%rdi,4),%r9d;\
121 movzx b ## H, %edi;\
122 ror $16, b ## D;\
123 xor s2(%r11,%rdi,4),%r8d;\
124 movzx a ## H, %edi;\
125 ror $16, a ## D;\
126 xor s3(%r11,%rdi,4),%r9d;\
127 movzx b ## B, %edi;\
128 xor s3(%r11,%rdi,4),%r8d;\
129 movzx a ## B, %edi;\
130 xor (%r11,%rdi,4), %r9d;\
131 xor a, %r10;\
132 movzx b ## H, %edi;\
133 xor (%r11,%rdi,4), %r8d;\
134 movzx a ## H, %edi;\
135 xor s1(%r11,%rdi,4),%r9d;\
136 add %r8d, %r9d;\
137 add %r9d, %r8d;\
138 add k+round(%r11), %r9d;\
139 xor %r9d, c ## D;\
140 ror $1, c ## D;\
141 add k+4+round(%r11),%r8d;\
142 xor %r8d, d ## D
143
144/*
145 * a input register containing a
146 * b input register containing b (rotated 16)
147 * c input register containing c (already rol $1)
148 * d input register containing d
149 * operations on a and b are interleaved to increase performance
150 */
151#define decrypt_round(a,b,c,d,round)\
152 movzx a ## B, %edi;\
153 mov (%r11,%rdi,4), %r9d;\
154 movzx b ## B, %edi;\
155 mov s3(%r11,%rdi,4),%r8d;\
156 movzx a ## H, %edi;\
157 ror $16, a ## D;\
158 xor s1(%r11,%rdi,4),%r9d;\
159 movzx b ## H, %edi;\
160 ror $16, b ## D;\
161 xor (%r11,%rdi,4), %r8d;\
162 movzx a ## B, %edi;\
163 xor s2(%r11,%rdi,4),%r9d;\
164 movzx b ## B, %edi;\
165 xor s1(%r11,%rdi,4),%r8d;\
166 movzx a ## H, %edi;\
167 ror $15, a ## D;\
168 xor s3(%r11,%rdi,4),%r9d;\
169 movzx b ## H, %edi;\
170 xor s2(%r11,%rdi,4),%r8d;\
171 add %r8d, %r9d;\
172 add %r9d, %r8d;\
173 add k+round(%r11), %r9d;\
174 xor %r9d, c ## D;\
175 add k+4+round(%r11),%r8d;\
176 xor %r8d, d ## D;\
177 rol $15, d ## D;
178
179/*
180 * a input register containing a
181 * b input register containing b
182 * c input register containing c (already rol $1)
183 * d input register containing d
184 * operations on a and b are interleaved to increase performance
185 * during the round a and b are prepared for the output whitening
186 */
187#define decrypt_last_round(a,b,c,d,round)\
188 movzx a ## B, %edi;\
189 mov (%r11,%rdi,4), %r9d;\
190 movzx b ## B, %edi;\
191 mov s3(%r11,%rdi,4),%r8d;\
192 movzx b ## H, %edi;\
193 ror $16, b ## D;\
194 xor (%r11,%rdi,4), %r8d;\
195 movzx a ## H, %edi;\
196 mov b ## D, %r10d;\
197 shl $32, %r10;\
198 xor a, %r10;\
199 ror $16, a ## D;\
200 xor s1(%r11,%rdi,4),%r9d;\
201 movzx b ## B, %edi;\
202 xor s1(%r11,%rdi,4),%r8d;\
203 movzx a ## B, %edi;\
204 xor s2(%r11,%rdi,4),%r9d;\
205 movzx b ## H, %edi;\
206 xor s2(%r11,%rdi,4),%r8d;\
207 movzx a ## H, %edi;\
208 xor s3(%r11,%rdi,4),%r9d;\
209 add %r8d, %r9d;\
210 add %r9d, %r8d;\
211 add k+round(%r11), %r9d;\
212 xor %r9d, c ## D;\
213 add k+4+round(%r11),%r8d;\
214 xor %r8d, d ## D;\
215 ror $1, d ## D;
216
217.align 8
218.global twofish_enc_blk
219.global twofish_dec_blk
220
221twofish_enc_blk:
222 pushq R1
223
224 /* %rdi contains the crypto tfm adress */
225 /* %rsi contains the output adress */
226 /* %rdx contains the input adress */
227 add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
228 /* ctx adress is moved to free one non-rex register
229 as target for the 8bit high operations */
230 mov %rdi, %r11
231
232 movq (R3), R1
233 movq 8(R3), R3
234 input_whitening(R1,%r11,a_offset)
235 input_whitening(R3,%r11,c_offset)
236 mov R1D, R0D
237 rol $16, R0D
238 shr $32, R1
239 mov R3D, R2D
240 shr $32, R3
241 rol $1, R3D
242
243 encrypt_round(R0,R1,R2,R3,0);
244 encrypt_round(R2,R3,R0,R1,8);
245 encrypt_round(R0,R1,R2,R3,2*8);
246 encrypt_round(R2,R3,R0,R1,3*8);
247 encrypt_round(R0,R1,R2,R3,4*8);
248 encrypt_round(R2,R3,R0,R1,5*8);
249 encrypt_round(R0,R1,R2,R3,6*8);
250 encrypt_round(R2,R3,R0,R1,7*8);
251 encrypt_round(R0,R1,R2,R3,8*8);
252 encrypt_round(R2,R3,R0,R1,9*8);
253 encrypt_round(R0,R1,R2,R3,10*8);
254 encrypt_round(R2,R3,R0,R1,11*8);
255 encrypt_round(R0,R1,R2,R3,12*8);
256 encrypt_round(R2,R3,R0,R1,13*8);
257 encrypt_round(R0,R1,R2,R3,14*8);
258 encrypt_last_round(R2,R3,R0,R1,15*8);
259
260
261 output_whitening(%r10,%r11,a_offset)
262 movq %r10, (%rsi)
263
264 shl $32, R1
265 xor R0, R1
266
267 output_whitening(R1,%r11,c_offset)
268 movq R1, 8(%rsi)
269
270 popq R1
271 movq $1,%rax
272 ret
273
274twofish_dec_blk:
275 pushq R1
276
277 /* %rdi contains the crypto tfm adress */
278 /* %rsi contains the output adress */
279 /* %rdx contains the input adress */
280 add $crypto_tfm_ctx_offset, %rdi /* set ctx adress */
281 /* ctx adress is moved to free one non-rex register
282 as target for the 8bit high operations */
283 mov %rdi, %r11
284
285 movq (R3), R1
286 movq 8(R3), R3
287 output_whitening(R1,%r11,a_offset)
288 output_whitening(R3,%r11,c_offset)
289 mov R1D, R0D
290 shr $32, R1
291 rol $16, R1D
292 mov R3D, R2D
293 shr $32, R3
294 rol $1, R2D
295
296 decrypt_round(R0,R1,R2,R3,15*8);
297 decrypt_round(R2,R3,R0,R1,14*8);
298 decrypt_round(R0,R1,R2,R3,13*8);
299 decrypt_round(R2,R3,R0,R1,12*8);
300 decrypt_round(R0,R1,R2,R3,11*8);
301 decrypt_round(R2,R3,R0,R1,10*8);
302 decrypt_round(R0,R1,R2,R3,9*8);
303 decrypt_round(R2,R3,R0,R1,8*8);
304 decrypt_round(R0,R1,R2,R3,7*8);
305 decrypt_round(R2,R3,R0,R1,6*8);
306 decrypt_round(R0,R1,R2,R3,5*8);
307 decrypt_round(R2,R3,R0,R1,4*8);
308 decrypt_round(R0,R1,R2,R3,3*8);
309 decrypt_round(R2,R3,R0,R1,2*8);
310 decrypt_round(R0,R1,R2,R3,1*8);
311 decrypt_last_round(R2,R3,R0,R1,0);
312
313 input_whitening(%r10,%r11,a_offset)
314 movq %r10, (%rsi)
315
316 shl $32, R1
317 xor R0, R1
318
319 input_whitening(R1,%r11,c_offset)
320 movq R1, 8(%rsi)
321
322 popq R1
323 movq $1,%rax
324 ret
diff --git a/arch/x86_64/crypto/twofish.c b/arch/x86_64/crypto/twofish.c
new file mode 100644
index 000000000000..182d91d5cfb9
--- /dev/null
+++ b/arch/x86_64/crypto/twofish.c
@@ -0,0 +1,97 @@
1/*
2 * Glue Code for optimized x86_64 assembler version of TWOFISH
3 *
4 * Originally Twofish for GPG
5 * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
6 * 256-bit key length added March 20, 1999
7 * Some modifications to reduce the text size by Werner Koch, April, 1998
8 * Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
9 * Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
10 *
11 * The original author has disclaimed all copyright interest in this
12 * code and thus put it in the public domain. The subsequent authors
13 * have put this under the GNU General Public License.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 * USA
29 *
30 * This code is a "clean room" implementation, written from the paper
31 * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
32 * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
33 * through http://www.counterpane.com/twofish.html
34 *
35 * For background information on multiplication in finite fields, used for
36 * the matrix operations in the key schedule, see the book _Contemporary
37 * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
38 * Third Edition.
39 */
40
41#include <crypto/twofish.h>
42#include <linux/crypto.h>
43#include <linux/init.h>
44#include <linux/kernel.h>
45#include <linux/module.h>
46#include <linux/types.h>
47
48asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
49asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
50
51static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
52{
53 twofish_enc_blk(tfm, dst, src);
54}
55
56static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
57{
58 twofish_dec_blk(tfm, dst, src);
59}
60
61static struct crypto_alg alg = {
62 .cra_name = "twofish",
63 .cra_driver_name = "twofish-x86_64",
64 .cra_priority = 200,
65 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
66 .cra_blocksize = TF_BLOCK_SIZE,
67 .cra_ctxsize = sizeof(struct twofish_ctx),
68 .cra_alignmask = 3,
69 .cra_module = THIS_MODULE,
70 .cra_list = LIST_HEAD_INIT(alg.cra_list),
71 .cra_u = {
72 .cipher = {
73 .cia_min_keysize = TF_MIN_KEY_SIZE,
74 .cia_max_keysize = TF_MAX_KEY_SIZE,
75 .cia_setkey = twofish_setkey,
76 .cia_encrypt = twofish_encrypt,
77 .cia_decrypt = twofish_decrypt
78 }
79 }
80};
81
82static int __init init(void)
83{
84 return crypto_register_alg(&alg);
85}
86
87static void __exit fini(void)
88{
89 crypto_unregister_alg(&alg);
90}
91
92module_init(init);
93module_exit(fini);
94
95MODULE_LICENSE("GPL");
96MODULE_DESCRIPTION ("Twofish Cipher Algorithm, x86_64 asm optimized");
97MODULE_ALIAS("twofish");