aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/boot/dts/bcm63138.dtsi2
-rw-r--r--arch/arm/common/sa1111.c13
-rw-r--r--arch/arm/include/asm/cacheflush.h10
-rw-r--r--arch/arm/include/asm/device.h1
-rw-r--r--arch/arm/include/asm/dma-mapping.h7
-rw-r--r--arch/arm/include/asm/fixmap.h31
-rw-r--r--arch/arm/include/asm/hw_irq.h1
-rw-r--r--arch/arm/include/asm/mcpm.h17
-rw-r--r--arch/arm/include/asm/percpu.h4
-rw-r--r--arch/arm/include/asm/pgalloc.h10
-rw-r--r--arch/arm/include/asm/pgtable-2level-hwdef.h2
-rw-r--r--arch/arm/include/asm/pgtable-3level-hwdef.h1
-rw-r--r--arch/arm/include/asm/pgtable.h62
-rw-r--r--arch/arm/include/asm/ptrace.h5
-rw-r--r--arch/arm/include/asm/thread_info.h9
-rw-r--r--arch/arm/include/asm/vfp.h5
-rw-r--r--arch/arm/include/asm/xen/page-coherent.h66
-rw-r--r--arch/arm/include/asm/xen/page.h4
-rw-r--r--arch/arm/kernel/Makefile4
-rw-r--r--arch/arm/kernel/atags_compat.c6
-rw-r--r--arch/arm/kernel/atags_parse.c5
-rw-r--r--arch/arm/kernel/atags_proc.c4
-rw-r--r--arch/arm/kernel/bios32.c2
-rw-r--r--arch/arm/kernel/dma-isa.c4
-rw-r--r--arch/arm/kernel/dma.c26
-rw-r--r--arch/arm/kernel/entry-common.S235
-rw-r--r--arch/arm/kernel/entry-ftrace.S243
-rw-r--r--arch/arm/kernel/etm.c12
-rw-r--r--arch/arm/kernel/fiq.c2
-rw-r--r--arch/arm/kernel/ftrace.c19
-rw-r--r--arch/arm/kernel/io.c5
-rw-r--r--arch/arm/kernel/irq.c8
-rw-r--r--arch/arm/kernel/iwmmxt.S13
-rw-r--r--arch/arm/kernel/jump_label.c2
-rw-r--r--arch/arm/kernel/kgdb.c29
-rw-r--r--arch/arm/kernel/machine_kexec.c15
-rw-r--r--arch/arm/kernel/module.c2
-rw-r--r--arch/arm/kernel/patch.c92
-rw-r--r--arch/arm/kernel/patch.h12
-rw-r--r--arch/arm/kernel/process.c4
-rw-r--r--arch/arm/kernel/return_address.c3
-rw-r--r--arch/arm/kernel/setup.c1
-rw-r--r--arch/arm/kernel/signal.c1
-rw-r--r--arch/arm/kernel/smp.c15
-rw-r--r--arch/arm/kernel/smp_twd.c4
-rw-r--r--arch/arm/kernel/stacktrace.c4
-rw-r--r--arch/arm/kernel/swp_emulate.c2
-rw-r--r--arch/arm/kernel/thumbee.c2
-rw-r--r--arch/arm/kernel/topology.c4
-rw-r--r--arch/arm/kernel/traps.c42
-rw-r--r--arch/arm/kernel/unwind.c3
-rw-r--r--arch/arm/kernel/vmlinux.lds.S19
-rw-r--r--arch/arm/kernel/xscale-cp0.c7
-rw-r--r--arch/arm/lib/copy_from_user.S5
-rw-r--r--arch/arm/lib/copy_template.S30
-rw-r--r--arch/arm/lib/copy_to_user.S5
-rw-r--r--arch/arm/lib/memcpy.S5
-rw-r--r--arch/arm/lib/memmove.S28
-rw-r--r--arch/arm/lib/memset.S12
-rw-r--r--arch/arm/lib/memzero.S12
-rw-r--r--arch/arm/mach-exynos/Kconfig2
-rw-r--r--arch/arm/mach-sa1100/clock.c43
-rw-r--r--arch/arm/mach-sa1100/collie.c55
-rw-r--r--arch/arm/mach-sa1100/include/mach/entry-macro.S41
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h102
-rw-r--r--arch/arm/mach-sa1100/irq.c229
-rw-r--r--arch/arm/mm/Kconfig21
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/alignment.c10
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c6
-rw-r--r--arch/arm/mm/cache-tauros2.c12
-rw-r--r--arch/arm/mm/context.c58
-rw-r--r--arch/arm/mm/copypage-v6.c2
-rw-r--r--arch/arm/mm/fault-armv.c6
-rw-r--r--arch/arm/mm/fault.c31
-rw-r--r--arch/arm/mm/flush.c2
-rw-r--r--arch/arm/mm/highmem.c15
-rw-r--r--arch/arm/mm/init.c153
-rw-r--r--arch/arm/mm/mmu.c127
-rw-r--r--arch/arm/mm/pageattr.c91
-rw-r--r--arch/arm/mm/proc-v7.S5
-rw-r--r--arch/arm/nwfpe/fpmodule.c8
-rw-r--r--arch/arm/vfp/vfphw.S6
-rw-r--r--arch/arm/vfp/vfpmodule.c102
-rw-r--r--arch/arm/vfp/vfpsingle.c2
-rw-r--r--arch/arm/xen/Makefile2
-rw-r--r--arch/arm/xen/enlighten.c5
-rw-r--r--arch/arm/xen/mm.c121
-rw-r--r--arch/arm/xen/mm32.c202
-rw-r--r--arch/arm64/include/asm/device.h1
-rw-r--r--arch/arm64/include/asm/dma-mapping.h7
-rw-r--r--arch/arm64/include/asm/xen/page-coherent.h44
-rw-r--r--arch/arm64/kernel/psci.c4
-rw-r--r--arch/mips/Kbuild.platforms2
-rw-r--r--arch/mips/Kconfig98
-rw-r--r--arch/mips/Kconfig.debug13
-rw-r--r--arch/mips/Makefile1
-rw-r--r--arch/mips/alchemy/common/clock.c7
-rw-r--r--arch/mips/alchemy/common/setup.c6
-rw-r--r--arch/mips/ar7/platform.c24
-rw-r--r--arch/mips/ath25/Kconfig16
-rw-r--r--arch/mips/ath25/Makefile16
-rw-r--r--arch/mips/ath25/Platform6
-rw-r--r--arch/mips/ath25/ar2315.c364
-rw-r--r--arch/mips/ath25/ar2315.h22
-rw-r--r--arch/mips/ath25/ar2315_regs.h410
-rw-r--r--arch/mips/ath25/ar5312.c393
-rw-r--r--arch/mips/ath25/ar5312.h22
-rw-r--r--arch/mips/ath25/ar5312_regs.h224
-rw-r--r--arch/mips/ath25/board.c234
-rw-r--r--arch/mips/ath25/devices.c125
-rw-r--r--arch/mips/ath25/devices.h43
-rw-r--r--arch/mips/ath25/early_printk.c44
-rw-r--r--arch/mips/ath25/prom.c26
-rw-r--r--arch/mips/ath79/irq.c1
-rw-r--r--arch/mips/ath79/prom.c38
-rw-r--r--arch/mips/ath79/setup.c5
-rw-r--r--arch/mips/bcm3384/Makefile1
-rw-r--r--arch/mips/bcm3384/Platform7
-rw-r--r--arch/mips/bcm3384/dma.c81
-rw-r--r--arch/mips/bcm3384/irq.c193
-rw-r--r--arch/mips/bcm3384/setup.c97
-rw-r--r--arch/mips/bcm47xx/bcm47xx_private.h6
-rw-r--r--arch/mips/bcm47xx/irq.c8
-rw-r--r--arch/mips/bcm47xx/nvram.c155
-rw-r--r--arch/mips/bcm47xx/setup.c91
-rw-r--r--arch/mips/bcm47xx/sprom.c82
-rw-r--r--arch/mips/bcm63xx/cpu.c2
-rw-r--r--arch/mips/boot/dts/Makefile1
-rw-r--r--arch/mips/boot/dts/bcm3384.dtsi109
-rw-r--r--arch/mips/boot/dts/bcm93384wvg.dts32
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c4
-rw-r--r--arch/mips/cavium-octeon/executive/octeon-model.c49
-rw-r--r--arch/mips/cavium-octeon/setup.c4
-rw-r--r--arch/mips/configs/bcm3384_defconfig78
-rw-r--r--arch/mips/fw/lib/cmdline.c8
-rw-r--r--arch/mips/include/asm/atomic.h374
-rw-r--r--arch/mips/include/asm/bitops.h35
-rw-r--r--arch/mips/include/asm/bmips.h1
-rw-r--r--arch/mips/include/asm/bootinfo.h13
-rw-r--r--arch/mips/include/asm/clock.h3
-rw-r--r--arch/mips/include/asm/cmpxchg.h27
-rw-r--r--arch/mips/include/asm/compiler.h8
-rw-r--r--arch/mips/include/asm/cpu-features.h4
-rw-r--r--arch/mips/include/asm/cpu.h2
-rw-r--r--arch/mips/include/asm/edac.h6
-rw-r--r--arch/mips/include/asm/elf.h74
-rw-r--r--arch/mips/include/asm/fpu.h49
-rw-r--r--arch/mips/include/asm/futex.h27
-rw-r--r--arch/mips/include/asm/gic.h384
-rw-r--r--arch/mips/include/asm/hpet.h73
-rw-r--r--arch/mips/include/asm/io.h8
-rw-r--r--arch/mips/include/asm/irq.h3
-rw-r--r--arch/mips/include/asm/irq_cpu.h4
-rw-r--r--arch/mips/include/asm/mach-ath25/ath25_platform.h73
-rw-r--r--arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h64
-rw-r--r--arch/mips/include/asm/mach-ath25/dma-coherence.h82
-rw-r--r--arch/mips/include/asm/mach-ath25/gpio.h16
-rw-r--r--arch/mips/include/asm/mach-ath25/war.h25
-rw-r--r--arch/mips/include/asm/mach-au1x00/ioremap.h10
-rw-r--r--arch/mips/include/asm/mach-bcm3384/dma-coherence.h48
-rw-r--r--arch/mips/include/asm/mach-bcm3384/war.h24
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h36
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/ioremap.h6
-rw-r--r--arch/mips/include/asm/mach-generic/ioremap.h4
-rw-r--r--arch/mips/include/asm/mach-generic/irq.h6
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/boot_param.h49
-rw-r--r--arch/mips/include/asm/mach-loongson/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-loongson/irq.h3
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson_hwmon.h55
-rw-r--r--arch/mips/include/asm/mach-loongson/machine.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/topology.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/workarounds.h7
-rw-r--r--arch/mips/include/asm/mach-loongson1/cpufreq.h23
-rw-r--r--arch/mips/include/asm/mach-loongson1/loongson1.h8
-rw-r--r--arch/mips/include/asm/mach-loongson1/platform.h10
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-clk.h23
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-mux.h67
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-pwm.h29
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-wdt.h11
-rw-r--r--arch/mips/include/asm/mach-malta/irq.h1
-rw-r--r--arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h25
-rw-r--r--arch/mips/include/asm/mach-ralink/mt7620.h64
-rw-r--r--arch/mips/include/asm/mach-ralink/pinmux.h55
-rw-r--r--arch/mips/include/asm/mach-ralink/ralink_regs.h7
-rw-r--r--arch/mips/include/asm/mach-ralink/rt305x.h35
-rw-r--r--arch/mips/include/asm/mach-ralink/rt3883.h16
-rw-r--r--arch/mips/include/asm/mach-sead3/irq.h1
-rw-r--r--arch/mips/include/asm/mach-tx39xx/ioremap.h4
-rw-r--r--arch/mips/include/asm/mach-tx49xx/ioremap.h4
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h24
-rw-r--r--arch/mips/include/asm/mips-boards/sead3int.h15
-rw-r--r--arch/mips/include/asm/mips-cm.h2
-rw-r--r--arch/mips/include/asm/mips-cpc.h4
-rw-r--r--arch/mips/include/asm/mipsregs.h43
-rw-r--r--arch/mips/include/asm/octeon/cvmx-cmd-queue.h4
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow.h69
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h63
-rw-r--r--arch/mips/include/asm/octeon/octeon-feature.h52
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h3
-rw-r--r--arch/mips/include/asm/paccess.h2
-rw-r--r--arch/mips/include/asm/page.h2
-rw-r--r--arch/mips/include/asm/pci.h2
-rw-r--r--arch/mips/include/asm/pgtable-32.h104
-rw-r--r--arch/mips/include/asm/pgtable-bits.h36
-rw-r--r--arch/mips/include/asm/pgtable.h18
-rw-r--r--arch/mips/include/asm/prom.h1
-rw-r--r--arch/mips/include/asm/r4kcache.h59
-rw-r--r--arch/mips/include/asm/spinlock.h50
-rw-r--r--arch/mips/include/asm/thread_info.h2
-rw-r--r--arch/mips/include/asm/time.h6
-rw-r--r--arch/mips/include/asm/types.h18
-rw-r--r--arch/mips/include/asm/uaccess.h27
-rw-r--r--arch/mips/include/asm/uasm.h2
-rw-r--r--arch/mips/include/uapi/asm/inst.h7
-rw-r--r--arch/mips/jz4740/setup.c2
-rw-r--r--arch/mips/kernel/Makefile10
-rw-r--r--arch/mips/kernel/cevt-gic.c105
-rw-r--r--arch/mips/kernel/cevt-r4k.c6
-rw-r--r--arch/mips/kernel/cpu-probe.c71
-rw-r--r--arch/mips/kernel/crash_dump.c4
-rw-r--r--arch/mips/kernel/csrc-gic.c40
-rw-r--r--arch/mips/kernel/elf.c191
-rw-r--r--arch/mips/kernel/i8259.c24
-rw-r--r--arch/mips/kernel/irq-gic.c402
-rw-r--r--arch/mips/kernel/irq_cpu.c48
-rw-r--r--arch/mips/kernel/mips-cm.c12
-rw-r--r--arch/mips/kernel/mips-cpc.c4
-rw-r--r--arch/mips/kernel/mips_ksyms.c4
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c30
-rw-r--r--arch/mips/kernel/process.c54
-rw-r--r--arch/mips/kernel/prom.c18
-rw-r--r--arch/mips/kernel/setup.c14
-rw-r--r--arch/mips/kernel/signal.c2
-rw-r--r--arch/mips/kernel/smp-bmips.c114
-rw-r--r--arch/mips/kernel/smp-cmp.c2
-rw-r--r--arch/mips/kernel/smp-cps.c6
-rw-r--r--arch/mips/kernel/smp-gic.c2
-rw-r--r--arch/mips/kernel/smp-mt.c6
-rw-r--r--arch/mips/kernel/syscall.c2
-rw-r--r--arch/mips/kernel/traps.c66
-rw-r--r--arch/mips/kernel/vdso.c15
-rw-r--r--arch/mips/lantiq/falcon/sysctrl.c11
-rw-r--r--arch/mips/lantiq/irq.c56
-rw-r--r--arch/mips/lantiq/prom.c18
-rw-r--r--arch/mips/lantiq/xway/Makefile2
-rw-r--r--arch/mips/lantiq/xway/reset.c70
-rw-r--r--arch/mips/lantiq/xway/vmmc.c69
-rw-r--r--arch/mips/lantiq/xway/xrx200_phy_fw.c23
-rw-r--r--arch/mips/lib/iomap.c18
-rw-r--r--arch/mips/lib/memset.S6
-rw-r--r--arch/mips/lib/mips-atomic.c20
-rw-r--r--arch/mips/lib/r3k_dump_tlb.c11
-rw-r--r--arch/mips/lib/strlen_user.S3
-rw-r--r--arch/mips/loongson/Kconfig17
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_pci.c25
-rw-r--r--arch/mips/loongson/common/dma-swiotlb.c14
-rw-r--r--arch/mips/loongson/common/early_printk.c2
-rw-r--r--arch/mips/loongson/common/env.c28
-rw-r--r--arch/mips/loongson/common/gpio.c2
-rw-r--r--arch/mips/loongson/common/init.c1
-rw-r--r--arch/mips/loongson/common/machtype.c23
-rw-r--r--arch/mips/loongson/common/rtc.c2
-rw-r--r--arch/mips/loongson/common/serial.c66
-rw-r--r--arch/mips/loongson/common/setup.c1
-rw-r--r--arch/mips/loongson/common/time.c5
-rw-r--r--arch/mips/loongson/common/uart_base.c30
-rw-r--r--arch/mips/loongson/lemote-2f/irq.c4
-rw-r--r--arch/mips/loongson/lemote-2f/reset.c2
-rw-r--r--arch/mips/loongson/loongson-3/Makefile4
-rw-r--r--arch/mips/loongson/loongson-3/hpet.c257
-rw-r--r--arch/mips/loongson/loongson-3/irq.c16
-rw-r--r--arch/mips/loongson/loongson-3/numa.c12
-rw-r--r--arch/mips/loongson/loongson-3/platform.c43
-rw-r--r--arch/mips/loongson/loongson-3/smp.c70
-rw-r--r--arch/mips/loongson1/Kconfig42
-rw-r--r--arch/mips/loongson1/common/Makefile2
-rw-r--r--arch/mips/loongson1/common/clock.c28
-rw-r--r--arch/mips/loongson1/common/platform.c141
-rw-r--r--arch/mips/loongson1/common/prom.c30
-rw-r--r--arch/mips/loongson1/common/reset.c20
-rw-r--r--arch/mips/loongson1/common/time.c226
-rw-r--r--arch/mips/loongson1/ls1b/board.c12
-rw-r--r--arch/mips/math-emu/cp1emu.c9
-rw-r--r--arch/mips/math-emu/ieee754dp.c2
-rw-r--r--arch/mips/math-emu/ieee754sp.c2
-rw-r--r--arch/mips/mm/Makefile10
-rw-r--r--arch/mips/mm/c-r4k.c43
-rw-r--r--arch/mips/mm/dma-default.c5
-rw-r--r--arch/mips/mm/gup.c2
-rw-r--r--arch/mips/mm/init.c2
-rw-r--r--arch/mips/mm/ioremap.c18
-rw-r--r--arch/mips/mm/sc-r5k.c2
-rw-r--r--arch/mips/mm/tlb-r4k.c2
-rw-r--r--arch/mips/mm/tlbex.c18
-rw-r--r--arch/mips/mm/uasm-mips.c2
-rw-r--r--arch/mips/mm/uasm.c14
-rw-r--r--arch/mips/mti-malta/malta-init.c2
-rw-r--r--arch/mips/mti-malta/malta-int.c327
-rw-r--r--arch/mips/mti-malta/malta-time.c51
-rw-r--r--arch/mips/mti-sead3/sead3-ehci.c8
-rw-r--r--arch/mips/mti-sead3/sead3-int.c131
-rw-r--r--arch/mips/mti-sead3/sead3-net.c14
-rw-r--r--arch/mips/mti-sead3/sead3-platform.c18
-rw-r--r--arch/mips/mti-sead3/sead3-serial.c45
-rw-r--r--arch/mips/mti-sead3/sead3-time.c35
-rw-r--r--arch/mips/oprofile/Makefile1
-rw-r--r--arch/mips/oprofile/backtrace.c5
-rw-r--r--arch/mips/oprofile/common.c11
-rw-r--r--arch/mips/oprofile/op_model_loongson3.c220
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c18
-rw-r--r--arch/mips/pci/Makefile2
-rw-r--r--arch/mips/pci/ops-bcm63xx.c2
-rw-r--r--arch/mips/pci/ops-nile4.c12
-rw-r--r--arch/mips/pci/ops-pmcmsp.c12
-rw-r--r--arch/mips/pci/pci-ar2315.c511
-rw-r--r--arch/mips/pci/pci-ar71xx.c13
-rw-r--r--arch/mips/pci/pci-ar724x.c23
-rw-r--r--arch/mips/pci/pci-octeon.c2
-rw-r--r--arch/mips/pci/pci-rt2880.c285
-rw-r--r--arch/mips/pci/pci-rt3883.c9
-rw-r--r--arch/mips/pci/pci-tx4939.c2
-rw-r--r--arch/mips/pmcs-msp71xx/msp_prom.c2
-rw-r--r--arch/mips/ralink/Kconfig3
-rw-r--r--arch/mips/ralink/Makefile4
-rw-r--r--arch/mips/ralink/bootrom.c48
-rw-r--r--arch/mips/ralink/clk.c6
-rw-r--r--arch/mips/ralink/common.h19
-rw-r--r--arch/mips/ralink/early_printk.c45
-rw-r--r--arch/mips/ralink/ill_acc.c87
-rw-r--r--arch/mips/ralink/irq.c45
-rw-r--r--arch/mips/ralink/mt7620.c465
-rw-r--r--arch/mips/ralink/of.c32
-rw-r--r--arch/mips/ralink/prom.c1
-rw-r--r--arch/mips/ralink/rt288x.c65
-rw-r--r--arch/mips/ralink/rt305x.c153
-rw-r--r--arch/mips/ralink/rt3883.c174
-rw-r--r--arch/mips/rb532/gpio.c2
-rw-r--r--arch/mips/rb532/prom.c8
-rw-r--r--arch/mips/sgi-ip22/ip22-mc.c6
-rw-r--r--arch/mips/sgi-ip22/ip28-berr.c6
-rw-r--r--arch/mips/sgi-ip27/ip27-klnuma.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c5
-rw-r--r--arch/mips/sibyte/common/cfe.c8
-rw-r--r--arch/mips/sibyte/swarm/platform.c2
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c4
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c4
-rw-r--r--arch/mips/sibyte/swarm/setup.c2
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c4
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c4
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c4
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/boot/dts/b4860emu.dts4
-rw-r--r--arch/powerpc/boot/dts/b4qds.dtsi23
-rw-r--r--arch/powerpc/boot/dts/bsc9131rdb.dtsi50
-rw-r--r--arch/powerpc/boot/dts/fsl/b4420si-post.dtsi28
-rw-r--r--arch/powerpc/boot/dts/fsl/b4860si-post.dtsi28
-rw-r--r--arch/powerpc/boot/dts/fsl/p2041si-post.dtsi48
-rw-r--r--arch/powerpc/boot/dts/fsl/p3041si-post.dtsi48
-rw-r--r--arch/powerpc/boot/dts/fsl/p4080si-post.dtsi48
-rw-r--r--arch/powerpc/boot/dts/fsl/p5020si-post.dtsi48
-rw-r--r--arch/powerpc/boot/dts/fsl/p5040si-post.dtsi48
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi85
-rw-r--r--arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi68
-rw-r--r--arch/powerpc/boot/dts/fsl/t1040si-post.dtsi30
-rw-r--r--arch/powerpc/boot/dts/fsl/t2081si-post.dtsi29
-rw-r--r--arch/powerpc/boot/dts/fsl/t4240si-post.dtsi29
-rw-r--r--arch/powerpc/boot/dts/p3041ds.dts20
-rw-r--r--arch/powerpc/boot/dts/p5020ds.dts20
-rw-r--r--arch/powerpc/boot/dts/p5040ds.dts20
-rw-r--r--arch/powerpc/boot/dts/t104xrdb.dtsi7
-rw-r--r--arch/powerpc/boot/dts/t208xqds.dtsi11
-rw-r--r--arch/powerpc/boot/dts/t4240emu.dts4
-rw-r--r--arch/powerpc/boot/main.c15
-rw-r--r--arch/powerpc/boot/ops.h2
-rw-r--r--arch/powerpc/boot/serial.c6
-rw-r--r--arch/powerpc/configs/corenet32_smp_defconfig1
-rw-r--r--arch/powerpc/configs/corenet64_smp_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig1
-rw-r--r--arch/powerpc/include/asm/bitops.h6
-rw-r--r--arch/powerpc/include/asm/cputable.h10
-rw-r--r--arch/powerpc/include/asm/eeh.h2
-rw-r--r--arch/powerpc/include/asm/elf.h3
-rw-r--r--arch/powerpc/include/asm/fsl_guts.h5
-rw-r--r--arch/powerpc/include/asm/hardirq.h7
-rw-r--r--arch/powerpc/include/asm/hugetlb.h8
-rw-r--r--arch/powerpc/include/asm/io.h3
-rw-r--r--arch/powerpc/include/asm/machdep.h19
-rw-r--r--arch/powerpc/include/asm/mmu-8xx.h2
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h22
-rw-r--r--arch/powerpc/include/asm/opal.h122
-rw-r--r--arch/powerpc/include/asm/paca.h7
-rw-r--r--arch/powerpc/include/asm/page.h4
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc32.h20
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-4k.h16
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-64k.h3
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h52
-rw-r--r--arch/powerpc/include/asm/pgtable.h6
-rw-r--r--arch/powerpc/include/asm/processor.h2
-rw-r--r--arch/powerpc/include/asm/pte-8xx.h7
-rw-r--r--arch/powerpc/include/asm/setup.h3
-rw-r--r--arch/powerpc/include/asm/thread_info.h5
-rw-r--r--arch/powerpc/include/asm/tlbflush.h10
-rw-r--r--arch/powerpc/include/asm/vga.h4
-rw-r--r--arch/powerpc/include/asm/xics.h8
-rw-r--r--arch/powerpc/kernel/align.c2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c7
-rw-r--r--arch/powerpc/kernel/crash_dump.c1
-rw-r--r--arch/powerpc/kernel/dbell.c2
-rw-r--r--arch/powerpc/kernel/eeh.c41
-rw-r--r--arch/powerpc/kernel/eeh_driver.c10
-rw-r--r--arch/powerpc/kernel/entry_32.S12
-rw-r--r--arch/powerpc/kernel/entry_64.S35
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S34
-rw-r--r--arch/powerpc/kernel/ftrace.c73
-rw-r--r--arch/powerpc/kernel/head_8xx.S230
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c6
-rw-r--r--arch/powerpc/kernel/idle_power7.S12
-rw-r--r--arch/powerpc/kernel/iommu.c2
-rw-r--r--arch/powerpc/kernel/irq.c5
-rw-r--r--arch/powerpc/kernel/kgdb.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c6
-rw-r--r--arch/powerpc/kernel/mce.c24
-rw-r--r--arch/powerpc/kernel/mce_power.c4
-rw-r--r--arch/powerpc/kernel/pci-common.c3
-rw-r--r--arch/powerpc/kernel/pci_32.c4
-rw-r--r--arch/powerpc/kernel/pci_64.c1
-rw-r--r--arch/powerpc/kernel/process.c36
-rw-r--r--arch/powerpc/kernel/prom.c11
-rw-r--r--arch/powerpc/kernel/rtas-proc.c20
-rw-r--r--arch/powerpc/kernel/rtas.c4
-rw-r--r--arch/powerpc/kernel/rtas_pci.c1
-rw-r--r--arch/powerpc/kernel/setup-common.c6
-rw-r--r--arch/powerpc/kernel/setup_32.c11
-rw-r--r--arch/powerpc/kernel/setup_64.c35
-rw-r--r--arch/powerpc/kernel/smp.c6
-rw-r--r--arch/powerpc/kernel/sysfs.c4
-rw-r--r--arch/powerpc/kernel/time.c23
-rw-r--r--arch/powerpc/kernel/traps.c8
-rw-r--r--arch/powerpc/kernel/udbg_16550.c6
-rw-r--r--arch/powerpc/kernel/vdso.c1
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c3
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S54
-rw-r--r--arch/powerpc/kvm/e500.c14
-rw-r--r--arch/powerpc/kvm/e500_mmu_host.c6
-rw-r--r--arch/powerpc/kvm/e500mc.c4
-rw-r--r--arch/powerpc/lib/Makefile1
-rw-r--r--arch/powerpc/lib/alloc.c4
-rw-r--r--arch/powerpc/lib/copyuser_power7.S2
-rw-r--r--arch/powerpc/lib/devres.c43
-rw-r--r--arch/powerpc/lib/memcpy_power7.S2
-rw-r--r--arch/powerpc/lib/sstep.c6
-rw-r--r--arch/powerpc/mm/Makefile2
-rw-r--r--arch/powerpc/mm/fault.c7
-rw-r--r--arch/powerpc/mm/gup.c235
-rw-r--r--arch/powerpc/mm/hash_low_64.S19
-rw-r--r--arch/powerpc/mm/hash_native_64.c41
-rw-r--r--arch/powerpc/mm/hash_utils_64.c114
-rw-r--r--arch/powerpc/mm/hugepage-hash64.c60
-rw-r--r--arch/powerpc/mm/hugetlbpage-book3e.c6
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c6
-rw-r--r--arch/powerpc/mm/hugetlbpage.c51
-rw-r--r--arch/powerpc/mm/init_32.c10
-rw-r--r--arch/powerpc/mm/init_64.c1
-rw-r--r--arch/powerpc/mm/mem.c77
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c8
-rw-r--r--arch/powerpc/mm/mmu_decl.h2
-rw-r--r--arch/powerpc/mm/numa.c224
-rw-r--r--arch/powerpc/mm/pgtable_32.c3
-rw-r--r--arch/powerpc/mm/pgtable_64.c104
-rw-r--r--arch/powerpc/oprofile/backtrace.c6
-rw-r--r--arch/powerpc/perf/core-book3s.c22
-rw-r--r--arch/powerpc/perf/core-fsl-emb.c6
-rw-r--r--arch/powerpc/platforms/44x/Kconfig1
-rw-r--r--arch/powerpc/platforms/44x/ppc476.c2
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_shared.c9
-rw-r--r--arch/powerpc/platforms/52xx/efika.c3
-rw-r--r--arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c8
-rw-r--r--arch/powerpc/platforms/85xx/corenet_generic.c2
-rw-r--r--arch/powerpc/platforms/85xx/sgy_cts1000.c4
-rw-r--r--arch/powerpc/platforms/8xx/Kconfig4
-rw-r--r--arch/powerpc/platforms/cell/beat_htab.c4
-rw-r--r--arch/powerpc/platforms/cell/celleb_pci.c6
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_epci.c1
-rw-r--r--arch/powerpc/platforms/cell/celleb_scc_pciex.c1
-rw-r--r--arch/powerpc/platforms/cell/celleb_setup.c4
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c6
-rw-r--r--arch/powerpc/platforms/cell/qpace_setup.c2
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c5
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c3
-rw-r--r--arch/powerpc/platforms/embedded6xx/gamecube.c3
-rw-r--r--arch/powerpc/platforms/embedded6xx/linkstation.c4
-rw-r--r--arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c6
-rw-r--r--arch/powerpc/platforms/embedded6xx/wii.c3
-rw-r--r--arch/powerpc/platforms/maple/pci.c1
-rw-r--r--arch/powerpc/platforms/maple/setup.c4
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c6
-rw-r--r--arch/powerpc/platforms/powermac/pci.c1
-rw-r--r--arch/powerpc/platforms/powermac/setup.c3
-rw-r--r--arch/powerpc/platforms/powernv/eeh-ioda.c16
-rw-r--r--arch/powerpc/platforms/powernv/opal-async.c3
-rw-r--r--arch/powerpc/platforms/powernv/opal-rtc.c65
-rw-r--r--arch/powerpc/platforms/powernv/opal-tracepoints.c4
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S6
-rw-r--r--arch/powerpc/platforms/powernv/opal.c21
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c217
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c44
-rw-r--r--arch/powerpc/platforms/powernv/pci.c1
-rw-r--r--arch/powerpc/platforms/powernv/pci.h2
-rw-r--r--arch/powerpc/platforms/powernv/setup.c6
-rw-r--r--arch/powerpc/platforms/powernv/smp.c23
-rw-r--r--arch/powerpc/platforms/ps3/htab.c2
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c9
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c2
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-memory.c21
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S4
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c4
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c11
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c10
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c2
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/ras.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c65
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c1
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c3
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c104
-rw-r--r--arch/powerpc/sysdev/fsl_rio.h13
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c5
-rw-r--r--arch/powerpc/sysdev/ipic.c1
-rw-r--r--arch/powerpc/sysdev/mpc5xxx_clocks.c3
-rw-r--r--arch/powerpc/sysdev/mpic.c1
-rw-r--r--arch/powerpc/sysdev/mpic_pasemi_msi.c1
-rw-r--r--arch/powerpc/sysdev/mpic_u3msi.c1
-rw-r--r--arch/powerpc/sysdev/ppc4xx_cpm.c8
-rw-r--r--arch/powerpc/sysdev/ppc4xx_msi.c1
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c1
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c1
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c1
-rw-r--r--arch/powerpc/sysdev/uic.c1
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c2
-rw-r--r--arch/powerpc/xmon/xmon.c82
-rw-r--r--arch/s390/include/asm/cmpxchg.h240
-rw-r--r--arch/s390/include/asm/cputime.h46
-rw-r--r--arch/s390/include/asm/debug.h29
-rw-r--r--arch/s390/include/asm/ftrace.h54
-rw-r--r--arch/s390/include/asm/idle.h3
-rw-r--r--arch/s390/include/asm/io.h9
-rw-r--r--arch/s390/include/asm/irq.h11
-rw-r--r--arch/s390/include/asm/kprobes.h1
-rw-r--r--arch/s390/include/asm/lowcore.h4
-rw-r--r--arch/s390/include/asm/pci.h5
-rw-r--r--arch/s390/include/asm/pci_io.h6
-rw-r--r--arch/s390/include/asm/pgalloc.h2
-rw-r--r--arch/s390/include/asm/pgtable.h33
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/include/asm/spinlock.h9
-rw-r--r--arch/s390/include/asm/tlb.h1
-rw-r--r--arch/s390/include/uapi/asm/unistd.h4
-rw-r--r--arch/s390/kernel/asm-offsets.c5
-rw-r--r--arch/s390/kernel/compat_signal.c2
-rw-r--r--arch/s390/kernel/compat_wrapper.c2
-rw-r--r--arch/s390/kernel/debug.c12
-rw-r--r--arch/s390/kernel/dumpstack.c3
-rw-r--r--arch/s390/kernel/early.c4
-rw-r--r--arch/s390/kernel/entry.S424
-rw-r--r--arch/s390/kernel/entry.h2
-rw-r--r--arch/s390/kernel/entry64.S372
-rw-r--r--arch/s390/kernel/ftrace.c136
-rw-r--r--arch/s390/kernel/idle.c29
-rw-r--r--arch/s390/kernel/irq.c5
-rw-r--r--arch/s390/kernel/kprobes.c178
-rw-r--r--arch/s390/kernel/mcount.S1
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c1
-rw-r--r--arch/s390/kernel/process.c3
-rw-r--r--arch/s390/kernel/ptrace.c115
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kernel/signal.c2
-rw-r--r--arch/s390/kernel/smp.c1
-rw-r--r--arch/s390/kernel/syscalls.S2
-rw-r--r--arch/s390/kernel/time.c3
-rw-r--r--arch/s390/kernel/traps.c25
-rw-r--r--arch/s390/kvm/kvm-s390.c2
-rw-r--r--arch/s390/kvm/priv.c17
-rw-r--r--arch/s390/mm/fault.c10
-rw-r--r--arch/s390/mm/pgtable.c185
-rw-r--r--arch/s390/pci/Makefile2
-rw-r--r--arch/s390/pci/pci.c9
-rw-r--r--arch/s390/pci/pci_clp.c1
-rw-r--r--arch/s390/pci/pci_debug.c7
-rw-r--r--arch/s390/pci/pci_mmio.c115
-rw-r--r--arch/x86/include/asm/xen/cpuid.h91
-rw-r--r--arch/x86/include/asm/xen/page-coherent.h4
-rw-r--r--arch/x86/include/asm/xen/page.h7
-rw-r--r--arch/x86/pci/xen.c31
601 files changed, 12590 insertions, 7739 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c8424a85bc04..0bee1fe209b1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -687,7 +687,9 @@ config ARCH_SA1100
687 select CPU_SA1100 687 select CPU_SA1100
688 select GENERIC_CLOCKEVENTS 688 select GENERIC_CLOCKEVENTS
689 select HAVE_IDE 689 select HAVE_IDE
690 select IRQ_DOMAIN
690 select ISA 691 select ISA
692 select MULTI_IRQ_HANDLER
691 select NEED_MACH_MEMORY_H 693 select NEED_MACH_MEMORY_H
692 select SPARSE_IRQ 694 select SPARSE_IRQ
693 help 695 help
diff --git a/arch/arm/boot/dts/bcm63138.dtsi b/arch/arm/boot/dts/bcm63138.dtsi
index f3bb2dd6269e..d2d8e94e0aa2 100644
--- a/arch/arm/boot/dts/bcm63138.dtsi
+++ b/arch/arm/boot/dts/bcm63138.dtsi
@@ -102,7 +102,7 @@
102 twd_watchdog: watchdog@1e620 { 102 twd_watchdog: watchdog@1e620 {
103 compatible = "arm,cortex-a9-twd-wdt"; 103 compatible = "arm,cortex-a9-twd-wdt";
104 reg = <0x1e620 0x20>; 104 reg = <0x1e620 0x20>;
105 interupts = <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>; 105 interrupts = <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>;
106 }; 106 };
107 }; 107 };
108 108
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index e57d7e5bf96a..7b69c5f9cd74 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -282,8 +282,8 @@ static int sa1111_retrigger_lowirq(struct irq_data *d)
282 } 282 }
283 283
284 if (i == 8) 284 if (i == 8)
285 printk(KERN_ERR "Danger Will Robinson: failed to " 285 pr_err("Danger Will Robinson: failed to re-trigger IRQ%d\n",
286 "re-trigger IRQ%d\n", d->irq); 286 d->irq);
287 return i == 8 ? -1 : 0; 287 return i == 8 ? -1 : 0;
288} 288}
289 289
@@ -384,8 +384,8 @@ static int sa1111_retrigger_highirq(struct irq_data *d)
384 } 384 }
385 385
386 if (i == 8) 386 if (i == 8)
387 printk(KERN_ERR "Danger Will Robinson: failed to " 387 pr_err("Danger Will Robinson: failed to re-trigger IRQ%d\n",
388 "re-trigger IRQ%d\n", d->irq); 388 d->irq);
389 return i == 8 ? -1 : 0; 389 return i == 8 ? -1 : 0;
390} 390}
391 391
@@ -740,9 +740,8 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
740 goto err_unmap; 740 goto err_unmap;
741 } 741 }
742 742
743 printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " 743 pr_info("SA1111 Microprocessor Companion Chip: silicon revision %lx, metal revision %lx\n",
744 "silicon revision %lx, metal revision %lx\n", 744 (id & SKID_SIREV_MASK) >> 4, id & SKID_MTREV_MASK);
745 (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
746 745
747 /* 746 /*
748 * We found it. Wake the chip up, and initialise. 747 * We found it. Wake the chip up, and initialise.
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 10e78d00a0bb..2d46862e7bef 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -487,6 +487,16 @@ int set_memory_rw(unsigned long addr, int numpages);
487int set_memory_x(unsigned long addr, int numpages); 487int set_memory_x(unsigned long addr, int numpages);
488int set_memory_nx(unsigned long addr, int numpages); 488int set_memory_nx(unsigned long addr, int numpages);
489 489
490#ifdef CONFIG_DEBUG_RODATA
491void mark_rodata_ro(void);
492void set_kernel_text_rw(void);
493void set_kernel_text_ro(void);
494#else
495static inline void set_kernel_text_rw(void) { }
496static inline void set_kernel_text_ro(void) { }
497#endif
498
490void flush_uprobe_xol_access(struct page *page, unsigned long uaddr, 499void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
491 void *kaddr, unsigned long len); 500 void *kaddr, unsigned long len);
501
492#endif 502#endif
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index dc662fca9230..4111592f0130 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -17,6 +17,7 @@ struct dev_archdata {
17#ifdef CONFIG_ARM_DMA_USE_IOMMU 17#ifdef CONFIG_ARM_DMA_USE_IOMMU
18 struct dma_iommu_mapping *mapping; 18 struct dma_iommu_mapping *mapping;
19#endif 19#endif
20 bool dma_coherent;
20}; 21};
21 22
22struct omap_device; 23struct omap_device;
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 85738b200023..e6e3446abdf6 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -123,11 +123,18 @@ static inline unsigned long dma_max_pfn(struct device *dev)
123 123
124static inline int set_arch_dma_coherent_ops(struct device *dev) 124static inline int set_arch_dma_coherent_ops(struct device *dev)
125{ 125{
126 dev->archdata.dma_coherent = true;
126 set_dma_ops(dev, &arm_coherent_dma_ops); 127 set_dma_ops(dev, &arm_coherent_dma_ops);
127 return 0; 128 return 0;
128} 129}
129#define set_arch_dma_coherent_ops(dev) set_arch_dma_coherent_ops(dev) 130#define set_arch_dma_coherent_ops(dev) set_arch_dma_coherent_ops(dev)
130 131
132/* do not use this function in a driver */
133static inline bool is_device_dma_coherent(struct device *dev)
134{
135 return dev->archdata.dma_coherent;
136}
137
131static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 138static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
132{ 139{
133 unsigned int offset = paddr & ~PAGE_MASK; 140 unsigned int offset = paddr & ~PAGE_MASK;
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 74124b0d0d79..0415eae1df27 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -2,27 +2,24 @@
2#define _ASM_FIXMAP_H 2#define _ASM_FIXMAP_H
3 3
4#define FIXADDR_START 0xffc00000UL 4#define FIXADDR_START 0xffc00000UL
5#define FIXADDR_TOP 0xffe00000UL 5#define FIXADDR_END 0xfff00000UL
6#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) 6#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)
7 7
8#define FIX_KMAP_NR_PTES (FIXADDR_SIZE >> PAGE_SHIFT) 8#include <asm/kmap_types.h>
9 9
10#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) 10enum fixed_addresses {
11#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) 11 FIX_KMAP_BEGIN,
12 FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
12 13
13extern void __this_fixmap_does_not_exist(void); 14 /* Support writing RO kernel text via kprobes, jump labels, etc. */
15 FIX_TEXT_POKE0,
16 FIX_TEXT_POKE1,
14 17
15static inline unsigned long fix_to_virt(const unsigned int idx) 18 __end_of_fixed_addresses
16{ 19};
17 if (idx >= FIX_KMAP_NR_PTES)
18 __this_fixmap_does_not_exist();
19 return __fix_to_virt(idx);
20}
21 20
22static inline unsigned int virt_to_fix(const unsigned long vaddr) 21void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
23{ 22
24 BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); 23#include <asm-generic/fixmap.h>
25 return __virt_to_fix(vaddr);
26}
27 24
28#endif 25#endif
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index a71b417b1856..af79da40af2a 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -8,6 +8,7 @@ static inline void ack_bad_irq(int irq)
8{ 8{
9 extern unsigned long irq_err_count; 9 extern unsigned long irq_err_count;
10 irq_err_count++; 10 irq_err_count++;
11 pr_crit("unexpected IRQ trap at vector %02x\n", irq);
11} 12}
12 13
13void set_irq_flags(unsigned int irq, unsigned int flags); 14void set_irq_flags(unsigned int irq, unsigned int flags);
diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h
index d428e386c88e..3446f6a1d9fa 100644
--- a/arch/arm/include/asm/mcpm.h
+++ b/arch/arm/include/asm/mcpm.h
@@ -219,6 +219,23 @@ void __mcpm_outbound_leave_critical(unsigned int cluster, int state);
219bool __mcpm_outbound_enter_critical(unsigned int this_cpu, unsigned int cluster); 219bool __mcpm_outbound_enter_critical(unsigned int this_cpu, unsigned int cluster);
220int __mcpm_cluster_state(unsigned int cluster); 220int __mcpm_cluster_state(unsigned int cluster);
221 221
222/**
223 * mcpm_sync_init - Initialize the cluster synchronization support
224 *
225 * @power_up_setup: platform specific function invoked during very
226 * early CPU/cluster bringup stage.
227 *
228 * This prepares memory used by vlocks and the MCPM state machine used
229 * across CPUs that may have their caches active or inactive. Must be
230 * called only after a successful call to mcpm_platform_register().
231 *
232 * The power_up_setup argument is a pointer to assembly code called when
233 * the MMU and caches are still disabled during boot and no stack space is
234 * available. The affinity level passed to that code corresponds to the
235 * resource that needs to be initialized (e.g. 1 for cluster level, 0 for
236 * CPU level). Proper exclusion mechanisms are already activated at that
237 * point.
238 */
222int __init mcpm_sync_init( 239int __init mcpm_sync_init(
223 void (*power_up_setup)(unsigned int affinity_level)); 240 void (*power_up_setup)(unsigned int affinity_level));
224 241
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index 209e6504922e..a89b4076cde4 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -30,14 +30,14 @@ static inline void set_my_cpu_offset(unsigned long off)
30static inline unsigned long __my_cpu_offset(void) 30static inline unsigned long __my_cpu_offset(void)
31{ 31{
32 unsigned long off; 32 unsigned long off;
33 register unsigned long *sp asm ("sp");
34 33
35 /* 34 /*
36 * Read TPIDRPRW. 35 * Read TPIDRPRW.
37 * We want to allow caching the value, so avoid using volatile and 36 * We want to allow caching the value, so avoid using volatile and
38 * instead use a fake stack read to hazard against barrier(). 37 * instead use a fake stack read to hazard against barrier().
39 */ 38 */
40 asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp)); 39 asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off)
40 : "Q" (*(const unsigned long *)current_stack_pointer));
41 41
42 return off; 42 return off;
43} 43}
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 78a779361682..19cfab526d13 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -157,7 +157,15 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
157static inline void 157static inline void
158pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) 158pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
159{ 159{
160 __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE); 160 extern pmdval_t user_pmd_table;
161 pmdval_t prot;
162
163 if (__LINUX_ARM_ARCH__ >= 6 && !IS_ENABLED(CONFIG_ARM_LPAE))
164 prot = user_pmd_table;
165 else
166 prot = _PAGE_USER_TABLE;
167
168 __pmd_populate(pmdp, page_to_phys(ptep), prot);
161} 169}
162#define pmd_pgtable(pmd) pmd_page(pmd) 170#define pmd_pgtable(pmd) pmd_page(pmd)
163 171
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
index 5cfba15cb401..5e68278e953e 100644
--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -20,12 +20,14 @@
20#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) 20#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
21#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0) 21#define PMD_TYPE_TABLE (_AT(pmdval_t, 1) << 0)
22#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0) 22#define PMD_TYPE_SECT (_AT(pmdval_t, 2) << 0)
23#define PMD_PXNTABLE (_AT(pmdval_t, 1) << 2) /* v7 */
23#define PMD_BIT4 (_AT(pmdval_t, 1) << 4) 24#define PMD_BIT4 (_AT(pmdval_t, 1) << 4)
24#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5) 25#define PMD_DOMAIN(x) (_AT(pmdval_t, (x)) << 5)
25#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */ 26#define PMD_PROTECTION (_AT(pmdval_t, 1) << 9) /* v5 */
26/* 27/*
27 * - section 28 * - section
28 */ 29 */
30#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */
29#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) 31#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
30#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) 32#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
31#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */ 33#define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h b/arch/arm/include/asm/pgtable-3level-hwdef.h
index 9fd61c72a33a..f8f1cff62065 100644
--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
@@ -76,6 +76,7 @@
76#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ 76#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
77#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ 77#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
78#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */ 78#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */
79#define PTE_EXT_PXN (_AT(pteval_t, 1) << 53) /* PXN */
79#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */ 80#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */
80 81
81/* 82/*
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 3b30062975b2..d5cac545ba33 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -252,17 +252,57 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
252 set_pte_ext(ptep, pteval, ext); 252 set_pte_ext(ptep, pteval, ext);
253} 253}
254 254
255#define PTE_BIT_FUNC(fn,op) \ 255static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
256static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 256{
257 257 pte_val(pte) &= ~pgprot_val(prot);
258PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY); 258 return pte;
259PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY); 259}
260PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); 260
261PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); 261static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot)
262PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); 262{
263PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); 263 pte_val(pte) |= pgprot_val(prot);
264PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); 264 return pte;
265PTE_BIT_FUNC(mknexec, |= L_PTE_XN); 265}
266
267static inline pte_t pte_wrprotect(pte_t pte)
268{
269 return set_pte_bit(pte, __pgprot(L_PTE_RDONLY));
270}
271
272static inline pte_t pte_mkwrite(pte_t pte)
273{
274 return clear_pte_bit(pte, __pgprot(L_PTE_RDONLY));
275}
276
277static inline pte_t pte_mkclean(pte_t pte)
278{
279 return clear_pte_bit(pte, __pgprot(L_PTE_DIRTY));
280}
281
282static inline pte_t pte_mkdirty(pte_t pte)
283{
284 return set_pte_bit(pte, __pgprot(L_PTE_DIRTY));
285}
286
287static inline pte_t pte_mkold(pte_t pte)
288{
289 return clear_pte_bit(pte, __pgprot(L_PTE_YOUNG));
290}
291
292static inline pte_t pte_mkyoung(pte_t pte)
293{
294 return set_pte_bit(pte, __pgprot(L_PTE_YOUNG));
295}
296
297static inline pte_t pte_mkexec(pte_t pte)
298{
299 return clear_pte_bit(pte, __pgprot(L_PTE_XN));
300}
301
302static inline pte_t pte_mknexec(pte_t pte)
303{
304 return set_pte_bit(pte, __pgprot(L_PTE_XN));
305}
266 306
267static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 307static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
268{ 308{
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 601264d983fa..51622ba7c4a6 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -154,9 +154,8 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
154 return regs->ARM_sp; 154 return regs->ARM_sp;
155} 155}
156 156
157#define current_pt_regs(void) ({ \ 157#define current_pt_regs(void) ({ (struct pt_regs *) \
158 register unsigned long sp asm ("sp"); \ 158 ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
159 (struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1; \
160}) 159})
161 160
162#endif /* __ASSEMBLY__ */ 161#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index ce73ab635414..d890e41f5520 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -90,14 +90,19 @@ struct thread_info {
90#define init_stack (init_thread_union.stack) 90#define init_stack (init_thread_union.stack)
91 91
92/* 92/*
93 * how to get the current stack pointer in C
94 */
95register unsigned long current_stack_pointer asm ("sp");
96
97/*
93 * how to get the thread information struct from C 98 * how to get the thread information struct from C
94 */ 99 */
95static inline struct thread_info *current_thread_info(void) __attribute_const__; 100static inline struct thread_info *current_thread_info(void) __attribute_const__;
96 101
97static inline struct thread_info *current_thread_info(void) 102static inline struct thread_info *current_thread_info(void)
98{ 103{
99 register unsigned long sp asm ("sp"); 104 return (struct thread_info *)
100 return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); 105 (current_stack_pointer & ~(THREAD_SIZE - 1));
101} 106}
102 107
103#define thread_saved_pc(tsk) \ 108#define thread_saved_pc(tsk) \
diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h
index f4ab34fd4f72..ee5f3084243c 100644
--- a/arch/arm/include/asm/vfp.h
+++ b/arch/arm/include/asm/vfp.h
@@ -22,6 +22,7 @@
22#define FPSID_NODOUBLE (1<<20) 22#define FPSID_NODOUBLE (1<<20)
23#define FPSID_ARCH_BIT (16) 23#define FPSID_ARCH_BIT (16)
24#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT) 24#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT)
25#define FPSID_CPUID_ARCH_MASK (0x7F << FPSID_ARCH_BIT)
25#define FPSID_PART_BIT (8) 26#define FPSID_PART_BIT (8)
26#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT) 27#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT)
27#define FPSID_VARIANT_BIT (4) 28#define FPSID_VARIANT_BIT (4)
@@ -75,6 +76,10 @@
75/* MVFR0 bits */ 76/* MVFR0 bits */
76#define MVFR0_A_SIMD_BIT (0) 77#define MVFR0_A_SIMD_BIT (0)
77#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT) 78#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT)
79#define MVFR0_SP_BIT (4)
80#define MVFR0_SP_MASK (0xf << MVFR0_SP_BIT)
81#define MVFR0_DP_BIT (8)
82#define MVFR0_DP_MASK (0xf << MVFR0_DP_BIT)
78 83
79/* Bit patterns for decoding the packaged operation descriptors */ 84/* Bit patterns for decoding the packaged operation descriptors */
80#define VFPOPDESC_LENGTH_BIT (9) 85#define VFPOPDESC_LENGTH_BIT (9)
diff --git a/arch/arm/include/asm/xen/page-coherent.h b/arch/arm/include/asm/xen/page-coherent.h
index e8275ea88e88..efd562412850 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -5,6 +5,18 @@
5#include <linux/dma-attrs.h> 5#include <linux/dma-attrs.h>
6#include <linux/dma-mapping.h> 6#include <linux/dma-mapping.h>
7 7
8void __xen_dma_map_page(struct device *hwdev, struct page *page,
9 dma_addr_t dev_addr, unsigned long offset, size_t size,
10 enum dma_data_direction dir, struct dma_attrs *attrs);
11void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
12 size_t size, enum dma_data_direction dir,
13 struct dma_attrs *attrs);
14void __xen_dma_sync_single_for_cpu(struct device *hwdev,
15 dma_addr_t handle, size_t size, enum dma_data_direction dir);
16
17void __xen_dma_sync_single_for_device(struct device *hwdev,
18 dma_addr_t handle, size_t size, enum dma_data_direction dir);
19
8static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size, 20static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
9 dma_addr_t *dma_handle, gfp_t flags, 21 dma_addr_t *dma_handle, gfp_t flags,
10 struct dma_attrs *attrs) 22 struct dma_attrs *attrs)
@@ -20,20 +32,56 @@ static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
20} 32}
21 33
22static inline void xen_dma_map_page(struct device *hwdev, struct page *page, 34static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
23 unsigned long offset, size_t size, enum dma_data_direction dir, 35 dma_addr_t dev_addr, unsigned long offset, size_t size,
24 struct dma_attrs *attrs) 36 enum dma_data_direction dir, struct dma_attrs *attrs)
25{ 37{
26 __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs); 38 bool local = PFN_DOWN(dev_addr) == page_to_pfn(page);
39 /* Dom0 is mapped 1:1, so if pfn == mfn the page is local otherwise
40 * is a foreign page grant-mapped in dom0. If the page is local we
41 * can safely call the native dma_ops function, otherwise we call
42 * the xen specific function. */
43 if (local)
44 __generic_dma_ops(hwdev)->map_page(hwdev, page, offset, size, dir, attrs);
45 else
46 __xen_dma_map_page(hwdev, page, dev_addr, offset, size, dir, attrs);
27} 47}
28 48
29void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, 49static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
30 size_t size, enum dma_data_direction dir, 50 size_t size, enum dma_data_direction dir,
31 struct dma_attrs *attrs); 51 struct dma_attrs *attrs)
52{
53 unsigned long pfn = PFN_DOWN(handle);
54 /* Dom0 is mapped 1:1, so calling pfn_valid on a foreign mfn will
55 * always return false. If the page is local we can safely call the
56 * native dma_ops function, otherwise we call the xen specific
57 * function. */
58 if (pfn_valid(pfn)) {
59 if (__generic_dma_ops(hwdev)->unmap_page)
60 __generic_dma_ops(hwdev)->unmap_page(hwdev, handle, size, dir, attrs);
61 } else
62 __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
63}
32 64
33void xen_dma_sync_single_for_cpu(struct device *hwdev, 65static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
34 dma_addr_t handle, size_t size, enum dma_data_direction dir); 66 dma_addr_t handle, size_t size, enum dma_data_direction dir)
67{
68 unsigned long pfn = PFN_DOWN(handle);
69 if (pfn_valid(pfn)) {
70 if (__generic_dma_ops(hwdev)->sync_single_for_cpu)
71 __generic_dma_ops(hwdev)->sync_single_for_cpu(hwdev, handle, size, dir);
72 } else
73 __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
74}
35 75
36void xen_dma_sync_single_for_device(struct device *hwdev, 76static inline void xen_dma_sync_single_for_device(struct device *hwdev,
37 dma_addr_t handle, size_t size, enum dma_data_direction dir); 77 dma_addr_t handle, size_t size, enum dma_data_direction dir)
78{
79 unsigned long pfn = PFN_DOWN(handle);
80 if (pfn_valid(pfn)) {
81 if (__generic_dma_ops(hwdev)->sync_single_for_device)
82 __generic_dma_ops(hwdev)->sync_single_for_device(hwdev, handle, size, dir);
83 } else
84 __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
85}
38 86
39#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */ 87#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 135c24a5ba26..68c739b3fdf4 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -107,4 +107,8 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
107#define xen_remap(cookie, size) ioremap_cache((cookie), (size)) 107#define xen_remap(cookie, size) ioremap_cache((cookie), (size))
108#define xen_unmap(cookie) iounmap((cookie)) 108#define xen_unmap(cookie) iounmap((cookie))
109 109
110bool xen_arch_need_swiotlb(struct device *dev,
111 unsigned long pfn,
112 unsigned long mfn);
113
110#endif /* _ASM_ARM_XEN_PAGE_H */ 114#endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 8dcbed5016ac..f290ac892a95 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -47,6 +47,7 @@ endif
47obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 47obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
48obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 48obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
49obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o 49obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o
50obj-$(CONFIG_FUNCTION_TRACER) += entry-ftrace.o
50obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o 51obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
51obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o 52obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
52obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o 53obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
@@ -67,7 +68,7 @@ test-kprobes-objs += kprobes-test-arm.o
67endif 68endif
68obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 69obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
69obj-$(CONFIG_ARM_THUMBEE) += thumbee.o 70obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
70obj-$(CONFIG_KGDB) += kgdb.o 71obj-$(CONFIG_KGDB) += kgdb.o patch.o
71obj-$(CONFIG_ARM_UNWIND) += unwind.o 72obj-$(CONFIG_ARM_UNWIND) += unwind.o
72obj-$(CONFIG_HAVE_TCM) += tcm.o 73obj-$(CONFIG_HAVE_TCM) += tcm.o
73obj-$(CONFIG_OF) += devtree.o 74obj-$(CONFIG_OF) += devtree.o
@@ -84,6 +85,7 @@ obj-$(CONFIG_CPU_PJ4B) += pj4-cp0.o
84obj-$(CONFIG_IWMMXT) += iwmmxt.o 85obj-$(CONFIG_IWMMXT) += iwmmxt.o
85obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o 86obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
86obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o 87obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o
88CFLAGS_pj4-cp0.o := -marm
87AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt 89AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
88obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o 90obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
89 91
diff --git a/arch/arm/kernel/atags_compat.c b/arch/arm/kernel/atags_compat.c
index 5236ad38f417..05c28b12353c 100644
--- a/arch/arm/kernel/atags_compat.c
+++ b/arch/arm/kernel/atags_compat.c
@@ -97,8 +97,7 @@ static void __init build_tag_list(struct param_struct *params, void *taglist)
97 struct tag *tag = taglist; 97 struct tag *tag = taglist;
98 98
99 if (params->u1.s.page_size != PAGE_SIZE) { 99 if (params->u1.s.page_size != PAGE_SIZE) {
100 printk(KERN_WARNING "Warning: bad configuration page, " 100 pr_warn("Warning: bad configuration page, trying to continue\n");
101 "trying to continue\n");
102 return; 101 return;
103 } 102 }
104 103
@@ -109,8 +108,7 @@ static void __init build_tag_list(struct param_struct *params, void *taglist)
109 params->u1.s.nr_pages != 0x04000 && 108 params->u1.s.nr_pages != 0x04000 &&
110 params->u1.s.nr_pages != 0x08000 && 109 params->u1.s.nr_pages != 0x08000 &&
111 params->u1.s.nr_pages != 0x10000) { 110 params->u1.s.nr_pages != 0x10000) {
112 printk(KERN_WARNING "Warning: bad NeTTrom parameters " 111 pr_warn("Warning: bad NeTTrom parameters detected, using defaults\n");
113 "detected, using defaults\n");
114 112
115 params->u1.s.nr_pages = 0x1000; /* 16MB */ 113 params->u1.s.nr_pages = 0x1000; /* 16MB */
116 params->u1.s.ramdisk_size = 0; 114 params->u1.s.ramdisk_size = 0;
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
index 528f8af2addb..68c6ae0b9e4c 100644
--- a/arch/arm/kernel/atags_parse.c
+++ b/arch/arm/kernel/atags_parse.c
@@ -167,8 +167,7 @@ static void __init parse_tags(const struct tag *t)
167{ 167{
168 for (; t->hdr.size; t = tag_next(t)) 168 for (; t->hdr.size; t = tag_next(t))
169 if (!parse_tag(t)) 169 if (!parse_tag(t))
170 printk(KERN_WARNING 170 pr_warn("Ignoring unrecognised tag 0x%08x\n",
171 "Ignoring unrecognised tag 0x%08x\n",
172 t->hdr.tag); 171 t->hdr.tag);
173} 172}
174 173
@@ -193,7 +192,7 @@ setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
193 */ 192 */
194 for_each_machine_desc(p) 193 for_each_machine_desc(p)
195 if (machine_nr == p->nr) { 194 if (machine_nr == p->nr) {
196 printk("Machine: %s\n", p->name); 195 pr_info("Machine: %s\n", p->name);
197 mdesc = p; 196 mdesc = p;
198 break; 197 break;
199 } 198 }
diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c
index c7ff8073416f..5a3379055f55 100644
--- a/arch/arm/kernel/atags_proc.c
+++ b/arch/arm/kernel/atags_proc.c
@@ -41,7 +41,7 @@ static int __init init_atags_procfs(void)
41 size_t size; 41 size_t size;
42 42
43 if (tag->hdr.tag != ATAG_CORE) { 43 if (tag->hdr.tag != ATAG_CORE) {
44 printk(KERN_INFO "No ATAGs?"); 44 pr_info("No ATAGs?");
45 return -EINVAL; 45 return -EINVAL;
46 } 46 }
47 47
@@ -68,7 +68,7 @@ static int __init init_atags_procfs(void)
68 68
69nomem: 69nomem:
70 kfree(b); 70 kfree(b);
71 printk(KERN_ERR "Exporting ATAGs: not enough memory\n"); 71 pr_err("Exporting ATAGs: not enough memory\n");
72 72
73 return -ENOMEM; 73 return -ENOMEM;
74} 74}
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index daaff73bc776..a4effd6d8f2f 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -364,7 +364,7 @@ void pcibios_fixup_bus(struct pci_bus *bus)
364 /* 364 /*
365 * Report what we did for this bus 365 * Report what we did for this bus
366 */ 366 */
367 printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", 367 pr_info("PCI: bus%d: Fast back to back transfers %sabled\n",
368 bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); 368 bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
369} 369}
370EXPORT_SYMBOL(pcibios_fixup_bus); 370EXPORT_SYMBOL(pcibios_fixup_bus);
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 360bb6d701f5..84363fe7bad2 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -213,8 +213,8 @@ void __init isa_init_dma(void)
213 for (chan = 0; chan < 8; chan++) { 213 for (chan = 0; chan < 8; chan++) {
214 int ret = isa_dma_add(chan, &isa_dma[chan]); 214 int ret = isa_dma_add(chan, &isa_dma[chan]);
215 if (ret) 215 if (ret)
216 printk(KERN_ERR "ISADMA%u: unable to register: %d\n", 216 pr_err("ISADMA%u: unable to register: %d\n",
217 chan, ret); 217 chan, ret);
218 } 218 }
219 219
220 request_dma(DMA_ISA_CASCADE, "cascade"); 220 request_dma(DMA_ISA_CASCADE, "cascade");
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 7b829d9663b1..e651c4d0a0d9 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -79,7 +79,7 @@ int request_dma(unsigned int chan, const char *device_id)
79 return ret; 79 return ret;
80 80
81bad_dma: 81bad_dma:
82 printk(KERN_ERR "dma: trying to allocate DMA%d\n", chan); 82 pr_err("dma: trying to allocate DMA%d\n", chan);
83 return -EINVAL; 83 return -EINVAL;
84 84
85busy: 85busy:
@@ -100,7 +100,7 @@ void free_dma(unsigned int chan)
100 goto bad_dma; 100 goto bad_dma;
101 101
102 if (dma->active) { 102 if (dma->active) {
103 printk(KERN_ERR "dma%d: freeing active DMA\n", chan); 103 pr_err("dma%d: freeing active DMA\n", chan);
104 dma->d_ops->disable(chan, dma); 104 dma->d_ops->disable(chan, dma);
105 dma->active = 0; 105 dma->active = 0;
106 } 106 }
@@ -111,11 +111,11 @@ void free_dma(unsigned int chan)
111 return; 111 return;
112 } 112 }
113 113
114 printk(KERN_ERR "dma%d: trying to free free DMA\n", chan); 114 pr_err("dma%d: trying to free free DMA\n", chan);
115 return; 115 return;
116 116
117bad_dma: 117bad_dma:
118 printk(KERN_ERR "dma: trying to free DMA%d\n", chan); 118 pr_err("dma: trying to free DMA%d\n", chan);
119} 119}
120EXPORT_SYMBOL(free_dma); 120EXPORT_SYMBOL(free_dma);
121 121
@@ -126,8 +126,7 @@ void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg)
126 dma_t *dma = dma_channel(chan); 126 dma_t *dma = dma_channel(chan);
127 127
128 if (dma->active) 128 if (dma->active)
129 printk(KERN_ERR "dma%d: altering DMA SG while " 129 pr_err("dma%d: altering DMA SG while DMA active\n", chan);
130 "DMA active\n", chan);
131 130
132 dma->sg = sg; 131 dma->sg = sg;
133 dma->sgcount = nr_sg; 132 dma->sgcount = nr_sg;
@@ -144,8 +143,7 @@ void __set_dma_addr (unsigned int chan, void *addr)
144 dma_t *dma = dma_channel(chan); 143 dma_t *dma = dma_channel(chan);
145 144
146 if (dma->active) 145 if (dma->active)
147 printk(KERN_ERR "dma%d: altering DMA address while " 146 pr_err("dma%d: altering DMA address while DMA active\n", chan);
148 "DMA active\n", chan);
149 147
150 dma->sg = NULL; 148 dma->sg = NULL;
151 dma->addr = addr; 149 dma->addr = addr;
@@ -162,8 +160,7 @@ void set_dma_count (unsigned int chan, unsigned long count)
162 dma_t *dma = dma_channel(chan); 160 dma_t *dma = dma_channel(chan);
163 161
164 if (dma->active) 162 if (dma->active)
165 printk(KERN_ERR "dma%d: altering DMA count while " 163 pr_err("dma%d: altering DMA count while DMA active\n", chan);
166 "DMA active\n", chan);
167 164
168 dma->sg = NULL; 165 dma->sg = NULL;
169 dma->count = count; 166 dma->count = count;
@@ -178,8 +175,7 @@ void set_dma_mode (unsigned int chan, unsigned int mode)
178 dma_t *dma = dma_channel(chan); 175 dma_t *dma = dma_channel(chan);
179 176
180 if (dma->active) 177 if (dma->active)
181 printk(KERN_ERR "dma%d: altering DMA mode while " 178 pr_err("dma%d: altering DMA mode while DMA active\n", chan);
182 "DMA active\n", chan);
183 179
184 dma->dma_mode = mode; 180 dma->dma_mode = mode;
185 dma->invalid = 1; 181 dma->invalid = 1;
@@ -202,7 +198,7 @@ void enable_dma (unsigned int chan)
202 return; 198 return;
203 199
204free_dma: 200free_dma:
205 printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan); 201 pr_err("dma%d: trying to enable free DMA\n", chan);
206 BUG(); 202 BUG();
207} 203}
208EXPORT_SYMBOL(enable_dma); 204EXPORT_SYMBOL(enable_dma);
@@ -223,7 +219,7 @@ void disable_dma (unsigned int chan)
223 return; 219 return;
224 220
225free_dma: 221free_dma:
226 printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan); 222 pr_err("dma%d: trying to disable free DMA\n", chan);
227 BUG(); 223 BUG();
228} 224}
229EXPORT_SYMBOL(disable_dma); 225EXPORT_SYMBOL(disable_dma);
@@ -240,7 +236,7 @@ EXPORT_SYMBOL(dma_channel_active);
240 236
241void set_dma_page(unsigned int chan, char pagenr) 237void set_dma_page(unsigned int chan, char pagenr)
242{ 238{
243 printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan); 239 pr_err("dma%d: trying to set_dma_page\n", chan);
244} 240}
245EXPORT_SYMBOL(set_dma_page); 241EXPORT_SYMBOL(set_dma_page);
246 242
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 6bb09d4abdea..f8ccc21fa032 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -109,241 +109,6 @@ ENDPROC(ret_from_fork)
109#undef CALL 109#undef CALL
110#define CALL(x) .long x 110#define CALL(x) .long x
111 111
112#ifdef CONFIG_FUNCTION_TRACER
113/*
114 * When compiling with -pg, gcc inserts a call to the mcount routine at the
115 * start of every function. In mcount, apart from the function's address (in
116 * lr), we need to get hold of the function's caller's address.
117 *
118 * Older GCCs (pre-4.4) inserted a call to a routine called mcount like this:
119 *
120 * bl mcount
121 *
122 * These versions have the limitation that in order for the mcount routine to
123 * be able to determine the function's caller's address, an APCS-style frame
124 * pointer (which is set up with something like the code below) is required.
125 *
126 * mov ip, sp
127 * push {fp, ip, lr, pc}
128 * sub fp, ip, #4
129 *
130 * With EABI, these frame pointers are not available unless -mapcs-frame is
131 * specified, and if building as Thumb-2, not even then.
132 *
133 * Newer GCCs (4.4+) solve this problem by introducing a new version of mcount,
134 * with call sites like:
135 *
136 * push {lr}
137 * bl __gnu_mcount_nc
138 *
139 * With these compilers, frame pointers are not necessary.
140 *
141 * mcount can be thought of as a function called in the middle of a subroutine
142 * call. As such, it needs to be transparent for both the caller and the
143 * callee: the original lr needs to be restored when leaving mcount, and no
144 * registers should be clobbered. (In the __gnu_mcount_nc implementation, we
145 * clobber the ip register. This is OK because the ARM calling convention
146 * allows it to be clobbered in subroutines and doesn't use it to hold
147 * parameters.)
148 *
149 * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
150 * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
151 * arch/arm/kernel/ftrace.c).
152 */
153
154#ifndef CONFIG_OLD_MCOUNT
155#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
156#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
157#endif
158#endif
159
160.macro mcount_adjust_addr rd, rn
161 bic \rd, \rn, #1 @ clear the Thumb bit if present
162 sub \rd, \rd, #MCOUNT_INSN_SIZE
163.endm
164
165.macro __mcount suffix
166 mcount_enter
167 ldr r0, =ftrace_trace_function
168 ldr r2, [r0]
169 adr r0, .Lftrace_stub
170 cmp r0, r2
171 bne 1f
172
173#ifdef CONFIG_FUNCTION_GRAPH_TRACER
174 ldr r1, =ftrace_graph_return
175 ldr r2, [r1]
176 cmp r0, r2
177 bne ftrace_graph_caller\suffix
178
179 ldr r1, =ftrace_graph_entry
180 ldr r2, [r1]
181 ldr r0, =ftrace_graph_entry_stub
182 cmp r0, r2
183 bne ftrace_graph_caller\suffix
184#endif
185
186 mcount_exit
187
1881: mcount_get_lr r1 @ lr of instrumented func
189 mcount_adjust_addr r0, lr @ instrumented function
190 adr lr, BSYM(2f)
191 mov pc, r2
1922: mcount_exit
193.endm
194
195.macro __ftrace_caller suffix
196 mcount_enter
197
198 mcount_get_lr r1 @ lr of instrumented func
199 mcount_adjust_addr r0, lr @ instrumented function
200
201 .globl ftrace_call\suffix
202ftrace_call\suffix:
203 bl ftrace_stub
204
205#ifdef CONFIG_FUNCTION_GRAPH_TRACER
206 .globl ftrace_graph_call\suffix
207ftrace_graph_call\suffix:
208 mov r0, r0
209#endif
210
211 mcount_exit
212.endm
213
214.macro __ftrace_graph_caller
215 sub r0, fp, #4 @ &lr of instrumented routine (&parent)
216#ifdef CONFIG_DYNAMIC_FTRACE
217 @ called from __ftrace_caller, saved in mcount_enter
218 ldr r1, [sp, #16] @ instrumented routine (func)
219 mcount_adjust_addr r1, r1
220#else
221 @ called from __mcount, untouched in lr
222 mcount_adjust_addr r1, lr @ instrumented routine (func)
223#endif
224 mov r2, fp @ frame pointer
225 bl prepare_ftrace_return
226 mcount_exit
227.endm
228
229#ifdef CONFIG_OLD_MCOUNT
230/*
231 * mcount
232 */
233
234.macro mcount_enter
235 stmdb sp!, {r0-r3, lr}
236.endm
237
238.macro mcount_get_lr reg
239 ldr \reg, [fp, #-4]
240.endm
241
242.macro mcount_exit
243 ldr lr, [fp, #-4]
244 ldmia sp!, {r0-r3, pc}
245.endm
246
247ENTRY(mcount)
248#ifdef CONFIG_DYNAMIC_FTRACE
249 stmdb sp!, {lr}
250 ldr lr, [fp, #-4]
251 ldmia sp!, {pc}
252#else
253 __mcount _old
254#endif
255ENDPROC(mcount)
256
257#ifdef CONFIG_DYNAMIC_FTRACE
258ENTRY(ftrace_caller_old)
259 __ftrace_caller _old
260ENDPROC(ftrace_caller_old)
261#endif
262
263#ifdef CONFIG_FUNCTION_GRAPH_TRACER
264ENTRY(ftrace_graph_caller_old)
265 __ftrace_graph_caller
266ENDPROC(ftrace_graph_caller_old)
267#endif
268
269.purgem mcount_enter
270.purgem mcount_get_lr
271.purgem mcount_exit
272#endif
273
274/*
275 * __gnu_mcount_nc
276 */
277
278.macro mcount_enter
279/*
280 * This pad compensates for the push {lr} at the call site. Note that we are
281 * unable to unwind through a function which does not otherwise save its lr.
282 */
283 UNWIND(.pad #4)
284 stmdb sp!, {r0-r3, lr}
285 UNWIND(.save {r0-r3, lr})
286.endm
287
288.macro mcount_get_lr reg
289 ldr \reg, [sp, #20]
290.endm
291
292.macro mcount_exit
293 ldmia sp!, {r0-r3, ip, lr}
294 ret ip
295.endm
296
297ENTRY(__gnu_mcount_nc)
298UNWIND(.fnstart)
299#ifdef CONFIG_DYNAMIC_FTRACE
300 mov ip, lr
301 ldmia sp!, {lr}
302 ret ip
303#else
304 __mcount
305#endif
306UNWIND(.fnend)
307ENDPROC(__gnu_mcount_nc)
308
309#ifdef CONFIG_DYNAMIC_FTRACE
310ENTRY(ftrace_caller)
311UNWIND(.fnstart)
312 __ftrace_caller
313UNWIND(.fnend)
314ENDPROC(ftrace_caller)
315#endif
316
317#ifdef CONFIG_FUNCTION_GRAPH_TRACER
318ENTRY(ftrace_graph_caller)
319UNWIND(.fnstart)
320 __ftrace_graph_caller
321UNWIND(.fnend)
322ENDPROC(ftrace_graph_caller)
323#endif
324
325.purgem mcount_enter
326.purgem mcount_get_lr
327.purgem mcount_exit
328
329#ifdef CONFIG_FUNCTION_GRAPH_TRACER
330 .globl return_to_handler
331return_to_handler:
332 stmdb sp!, {r0-r3}
333 mov r0, fp @ frame pointer
334 bl ftrace_return_to_handler
335 mov lr, r0 @ r0 has real ret addr
336 ldmia sp!, {r0-r3}
337 ret lr
338#endif
339
340ENTRY(ftrace_stub)
341.Lftrace_stub:
342 ret lr
343ENDPROC(ftrace_stub)
344
345#endif /* CONFIG_FUNCTION_TRACER */
346
347/*============================================================================= 112/*=============================================================================
348 * SWI handler 113 * SWI handler
349 *----------------------------------------------------------------------------- 114 *-----------------------------------------------------------------------------
diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
new file mode 100644
index 000000000000..fe57c73e70a4
--- /dev/null
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -0,0 +1,243 @@
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 version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#include <asm/assembler.h>
8#include <asm/ftrace.h>
9#include <asm/unwind.h>
10
11#include "entry-header.S"
12
13/*
14 * When compiling with -pg, gcc inserts a call to the mcount routine at the
15 * start of every function. In mcount, apart from the function's address (in
16 * lr), we need to get hold of the function's caller's address.
17 *
18 * Older GCCs (pre-4.4) inserted a call to a routine called mcount like this:
19 *
20 * bl mcount
21 *
22 * These versions have the limitation that in order for the mcount routine to
23 * be able to determine the function's caller's address, an APCS-style frame
24 * pointer (which is set up with something like the code below) is required.
25 *
26 * mov ip, sp
27 * push {fp, ip, lr, pc}
28 * sub fp, ip, #4
29 *
30 * With EABI, these frame pointers are not available unless -mapcs-frame is
31 * specified, and if building as Thumb-2, not even then.
32 *
33 * Newer GCCs (4.4+) solve this problem by introducing a new version of mcount,
34 * with call sites like:
35 *
36 * push {lr}
37 * bl __gnu_mcount_nc
38 *
39 * With these compilers, frame pointers are not necessary.
40 *
41 * mcount can be thought of as a function called in the middle of a subroutine
42 * call. As such, it needs to be transparent for both the caller and the
43 * callee: the original lr needs to be restored when leaving mcount, and no
44 * registers should be clobbered. (In the __gnu_mcount_nc implementation, we
45 * clobber the ip register. This is OK because the ARM calling convention
46 * allows it to be clobbered in subroutines and doesn't use it to hold
47 * parameters.)
48 *
49 * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
50 * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
51 * arch/arm/kernel/ftrace.c).
52 */
53
54#ifndef CONFIG_OLD_MCOUNT
55#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
56#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
57#endif
58#endif
59
60.macro mcount_adjust_addr rd, rn
61 bic \rd, \rn, #1 @ clear the Thumb bit if present
62 sub \rd, \rd, #MCOUNT_INSN_SIZE
63.endm
64
65.macro __mcount suffix
66 mcount_enter
67 ldr r0, =ftrace_trace_function
68 ldr r2, [r0]
69 adr r0, .Lftrace_stub
70 cmp r0, r2
71 bne 1f
72
73#ifdef CONFIG_FUNCTION_GRAPH_TRACER
74 ldr r1, =ftrace_graph_return
75 ldr r2, [r1]
76 cmp r0, r2
77 bne ftrace_graph_caller\suffix
78
79 ldr r1, =ftrace_graph_entry
80 ldr r2, [r1]
81 ldr r0, =ftrace_graph_entry_stub
82 cmp r0, r2
83 bne ftrace_graph_caller\suffix
84#endif
85
86 mcount_exit
87
881: mcount_get_lr r1 @ lr of instrumented func
89 mcount_adjust_addr r0, lr @ instrumented function
90 adr lr, BSYM(2f)
91 mov pc, r2
922: mcount_exit
93.endm
94
95.macro __ftrace_caller suffix
96 mcount_enter
97
98 mcount_get_lr r1 @ lr of instrumented func
99 mcount_adjust_addr r0, lr @ instrumented function
100
101 .globl ftrace_call\suffix
102ftrace_call\suffix:
103 bl ftrace_stub
104
105#ifdef CONFIG_FUNCTION_GRAPH_TRACER
106 .globl ftrace_graph_call\suffix
107ftrace_graph_call\suffix:
108 mov r0, r0
109#endif
110
111 mcount_exit
112.endm
113
114.macro __ftrace_graph_caller
115 sub r0, fp, #4 @ &lr of instrumented routine (&parent)
116#ifdef CONFIG_DYNAMIC_FTRACE
117 @ called from __ftrace_caller, saved in mcount_enter
118 ldr r1, [sp, #16] @ instrumented routine (func)
119 mcount_adjust_addr r1, r1
120#else
121 @ called from __mcount, untouched in lr
122 mcount_adjust_addr r1, lr @ instrumented routine (func)
123#endif
124 mov r2, fp @ frame pointer
125 bl prepare_ftrace_return
126 mcount_exit
127.endm
128
129#ifdef CONFIG_OLD_MCOUNT
130/*
131 * mcount
132 */
133
134.macro mcount_enter
135 stmdb sp!, {r0-r3, lr}
136.endm
137
138.macro mcount_get_lr reg
139 ldr \reg, [fp, #-4]
140.endm
141
142.macro mcount_exit
143 ldr lr, [fp, #-4]
144 ldmia sp!, {r0-r3, pc}
145.endm
146
147ENTRY(mcount)
148#ifdef CONFIG_DYNAMIC_FTRACE
149 stmdb sp!, {lr}
150 ldr lr, [fp, #-4]
151 ldmia sp!, {pc}
152#else
153 __mcount _old
154#endif
155ENDPROC(mcount)
156
157#ifdef CONFIG_DYNAMIC_FTRACE
158ENTRY(ftrace_caller_old)
159 __ftrace_caller _old
160ENDPROC(ftrace_caller_old)
161#endif
162
163#ifdef CONFIG_FUNCTION_GRAPH_TRACER
164ENTRY(ftrace_graph_caller_old)
165 __ftrace_graph_caller
166ENDPROC(ftrace_graph_caller_old)
167#endif
168
169.purgem mcount_enter
170.purgem mcount_get_lr
171.purgem mcount_exit
172#endif
173
174/*
175 * __gnu_mcount_nc
176 */
177
178.macro mcount_enter
179/*
180 * This pad compensates for the push {lr} at the call site. Note that we are
181 * unable to unwind through a function which does not otherwise save its lr.
182 */
183 UNWIND(.pad #4)
184 stmdb sp!, {r0-r3, lr}
185 UNWIND(.save {r0-r3, lr})
186.endm
187
188.macro mcount_get_lr reg
189 ldr \reg, [sp, #20]
190.endm
191
192.macro mcount_exit
193 ldmia sp!, {r0-r3, ip, lr}
194 ret ip
195.endm
196
197ENTRY(__gnu_mcount_nc)
198UNWIND(.fnstart)
199#ifdef CONFIG_DYNAMIC_FTRACE
200 mov ip, lr
201 ldmia sp!, {lr}
202 ret ip
203#else
204 __mcount
205#endif
206UNWIND(.fnend)
207ENDPROC(__gnu_mcount_nc)
208
209#ifdef CONFIG_DYNAMIC_FTRACE
210ENTRY(ftrace_caller)
211UNWIND(.fnstart)
212 __ftrace_caller
213UNWIND(.fnend)
214ENDPROC(ftrace_caller)
215#endif
216
217#ifdef CONFIG_FUNCTION_GRAPH_TRACER
218ENTRY(ftrace_graph_caller)
219UNWIND(.fnstart)
220 __ftrace_graph_caller
221UNWIND(.fnend)
222ENDPROC(ftrace_graph_caller)
223#endif
224
225.purgem mcount_enter
226.purgem mcount_get_lr
227.purgem mcount_exit
228
229#ifdef CONFIG_FUNCTION_GRAPH_TRACER
230 .globl return_to_handler
231return_to_handler:
232 stmdb sp!, {r0-r3}
233 mov r0, fp @ frame pointer
234 bl ftrace_return_to_handler
235 mov lr, r0 @ r0 has real ret addr
236 ldmia sp!, {r0-r3}
237 ret lr
238#endif
239
240ENTRY(ftrace_stub)
241.Lftrace_stub:
242 ret lr
243ENDPROC(ftrace_stub)
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 131a6ab5f355..8b96972dcb1d 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -213,7 +213,7 @@ static void etm_dump(void)
213 int length; 213 int length;
214 214
215 if (!t->etb_regs) { 215 if (!t->etb_regs) {
216 printk(KERN_INFO "No tracing hardware found\n"); 216 pr_info("No tracing hardware found\n");
217 return; 217 return;
218 } 218 }
219 219
@@ -229,11 +229,11 @@ static void etm_dump(void)
229 229
230 etb_writel(t, first, ETBR_READADDR); 230 etb_writel(t, first, ETBR_READADDR);
231 231
232 printk(KERN_INFO "Trace buffer contents length: %d\n", length); 232 pr_info("Trace buffer contents length: %d\n", length);
233 printk(KERN_INFO "--- ETB buffer begin ---\n"); 233 pr_info("--- ETB buffer begin ---\n");
234 for (; length; length--) 234 for (; length; length--)
235 printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM))); 235 printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
236 printk(KERN_INFO "\n--- ETB buffer end ---\n"); 236 pr_info("\n--- ETB buffer end ---\n");
237 237
238 /* deassert the overflow bit */ 238 /* deassert the overflow bit */
239 etb_writel(t, 1, ETBR_CTRL); 239 etb_writel(t, 1, ETBR_CTRL);
@@ -633,14 +633,14 @@ static int __init etm_init(void)
633 633
634 retval = amba_driver_register(&etb_driver); 634 retval = amba_driver_register(&etb_driver);
635 if (retval) { 635 if (retval) {
636 printk(KERN_ERR "Failed to register etb\n"); 636 pr_err("Failed to register etb\n");
637 return retval; 637 return retval;
638 } 638 }
639 639
640 retval = amba_driver_register(&etm_driver); 640 retval = amba_driver_register(&etm_driver);
641 if (retval) { 641 if (retval) {
642 amba_driver_unregister(&etb_driver); 642 amba_driver_unregister(&etb_driver);
643 printk(KERN_ERR "Failed to probe etm\n"); 643 pr_err("Failed to probe etm\n");
644 return retval; 644 return retval;
645 } 645 }
646 646
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index b37752a96652..059c3da0fee3 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -124,7 +124,7 @@ int claim_fiq(struct fiq_handler *f)
124void release_fiq(struct fiq_handler *f) 124void release_fiq(struct fiq_handler *f)
125{ 125{
126 if (current_fiq != f) { 126 if (current_fiq != f) {
127 printk(KERN_ERR "%s FIQ trying to release %s FIQ\n", 127 pr_err("%s FIQ trying to release %s FIQ\n",
128 f->name, current_fiq->name); 128 f->name, current_fiq->name);
129 dump_stack(); 129 dump_stack();
130 return; 130 return;
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index af9a8a927a4e..b8c75e45a950 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -15,6 +15,7 @@
15#include <linux/ftrace.h> 15#include <linux/ftrace.h>
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/stop_machine.h>
18 19
19#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
20#include <asm/opcodes.h> 21#include <asm/opcodes.h>
@@ -35,6 +36,22 @@
35 36
36#define OLD_NOP 0xe1a00000 /* mov r0, r0 */ 37#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
37 38
39static int __ftrace_modify_code(void *data)
40{
41 int *command = data;
42
43 set_kernel_text_rw();
44 ftrace_modify_all_code(*command);
45 set_kernel_text_ro();
46
47 return 0;
48}
49
50void arch_ftrace_update_code(int command)
51{
52 stop_machine(__ftrace_modify_code, &command, NULL);
53}
54
38static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec) 55static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
39{ 56{
40 return rec->arch.old_mcount ? OLD_NOP : NOP; 57 return rec->arch.old_mcount ? OLD_NOP : NOP;
@@ -73,6 +90,8 @@ int ftrace_arch_code_modify_prepare(void)
73int ftrace_arch_code_modify_post_process(void) 90int ftrace_arch_code_modify_post_process(void)
74{ 91{
75 set_all_modules_text_ro(); 92 set_all_modules_text_ro();
93 /* Make sure any TLB misses during machine stop are cleared. */
94 flush_tlb_all();
76 return 0; 95 return 0;
77} 96}
78 97
diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c
index 9203cf883330..eedefe050022 100644
--- a/arch/arm/kernel/io.c
+++ b/arch/arm/kernel/io.c
@@ -51,6 +51,7 @@ void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
51 from++; 51 from++;
52 } 52 }
53} 53}
54EXPORT_SYMBOL(_memcpy_fromio);
54 55
55/* 56/*
56 * Copy data from "real" memory space to IO memory space. 57 * Copy data from "real" memory space to IO memory space.
@@ -66,6 +67,7 @@ void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
66 to++; 67 to++;
67 } 68 }
68} 69}
70EXPORT_SYMBOL(_memcpy_toio);
69 71
70/* 72/*
71 * "memset" on IO memory space. 73 * "memset" on IO memory space.
@@ -79,7 +81,4 @@ void _memset_io(volatile void __iomem *dst, int c, size_t count)
79 dst++; 81 dst++;
80 } 82 }
81} 83}
82
83EXPORT_SYMBOL(_memcpy_fromio);
84EXPORT_SYMBOL(_memcpy_toio);
85EXPORT_SYMBOL(_memset_io); 84EXPORT_SYMBOL(_memset_io);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 7c81ec428b9b..ad857bada96c 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -31,6 +31,7 @@
31#include <linux/smp.h> 31#include <linux/smp.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/ratelimit.h>
34#include <linux/errno.h> 35#include <linux/errno.h>
35#include <linux/list.h> 36#include <linux/list.h>
36#include <linux/kallsyms.h> 37#include <linux/kallsyms.h>
@@ -82,7 +83,7 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
82 unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; 83 unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
83 84
84 if (irq >= nr_irqs) { 85 if (irq >= nr_irqs) {
85 printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); 86 pr_err("Trying to set irq flags for IRQ%d\n", irq);
86 return; 87 return;
87 } 88 }
88 89
@@ -135,7 +136,6 @@ int __init arch_probe_nr_irqs(void)
135#endif 136#endif
136 137
137#ifdef CONFIG_HOTPLUG_CPU 138#ifdef CONFIG_HOTPLUG_CPU
138
139static bool migrate_one_irq(struct irq_desc *desc) 139static bool migrate_one_irq(struct irq_desc *desc)
140{ 140{
141 struct irq_data *d = irq_desc_get_irq_data(desc); 141 struct irq_data *d = irq_desc_get_irq_data(desc);
@@ -187,8 +187,8 @@ void migrate_irqs(void)
187 affinity_broken = migrate_one_irq(desc); 187 affinity_broken = migrate_one_irq(desc);
188 raw_spin_unlock(&desc->lock); 188 raw_spin_unlock(&desc->lock);
189 189
190 if (affinity_broken && printk_ratelimit()) 190 if (affinity_broken)
191 pr_warn("IRQ%u no longer affine to CPU%u\n", 191 pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n",
192 i, smp_processor_id()); 192 i, smp_processor_id());
193 } 193 }
194 194
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index ad58e565fe98..49fadbda8c63 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -58,6 +58,7 @@
58#define MMX_SIZE (0x98) 58#define MMX_SIZE (0x98)
59 59
60 .text 60 .text
61 .arm
61 62
62/* 63/*
63 * Lazy switching of Concan coprocessor context 64 * Lazy switching of Concan coprocessor context
@@ -182,6 +183,8 @@ concan_load:
182 tmcr wCon, r2 183 tmcr wCon, r2
183 ret lr 184 ret lr
184 185
186ENDPROC(iwmmxt_task_enable)
187
185/* 188/*
186 * Back up Concan regs to save area and disable access to them 189 * Back up Concan regs to save area and disable access to them
187 * (mainly for gdb or sleep mode usage) 190 * (mainly for gdb or sleep mode usage)
@@ -232,6 +235,8 @@ ENTRY(iwmmxt_task_disable)
2321: msr cpsr_c, ip @ restore interrupt mode 2351: msr cpsr_c, ip @ restore interrupt mode
233 ldmfd sp!, {r4, pc} 236 ldmfd sp!, {r4, pc}
234 237
238ENDPROC(iwmmxt_task_disable)
239
235/* 240/*
236 * Copy Concan state to given memory address 241 * Copy Concan state to given memory address
237 * 242 *
@@ -268,6 +273,8 @@ ENTRY(iwmmxt_task_copy)
268 msr cpsr_c, ip @ restore interrupt mode 273 msr cpsr_c, ip @ restore interrupt mode
269 ret r3 274 ret r3
270 275
276ENDPROC(iwmmxt_task_copy)
277
271/* 278/*
272 * Restore Concan state from given memory address 279 * Restore Concan state from given memory address
273 * 280 *
@@ -304,6 +311,8 @@ ENTRY(iwmmxt_task_restore)
304 msr cpsr_c, ip @ restore interrupt mode 311 msr cpsr_c, ip @ restore interrupt mode
305 ret r3 312 ret r3
306 313
314ENDPROC(iwmmxt_task_restore)
315
307/* 316/*
308 * Concan handling on task switch 317 * Concan handling on task switch
309 * 318 *
@@ -335,6 +344,8 @@ ENTRY(iwmmxt_task_switch)
335 mrc p15, 0, r1, c2, c0, 0 344 mrc p15, 0, r1, c2, c0, 0
336 sub pc, lr, r1, lsr #32 @ cpwait and return 345 sub pc, lr, r1, lsr #32 @ cpwait and return
337 346
347ENDPROC(iwmmxt_task_switch)
348
338/* 349/*
339 * Remove Concan ownership of given task 350 * Remove Concan ownership of given task
340 * 351 *
@@ -353,6 +364,8 @@ ENTRY(iwmmxt_task_release)
353 msr cpsr_c, r2 @ restore interrupts 364 msr cpsr_c, r2 @ restore interrupts
354 ret lr 365 ret lr
355 366
367ENDPROC(iwmmxt_task_release)
368
356 .data 369 .data
357concan_owner: 370concan_owner:
358 .word 0 371 .word 0
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
index 4ce4f789446d..afeeb9ea6f43 100644
--- a/arch/arm/kernel/jump_label.c
+++ b/arch/arm/kernel/jump_label.c
@@ -19,7 +19,7 @@ static void __arch_jump_label_transform(struct jump_entry *entry,
19 insn = arm_gen_nop(); 19 insn = arm_gen_nop();
20 20
21 if (is_static) 21 if (is_static)
22 __patch_text(addr, insn); 22 __patch_text_early(addr, insn);
23 else 23 else
24 patch_text(addr, insn); 24 patch_text(addr, insn);
25} 25}
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index a74b53c1b7df..07db2f8a1b45 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -12,8 +12,12 @@
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <linux/kdebug.h> 13#include <linux/kdebug.h>
14#include <linux/kgdb.h> 14#include <linux/kgdb.h>
15#include <linux/uaccess.h>
16
15#include <asm/traps.h> 17#include <asm/traps.h>
16 18
19#include "patch.h"
20
17struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = 21struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
18{ 22{
19 { "r0", 4, offsetof(struct pt_regs, ARM_r0)}, 23 { "r0", 4, offsetof(struct pt_regs, ARM_r0)},
@@ -244,6 +248,31 @@ void kgdb_arch_exit(void)
244 unregister_die_notifier(&kgdb_notifier); 248 unregister_die_notifier(&kgdb_notifier);
245} 249}
246 250
251int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
252{
253 int err;
254
255 /* patch_text() only supports int-sized breakpoints */
256 BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE);
257
258 err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
259 BREAK_INSTR_SIZE);
260 if (err)
261 return err;
262
263 patch_text((void *)bpt->bpt_addr,
264 *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
265
266 return err;
267}
268
269int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
270{
271 patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
272
273 return 0;
274}
275
247/* 276/*
248 * Register our undef instruction hooks with ARM undef core. 277 * Register our undef instruction hooks with ARM undef core.
249 * We regsiter a hook specifically looking for the KGB break inst 278 * We regsiter a hook specifically looking for the KGB break inst
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 8cf0996aa1a8..de2b085ad753 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -29,6 +29,7 @@ extern unsigned long kexec_boot_atags;
29 29
30static atomic_t waiting_for_crash_ipi; 30static atomic_t waiting_for_crash_ipi;
31 31
32static unsigned long dt_mem;
32/* 33/*
33 * Provide a dummy crash_notes definition while crash dump arrives to arm. 34 * Provide a dummy crash_notes definition while crash dump arrives to arm.
34 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. 35 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -64,7 +65,7 @@ int machine_kexec_prepare(struct kimage *image)
64 return err; 65 return err;
65 66
66 if (be32_to_cpu(header) == OF_DT_HEADER) 67 if (be32_to_cpu(header) == OF_DT_HEADER)
67 kexec_boot_atags = current_segment->mem; 68 dt_mem = current_segment->mem;
68 } 69 }
69 return 0; 70 return 0;
70} 71}
@@ -126,12 +127,12 @@ void machine_crash_shutdown(struct pt_regs *regs)
126 msecs--; 127 msecs--;
127 } 128 }
128 if (atomic_read(&waiting_for_crash_ipi) > 0) 129 if (atomic_read(&waiting_for_crash_ipi) > 0)
129 printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); 130 pr_warn("Non-crashing CPUs did not react to IPI\n");
130 131
131 crash_save_cpu(regs, smp_processor_id()); 132 crash_save_cpu(regs, smp_processor_id());
132 machine_kexec_mask_interrupts(); 133 machine_kexec_mask_interrupts();
133 134
134 printk(KERN_INFO "Loading crashdump kernel...\n"); 135 pr_info("Loading crashdump kernel...\n");
135} 136}
136 137
137/* 138/*
@@ -163,12 +164,12 @@ void machine_kexec(struct kimage *image)
163 reboot_code_buffer = page_address(image->control_code_page); 164 reboot_code_buffer = page_address(image->control_code_page);
164 165
165 /* Prepare parameters for reboot_code_buffer*/ 166 /* Prepare parameters for reboot_code_buffer*/
167 set_kernel_text_rw();
166 kexec_start_address = image->start; 168 kexec_start_address = image->start;
167 kexec_indirection_page = page_list; 169 kexec_indirection_page = page_list;
168 kexec_mach_type = machine_arch_type; 170 kexec_mach_type = machine_arch_type;
169 if (!kexec_boot_atags) 171 kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET
170 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; 172 + KEXEC_ARM_ATAGS_OFFSET;
171
172 173
173 /* copy our kernel relocation code to the control code page */ 174 /* copy our kernel relocation code to the control code page */
174 reboot_entry = fncpy(reboot_code_buffer, 175 reboot_entry = fncpy(reboot_code_buffer,
@@ -177,7 +178,7 @@ void machine_kexec(struct kimage *image)
177 reboot_entry_phys = (unsigned long)reboot_entry + 178 reboot_entry_phys = (unsigned long)reboot_entry +
178 (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); 179 (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer);
179 180
180 printk(KERN_INFO "Bye!\n"); 181 pr_info("Bye!\n");
181 182
182 if (kexec_reinit) 183 if (kexec_reinit)
183 kexec_reinit(); 184 kexec_reinit();
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 6a4dffefd357..bea7db9e5b80 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -251,7 +251,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
251#endif 251#endif
252 252
253 default: 253 default:
254 printk(KERN_ERR "%s: unknown relocation: %u\n", 254 pr_err("%s: unknown relocation: %u\n",
255 module->name, ELF32_R_TYPE(rel->r_info)); 255 module->name, ELF32_R_TYPE(rel->r_info));
256 return -ENOEXEC; 256 return -ENOEXEC;
257 } 257 }
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 07314af47733..5038960e3c55 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -1,8 +1,11 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/spinlock.h>
2#include <linux/kprobes.h> 3#include <linux/kprobes.h>
4#include <linux/mm.h>
3#include <linux/stop_machine.h> 5#include <linux/stop_machine.h>
4 6
5#include <asm/cacheflush.h> 7#include <asm/cacheflush.h>
8#include <asm/fixmap.h>
6#include <asm/smp_plat.h> 9#include <asm/smp_plat.h>
7#include <asm/opcodes.h> 10#include <asm/opcodes.h>
8 11
@@ -13,21 +16,77 @@ struct patch {
13 unsigned int insn; 16 unsigned int insn;
14}; 17};
15 18
16void __kprobes __patch_text(void *addr, unsigned int insn) 19static DEFINE_SPINLOCK(patch_lock);
20
21static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
22 __acquires(&patch_lock)
23{
24 unsigned int uintaddr = (uintptr_t) addr;
25 bool module = !core_kernel_text(uintaddr);
26 struct page *page;
27
28 if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
29 page = vmalloc_to_page(addr);
30 else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA))
31 page = virt_to_page(addr);
32 else
33 return addr;
34
35 if (flags)
36 spin_lock_irqsave(&patch_lock, *flags);
37 else
38 __acquire(&patch_lock);
39
40 set_fixmap(fixmap, page_to_phys(page));
41
42 return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
43}
44
45static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
46 __releases(&patch_lock)
47{
48 clear_fixmap(fixmap);
49
50 if (flags)
51 spin_unlock_irqrestore(&patch_lock, *flags);
52 else
53 __release(&patch_lock);
54}
55
56void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
17{ 57{
18 bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL); 58 bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
59 unsigned int uintaddr = (uintptr_t) addr;
60 bool twopage = false;
61 unsigned long flags;
62 void *waddr = addr;
19 int size; 63 int size;
20 64
65 if (remap)
66 waddr = patch_map(addr, FIX_TEXT_POKE0, &flags);
67 else
68 __acquire(&patch_lock);
69
21 if (thumb2 && __opcode_is_thumb16(insn)) { 70 if (thumb2 && __opcode_is_thumb16(insn)) {
22 *(u16 *)addr = __opcode_to_mem_thumb16(insn); 71 *(u16 *)waddr = __opcode_to_mem_thumb16(insn);
23 size = sizeof(u16); 72 size = sizeof(u16);
24 } else if (thumb2 && ((uintptr_t)addr & 2)) { 73 } else if (thumb2 && (uintaddr & 2)) {
25 u16 first = __opcode_thumb32_first(insn); 74 u16 first = __opcode_thumb32_first(insn);
26 u16 second = __opcode_thumb32_second(insn); 75 u16 second = __opcode_thumb32_second(insn);
27 u16 *addrh = addr; 76 u16 *addrh0 = waddr;
77 u16 *addrh1 = waddr + 2;
78
79 twopage = (uintaddr & ~PAGE_MASK) == PAGE_SIZE - 2;
80 if (twopage && remap)
81 addrh1 = patch_map(addr + 2, FIX_TEXT_POKE1, NULL);
82
83 *addrh0 = __opcode_to_mem_thumb16(first);
84 *addrh1 = __opcode_to_mem_thumb16(second);
28 85
29 addrh[0] = __opcode_to_mem_thumb16(first); 86 if (twopage && addrh1 != addr + 2) {
30 addrh[1] = __opcode_to_mem_thumb16(second); 87 flush_kernel_vmap_range(addrh1, 2);
88 patch_unmap(FIX_TEXT_POKE1, NULL);
89 }
31 90
32 size = sizeof(u32); 91 size = sizeof(u32);
33 } else { 92 } else {
@@ -36,10 +95,16 @@ void __kprobes __patch_text(void *addr, unsigned int insn)
36 else 95 else
37 insn = __opcode_to_mem_arm(insn); 96 insn = __opcode_to_mem_arm(insn);
38 97
39 *(u32 *)addr = insn; 98 *(u32 *)waddr = insn;
40 size = sizeof(u32); 99 size = sizeof(u32);
41 } 100 }
42 101
102 if (waddr != addr) {
103 flush_kernel_vmap_range(waddr, twopage ? size / 2 : size);
104 patch_unmap(FIX_TEXT_POKE0, &flags);
105 } else
106 __release(&patch_lock);
107
43 flush_icache_range((uintptr_t)(addr), 108 flush_icache_range((uintptr_t)(addr),
44 (uintptr_t)(addr) + size); 109 (uintptr_t)(addr) + size);
45} 110}
@@ -60,16 +125,5 @@ void __kprobes patch_text(void *addr, unsigned int insn)
60 .insn = insn, 125 .insn = insn,
61 }; 126 };
62 127
63 if (cache_ops_need_broadcast()) { 128 stop_machine(patch_text_stop_machine, &patch, NULL);
64 stop_machine(patch_text_stop_machine, &patch, cpu_online_mask);
65 } else {
66 bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL)
67 && __opcode_is_thumb32(insn)
68 && ((uintptr_t)addr & 2);
69
70 if (straddles_word)
71 stop_machine(patch_text_stop_machine, &patch, NULL);
72 else
73 __patch_text(addr, insn);
74 }
75} 129}
diff --git a/arch/arm/kernel/patch.h b/arch/arm/kernel/patch.h
index b4731f2dac38..77e054c2f6cd 100644
--- a/arch/arm/kernel/patch.h
+++ b/arch/arm/kernel/patch.h
@@ -2,6 +2,16 @@
2#define _ARM_KERNEL_PATCH_H 2#define _ARM_KERNEL_PATCH_H
3 3
4void patch_text(void *addr, unsigned int insn); 4void patch_text(void *addr, unsigned int insn);
5void __patch_text(void *addr, unsigned int insn); 5void __patch_text_real(void *addr, unsigned int insn, bool remap);
6
7static inline void __patch_text(void *addr, unsigned int insn)
8{
9 __patch_text_real(addr, insn, true);
10}
11
12static inline void __patch_text_early(void *addr, unsigned int insn)
13{
14 __patch_text_real(addr, insn, false);
15}
6 16
7#endif 17#endif
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index fe972a2f3df3..fdfa3a78ec8c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -51,8 +51,8 @@ EXPORT_SYMBOL(__stack_chk_guard);
51static const char *processor_modes[] __maybe_unused = { 51static const char *processor_modes[] __maybe_unused = {
52 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" , 52 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
53 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26", 53 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
54 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" , 54 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "MON_32" , "ABT_32" ,
55 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32" 55 "UK8_32" , "UK9_32" , "HYP_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
56}; 56};
57 57
58static const char *isa_modes[] __maybe_unused = { 58static const char *isa_modes[] __maybe_unused = {
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index 98ea4b7eb406..24b4a04846eb 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -39,13 +39,12 @@ void *return_address(unsigned int level)
39{ 39{
40 struct return_address_data data; 40 struct return_address_data data;
41 struct stackframe frame; 41 struct stackframe frame;
42 register unsigned long current_sp asm ("sp");
43 42
44 data.level = level + 2; 43 data.level = level + 2;
45 data.addr = NULL; 44 data.addr = NULL;
46 45
47 frame.fp = (unsigned long)__builtin_frame_address(0); 46 frame.fp = (unsigned long)__builtin_frame_address(0);
48 frame.sp = current_sp; 47 frame.sp = current_stack_pointer;
49 frame.lr = (unsigned long)__builtin_return_address(0); 48 frame.lr = (unsigned long)__builtin_return_address(0);
50 frame.pc = (unsigned long)return_address; 49 frame.pc = (unsigned long)return_address;
51 50
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c03106378b49..8361652b6dab 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -900,6 +900,7 @@ void __init setup_arch(char **cmdline_p)
900 mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); 900 mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);
901 machine_desc = mdesc; 901 machine_desc = mdesc;
902 machine_name = mdesc->name; 902 machine_name = mdesc->name;
903 dump_stack_set_arch_desc("%s", mdesc->name);
903 904
904 if (mdesc->reboot_mode != REBOOT_HARD) 905 if (mdesc->reboot_mode != REBOOT_HARD)
905 reboot_mode = mdesc->reboot_mode; 906 reboot_mode = mdesc->reboot_mode;
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index bd1983437205..8aa6f1b87c9e 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -592,7 +592,6 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
592 } 592 }
593 syscall = 0; 593 syscall = 0;
594 } else if (thread_flags & _TIF_UPROBE) { 594 } else if (thread_flags & _TIF_UPROBE) {
595 clear_thread_flag(TIF_UPROBE);
596 uprobe_notify_resume(regs); 595 uprobe_notify_resume(regs);
597 } else { 596 } else {
598 clear_thread_flag(TIF_NOTIFY_RESUME); 597 clear_thread_flag(TIF_NOTIFY_RESUME);
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 13396d3d600e..5e6052e18850 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -225,7 +225,7 @@ void __cpu_die(unsigned int cpu)
225 pr_err("CPU%u: cpu didn't die\n", cpu); 225 pr_err("CPU%u: cpu didn't die\n", cpu);
226 return; 226 return;
227 } 227 }
228 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); 228 pr_notice("CPU%u: shutdown\n", cpu);
229 229
230 /* 230 /*
231 * platform_cpu_kill() is generally expected to do the powering off 231 * platform_cpu_kill() is generally expected to do the powering off
@@ -235,7 +235,7 @@ void __cpu_die(unsigned int cpu)
235 * the requesting CPU and the dying CPU actually losing power. 235 * the requesting CPU and the dying CPU actually losing power.
236 */ 236 */
237 if (!platform_cpu_kill(cpu)) 237 if (!platform_cpu_kill(cpu))
238 printk("CPU%u: unable to kill\n", cpu); 238 pr_err("CPU%u: unable to kill\n", cpu);
239} 239}
240 240
241/* 241/*
@@ -351,7 +351,7 @@ asmlinkage void secondary_start_kernel(void)
351 351
352 cpu_init(); 352 cpu_init();
353 353
354 printk("CPU%u: Booted secondary processor\n", cpu); 354 pr_debug("CPU%u: Booted secondary processor\n", cpu);
355 355
356 preempt_disable(); 356 preempt_disable();
357 trace_hardirqs_off(); 357 trace_hardirqs_off();
@@ -387,9 +387,6 @@ asmlinkage void secondary_start_kernel(void)
387 387
388void __init smp_cpus_done(unsigned int max_cpus) 388void __init smp_cpus_done(unsigned int max_cpus)
389{ 389{
390 printk(KERN_INFO "SMP: Total of %d processors activated.\n",
391 num_online_cpus());
392
393 hyp_mode_check(); 390 hyp_mode_check();
394} 391}
395 392
@@ -521,7 +518,7 @@ static void ipi_cpu_stop(unsigned int cpu)
521 if (system_state == SYSTEM_BOOTING || 518 if (system_state == SYSTEM_BOOTING ||
522 system_state == SYSTEM_RUNNING) { 519 system_state == SYSTEM_RUNNING) {
523 raw_spin_lock(&stop_lock); 520 raw_spin_lock(&stop_lock);
524 printk(KERN_CRIT "CPU%u: stopping\n", cpu); 521 pr_crit("CPU%u: stopping\n", cpu);
525 dump_stack(); 522 dump_stack();
526 raw_spin_unlock(&stop_lock); 523 raw_spin_unlock(&stop_lock);
527 } 524 }
@@ -615,8 +612,8 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
615 break; 612 break;
616 613
617 default: 614 default:
618 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", 615 pr_crit("CPU%u: Unknown IPI message 0x%x\n",
619 cpu, ipinr); 616 cpu, ipinr);
620 break; 617 break;
621 } 618 }
622 619
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 93090213c71c..172c6a05d27f 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -199,7 +199,7 @@ static void twd_calibrate_rate(void)
199 * the timer ticks 199 * the timer ticks
200 */ 200 */
201 if (twd_timer_rate == 0) { 201 if (twd_timer_rate == 0) {
202 printk(KERN_INFO "Calibrating local timer... "); 202 pr_info("Calibrating local timer... ");
203 203
204 /* Wait for a tick to start */ 204 /* Wait for a tick to start */
205 waitjiffies = get_jiffies_64() + 1; 205 waitjiffies = get_jiffies_64() + 1;
@@ -223,7 +223,7 @@ static void twd_calibrate_rate(void)
223 223
224 twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); 224 twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
225 225
226 printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, 226 pr_cont("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
227 (twd_timer_rate / 10000) % 100); 227 (twd_timer_rate / 10000) % 100);
228 } 228 }
229} 229}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index f065eb05d254..92b72375c4c7 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -134,12 +134,10 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
134 frame.pc = thread_saved_pc(tsk); 134 frame.pc = thread_saved_pc(tsk);
135#endif 135#endif
136 } else { 136 } else {
137 register unsigned long current_sp asm ("sp");
138
139 /* We don't want this function nor the caller */ 137 /* We don't want this function nor the caller */
140 data.skip += 2; 138 data.skip += 2;
141 frame.fp = (unsigned long)__builtin_frame_address(0); 139 frame.fp = (unsigned long)__builtin_frame_address(0);
142 frame.sp = current_sp; 140 frame.sp = current_stack_pointer;
143 frame.lr = (unsigned long)__builtin_return_address(0); 141 frame.lr = (unsigned long)__builtin_return_address(0);
144 frame.pc = (unsigned long)__save_stack_trace; 142 frame.pc = (unsigned long)__save_stack_trace;
145 } 143 }
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 587fdfe1a72c..afdd51e30bec 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -260,7 +260,7 @@ static int __init swp_emulation_init(void)
260 return -ENOMEM; 260 return -ENOMEM;
261#endif /* CONFIG_PROC_FS */ 261#endif /* CONFIG_PROC_FS */
262 262
263 printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n"); 263 pr_notice("Registering SWP/SWPB emulation handler\n");
264 register_undef_hook(&swp_hook); 264 register_undef_hook(&swp_hook);
265 265
266 return 0; 266 return 0;
diff --git a/arch/arm/kernel/thumbee.c b/arch/arm/kernel/thumbee.c
index 80f0d69205e7..8ff8dbfbe9fb 100644
--- a/arch/arm/kernel/thumbee.c
+++ b/arch/arm/kernel/thumbee.c
@@ -72,7 +72,7 @@ static int __init thumbee_init(void)
72 if ((pfr0 & 0x0000f000) != 0x00001000) 72 if ((pfr0 & 0x0000f000) != 0x00001000)
73 return 0; 73 return 0;
74 74
75 printk(KERN_INFO "ThumbEE CPU extension supported.\n"); 75 pr_info("ThumbEE CPU extension supported.\n");
76 elf_hwcap |= HWCAP_THUMBEE; 76 elf_hwcap |= HWCAP_THUMBEE;
77 thread_register_notifier(&thumbee_notifier_block); 77 thread_register_notifier(&thumbee_notifier_block);
78 78
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index 89cfdd6e50cb..08b7847bf912 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -165,7 +165,7 @@ static void update_cpu_capacity(unsigned int cpu)
165 165
166 set_capacity_scale(cpu, cpu_capacity(cpu) / middle_capacity); 166 set_capacity_scale(cpu, cpu_capacity(cpu) / middle_capacity);
167 167
168 printk(KERN_INFO "CPU%u: update cpu_capacity %lu\n", 168 pr_info("CPU%u: update cpu_capacity %lu\n",
169 cpu, arch_scale_cpu_capacity(NULL, cpu)); 169 cpu, arch_scale_cpu_capacity(NULL, cpu));
170} 170}
171 171
@@ -269,7 +269,7 @@ void store_cpu_topology(unsigned int cpuid)
269 269
270 update_cpu_capacity(cpuid); 270 update_cpu_capacity(cpuid);
271 271
272 printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", 272 pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
273 cpuid, cpu_topology[cpuid].thread_id, 273 cpuid, cpu_topology[cpuid].thread_id,
274 cpu_topology[cpuid].core_id, 274 cpu_topology[cpuid].core_id,
275 cpu_topology[cpuid].socket_id, mpidr); 275 cpu_topology[cpuid].socket_id, mpidr);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 9f5d81881eb6..788e23fe64d8 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -198,14 +198,14 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
198 } 198 }
199 199
200 if (!fp) { 200 if (!fp) {
201 printk("no frame pointer"); 201 pr_cont("no frame pointer");
202 ok = 0; 202 ok = 0;
203 } else if (verify_stack(fp)) { 203 } else if (verify_stack(fp)) {
204 printk("invalid frame pointer 0x%08x", fp); 204 pr_cont("invalid frame pointer 0x%08x", fp);
205 ok = 0; 205 ok = 0;
206 } else if (fp < (unsigned long)end_of_stack(tsk)) 206 } else if (fp < (unsigned long)end_of_stack(tsk))
207 printk("frame pointer underflow"); 207 pr_cont("frame pointer underflow");
208 printk("\n"); 208 pr_cont("\n");
209 209
210 if (ok) 210 if (ok)
211 c_backtrace(fp, mode); 211 c_backtrace(fp, mode);
@@ -240,8 +240,8 @@ static int __die(const char *str, int err, struct pt_regs *regs)
240 static int die_counter; 240 static int die_counter;
241 int ret; 241 int ret;
242 242
243 printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP 243 pr_emerg("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP S_ISA "\n",
244 S_ISA "\n", str, err, ++die_counter); 244 str, err, ++die_counter);
245 245
246 /* trap and error numbers are mostly meaningless on ARM */ 246 /* trap and error numbers are mostly meaningless on ARM */
247 ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); 247 ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
@@ -250,8 +250,8 @@ static int __die(const char *str, int err, struct pt_regs *regs)
250 250
251 print_modules(); 251 print_modules();
252 __show_regs(regs); 252 __show_regs(regs);
253 printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n", 253 pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
254 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk)); 254 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), end_of_stack(tsk));
255 255
256 if (!user_mode(regs) || in_interrupt()) { 256 if (!user_mode(regs) || in_interrupt()) {
257 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp, 257 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
@@ -446,7 +446,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
446die_sig: 446die_sig:
447#ifdef CONFIG_DEBUG_USER 447#ifdef CONFIG_DEBUG_USER
448 if (user_debug & UDBG_UNDEFINED) { 448 if (user_debug & UDBG_UNDEFINED) {
449 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", 449 pr_info("%s (%d): undefined instruction: pc=%p\n",
450 current->comm, task_pid_nr(current), pc); 450 current->comm, task_pid_nr(current), pc);
451 __show_regs(regs); 451 __show_regs(regs);
452 dump_instr(KERN_INFO, regs); 452 dump_instr(KERN_INFO, regs);
@@ -496,7 +496,7 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason)
496{ 496{
497 console_verbose(); 497 console_verbose();
498 498
499 printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]); 499 pr_crit("Bad mode in %s handler detected\n", handler[reason]);
500 500
501 die("Oops - bad mode", regs, 0); 501 die("Oops - bad mode", regs, 0);
502 local_irq_disable(); 502 local_irq_disable();
@@ -516,7 +516,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
516 516
517#ifdef CONFIG_DEBUG_USER 517#ifdef CONFIG_DEBUG_USER
518 if (user_debug & UDBG_SYSCALL) { 518 if (user_debug & UDBG_SYSCALL) {
519 printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", 519 pr_err("[%d] %s: obsolete system call %08x.\n",
520 task_pid_nr(current), current->comm, n); 520 task_pid_nr(current), current->comm, n);
521 dump_instr(KERN_ERR, regs); 521 dump_instr(KERN_ERR, regs);
522 } 522 }
@@ -694,7 +694,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
694 * something catastrophic has happened 694 * something catastrophic has happened
695 */ 695 */
696 if (user_debug & UDBG_SYSCALL) { 696 if (user_debug & UDBG_SYSCALL) {
697 printk("[%d] %s: arm syscall %d\n", 697 pr_err("[%d] %s: arm syscall %d\n",
698 task_pid_nr(current), current->comm, no); 698 task_pid_nr(current), current->comm, no);
699 dump_instr("", regs); 699 dump_instr("", regs);
700 if (user_mode(regs)) { 700 if (user_mode(regs)) {
@@ -753,8 +753,8 @@ late_initcall(arm_mrc_hook_init);
753 753
754void __bad_xchg(volatile void *ptr, int size) 754void __bad_xchg(volatile void *ptr, int size)
755{ 755{
756 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", 756 pr_err("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
757 __builtin_return_address(0), ptr, size); 757 __builtin_return_address(0), ptr, size);
758 BUG(); 758 BUG();
759} 759}
760EXPORT_SYMBOL(__bad_xchg); 760EXPORT_SYMBOL(__bad_xchg);
@@ -771,8 +771,8 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
771 771
772#ifdef CONFIG_DEBUG_USER 772#ifdef CONFIG_DEBUG_USER
773 if (user_debug & UDBG_BADABORT) { 773 if (user_debug & UDBG_BADABORT) {
774 printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", 774 pr_err("[%d] %s: bad data abort: code %d instr 0x%08lx\n",
775 task_pid_nr(current), current->comm, code, instr); 775 task_pid_nr(current), current->comm, code, instr);
776 dump_instr(KERN_ERR, regs); 776 dump_instr(KERN_ERR, regs);
777 show_pte(current->mm, addr); 777 show_pte(current->mm, addr);
778 } 778 }
@@ -788,29 +788,29 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
788 788
789void __readwrite_bug(const char *fn) 789void __readwrite_bug(const char *fn)
790{ 790{
791 printk("%s called, but not implemented\n", fn); 791 pr_err("%s called, but not implemented\n", fn);
792 BUG(); 792 BUG();
793} 793}
794EXPORT_SYMBOL(__readwrite_bug); 794EXPORT_SYMBOL(__readwrite_bug);
795 795
796void __pte_error(const char *file, int line, pte_t pte) 796void __pte_error(const char *file, int line, pte_t pte)
797{ 797{
798 printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); 798 pr_err("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
799} 799}
800 800
801void __pmd_error(const char *file, int line, pmd_t pmd) 801void __pmd_error(const char *file, int line, pmd_t pmd)
802{ 802{
803 printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd)); 803 pr_err("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
804} 804}
805 805
806void __pgd_error(const char *file, int line, pgd_t pgd) 806void __pgd_error(const char *file, int line, pgd_t pgd)
807{ 807{
808 printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd)); 808 pr_err("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
809} 809}
810 810
811asmlinkage void __div0(void) 811asmlinkage void __div0(void)
812{ 812{
813 printk("Division by zero in kernel.\n"); 813 pr_err("Division by zero in kernel.\n");
814 dump_stack(); 814 dump_stack();
815} 815}
816EXPORT_SYMBOL(__div0); 816EXPORT_SYMBOL(__div0);
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index cbb85c5fabf9..0bee233fef9a 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -471,7 +471,6 @@ int unwind_frame(struct stackframe *frame)
471void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk) 471void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
472{ 472{
473 struct stackframe frame; 473 struct stackframe frame;
474 register unsigned long current_sp asm ("sp");
475 474
476 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); 475 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
477 476
@@ -485,7 +484,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
485 frame.pc = regs->ARM_lr; 484 frame.pc = regs->ARM_lr;
486 } else if (tsk == current) { 485 } else if (tsk == current) {
487 frame.fp = (unsigned long)__builtin_frame_address(0); 486 frame.fp = (unsigned long)__builtin_frame_address(0);
488 frame.sp = current_sp; 487 frame.sp = current_stack_pointer;
489 frame.lr = (unsigned long)__builtin_return_address(0); 488 frame.lr = (unsigned long)__builtin_return_address(0);
490 frame.pc = (unsigned long)unwind_backtrace; 489 frame.pc = (unsigned long)unwind_backtrace;
491 } else { 490 } else {
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8e95aa47457a..b31aa73e8076 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -8,6 +8,9 @@
8#include <asm/thread_info.h> 8#include <asm/thread_info.h>
9#include <asm/memory.h> 9#include <asm/memory.h>
10#include <asm/page.h> 10#include <asm/page.h>
11#ifdef CONFIG_ARM_KERNMEM_PERMS
12#include <asm/pgtable.h>
13#endif
11 14
12#define PROC_INFO \ 15#define PROC_INFO \
13 . = ALIGN(4); \ 16 . = ALIGN(4); \
@@ -90,6 +93,11 @@ SECTIONS
90 _text = .; 93 _text = .;
91 HEAD_TEXT 94 HEAD_TEXT
92 } 95 }
96
97#ifdef CONFIG_ARM_KERNMEM_PERMS
98 . = ALIGN(1<<SECTION_SHIFT);
99#endif
100
93 .text : { /* Real text segment */ 101 .text : { /* Real text segment */
94 _stext = .; /* Text and read-only data */ 102 _stext = .; /* Text and read-only data */
95 __exception_text_start = .; 103 __exception_text_start = .;
@@ -112,6 +120,9 @@ SECTIONS
112 ARM_CPU_KEEP(PROC_INFO) 120 ARM_CPU_KEEP(PROC_INFO)
113 } 121 }
114 122
123#ifdef CONFIG_DEBUG_RODATA
124 . = ALIGN(1<<SECTION_SHIFT);
125#endif
115 RO_DATA(PAGE_SIZE) 126 RO_DATA(PAGE_SIZE)
116 127
117 . = ALIGN(4); 128 . = ALIGN(4);
@@ -145,7 +156,11 @@ SECTIONS
145 _etext = .; /* End of text and rodata section */ 156 _etext = .; /* End of text and rodata section */
146 157
147#ifndef CONFIG_XIP_KERNEL 158#ifndef CONFIG_XIP_KERNEL
159# ifdef CONFIG_ARM_KERNMEM_PERMS
160 . = ALIGN(1<<SECTION_SHIFT);
161# else
148 . = ALIGN(PAGE_SIZE); 162 . = ALIGN(PAGE_SIZE);
163# endif
149 __init_begin = .; 164 __init_begin = .;
150#endif 165#endif
151 /* 166 /*
@@ -219,7 +234,11 @@ SECTIONS
219 __data_loc = ALIGN(4); /* location in binary */ 234 __data_loc = ALIGN(4); /* location in binary */
220 . = PAGE_OFFSET + TEXT_OFFSET; 235 . = PAGE_OFFSET + TEXT_OFFSET;
221#else 236#else
237#ifdef CONFIG_ARM_KERNMEM_PERMS
238 . = ALIGN(1<<SECTION_SHIFT);
239#else
222 . = ALIGN(THREAD_SIZE); 240 . = ALIGN(THREAD_SIZE);
241#endif
223 __init_end = .; 242 __init_end = .;
224 __data_loc = .; 243 __data_loc = .;
225#endif 244#endif
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c
index e42adc6bcdb1..bdbb8853a19b 100644
--- a/arch/arm/kernel/xscale-cp0.c
+++ b/arch/arm/kernel/xscale-cp0.c
@@ -157,15 +157,14 @@ static int __init xscale_cp0_init(void)
157 157
158 if (cpu_has_iwmmxt()) { 158 if (cpu_has_iwmmxt()) {
159#ifndef CONFIG_IWMMXT 159#ifndef CONFIG_IWMMXT
160 printk(KERN_WARNING "CAUTION: XScale iWMMXt coprocessor " 160 pr_warn("CAUTION: XScale iWMMXt coprocessor detected, but kernel support is missing.\n");
161 "detected, but kernel support is missing.\n");
162#else 161#else
163 printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n"); 162 pr_info("XScale iWMMXt coprocessor detected.\n");
164 elf_hwcap |= HWCAP_IWMMXT; 163 elf_hwcap |= HWCAP_IWMMXT;
165 thread_register_notifier(&iwmmxt_notifier_block); 164 thread_register_notifier(&iwmmxt_notifier_block);
166#endif 165#endif
167 } else { 166 } else {
168 printk(KERN_INFO "XScale DSP coprocessor detected.\n"); 167 pr_info("XScale DSP coprocessor detected.\n");
169 thread_register_notifier(&dsp_notifier_block); 168 thread_register_notifier(&dsp_notifier_block);
170 cp_access |= 1; 169 cp_access |= 1;
171 } 170 }
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 66a477a3e3cc..7a235b9952be 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -12,6 +12,7 @@
12 12
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15#include <asm/unwind.h>
15 16
16/* 17/*
17 * Prototype: 18 * Prototype:
@@ -77,6 +78,10 @@
77 stmdb sp!, {r0, r2, r3, \reg1, \reg2} 78 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
78 .endm 79 .endm
79 80
81 .macro usave reg1 reg2
82 UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
83 .endm
84
80 .macro exit reg1 reg2 85 .macro exit reg1 reg2
81 add sp, sp, #8 86 add sp, sp, #8
82 ldmfd sp!, {r0, \reg1, \reg2} 87 ldmfd sp!, {r0, \reg1, \reg2}
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 3bc8eb811a73..652e4d98cd47 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -53,6 +53,12 @@
53 * data as needed by the implementation including this code. Called 53 * data as needed by the implementation including this code. Called
54 * upon code entry. 54 * upon code entry.
55 * 55 *
56 * usave reg1 reg2
57 *
58 * Unwind annotation macro is corresponding for 'enter' macro.
59 * It tell unwinder that preserved some provided registers on the stack
60 * and additional data by a prior 'enter' macro.
61 *
56 * exit reg1 reg2 62 * exit reg1 reg2
57 * 63 *
58 * Restore registers with the values previously saved with the 64 * Restore registers with the values previously saved with the
@@ -67,7 +73,12 @@
67 */ 73 */
68 74
69 75
76 UNWIND( .fnstart )
70 enter r4, lr 77 enter r4, lr
78 UNWIND( .fnend )
79
80 UNWIND( .fnstart )
81 usave r4, lr @ in first stmdb block
71 82
72 subs r2, r2, #4 83 subs r2, r2, #4
73 blt 8f 84 blt 8f
@@ -79,6 +90,11 @@
79 90
801: subs r2, r2, #(28) 911: subs r2, r2, #(28)
81 stmfd sp!, {r5 - r8} 92 stmfd sp!, {r5 - r8}
93 UNWIND( .fnend )
94
95 UNWIND( .fnstart )
96 usave r4, lr
97 UNWIND( .save {r5 - r8} ) @ in second stmfd block
82 blt 5f 98 blt 5f
83 99
84 CALGN( ands ip, r0, #31 ) 100 CALGN( ands ip, r0, #31 )
@@ -144,7 +160,10 @@
144 CALGN( bcs 2b ) 160 CALGN( bcs 2b )
145 161
1467: ldmfd sp!, {r5 - r8} 1627: ldmfd sp!, {r5 - r8}
163 UNWIND( .fnend ) @ end of second stmfd block
147 164
165 UNWIND( .fnstart )
166 usave r4, lr @ still in first stmdb block
1488: movs r2, r2, lsl #31 1678: movs r2, r2, lsl #31
149 ldr1b r1, r3, ne, abort=21f 168 ldr1b r1, r3, ne, abort=21f
150 ldr1b r1, r4, cs, abort=21f 169 ldr1b r1, r4, cs, abort=21f
@@ -173,10 +192,13 @@
173 ldr1w r1, lr, abort=21f 192 ldr1w r1, lr, abort=21f
174 beq 17f 193 beq 17f
175 bgt 18f 194 bgt 18f
195 UNWIND( .fnend )
176 196
177 197
178 .macro forward_copy_shift pull push 198 .macro forward_copy_shift pull push
179 199
200 UNWIND( .fnstart )
201 usave r4, lr @ still in first stmdb block
180 subs r2, r2, #28 202 subs r2, r2, #28
181 blt 14f 203 blt 14f
182 204
@@ -187,7 +209,11 @@
187 CALGN( bcc 15f ) 209 CALGN( bcc 15f )
188 210
18911: stmfd sp!, {r5 - r9} 21111: stmfd sp!, {r5 - r9}
212 UNWIND( .fnend )
190 213
214 UNWIND( .fnstart )
215 usave r4, lr
216 UNWIND( .save {r5 - r9} ) @ in new second stmfd block
191 PLD( pld [r1, #0] ) 217 PLD( pld [r1, #0] )
192 PLD( subs r2, r2, #96 ) 218 PLD( subs r2, r2, #96 )
193 PLD( pld [r1, #28] ) 219 PLD( pld [r1, #28] )
@@ -221,7 +247,10 @@
221 PLD( bge 13b ) 247 PLD( bge 13b )
222 248
223 ldmfd sp!, {r5 - r9} 249 ldmfd sp!, {r5 - r9}
250 UNWIND( .fnend ) @ end of the second stmfd block
224 251
252 UNWIND( .fnstart )
253 usave r4, lr @ still in first stmdb block
22514: ands ip, r2, #28 25414: ands ip, r2, #28
226 beq 16f 255 beq 16f
227 256
@@ -236,6 +265,7 @@
236 265
23716: sub r1, r1, #(\push / 8) 26616: sub r1, r1, #(\push / 8)
238 b 8b 267 b 8b
268 UNWIND( .fnend )
239 269
240 .endm 270 .endm
241 271
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index d066df686e17..a9d3db16ecb5 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -12,6 +12,7 @@
12 12
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15#include <asm/unwind.h>
15 16
16/* 17/*
17 * Prototype: 18 * Prototype:
@@ -80,6 +81,10 @@
80 stmdb sp!, {r0, r2, r3, \reg1, \reg2} 81 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
81 .endm 82 .endm
82 83
84 .macro usave reg1 reg2
85 UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
86 .endm
87
83 .macro exit reg1 reg2 88 .macro exit reg1 reg2
84 add sp, sp, #8 89 add sp, sp, #8
85 ldmfd sp!, {r0, \reg1, \reg2} 90 ldmfd sp!, {r0, \reg1, \reg2}
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index a9b9e2287a09..7797e81e40e0 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -12,6 +12,7 @@
12 12
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15#include <asm/unwind.h>
15 16
16#define LDR1W_SHIFT 0 17#define LDR1W_SHIFT 0
17#define STR1W_SHIFT 0 18#define STR1W_SHIFT 0
@@ -48,6 +49,10 @@
48 stmdb sp!, {r0, \reg1, \reg2} 49 stmdb sp!, {r0, \reg1, \reg2}
49 .endm 50 .endm
50 51
52 .macro usave reg1 reg2
53 UNWIND( .save {r0, \reg1, \reg2} )
54 .endm
55
51 .macro exit reg1 reg2 56 .macro exit reg1 reg2
52 ldmfd sp!, {r0, \reg1, \reg2} 57 ldmfd sp!, {r0, \reg1, \reg2}
53 .endm 58 .endm
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index d1fc0c0c342c..69a9d47fc5ab 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -12,6 +12,7 @@
12 12
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15#include <asm/unwind.h>
15 16
16 .text 17 .text
17 18
@@ -27,12 +28,17 @@
27 */ 28 */
28 29
29ENTRY(memmove) 30ENTRY(memmove)
31 UNWIND( .fnstart )
30 32
31 subs ip, r0, r1 33 subs ip, r0, r1
32 cmphi r2, ip 34 cmphi r2, ip
33 bls memcpy 35 bls memcpy
34 36
35 stmfd sp!, {r0, r4, lr} 37 stmfd sp!, {r0, r4, lr}
38 UNWIND( .fnend )
39
40 UNWIND( .fnstart )
41 UNWIND( .save {r0, r4, lr} ) @ in first stmfd block
36 add r1, r1, r2 42 add r1, r1, r2
37 add r0, r0, r2 43 add r0, r0, r2
38 subs r2, r2, #4 44 subs r2, r2, #4
@@ -45,6 +51,11 @@ ENTRY(memmove)
45 51
461: subs r2, r2, #(28) 521: subs r2, r2, #(28)
47 stmfd sp!, {r5 - r8} 53 stmfd sp!, {r5 - r8}
54 UNWIND( .fnend )
55
56 UNWIND( .fnstart )
57 UNWIND( .save {r0, r4, lr} )
58 UNWIND( .save {r5 - r8} ) @ in second stmfd block
48 blt 5f 59 blt 5f
49 60
50 CALGN( ands ip, r0, #31 ) 61 CALGN( ands ip, r0, #31 )
@@ -97,6 +108,10 @@ ENTRY(memmove)
97 CALGN( bcs 2b ) 108 CALGN( bcs 2b )
98 109
997: ldmfd sp!, {r5 - r8} 1107: ldmfd sp!, {r5 - r8}
111 UNWIND( .fnend ) @ end of second stmfd block
112
113 UNWIND( .fnstart )
114 UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
100 115
1018: movs r2, r2, lsl #31 1168: movs r2, r2, lsl #31
102 ldrneb r3, [r1, #-1]! 117 ldrneb r3, [r1, #-1]!
@@ -124,10 +139,13 @@ ENTRY(memmove)
124 ldr r3, [r1, #0] 139 ldr r3, [r1, #0]
125 beq 17f 140 beq 17f
126 blt 18f 141 blt 18f
142 UNWIND( .fnend )
127 143
128 144
129 .macro backward_copy_shift push pull 145 .macro backward_copy_shift push pull
130 146
147 UNWIND( .fnstart )
148 UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
131 subs r2, r2, #28 149 subs r2, r2, #28
132 blt 14f 150 blt 14f
133 151
@@ -137,6 +155,11 @@ ENTRY(memmove)
137 CALGN( bcc 15f ) 155 CALGN( bcc 15f )
138 156
13911: stmfd sp!, {r5 - r9} 15711: stmfd sp!, {r5 - r9}
158 UNWIND( .fnend )
159
160 UNWIND( .fnstart )
161 UNWIND( .save {r0, r4, lr} )
162 UNWIND( .save {r5 - r9} ) @ in new second stmfd block
140 163
141 PLD( pld [r1, #-4] ) 164 PLD( pld [r1, #-4] )
142 PLD( subs r2, r2, #96 ) 165 PLD( subs r2, r2, #96 )
@@ -171,6 +194,10 @@ ENTRY(memmove)
171 PLD( bge 13b ) 194 PLD( bge 13b )
172 195
173 ldmfd sp!, {r5 - r9} 196 ldmfd sp!, {r5 - r9}
197 UNWIND( .fnend ) @ end of the second stmfd block
198
199 UNWIND( .fnstart )
200 UNWIND( .save {r0, r4, lr} ) @ still in first stmfd block
174 201
17514: ands ip, r2, #28 20214: ands ip, r2, #28
176 beq 16f 203 beq 16f
@@ -186,6 +213,7 @@ ENTRY(memmove)
186 213
18716: add r1, r1, #(\pull / 8) 21416: add r1, r1, #(\pull / 8)
188 b 8b 215 b 8b
216 UNWIND( .fnend )
189 217
190 .endm 218 .endm
191 219
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index 671455c854fa..a4ee97b5a2bf 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -11,11 +11,13 @@
11 */ 11 */
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <asm/assembler.h> 13#include <asm/assembler.h>
14#include <asm/unwind.h>
14 15
15 .text 16 .text
16 .align 5 17 .align 5
17 18
18ENTRY(memset) 19ENTRY(memset)
20UNWIND( .fnstart )
19 ands r3, r0, #3 @ 1 unaligned? 21 ands r3, r0, #3 @ 1 unaligned?
20 mov ip, r0 @ preserve r0 as return value 22 mov ip, r0 @ preserve r0 as return value
21 bne 6f @ 1 23 bne 6f @ 1
@@ -34,6 +36,9 @@ ENTRY(memset)
34 * We need 2 extra registers for this loop - use r8 and the LR 36 * We need 2 extra registers for this loop - use r8 and the LR
35 */ 37 */
36 stmfd sp!, {r8, lr} 38 stmfd sp!, {r8, lr}
39UNWIND( .fnend )
40UNWIND( .fnstart )
41UNWIND( .save {r8, lr} )
37 mov r8, r1 42 mov r8, r1
38 mov lr, r1 43 mov lr, r1
39 44
@@ -53,6 +58,7 @@ ENTRY(memset)
53 tst r2, #16 58 tst r2, #16
54 stmneia ip!, {r1, r3, r8, lr} 59 stmneia ip!, {r1, r3, r8, lr}
55 ldmfd sp!, {r8, lr} 60 ldmfd sp!, {r8, lr}
61UNWIND( .fnend )
56 62
57#else 63#else
58 64
@@ -62,6 +68,9 @@ ENTRY(memset)
62 */ 68 */
63 69
64 stmfd sp!, {r4-r8, lr} 70 stmfd sp!, {r4-r8, lr}
71UNWIND( .fnend )
72UNWIND( .fnstart )
73UNWIND( .save {r4-r8, lr} )
65 mov r4, r1 74 mov r4, r1
66 mov r5, r1 75 mov r5, r1
67 mov r6, r1 76 mov r6, r1
@@ -94,9 +103,11 @@ ENTRY(memset)
94 tst r2, #16 103 tst r2, #16
95 stmneia ip!, {r4-r7} 104 stmneia ip!, {r4-r7}
96 ldmfd sp!, {r4-r8, lr} 105 ldmfd sp!, {r4-r8, lr}
106UNWIND( .fnend )
97 107
98#endif 108#endif
99 109
110UNWIND( .fnstart )
1004: tst r2, #8 1114: tst r2, #8
101 stmneia ip!, {r1, r3} 112 stmneia ip!, {r1, r3}
102 tst r2, #4 113 tst r2, #4
@@ -120,4 +131,5 @@ ENTRY(memset)
120 strb r1, [ip], #1 @ 1 131 strb r1, [ip], #1 @ 1
121 add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) 132 add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
122 b 1b 133 b 1b
134UNWIND( .fnend )
123ENDPROC(memset) 135ENDPROC(memset)
diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S
index 385ccb306fa2..0eded952e089 100644
--- a/arch/arm/lib/memzero.S
+++ b/arch/arm/lib/memzero.S
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/linkage.h> 10#include <linux/linkage.h>
11#include <asm/assembler.h> 11#include <asm/assembler.h>
12#include <asm/unwind.h>
12 13
13 .text 14 .text
14 .align 5 15 .align 5
@@ -18,6 +19,7 @@
18 * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we 19 * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we
19 * don't bother; we use byte stores instead. 20 * don't bother; we use byte stores instead.
20 */ 21 */
22UNWIND( .fnstart )
211: subs r1, r1, #4 @ 1 do we have enough 231: subs r1, r1, #4 @ 1 do we have enough
22 blt 5f @ 1 bytes to align with? 24 blt 5f @ 1 bytes to align with?
23 cmp r3, #2 @ 1 25 cmp r3, #2 @ 1
@@ -47,6 +49,9 @@ ENTRY(__memzero)
47 * use the LR 49 * use the LR
48 */ 50 */
49 str lr, [sp, #-4]! @ 1 51 str lr, [sp, #-4]! @ 1
52UNWIND( .fnend )
53UNWIND( .fnstart )
54UNWIND( .save {lr} )
50 mov ip, r2 @ 1 55 mov ip, r2 @ 1
51 mov lr, r2 @ 1 56 mov lr, r2 @ 1
52 57
@@ -66,6 +71,7 @@ ENTRY(__memzero)
66 tst r1, #16 @ 1 16 bytes or more? 71 tst r1, #16 @ 1 16 bytes or more?
67 stmneia r0!, {r2, r3, ip, lr} @ 4 72 stmneia r0!, {r2, r3, ip, lr} @ 4
68 ldr lr, [sp], #4 @ 1 73 ldr lr, [sp], #4 @ 1
74UNWIND( .fnend )
69 75
70#else 76#else
71 77
@@ -75,6 +81,9 @@ ENTRY(__memzero)
75 */ 81 */
76 82
77 stmfd sp!, {r4-r7, lr} 83 stmfd sp!, {r4-r7, lr}
84UNWIND( .fnend )
85UNWIND( .fnstart )
86UNWIND( .save {r4-r7, lr} )
78 mov r4, r2 87 mov r4, r2
79 mov r5, r2 88 mov r5, r2
80 mov r6, r2 89 mov r6, r2
@@ -105,9 +114,11 @@ ENTRY(__memzero)
105 tst r1, #16 114 tst r1, #16
106 stmneia r0!, {r4-r7} 115 stmneia r0!, {r4-r7}
107 ldmfd sp!, {r4-r7, lr} 116 ldmfd sp!, {r4-r7, lr}
117UNWIND( .fnend )
108 118
109#endif 119#endif
110 120
121UNWIND( .fnstart )
1114: tst r1, #8 @ 1 8 bytes or more? 1224: tst r1, #8 @ 1 8 bytes or more?
112 stmneia r0!, {r2, r3} @ 2 123 stmneia r0!, {r2, r3} @ 2
113 tst r1, #4 @ 1 4 bytes or more? 124 tst r1, #4 @ 1 4 bytes or more?
@@ -122,4 +133,5 @@ ENTRY(__memzero)
122 tst r1, #1 @ 1 a byte left over 133 tst r1, #1 @ 1 a byte left over
123 strneb r2, [r0], #1 @ 1 134 strneb r2, [r0], #1 @ 1
124 ret lr @ 1 135 ret lr @ 1
136UNWIND( .fnend )
125ENDPROC(__memzero) 137ENDPROC(__memzero)
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index b9e3f1c61baf..e4a00bafffc1 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -34,7 +34,7 @@ config ARCH_EXYNOS3
34 bool "SAMSUNG EXYNOS3" 34 bool "SAMSUNG EXYNOS3"
35 select ARM_CPU_SUSPEND if PM 35 select ARM_CPU_SUSPEND if PM
36 help 36 help
37 Samsung EXYNOS3 (Crotex-A7) SoC based systems 37 Samsung EXYNOS3 (Cortex-A7) SoC based systems
38 38
39config ARCH_EXYNOS4 39config ARCH_EXYNOS4
40 bool "SAMSUNG EXYNOS4" 40 bool "SAMSUNG EXYNOS4"
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 9fa6a990cf03..03c75a811cb0 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -15,10 +15,12 @@
15#include <linux/clkdev.h> 15#include <linux/clkdev.h>
16 16
17#include <mach/hardware.h> 17#include <mach/hardware.h>
18#include <mach/generic.h>
18 19
19struct clkops { 20struct clkops {
20 void (*enable)(struct clk *); 21 void (*enable)(struct clk *);
21 void (*disable)(struct clk *); 22 void (*disable)(struct clk *);
23 unsigned long (*get_rate)(struct clk *);
22}; 24};
23 25
24struct clk { 26struct clk {
@@ -33,13 +35,6 @@ struct clk clk_##_name = { \
33 35
34static DEFINE_SPINLOCK(clocks_lock); 36static DEFINE_SPINLOCK(clocks_lock);
35 37
36/* Dummy clk routine to build generic kernel parts that may be using them */
37unsigned long clk_get_rate(struct clk *clk)
38{
39 return 0;
40}
41EXPORT_SYMBOL(clk_get_rate);
42
43static void clk_gpio27_enable(struct clk *clk) 38static void clk_gpio27_enable(struct clk *clk)
44{ 39{
45 /* 40 /*
@@ -58,6 +53,19 @@ static void clk_gpio27_disable(struct clk *clk)
58 GAFR &= ~GPIO_32_768kHz; 53 GAFR &= ~GPIO_32_768kHz;
59} 54}
60 55
56static void clk_cpu_enable(struct clk *clk)
57{
58}
59
60static void clk_cpu_disable(struct clk *clk)
61{
62}
63
64static unsigned long clk_cpu_get_rate(struct clk *clk)
65{
66 return sa11x0_getspeed(0) * 1000;
67}
68
61int clk_enable(struct clk *clk) 69int clk_enable(struct clk *clk)
62{ 70{
63 unsigned long flags; 71 unsigned long flags;
@@ -87,16 +95,37 @@ void clk_disable(struct clk *clk)
87} 95}
88EXPORT_SYMBOL(clk_disable); 96EXPORT_SYMBOL(clk_disable);
89 97
98unsigned long clk_get_rate(struct clk *clk)
99{
100 if (clk && clk->ops && clk->ops->get_rate)
101 return clk->ops->get_rate(clk);
102
103 return 0;
104}
105EXPORT_SYMBOL(clk_get_rate);
106
90const struct clkops clk_gpio27_ops = { 107const struct clkops clk_gpio27_ops = {
91 .enable = clk_gpio27_enable, 108 .enable = clk_gpio27_enable,
92 .disable = clk_gpio27_disable, 109 .disable = clk_gpio27_disable,
93}; 110};
94 111
112const struct clkops clk_cpu_ops = {
113 .enable = clk_cpu_enable,
114 .disable = clk_cpu_disable,
115 .get_rate = clk_cpu_get_rate,
116};
117
95static DEFINE_CLK(gpio27, &clk_gpio27_ops); 118static DEFINE_CLK(gpio27, &clk_gpio27_ops);
96 119
120static DEFINE_CLK(cpu, &clk_cpu_ops);
121
97static struct clk_lookup sa11xx_clkregs[] = { 122static struct clk_lookup sa11xx_clkregs[] = {
98 CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27), 123 CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
99 CLKDEV_INIT("sa1100-rtc", NULL, NULL), 124 CLKDEV_INIT("sa1100-rtc", NULL, NULL),
125 CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
126 CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
127 /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
128 CLKDEV_INIT("1800", NULL, &clk_cpu),
100}; 129};
101 130
102static int __init sa11xx_clk_init(void) 131static int __init sa11xx_clk_init(void)
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 108939f8d053..b90c7d828391 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -30,7 +30,7 @@
30#include <linux/gpio_keys.h> 30#include <linux/gpio_keys.h>
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/pda_power.h> 33#include <linux/power/gpio-charger.h>
34 34
35#include <video/sa1100fb.h> 35#include <video/sa1100fb.h>
36 36
@@ -131,62 +131,24 @@ static struct irda_platform_data collie_ir_data = {
131/* 131/*
132 * Collie AC IN 132 * Collie AC IN
133 */ 133 */
134static int collie_power_init(struct device *dev)
135{
136 int ret = gpio_request(COLLIE_GPIO_AC_IN, "ac in");
137 if (ret)
138 goto err_gpio_req;
139
140 ret = gpio_direction_input(COLLIE_GPIO_AC_IN);
141 if (ret)
142 goto err_gpio_in;
143
144 return 0;
145
146err_gpio_in:
147 gpio_free(COLLIE_GPIO_AC_IN);
148err_gpio_req:
149 return ret;
150}
151
152static void collie_power_exit(struct device *dev)
153{
154 gpio_free(COLLIE_GPIO_AC_IN);
155}
156
157static int collie_power_ac_online(void)
158{
159 return gpio_get_value(COLLIE_GPIO_AC_IN) == 2;
160}
161
162static char *collie_ac_supplied_to[] = { 134static char *collie_ac_supplied_to[] = {
163 "main-battery", 135 "main-battery",
164 "backup-battery", 136 "backup-battery",
165}; 137};
166 138
167static struct pda_power_pdata collie_power_data = { 139
168 .init = collie_power_init, 140static struct gpio_charger_platform_data collie_power_data = {
169 .is_ac_online = collie_power_ac_online, 141 .name = "charger",
170 .exit = collie_power_exit, 142 .type = POWER_SUPPLY_TYPE_MAINS,
143 .gpio = COLLIE_GPIO_AC_IN,
171 .supplied_to = collie_ac_supplied_to, 144 .supplied_to = collie_ac_supplied_to,
172 .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to), 145 .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to),
173}; 146};
174 147
175static struct resource collie_power_resource[] = {
176 {
177 .name = "ac",
178 .flags = IORESOURCE_IRQ |
179 IORESOURCE_IRQ_HIGHEDGE |
180 IORESOURCE_IRQ_LOWEDGE,
181 },
182};
183
184static struct platform_device collie_power_device = { 148static struct platform_device collie_power_device = {
185 .name = "pda-power", 149 .name = "gpio-charger",
186 .id = -1, 150 .id = -1,
187 .dev.platform_data = &collie_power_data, 151 .dev.platform_data = &collie_power_data,
188 .resource = collie_power_resource,
189 .num_resources = ARRAY_SIZE(collie_power_resource),
190}; 152};
191 153
192#ifdef CONFIG_SHARP_LOCOMO 154#ifdef CONFIG_SHARP_LOCOMO
@@ -420,9 +382,6 @@ static void __init collie_init(void)
420 382
421 GPSR |= _COLLIE_GPIO_UCB1x00_RESET; 383 GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
422 384
423 collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
424 collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
425
426 sa11x0_ppc_configure_mcp(); 385 sa11x0_ppc_configure_mcp();
427 386
428 387
diff --git a/arch/arm/mach-sa1100/include/mach/entry-macro.S b/arch/arm/mach-sa1100/include/mach/entry-macro.S
deleted file mode 100644
index 8cf7630bf024..000000000000
--- a/arch/arm/mach-sa1100/include/mach/entry-macro.S
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * arch/arm/mach-sa1100/include/mach/entry-macro.S
3 *
4 * Low-level IRQ helper macros for SA1100-based platforms
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 .macro get_irqnr_preamble, base, tmp
12 mov \base, #0xfa000000 @ ICIP = 0xfa050000
13 add \base, \base, #0x00050000
14 .endm
15
16 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
17 ldr \irqstat, [\base] @ get irqs
18 ldr \irqnr, [\base, #4] @ ICMR = 0xfa050004
19 ands \irqstat, \irqstat, \irqnr
20 mov \irqnr, #0
21 beq 1001f
22 tst \irqstat, #0xff
23 moveq \irqstat, \irqstat, lsr #8
24 addeq \irqnr, \irqnr, #8
25 tsteq \irqstat, #0xff
26 moveq \irqstat, \irqstat, lsr #8
27 addeq \irqnr, \irqnr, #8
28 tsteq \irqstat, #0xff
29 moveq \irqstat, \irqstat, lsr #8
30 addeq \irqnr, \irqnr, #8
31 tst \irqstat, #0x0f
32 moveq \irqstat, \irqstat, lsr #4
33 addeq \irqnr, \irqnr, #4
34 tst \irqstat, #0x03
35 moveq \irqstat, \irqstat, lsr #2
36 addeq \irqnr, \irqnr, #2
37 tst \irqstat, #0x01
38 addeqs \irqnr, \irqnr, #1
391001:
40 .endm
41
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 3790298b7142..de0983494c7e 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -8,56 +8,56 @@
8 * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs. 8 * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
9 */ 9 */
10 10
11#define IRQ_GPIO0 0 11#define IRQ_GPIO0 1
12#define IRQ_GPIO1 1 12#define IRQ_GPIO1 2
13#define IRQ_GPIO2 2 13#define IRQ_GPIO2 3
14#define IRQ_GPIO3 3 14#define IRQ_GPIO3 4
15#define IRQ_GPIO4 4 15#define IRQ_GPIO4 5
16#define IRQ_GPIO5 5 16#define IRQ_GPIO5 6
17#define IRQ_GPIO6 6 17#define IRQ_GPIO6 7
18#define IRQ_GPIO7 7 18#define IRQ_GPIO7 8
19#define IRQ_GPIO8 8 19#define IRQ_GPIO8 9
20#define IRQ_GPIO9 9 20#define IRQ_GPIO9 10
21#define IRQ_GPIO10 10 21#define IRQ_GPIO10 11
22#define IRQ_GPIO11_27 11 22#define IRQ_GPIO11_27 12
23#define IRQ_LCD 12 /* LCD controller */ 23#define IRQ_LCD 13 /* LCD controller */
24#define IRQ_Ser0UDC 13 /* Ser. port 0 UDC */ 24#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */
25#define IRQ_Ser1SDLC 14 /* Ser. port 1 SDLC */ 25#define IRQ_Ser1SDLC 15 /* Ser. port 1 SDLC */
26#define IRQ_Ser1UART 15 /* Ser. port 1 UART */ 26#define IRQ_Ser1UART 16 /* Ser. port 1 UART */
27#define IRQ_Ser2ICP 16 /* Ser. port 2 ICP */ 27#define IRQ_Ser2ICP 17 /* Ser. port 2 ICP */
28#define IRQ_Ser3UART 17 /* Ser. port 3 UART */ 28#define IRQ_Ser3UART 18 /* Ser. port 3 UART */
29#define IRQ_Ser4MCP 18 /* Ser. port 4 MCP */ 29#define IRQ_Ser4MCP 19 /* Ser. port 4 MCP */
30#define IRQ_Ser4SSP 19 /* Ser. port 4 SSP */ 30#define IRQ_Ser4SSP 20 /* Ser. port 4 SSP */
31#define IRQ_DMA0 20 /* DMA controller channel 0 */ 31#define IRQ_DMA0 21 /* DMA controller channel 0 */
32#define IRQ_DMA1 21 /* DMA controller channel 1 */ 32#define IRQ_DMA1 22 /* DMA controller channel 1 */
33#define IRQ_DMA2 22 /* DMA controller channel 2 */ 33#define IRQ_DMA2 23 /* DMA controller channel 2 */
34#define IRQ_DMA3 23 /* DMA controller channel 3 */ 34#define IRQ_DMA3 24 /* DMA controller channel 3 */
35#define IRQ_DMA4 24 /* DMA controller channel 4 */ 35#define IRQ_DMA4 25 /* DMA controller channel 4 */
36#define IRQ_DMA5 25 /* DMA controller channel 5 */ 36#define IRQ_DMA5 26 /* DMA controller channel 5 */
37#define IRQ_OST0 26 /* OS Timer match 0 */ 37#define IRQ_OST0 27 /* OS Timer match 0 */
38#define IRQ_OST1 27 /* OS Timer match 1 */ 38#define IRQ_OST1 28 /* OS Timer match 1 */
39#define IRQ_OST2 28 /* OS Timer match 2 */ 39#define IRQ_OST2 29 /* OS Timer match 2 */
40#define IRQ_OST3 29 /* OS Timer match 3 */ 40#define IRQ_OST3 30 /* OS Timer match 3 */
41#define IRQ_RTC1Hz 30 /* RTC 1 Hz clock */ 41#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */
42#define IRQ_RTCAlrm 31 /* RTC Alarm */ 42#define IRQ_RTCAlrm 32 /* RTC Alarm */
43 43
44#define IRQ_GPIO11 32 44#define IRQ_GPIO11 33
45#define IRQ_GPIO12 33 45#define IRQ_GPIO12 34
46#define IRQ_GPIO13 34 46#define IRQ_GPIO13 35
47#define IRQ_GPIO14 35 47#define IRQ_GPIO14 36
48#define IRQ_GPIO15 36 48#define IRQ_GPIO15 37
49#define IRQ_GPIO16 37 49#define IRQ_GPIO16 38
50#define IRQ_GPIO17 38 50#define IRQ_GPIO17 39
51#define IRQ_GPIO18 39 51#define IRQ_GPIO18 40
52#define IRQ_GPIO19 40 52#define IRQ_GPIO19 41
53#define IRQ_GPIO20 41 53#define IRQ_GPIO20 42
54#define IRQ_GPIO21 42 54#define IRQ_GPIO21 43
55#define IRQ_GPIO22 43 55#define IRQ_GPIO22 44
56#define IRQ_GPIO23 44 56#define IRQ_GPIO23 45
57#define IRQ_GPIO24 45 57#define IRQ_GPIO24 46
58#define IRQ_GPIO25 46 58#define IRQ_GPIO25 47
59#define IRQ_GPIO26 47 59#define IRQ_GPIO26 48
60#define IRQ_GPIO27 48 60#define IRQ_GPIO27 49
61 61
62/* 62/*
63 * The next 16 interrupts are for board specific purposes. Since 63 * The next 16 interrupts are for board specific purposes. Since
@@ -65,8 +65,8 @@
65 * these. If you need more, increase IRQ_BOARD_END, but keep it 65 * these. If you need more, increase IRQ_BOARD_END, but keep it
66 * within sensible limits. IRQs 49 to 64 are available. 66 * within sensible limits. IRQs 49 to 64 are available.
67 */ 67 */
68#define IRQ_BOARD_START 49 68#define IRQ_BOARD_START 50
69#define IRQ_BOARD_END 65 69#define IRQ_BOARD_END 66
70 70
71/* 71/*
72 * Figure out the MAX IRQ number. 72 * Figure out the MAX IRQ number.
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 2124f1fc2fbe..63e2901db416 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -14,17 +14,73 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/irqdomain.h>
17#include <linux/ioport.h> 18#include <linux/ioport.h>
18#include <linux/syscore_ops.h> 19#include <linux/syscore_ops.h>
19 20
20#include <mach/hardware.h> 21#include <mach/hardware.h>
21#include <mach/irqs.h> 22#include <mach/irqs.h>
22#include <asm/mach/irq.h> 23#include <asm/mach/irq.h>
24#include <asm/exception.h>
23 25
24#include "generic.h" 26#include "generic.h"
25 27
26 28
27/* 29/*
30 * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
31 * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
32 */
33static void sa1100_mask_irq(struct irq_data *d)
34{
35 ICMR &= ~BIT(d->hwirq);
36}
37
38static void sa1100_unmask_irq(struct irq_data *d)
39{
40 ICMR |= BIT(d->hwirq);
41}
42
43/*
44 * Apart form GPIOs, only the RTC alarm can be a wakeup event.
45 */
46static int sa1100_set_wake(struct irq_data *d, unsigned int on)
47{
48 if (BIT(d->hwirq) == IC_RTCAlrm) {
49 if (on)
50 PWER |= PWER_RTC;
51 else
52 PWER &= ~PWER_RTC;
53 return 0;
54 }
55 return -EINVAL;
56}
57
58static struct irq_chip sa1100_normal_chip = {
59 .name = "SC",
60 .irq_ack = sa1100_mask_irq,
61 .irq_mask = sa1100_mask_irq,
62 .irq_unmask = sa1100_unmask_irq,
63 .irq_set_wake = sa1100_set_wake,
64};
65
66static int sa1100_normal_irqdomain_map(struct irq_domain *d,
67 unsigned int irq, irq_hw_number_t hwirq)
68{
69 irq_set_chip_and_handler(irq, &sa1100_normal_chip,
70 handle_level_irq);
71 set_irq_flags(irq, IRQF_VALID);
72
73 return 0;
74}
75
76static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
77 .map = sa1100_normal_irqdomain_map,
78 .xlate = irq_domain_xlate_onetwocell,
79};
80
81static struct irq_domain *sa1100_normal_irqdomain;
82
83/*
28 * SA1100 GPIO edge detection for IRQs: 84 * SA1100 GPIO edge detection for IRQs:
29 * IRQs are generated on Falling-Edge, Rising-Edge, or both. 85 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
30 * Use this instead of directly setting GRER/GFER. 86 * Use this instead of directly setting GRER/GFER.
@@ -33,20 +89,11 @@ static int GPIO_IRQ_rising_edge;
33static int GPIO_IRQ_falling_edge; 89static int GPIO_IRQ_falling_edge;
34static int GPIO_IRQ_mask = (1 << 11) - 1; 90static int GPIO_IRQ_mask = (1 << 11) - 1;
35 91
36/*
37 * To get the GPIO number from an IRQ number
38 */
39#define GPIO_11_27_IRQ(i) ((i) - 21)
40#define GPIO11_27_MASK(irq) (1 << GPIO_11_27_IRQ(irq))
41
42static int sa1100_gpio_type(struct irq_data *d, unsigned int type) 92static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
43{ 93{
44 unsigned int mask; 94 unsigned int mask;
45 95
46 if (d->irq <= 10) 96 mask = BIT(d->hwirq);
47 mask = 1 << d->irq;
48 else
49 mask = GPIO11_27_MASK(d->irq);
50 97
51 if (type == IRQ_TYPE_PROBE) { 98 if (type == IRQ_TYPE_PROBE) {
52 if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask) 99 if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
@@ -70,41 +117,51 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
70} 117}
71 118
72/* 119/*
73 * GPIO IRQs must be acknowledged. This is for IRQs from 0 to 10. 120 * GPIO IRQs must be acknowledged.
74 */ 121 */
75static void sa1100_low_gpio_ack(struct irq_data *d) 122static void sa1100_gpio_ack(struct irq_data *d)
76{
77 GEDR = (1 << d->irq);
78}
79
80static void sa1100_low_gpio_mask(struct irq_data *d)
81{
82 ICMR &= ~(1 << d->irq);
83}
84
85static void sa1100_low_gpio_unmask(struct irq_data *d)
86{ 123{
87 ICMR |= 1 << d->irq; 124 GEDR = BIT(d->hwirq);
88} 125}
89 126
90static int sa1100_low_gpio_wake(struct irq_data *d, unsigned int on) 127static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
91{ 128{
92 if (on) 129 if (on)
93 PWER |= 1 << d->irq; 130 PWER |= BIT(d->hwirq);
94 else 131 else
95 PWER &= ~(1 << d->irq); 132 PWER &= ~BIT(d->hwirq);
96 return 0; 133 return 0;
97} 134}
98 135
136/*
137 * This is for IRQs from 0 to 10.
138 */
99static struct irq_chip sa1100_low_gpio_chip = { 139static struct irq_chip sa1100_low_gpio_chip = {
100 .name = "GPIO-l", 140 .name = "GPIO-l",
101 .irq_ack = sa1100_low_gpio_ack, 141 .irq_ack = sa1100_gpio_ack,
102 .irq_mask = sa1100_low_gpio_mask, 142 .irq_mask = sa1100_mask_irq,
103 .irq_unmask = sa1100_low_gpio_unmask, 143 .irq_unmask = sa1100_unmask_irq,
104 .irq_set_type = sa1100_gpio_type, 144 .irq_set_type = sa1100_gpio_type,
105 .irq_set_wake = sa1100_low_gpio_wake, 145 .irq_set_wake = sa1100_gpio_wake,
146};
147
148static int sa1100_low_gpio_irqdomain_map(struct irq_domain *d,
149 unsigned int irq, irq_hw_number_t hwirq)
150{
151 irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
152 handle_edge_irq);
153 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
154
155 return 0;
156}
157
158static struct irq_domain_ops sa1100_low_gpio_irqdomain_ops = {
159 .map = sa1100_low_gpio_irqdomain_map,
160 .xlate = irq_domain_xlate_onetwocell,
106}; 161};
107 162
163static struct irq_domain *sa1100_low_gpio_irqdomain;
164
108/* 165/*
109 * IRQ11 (GPIO11 through 27) handler. We enter here with the 166 * IRQ11 (GPIO11 through 27) handler. We enter here with the
110 * irq_controller_lock held, and IRQs disabled. Decode the IRQ 167 * irq_controller_lock held, and IRQs disabled. Decode the IRQ
@@ -141,16 +198,9 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
141 * In addition, the IRQs are all collected up into one bit in the 198 * In addition, the IRQs are all collected up into one bit in the
142 * interrupt controller registers. 199 * interrupt controller registers.
143 */ 200 */
144static void sa1100_high_gpio_ack(struct irq_data *d)
145{
146 unsigned int mask = GPIO11_27_MASK(d->irq);
147
148 GEDR = mask;
149}
150
151static void sa1100_high_gpio_mask(struct irq_data *d) 201static void sa1100_high_gpio_mask(struct irq_data *d)
152{ 202{
153 unsigned int mask = GPIO11_27_MASK(d->irq); 203 unsigned int mask = BIT(d->hwirq);
154 204
155 GPIO_IRQ_mask &= ~mask; 205 GPIO_IRQ_mask &= ~mask;
156 206
@@ -160,7 +210,7 @@ static void sa1100_high_gpio_mask(struct irq_data *d)
160 210
161static void sa1100_high_gpio_unmask(struct irq_data *d) 211static void sa1100_high_gpio_unmask(struct irq_data *d)
162{ 212{
163 unsigned int mask = GPIO11_27_MASK(d->irq); 213 unsigned int mask = BIT(d->hwirq);
164 214
165 GPIO_IRQ_mask |= mask; 215 GPIO_IRQ_mask |= mask;
166 216
@@ -168,61 +218,32 @@ static void sa1100_high_gpio_unmask(struct irq_data *d)
168 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; 218 GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
169} 219}
170 220
171static int sa1100_high_gpio_wake(struct irq_data *d, unsigned int on)
172{
173 if (on)
174 PWER |= GPIO11_27_MASK(d->irq);
175 else
176 PWER &= ~GPIO11_27_MASK(d->irq);
177 return 0;
178}
179
180static struct irq_chip sa1100_high_gpio_chip = { 221static struct irq_chip sa1100_high_gpio_chip = {
181 .name = "GPIO-h", 222 .name = "GPIO-h",
182 .irq_ack = sa1100_high_gpio_ack, 223 .irq_ack = sa1100_gpio_ack,
183 .irq_mask = sa1100_high_gpio_mask, 224 .irq_mask = sa1100_high_gpio_mask,
184 .irq_unmask = sa1100_high_gpio_unmask, 225 .irq_unmask = sa1100_high_gpio_unmask,
185 .irq_set_type = sa1100_gpio_type, 226 .irq_set_type = sa1100_gpio_type,
186 .irq_set_wake = sa1100_high_gpio_wake, 227 .irq_set_wake = sa1100_gpio_wake,
187}; 228};
188 229
189/* 230static int sa1100_high_gpio_irqdomain_map(struct irq_domain *d,
190 * We don't need to ACK IRQs on the SA1100 unless they're GPIOs 231 unsigned int irq, irq_hw_number_t hwirq)
191 * this is for internal IRQs i.e. from 11 to 31.
192 */
193static void sa1100_mask_irq(struct irq_data *d)
194{
195 ICMR &= ~(1 << d->irq);
196}
197
198static void sa1100_unmask_irq(struct irq_data *d)
199{ 232{
200 ICMR |= (1 << d->irq); 233 irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
201} 234 handle_edge_irq);
235 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
202 236
203/* 237 return 0;
204 * Apart form GPIOs, only the RTC alarm can be a wakeup event.
205 */
206static int sa1100_set_wake(struct irq_data *d, unsigned int on)
207{
208 if (d->irq == IRQ_RTCAlrm) {
209 if (on)
210 PWER |= PWER_RTC;
211 else
212 PWER &= ~PWER_RTC;
213 return 0;
214 }
215 return -EINVAL;
216} 238}
217 239
218static struct irq_chip sa1100_normal_chip = { 240static struct irq_domain_ops sa1100_high_gpio_irqdomain_ops = {
219 .name = "SC", 241 .map = sa1100_high_gpio_irqdomain_map,
220 .irq_ack = sa1100_mask_irq, 242 .xlate = irq_domain_xlate_onetwocell,
221 .irq_mask = sa1100_mask_irq,
222 .irq_unmask = sa1100_unmask_irq,
223 .irq_set_wake = sa1100_set_wake,
224}; 243};
225 244
245static struct irq_domain *sa1100_high_gpio_irqdomain;
246
226static struct resource irq_resource = 247static struct resource irq_resource =
227 DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); 248 DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
228 249
@@ -291,10 +312,25 @@ static int __init sa1100irq_init_devicefs(void)
291 312
292device_initcall(sa1100irq_init_devicefs); 313device_initcall(sa1100irq_init_devicefs);
293 314
294void __init sa1100_init_irq(void) 315static asmlinkage void __exception_irq_entry
316sa1100_handle_irq(struct pt_regs *regs)
295{ 317{
296 unsigned int irq; 318 uint32_t icip, icmr, mask;
319
320 do {
321 icip = (ICIP);
322 icmr = (ICMR);
323 mask = icip & icmr;
324
325 if (mask == 0)
326 break;
327
328 handle_IRQ(ffs(mask) - 1 + IRQ_GPIO0, regs);
329 } while (1);
330}
297 331
332void __init sa1100_init_irq(void)
333{
298 request_resource(&iomem_resource, &irq_resource); 334 request_resource(&iomem_resource, &irq_resource);
299 335
300 /* disable all IRQs */ 336 /* disable all IRQs */
@@ -314,29 +350,24 @@ void __init sa1100_init_irq(void)
314 */ 350 */
315 ICCR = 1; 351 ICCR = 1;
316 352
317 for (irq = 0; irq <= 10; irq++) { 353 sa1100_low_gpio_irqdomain = irq_domain_add_legacy(NULL,
318 irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip, 354 11, IRQ_GPIO0, 0,
319 handle_edge_irq); 355 &sa1100_low_gpio_irqdomain_ops, NULL);
320 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
321 }
322 356
323 for (irq = 12; irq <= 31; irq++) { 357 sa1100_normal_irqdomain = irq_domain_add_legacy(NULL,
324 irq_set_chip_and_handler(irq, &sa1100_normal_chip, 358 21, IRQ_GPIO11_27, 11,
325 handle_level_irq); 359 &sa1100_normal_irqdomain_ops, NULL);
326 set_irq_flags(irq, IRQF_VALID);
327 }
328 360
329 for (irq = 32; irq <= 48; irq++) { 361 sa1100_high_gpio_irqdomain = irq_domain_add_legacy(NULL,
330 irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip, 362 17, IRQ_GPIO11, 11,
331 handle_edge_irq); 363 &sa1100_high_gpio_irqdomain_ops, NULL);
332 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
333 }
334 364
335 /* 365 /*
336 * Install handler for GPIO 11-27 edge detect interrupts 366 * Install handler for GPIO 11-27 edge detect interrupts
337 */ 367 */
338 irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
339 irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler); 368 irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
340 369
370 set_handle_irq(sa1100_handle_irq);
371
341 sa1100_init_gpio(); 372 sa1100_init_gpio();
342} 373}
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ab906b801047..03823e784f63 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -1009,3 +1009,24 @@ config ARCH_SUPPORTS_BIG_ENDIAN
1009 help 1009 help
1010 This option specifies the architecture can support big endian 1010 This option specifies the architecture can support big endian
1011 operation. 1011 operation.
1012
1013config ARM_KERNMEM_PERMS
1014 bool "Restrict kernel memory permissions"
1015 help
1016 If this is set, kernel memory other than kernel text (and rodata)
1017 will be made non-executable. The tradeoff is that each region is
1018 padded to section-size (1MiB) boundaries (because their permissions
1019 are different and splitting the 1M pages into 4K ones causes TLB
1020 performance problems), wasting memory.
1021
1022config DEBUG_RODATA
1023 bool "Make kernel text and rodata read-only"
1024 depends on ARM_KERNMEM_PERMS
1025 default y
1026 help
1027 If this is set, kernel text and rodata will be made read-only. This
1028 is to help catch accidental or malicious attempts to change the
1029 kernel's executable code. Additionally splits rodata from kernel
1030 text so it can be made explicitly non-executable. This creates
1031 another section-size padded region, so it can waste more memory
1032 space while gaining the read-only protections.
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 91da64de440f..d3afdf9eb65a 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -6,7 +6,7 @@ obj-y := dma-mapping.o extable.o fault.o init.o \
6 iomap.o 6 iomap.o
7 7
8obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \ 8obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
9 mmap.o pgd.o mmu.o 9 mmap.o pgd.o mmu.o pageattr.o
10 10
11ifneq ($(CONFIG_MMU),y) 11ifneq ($(CONFIG_MMU),y)
12obj-y += nommu.o 12obj-y += nommu.o
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 83792f4324ea..2c0c541c60ca 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -113,7 +113,7 @@ static int safe_usermode(int new_usermode, bool warn)
113 new_usermode |= UM_FIXUP; 113 new_usermode |= UM_FIXUP;
114 114
115 if (warn) 115 if (warn)
116 printk(KERN_WARNING "alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n"); 116 pr_warn("alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n");
117 } 117 }
118 118
119 return new_usermode; 119 return new_usermode;
@@ -523,7 +523,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
523 * processor for us. 523 * processor for us.
524 */ 524 */
525 if (addr != eaddr) { 525 if (addr != eaddr) {
526 printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, " 526 pr_err("LDMSTM: PC = %08lx, instr = %08lx, "
527 "addr = %08lx, eaddr = %08lx\n", 527 "addr = %08lx, eaddr = %08lx\n",
528 instruction_pointer(regs), instr, addr, eaddr); 528 instruction_pointer(regs), instr, addr, eaddr);
529 show_regs(regs); 529 show_regs(regs);
@@ -567,7 +567,7 @@ fault:
567 return TYPE_FAULT; 567 return TYPE_FAULT;
568 568
569bad: 569bad:
570 printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n"); 570 pr_err("Alignment trap: not handling ldm with s-bit set\n");
571 return TYPE_ERROR; 571 return TYPE_ERROR;
572} 572}
573 573
@@ -899,13 +899,13 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
899 return 0; 899 return 0;
900 900
901 swp: 901 swp:
902 printk(KERN_ERR "Alignment trap: not handling swp instruction\n"); 902 pr_err("Alignment trap: not handling swp instruction\n");
903 903
904 bad: 904 bad:
905 /* 905 /*
906 * Oops, we didn't handle the instruction. 906 * Oops, we didn't handle the instruction.
907 */ 907 */
908 printk(KERN_ERR "Alignment trap: not handling instruction " 908 pr_err("Alignment trap: not handling instruction "
909 "%0*lx at [<%08lx>]\n", 909 "%0*lx at [<%08lx>]\n",
910 isize << 1, 910 isize << 1,
911 isize == 2 ? tinstr : instr, instrptr); 911 isize == 2 ? tinstr : instr, instrptr);
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index e028a7f2ebcc..097181e08c25 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -313,7 +313,7 @@ static void __init disable_l2_prefetch(void)
313 */ 313 */
314 u = read_extra_features(); 314 u = read_extra_features();
315 if (!(u & 0x01000000)) { 315 if (!(u & 0x01000000)) {
316 printk(KERN_INFO "Feroceon L2: Disabling L2 prefetch.\n"); 316 pr_info("Feroceon L2: Disabling L2 prefetch.\n");
317 write_extra_features(u | 0x01000000); 317 write_extra_features(u | 0x01000000);
318 } 318 }
319} 319}
@@ -326,7 +326,7 @@ static void __init enable_l2(void)
326 if (!(u & 0x00400000)) { 326 if (!(u & 0x00400000)) {
327 int i, d; 327 int i, d;
328 328
329 printk(KERN_INFO "Feroceon L2: Enabling L2\n"); 329 pr_info("Feroceon L2: Enabling L2\n");
330 330
331 d = flush_and_disable_dcache(); 331 d = flush_and_disable_dcache();
332 i = invalidate_and_disable_icache(); 332 i = invalidate_and_disable_icache();
@@ -353,7 +353,7 @@ void __init feroceon_l2_init(int __l2_wt_override)
353 353
354 enable_l2(); 354 enable_l2();
355 355
356 printk(KERN_INFO "Feroceon L2: Cache support initialised%s.\n", 356 pr_info("Feroceon L2: Cache support initialised%s.\n",
357 l2_wt_override ? ", in WT override mode" : ""); 357 l2_wt_override ? ", in WT override mode" : "");
358} 358}
359#ifdef CONFIG_OF 359#ifdef CONFIG_OF
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c
index b273739e6359..1e373d268c04 100644
--- a/arch/arm/mm/cache-tauros2.c
+++ b/arch/arm/mm/cache-tauros2.c
@@ -185,7 +185,7 @@ static void enable_extra_feature(unsigned int features)
185 u &= ~0x01000000; 185 u &= ~0x01000000;
186 else 186 else
187 u |= 0x01000000; 187 u |= 0x01000000;
188 printk(KERN_INFO "Tauros2: %s L2 prefetch.\n", 188 pr_info("Tauros2: %s L2 prefetch.\n",
189 (features & CACHE_TAUROS2_PREFETCH_ON) 189 (features & CACHE_TAUROS2_PREFETCH_ON)
190 ? "Enabling" : "Disabling"); 190 ? "Enabling" : "Disabling");
191 191
@@ -193,7 +193,7 @@ static void enable_extra_feature(unsigned int features)
193 u |= 0x00100000; 193 u |= 0x00100000;
194 else 194 else
195 u &= ~0x00100000; 195 u &= ~0x00100000;
196 printk(KERN_INFO "Tauros2: %s line fill burt8.\n", 196 pr_info("Tauros2: %s line fill burt8.\n",
197 (features & CACHE_TAUROS2_LINEFILL_BURST8) 197 (features & CACHE_TAUROS2_LINEFILL_BURST8)
198 ? "Enabling" : "Disabling"); 198 ? "Enabling" : "Disabling");
199 199
@@ -216,7 +216,7 @@ static void __init tauros2_internal_init(unsigned int features)
216 */ 216 */
217 feat = read_extra_features(); 217 feat = read_extra_features();
218 if (!(feat & 0x00400000)) { 218 if (!(feat & 0x00400000)) {
219 printk(KERN_INFO "Tauros2: Enabling L2 cache.\n"); 219 pr_info("Tauros2: Enabling L2 cache.\n");
220 write_extra_features(feat | 0x00400000); 220 write_extra_features(feat | 0x00400000);
221 } 221 }
222 222
@@ -253,7 +253,7 @@ static void __init tauros2_internal_init(unsigned int features)
253 */ 253 */
254 actlr = read_actlr(); 254 actlr = read_actlr();
255 if (!(actlr & 0x00000002)) { 255 if (!(actlr & 0x00000002)) {
256 printk(KERN_INFO "Tauros2: Enabling L2 cache.\n"); 256 pr_info("Tauros2: Enabling L2 cache.\n");
257 write_actlr(actlr | 0x00000002); 257 write_actlr(actlr | 0x00000002);
258 } 258 }
259 259
@@ -262,11 +262,11 @@ static void __init tauros2_internal_init(unsigned int features)
262#endif 262#endif
263 263
264 if (mode == NULL) { 264 if (mode == NULL) {
265 printk(KERN_CRIT "Tauros2: Unable to detect CPU mode.\n"); 265 pr_crit("Tauros2: Unable to detect CPU mode.\n");
266 return; 266 return;
267 } 267 }
268 268
269 printk(KERN_INFO "Tauros2: L2 cache support initialised " 269 pr_info("Tauros2: L2 cache support initialised "
270 "in %s mode.\n", mode); 270 "in %s mode.\n", mode);
271} 271}
272 272
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 6eb97b3a7481..91892569710f 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -184,36 +184,46 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
184 u64 asid = atomic64_read(&mm->context.id); 184 u64 asid = atomic64_read(&mm->context.id);
185 u64 generation = atomic64_read(&asid_generation); 185 u64 generation = atomic64_read(&asid_generation);
186 186
187 if (asid != 0 && is_reserved_asid(asid)) { 187 if (asid != 0) {
188 /* 188 /*
189 * Our current ASID was active during a rollover, we can 189 * If our current ASID was active during a rollover, we
190 * continue to use it and this was just a false alarm. 190 * can continue to use it and this was just a false alarm.
191 */ 191 */
192 asid = generation | (asid & ~ASID_MASK); 192 if (is_reserved_asid(asid))
193 } else { 193 return generation | (asid & ~ASID_MASK);
194
194 /* 195 /*
195 * Allocate a free ASID. If we can't find one, take a 196 * We had a valid ASID in a previous life, so try to re-use
196 * note of the currently active ASIDs and mark the TLBs 197 * it if possible.,
197 * as requiring flushes. We always count from ASID #1,
198 * as we reserve ASID #0 to switch via TTBR0 and to
199 * avoid speculative page table walks from hitting in
200 * any partial walk caches, which could be populated
201 * from overlapping level-1 descriptors used to map both
202 * the module area and the userspace stack.
203 */ 198 */
204 asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx); 199 asid &= ~ASID_MASK;
205 if (asid == NUM_USER_ASIDS) { 200 if (!__test_and_set_bit(asid, asid_map))
206 generation = atomic64_add_return(ASID_FIRST_VERSION, 201 goto bump_gen;
207 &asid_generation);
208 flush_context(cpu);
209 asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
210 }
211 __set_bit(asid, asid_map);
212 cur_idx = asid;
213 asid |= generation;
214 cpumask_clear(mm_cpumask(mm));
215 } 202 }
216 203
204 /*
205 * Allocate a free ASID. If we can't find one, take a note of the
206 * currently active ASIDs and mark the TLBs as requiring flushes.
207 * We always count from ASID #1, as we reserve ASID #0 to switch
208 * via TTBR0 and to avoid speculative page table walks from hitting
209 * in any partial walk caches, which could be populated from
210 * overlapping level-1 descriptors used to map both the module
211 * area and the userspace stack.
212 */
213 asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
214 if (asid == NUM_USER_ASIDS) {
215 generation = atomic64_add_return(ASID_FIRST_VERSION,
216 &asid_generation);
217 flush_context(cpu);
218 asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
219 }
220
221 __set_bit(asid, asid_map);
222 cur_idx = asid;
223
224bump_gen:
225 asid |= generation;
226 cpumask_clear(mm_cpumask(mm));
217 return asid; 227 return asid;
218} 228}
219 229
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index b9bcc9d79176..70423345da26 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -62,7 +62,7 @@ static void discard_old_kernel_data(void *kto)
62 __asm__("mcrr p15, 0, %1, %0, c6 @ 0xec401f06" 62 __asm__("mcrr p15, 0, %1, %0, c6 @ 0xec401f06"
63 : 63 :
64 : "r" (kto), 64 : "r" (kto),
65 "r" ((unsigned long)kto + PAGE_SIZE - L1_CACHE_BYTES) 65 "r" ((unsigned long)kto + PAGE_SIZE - 1)
66 : "cc"); 66 : "cc");
67} 67}
68 68
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index ff379ac115df..d9e0d00a6699 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -235,7 +235,7 @@ void __init check_writebuffer_bugs(void)
235 const char *reason; 235 const char *reason;
236 unsigned long v = 1; 236 unsigned long v = 1;
237 237
238 printk(KERN_INFO "CPU: Testing write buffer coherency: "); 238 pr_info("CPU: Testing write buffer coherency: ");
239 239
240 page = alloc_page(GFP_KERNEL); 240 page = alloc_page(GFP_KERNEL);
241 if (page) { 241 if (page) {
@@ -261,9 +261,9 @@ void __init check_writebuffer_bugs(void)
261 } 261 }
262 262
263 if (v) { 263 if (v) {
264 printk("failed, %s\n", reason); 264 pr_cont("failed, %s\n", reason);
265 shared_pte_mask = L_PTE_MT_UNCACHED; 265 shared_pte_mask = L_PTE_MT_UNCACHED;
266 } else { 266 } else {
267 printk("ok\n"); 267 pr_cont("ok\n");
268 } 268 }
269} 269}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index eb8830a4c5ed..a982dc3190df 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -63,9 +63,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
63 if (!mm) 63 if (!mm)
64 mm = &init_mm; 64 mm = &init_mm;
65 65
66 printk(KERN_ALERT "pgd = %p\n", mm->pgd); 66 pr_alert("pgd = %p\n", mm->pgd);
67 pgd = pgd_offset(mm, addr); 67 pgd = pgd_offset(mm, addr);
68 printk(KERN_ALERT "[%08lx] *pgd=%08llx", 68 pr_alert("[%08lx] *pgd=%08llx",
69 addr, (long long)pgd_val(*pgd)); 69 addr, (long long)pgd_val(*pgd));
70 70
71 do { 71 do {
@@ -77,31 +77,31 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
77 break; 77 break;
78 78
79 if (pgd_bad(*pgd)) { 79 if (pgd_bad(*pgd)) {
80 printk("(bad)"); 80 pr_cont("(bad)");
81 break; 81 break;
82 } 82 }
83 83
84 pud = pud_offset(pgd, addr); 84 pud = pud_offset(pgd, addr);
85 if (PTRS_PER_PUD != 1) 85 if (PTRS_PER_PUD != 1)
86 printk(", *pud=%08llx", (long long)pud_val(*pud)); 86 pr_cont(", *pud=%08llx", (long long)pud_val(*pud));
87 87
88 if (pud_none(*pud)) 88 if (pud_none(*pud))
89 break; 89 break;
90 90
91 if (pud_bad(*pud)) { 91 if (pud_bad(*pud)) {
92 printk("(bad)"); 92 pr_cont("(bad)");
93 break; 93 break;
94 } 94 }
95 95
96 pmd = pmd_offset(pud, addr); 96 pmd = pmd_offset(pud, addr);
97 if (PTRS_PER_PMD != 1) 97 if (PTRS_PER_PMD != 1)
98 printk(", *pmd=%08llx", (long long)pmd_val(*pmd)); 98 pr_cont(", *pmd=%08llx", (long long)pmd_val(*pmd));
99 99
100 if (pmd_none(*pmd)) 100 if (pmd_none(*pmd))
101 break; 101 break;
102 102
103 if (pmd_bad(*pmd)) { 103 if (pmd_bad(*pmd)) {
104 printk("(bad)"); 104 pr_cont("(bad)");
105 break; 105 break;
106 } 106 }
107 107
@@ -110,15 +110,15 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
110 break; 110 break;
111 111
112 pte = pte_offset_map(pmd, addr); 112 pte = pte_offset_map(pmd, addr);
113 printk(", *pte=%08llx", (long long)pte_val(*pte)); 113 pr_cont(", *pte=%08llx", (long long)pte_val(*pte));
114#ifndef CONFIG_ARM_LPAE 114#ifndef CONFIG_ARM_LPAE
115 printk(", *ppte=%08llx", 115 pr_cont(", *ppte=%08llx",
116 (long long)pte_val(pte[PTE_HWTABLE_PTRS])); 116 (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
117#endif 117#endif
118 pte_unmap(pte); 118 pte_unmap(pte);
119 } while(0); 119 } while(0);
120 120
121 printk("\n"); 121 pr_cont("\n");
122} 122}
123#else /* CONFIG_MMU */ 123#else /* CONFIG_MMU */
124void show_pte(struct mm_struct *mm, unsigned long addr) 124void show_pte(struct mm_struct *mm, unsigned long addr)
@@ -142,10 +142,9 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
142 * No handler, we'll have to terminate things with extreme prejudice. 142 * No handler, we'll have to terminate things with extreme prejudice.
143 */ 143 */
144 bust_spinlocks(1); 144 bust_spinlocks(1);
145 printk(KERN_ALERT 145 pr_alert("Unable to handle kernel %s at virtual address %08lx\n",
146 "Unable to handle kernel %s at virtual address %08lx\n", 146 (addr < PAGE_SIZE) ? "NULL pointer dereference" :
147 (addr < PAGE_SIZE) ? "NULL pointer dereference" : 147 "paging request", addr);
148 "paging request", addr);
149 148
150 show_pte(mm, addr); 149 show_pte(mm, addr);
151 die("Oops", regs, fsr); 150 die("Oops", regs, fsr);
@@ -551,7 +550,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
551 if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) 550 if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
552 return; 551 return;
553 552
554 printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", 553 pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
555 inf->name, fsr, addr); 554 inf->name, fsr, addr);
556 555
557 info.si_signo = inf->sig; 556 info.si_signo = inf->sig;
@@ -583,7 +582,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
583 if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) 582 if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
584 return; 583 return;
585 584
586 printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", 585 pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
587 inf->name, ifsr, addr); 586 inf->name, ifsr, addr);
588 587
589 info.si_signo = inf->sig; 588 info.si_signo = inf->sig;
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 265b836b3bd1..34b66af516ea 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -33,7 +33,7 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
33 asm( "mcrr p15, 0, %1, %0, c14\n" 33 asm( "mcrr p15, 0, %1, %0, c14\n"
34 " mcr p15, 0, %2, c7, c10, 4" 34 " mcr p15, 0, %2, c7, c10, 4"
35 : 35 :
36 : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) 36 : "r" (to), "r" (to + PAGE_SIZE - 1), "r" (zero)
37 : "cc"); 37 : "cc");
38} 38}
39 39
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index e17ed00828d7..b98895d9fe57 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -18,19 +18,20 @@
18#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
19#include "mm.h" 19#include "mm.h"
20 20
21pte_t *fixmap_page_table;
22
23static inline void set_fixmap_pte(int idx, pte_t pte) 21static inline void set_fixmap_pte(int idx, pte_t pte)
24{ 22{
25 unsigned long vaddr = __fix_to_virt(idx); 23 unsigned long vaddr = __fix_to_virt(idx);
26 set_pte_ext(fixmap_page_table + idx, pte, 0); 24 pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
25
26 set_pte_ext(ptep, pte, 0);
27 local_flush_tlb_kernel_page(vaddr); 27 local_flush_tlb_kernel_page(vaddr);
28} 28}
29 29
30static inline pte_t get_fixmap_pte(unsigned long vaddr) 30static inline pte_t get_fixmap_pte(unsigned long vaddr)
31{ 31{
32 unsigned long idx = __virt_to_fix(vaddr); 32 pte_t *ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
33 return *(fixmap_page_table + idx); 33
34 return *ptep;
34} 35}
35 36
36void *kmap(struct page *page) 37void *kmap(struct page *page)
@@ -84,7 +85,7 @@ void *kmap_atomic(struct page *page)
84 * With debugging enabled, kunmap_atomic forces that entry to 0. 85 * With debugging enabled, kunmap_atomic forces that entry to 0.
85 * Make sure it was indeed properly unmapped. 86 * Make sure it was indeed properly unmapped.
86 */ 87 */
87 BUG_ON(!pte_none(*(fixmap_page_table + idx))); 88 BUG_ON(!pte_none(get_fixmap_pte(vaddr)));
88#endif 89#endif
89 /* 90 /*
90 * When debugging is off, kunmap_atomic leaves the previous mapping 91 * When debugging is off, kunmap_atomic leaves the previous mapping
@@ -137,7 +138,7 @@ void *kmap_atomic_pfn(unsigned long pfn)
137 idx = type + KM_TYPE_NR * smp_processor_id(); 138 idx = type + KM_TYPE_NR * smp_processor_id();
138 vaddr = __fix_to_virt(idx); 139 vaddr = __fix_to_virt(idx);
139#ifdef CONFIG_DEBUG_HIGHMEM 140#ifdef CONFIG_DEBUG_HIGHMEM
140 BUG_ON(!pte_none(*(fixmap_page_table + idx))); 141 BUG_ON(!pte_none(get_fixmap_pte(vaddr)));
141#endif 142#endif
142 set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot)); 143 set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
143 144
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 9481f85c56e6..98ad9c79ea0e 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -29,6 +29,7 @@
29#include <asm/prom.h> 29#include <asm/prom.h>
30#include <asm/sections.h> 30#include <asm/sections.h>
31#include <asm/setup.h> 31#include <asm/setup.h>
32#include <asm/system_info.h>
32#include <asm/tlb.h> 33#include <asm/tlb.h>
33#include <asm/fixmap.h> 34#include <asm/fixmap.h>
34 35
@@ -67,7 +68,7 @@ early_param("initrd", early_initrd);
67 68
68static int __init parse_tag_initrd(const struct tag *tag) 69static int __init parse_tag_initrd(const struct tag *tag)
69{ 70{
70 printk(KERN_WARNING "ATAG_INITRD is deprecated; " 71 pr_warn("ATAG_INITRD is deprecated; "
71 "please update your bootloader.\n"); 72 "please update your bootloader.\n");
72 phys_initrd_start = __virt_to_phys(tag->u.initrd.start); 73 phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
73 phys_initrd_size = tag->u.initrd.size; 74 phys_initrd_size = tag->u.initrd.size;
@@ -544,7 +545,7 @@ void __init mem_init(void)
544#define MLM(b, t) b, t, ((t) - (b)) >> 20 545#define MLM(b, t) b, t, ((t) - (b)) >> 20
545#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) 546#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
546 547
547 printk(KERN_NOTICE "Virtual kernel memory layout:\n" 548 pr_notice("Virtual kernel memory layout:\n"
548 " vector : 0x%08lx - 0x%08lx (%4ld kB)\n" 549 " vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
549#ifdef CONFIG_HAVE_TCM 550#ifdef CONFIG_HAVE_TCM
550 " DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n" 551 " DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
@@ -570,7 +571,7 @@ void __init mem_init(void)
570 MLK(DTCM_OFFSET, (unsigned long) dtcm_end), 571 MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
571 MLK(ITCM_OFFSET, (unsigned long) itcm_end), 572 MLK(ITCM_OFFSET, (unsigned long) itcm_end),
572#endif 573#endif
573 MLK(FIXADDR_START, FIXADDR_TOP), 574 MLK(FIXADDR_START, FIXADDR_END),
574 MLM(VMALLOC_START, VMALLOC_END), 575 MLM(VMALLOC_START, VMALLOC_END),
575 MLM(PAGE_OFFSET, (unsigned long)high_memory), 576 MLM(PAGE_OFFSET, (unsigned long)high_memory),
576#ifdef CONFIG_HIGHMEM 577#ifdef CONFIG_HIGHMEM
@@ -615,7 +616,145 @@ void __init mem_init(void)
615 } 616 }
616} 617}
617 618
618void free_initmem(void) 619#ifdef CONFIG_ARM_KERNMEM_PERMS
620struct section_perm {
621 unsigned long start;
622 unsigned long end;
623 pmdval_t mask;
624 pmdval_t prot;
625 pmdval_t clear;
626};
627
628static struct section_perm nx_perms[] = {
629 /* Make pages tables, etc before _stext RW (set NX). */
630 {
631 .start = PAGE_OFFSET,
632 .end = (unsigned long)_stext,
633 .mask = ~PMD_SECT_XN,
634 .prot = PMD_SECT_XN,
635 },
636 /* Make init RW (set NX). */
637 {
638 .start = (unsigned long)__init_begin,
639 .end = (unsigned long)_sdata,
640 .mask = ~PMD_SECT_XN,
641 .prot = PMD_SECT_XN,
642 },
643#ifdef CONFIG_DEBUG_RODATA
644 /* Make rodata NX (set RO in ro_perms below). */
645 {
646 .start = (unsigned long)__start_rodata,
647 .end = (unsigned long)__init_begin,
648 .mask = ~PMD_SECT_XN,
649 .prot = PMD_SECT_XN,
650 },
651#endif
652};
653
654#ifdef CONFIG_DEBUG_RODATA
655static struct section_perm ro_perms[] = {
656 /* Make kernel code and rodata RX (set RO). */
657 {
658 .start = (unsigned long)_stext,
659 .end = (unsigned long)__init_begin,
660#ifdef CONFIG_ARM_LPAE
661 .mask = ~PMD_SECT_RDONLY,
662 .prot = PMD_SECT_RDONLY,
663#else
664 .mask = ~(PMD_SECT_APX | PMD_SECT_AP_WRITE),
665 .prot = PMD_SECT_APX | PMD_SECT_AP_WRITE,
666 .clear = PMD_SECT_AP_WRITE,
667#endif
668 },
669};
670#endif
671
672/*
673 * Updates section permissions only for the current mm (sections are
674 * copied into each mm). During startup, this is the init_mm. Is only
675 * safe to be called with preemption disabled, as under stop_machine().
676 */
677static inline void section_update(unsigned long addr, pmdval_t mask,
678 pmdval_t prot)
679{
680 struct mm_struct *mm;
681 pmd_t *pmd;
682
683 mm = current->active_mm;
684 pmd = pmd_offset(pud_offset(pgd_offset(mm, addr), addr), addr);
685
686#ifdef CONFIG_ARM_LPAE
687 pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot);
688#else
689 if (addr & SECTION_SIZE)
690 pmd[1] = __pmd((pmd_val(pmd[1]) & mask) | prot);
691 else
692 pmd[0] = __pmd((pmd_val(pmd[0]) & mask) | prot);
693#endif
694 flush_pmd_entry(pmd);
695 local_flush_tlb_kernel_range(addr, addr + SECTION_SIZE);
696}
697
698/* Make sure extended page tables are in use. */
699static inline bool arch_has_strict_perms(void)
700{
701 if (cpu_architecture() < CPU_ARCH_ARMv6)
702 return false;
703
704 return !!(get_cr() & CR_XP);
705}
706
707#define set_section_perms(perms, field) { \
708 size_t i; \
709 unsigned long addr; \
710 \
711 if (!arch_has_strict_perms()) \
712 return; \
713 \
714 for (i = 0; i < ARRAY_SIZE(perms); i++) { \
715 if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || \
716 !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { \
717 pr_err("BUG: section %lx-%lx not aligned to %lx\n", \
718 perms[i].start, perms[i].end, \
719 SECTION_SIZE); \
720 continue; \
721 } \
722 \
723 for (addr = perms[i].start; \
724 addr < perms[i].end; \
725 addr += SECTION_SIZE) \
726 section_update(addr, perms[i].mask, \
727 perms[i].field); \
728 } \
729}
730
731static inline void fix_kernmem_perms(void)
732{
733 set_section_perms(nx_perms, prot);
734}
735
736#ifdef CONFIG_DEBUG_RODATA
737void mark_rodata_ro(void)
738{
739 set_section_perms(ro_perms, prot);
740}
741
742void set_kernel_text_rw(void)
743{
744 set_section_perms(ro_perms, clear);
745}
746
747void set_kernel_text_ro(void)
748{
749 set_section_perms(ro_perms, prot);
750}
751#endif /* CONFIG_DEBUG_RODATA */
752
753#else
754static inline void fix_kernmem_perms(void) { }
755#endif /* CONFIG_ARM_KERNMEM_PERMS */
756
757void free_tcmmem(void)
619{ 758{
620#ifdef CONFIG_HAVE_TCM 759#ifdef CONFIG_HAVE_TCM
621 extern char __tcm_start, __tcm_end; 760 extern char __tcm_start, __tcm_end;
@@ -623,6 +762,12 @@ void free_initmem(void)
623 poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); 762 poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
624 free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link"); 763 free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link");
625#endif 764#endif
765}
766
767void free_initmem(void)
768{
769 fix_kernmem_perms();
770 free_tcmmem();
626 771
627 poison_init_mem(__init_begin, __init_end - __init_begin); 772 poison_init_mem(__init_begin, __init_end - __init_begin);
628 if (!machine_is_integrator() && !machine_is_cintegrator()) 773 if (!machine_is_integrator() && !machine_is_cintegrator())
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 9f98cec7fe1e..cda7c40999b6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -22,6 +22,7 @@
22#include <asm/cputype.h> 22#include <asm/cputype.h>
23#include <asm/sections.h> 23#include <asm/sections.h>
24#include <asm/cachetype.h> 24#include <asm/cachetype.h>
25#include <asm/fixmap.h>
25#include <asm/sections.h> 26#include <asm/sections.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
27#include <asm/smp_plat.h> 28#include <asm/smp_plat.h>
@@ -52,6 +53,8 @@ EXPORT_SYMBOL(empty_zero_page);
52 */ 53 */
53pmd_t *top_pmd; 54pmd_t *top_pmd;
54 55
56pmdval_t user_pmd_table = _PAGE_USER_TABLE;
57
55#define CPOLICY_UNCACHED 0 58#define CPOLICY_UNCACHED 0
56#define CPOLICY_BUFFERED 1 59#define CPOLICY_BUFFERED 1
57#define CPOLICY_WRITETHROUGH 2 60#define CPOLICY_WRITETHROUGH 2
@@ -192,7 +195,7 @@ early_param("cachepolicy", early_cachepolicy);
192static int __init early_nocache(char *__unused) 195static int __init early_nocache(char *__unused)
193{ 196{
194 char *p = "buffered"; 197 char *p = "buffered";
195 printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); 198 pr_warn("nocache is deprecated; use cachepolicy=%s\n", p);
196 early_cachepolicy(p); 199 early_cachepolicy(p);
197 return 0; 200 return 0;
198} 201}
@@ -201,7 +204,7 @@ early_param("nocache", early_nocache);
201static int __init early_nowrite(char *__unused) 204static int __init early_nowrite(char *__unused)
202{ 205{
203 char *p = "uncached"; 206 char *p = "uncached";
204 printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); 207 pr_warn("nowb is deprecated; use cachepolicy=%s\n", p);
205 early_cachepolicy(p); 208 early_cachepolicy(p);
206 return 0; 209 return 0;
207} 210}
@@ -354,43 +357,28 @@ const struct mem_type *get_mem_type(unsigned int type)
354} 357}
355EXPORT_SYMBOL(get_mem_type); 358EXPORT_SYMBOL(get_mem_type);
356 359
357#define PTE_SET_FN(_name, pteop) \ 360/*
358static int pte_set_##_name(pte_t *ptep, pgtable_t token, unsigned long addr, \ 361 * To avoid TLB flush broadcasts, this uses local_flush_tlb_kernel_range().
359 void *data) \ 362 * As a result, this can only be called with preemption disabled, as under
360{ \ 363 * stop_machine().
361 pte_t pte = pteop(*ptep); \ 364 */
362\ 365void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
363 set_pte_ext(ptep, pte, 0); \ 366{
364 return 0; \ 367 unsigned long vaddr = __fix_to_virt(idx);
365} \ 368 pte_t *pte = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
366
367#define SET_MEMORY_FN(_name, callback) \
368int set_memory_##_name(unsigned long addr, int numpages) \
369{ \
370 unsigned long start = addr; \
371 unsigned long size = PAGE_SIZE*numpages; \
372 unsigned end = start + size; \
373\
374 if (start < MODULES_VADDR || start >= MODULES_END) \
375 return -EINVAL;\
376\
377 if (end < MODULES_VADDR || end >= MODULES_END) \
378 return -EINVAL; \
379\
380 apply_to_page_range(&init_mm, start, size, callback, NULL); \
381 flush_tlb_kernel_range(start, end); \
382 return 0;\
383}
384 369
385PTE_SET_FN(ro, pte_wrprotect) 370 /* Make sure fixmap region does not exceed available allocation. */
386PTE_SET_FN(rw, pte_mkwrite) 371 BUILD_BUG_ON(FIXADDR_START + (__end_of_fixed_addresses * PAGE_SIZE) >
387PTE_SET_FN(x, pte_mkexec) 372 FIXADDR_END);
388PTE_SET_FN(nx, pte_mknexec) 373 BUG_ON(idx >= __end_of_fixed_addresses);
389 374
390SET_MEMORY_FN(ro, pte_set_ro) 375 if (pgprot_val(prot))
391SET_MEMORY_FN(rw, pte_set_rw) 376 set_pte_at(NULL, vaddr, pte,
392SET_MEMORY_FN(x, pte_set_x) 377 pfn_pte(phys >> PAGE_SHIFT, prot));
393SET_MEMORY_FN(nx, pte_set_nx) 378 else
379 pte_clear(NULL, vaddr, pte);
380 local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
381}
394 382
395/* 383/*
396 * Adjust the PMD section entries according to the CPU in use. 384 * Adjust the PMD section entries according to the CPU in use.
@@ -528,14 +516,23 @@ static void __init build_mem_type_table(void)
528 hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte; 516 hyp_device_pgprot = mem_types[MT_DEVICE].prot_pte;
529 s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2; 517 s2_device_pgprot = mem_types[MT_DEVICE].prot_pte_s2;
530 518
519#ifndef CONFIG_ARM_LPAE
531 /* 520 /*
532 * We don't use domains on ARMv6 (since this causes problems with 521 * We don't use domains on ARMv6 (since this causes problems with
533 * v6/v7 kernels), so we must use a separate memory type for user 522 * v6/v7 kernels), so we must use a separate memory type for user
534 * r/o, kernel r/w to map the vectors page. 523 * r/o, kernel r/w to map the vectors page.
535 */ 524 */
536#ifndef CONFIG_ARM_LPAE
537 if (cpu_arch == CPU_ARCH_ARMv6) 525 if (cpu_arch == CPU_ARCH_ARMv6)
538 vecs_pgprot |= L_PTE_MT_VECTORS; 526 vecs_pgprot |= L_PTE_MT_VECTORS;
527
528 /*
529 * Check is it with support for the PXN bit
530 * in the Short-descriptor translation table format descriptors.
531 */
532 if (cpu_arch == CPU_ARCH_ARMv7 &&
533 (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) == 4) {
534 user_pmd_table |= PMD_PXNTABLE;
535 }
539#endif 536#endif
540 537
541 /* 538 /*
@@ -605,6 +602,11 @@ static void __init build_mem_type_table(void)
605 } 602 }
606 kern_pgprot |= PTE_EXT_AF; 603 kern_pgprot |= PTE_EXT_AF;
607 vecs_pgprot |= PTE_EXT_AF; 604 vecs_pgprot |= PTE_EXT_AF;
605
606 /*
607 * Set PXN for user mappings
608 */
609 user_pgprot |= PTE_EXT_PXN;
608#endif 610#endif
609 611
610 for (i = 0; i < 16; i++) { 612 for (i = 0; i < 16; i++) {
@@ -786,8 +788,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
786 length = PAGE_ALIGN(md->length); 788 length = PAGE_ALIGN(md->length);
787 789
788 if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { 790 if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
789 printk(KERN_ERR "MM: CPU does not support supersection " 791 pr_err("MM: CPU does not support supersection mapping for 0x%08llx at 0x%08lx\n",
790 "mapping for 0x%08llx at 0x%08lx\n",
791 (long long)__pfn_to_phys((u64)md->pfn), addr); 792 (long long)__pfn_to_phys((u64)md->pfn), addr);
792 return; 793 return;
793 } 794 }
@@ -799,15 +800,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
799 * of the actual domain assignments in use. 800 * of the actual domain assignments in use.
800 */ 801 */
801 if (type->domain) { 802 if (type->domain) {
802 printk(KERN_ERR "MM: invalid domain in supersection " 803 pr_err("MM: invalid domain in supersection mapping for 0x%08llx at 0x%08lx\n",
803 "mapping for 0x%08llx at 0x%08lx\n",
804 (long long)__pfn_to_phys((u64)md->pfn), addr); 804 (long long)__pfn_to_phys((u64)md->pfn), addr);
805 return; 805 return;
806 } 806 }
807 807
808 if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { 808 if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
809 printk(KERN_ERR "MM: cannot create mapping for 0x%08llx" 809 pr_err("MM: cannot create mapping for 0x%08llx at 0x%08lx invalid alignment\n",
810 " at 0x%08lx invalid alignment\n",
811 (long long)__pfn_to_phys((u64)md->pfn), addr); 810 (long long)__pfn_to_phys((u64)md->pfn), addr);
812 return; 811 return;
813 } 812 }
@@ -850,18 +849,16 @@ static void __init create_mapping(struct map_desc *md)
850 pgd_t *pgd; 849 pgd_t *pgd;
851 850
852 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { 851 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
853 printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx" 852 pr_warn("BUG: not creating mapping for 0x%08llx at 0x%08lx in user region\n",
854 " at 0x%08lx in user region\n", 853 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
855 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
856 return; 854 return;
857 } 855 }
858 856
859 if ((md->type == MT_DEVICE || md->type == MT_ROM) && 857 if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
860 md->virtual >= PAGE_OFFSET && 858 md->virtual >= PAGE_OFFSET &&
861 (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { 859 (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
862 printk(KERN_WARNING "BUG: mapping for 0x%08llx" 860 pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
863 " at 0x%08lx out of vmalloc space\n", 861 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
864 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
865 } 862 }
866 863
867 type = &mem_types[md->type]; 864 type = &mem_types[md->type];
@@ -881,9 +878,8 @@ static void __init create_mapping(struct map_desc *md)
881 length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); 878 length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
882 879
883 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { 880 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
884 printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not " 881 pr_warn("BUG: map for 0x%08llx at 0x%08lx can not be mapped using pages, ignoring.\n",
885 "be mapped using pages, ignoring.\n", 882 (long long)__pfn_to_phys(md->pfn), addr);
886 (long long)__pfn_to_phys(md->pfn), addr);
887 return; 883 return;
888 } 884 }
889 885
@@ -1053,15 +1049,13 @@ static int __init early_vmalloc(char *arg)
1053 1049
1054 if (vmalloc_reserve < SZ_16M) { 1050 if (vmalloc_reserve < SZ_16M) {
1055 vmalloc_reserve = SZ_16M; 1051 vmalloc_reserve = SZ_16M;
1056 printk(KERN_WARNING 1052 pr_warn("vmalloc area too small, limiting to %luMB\n",
1057 "vmalloc area too small, limiting to %luMB\n",
1058 vmalloc_reserve >> 20); 1053 vmalloc_reserve >> 20);
1059 } 1054 }
1060 1055
1061 if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) { 1056 if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) {
1062 vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M); 1057 vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M);
1063 printk(KERN_WARNING 1058 pr_warn("vmalloc area is too big, limiting to %luMB\n",
1064 "vmalloc area is too big, limiting to %luMB\n",
1065 vmalloc_reserve >> 20); 1059 vmalloc_reserve >> 20);
1066 } 1060 }
1067 1061
@@ -1094,7 +1088,7 @@ void __init sanity_check_meminfo(void)
1094 1088
1095 if (highmem) { 1089 if (highmem) {
1096 pr_notice("Ignoring RAM at %pa-%pa (!CONFIG_HIGHMEM)\n", 1090 pr_notice("Ignoring RAM at %pa-%pa (!CONFIG_HIGHMEM)\n",
1097 &block_start, &block_end); 1091 &block_start, &block_end);
1098 memblock_remove(reg->base, reg->size); 1092 memblock_remove(reg->base, reg->size);
1099 continue; 1093 continue;
1100 } 1094 }
@@ -1103,7 +1097,7 @@ void __init sanity_check_meminfo(void)
1103 phys_addr_t overlap_size = reg->size - size_limit; 1097 phys_addr_t overlap_size = reg->size - size_limit;
1104 1098
1105 pr_notice("Truncating RAM at %pa-%pa to -%pa", 1099 pr_notice("Truncating RAM at %pa-%pa to -%pa",
1106 &block_start, &block_end, &vmalloc_limit); 1100 &block_start, &block_end, &vmalloc_limit);
1107 memblock_remove(vmalloc_limit, overlap_size); 1101 memblock_remove(vmalloc_limit, overlap_size);
1108 block_end = vmalloc_limit; 1102 block_end = vmalloc_limit;
1109 } 1103 }
@@ -1326,10 +1320,10 @@ static void __init kmap_init(void)
1326#ifdef CONFIG_HIGHMEM 1320#ifdef CONFIG_HIGHMEM
1327 pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE), 1321 pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
1328 PKMAP_BASE, _PAGE_KERNEL_TABLE); 1322 PKMAP_BASE, _PAGE_KERNEL_TABLE);
1329
1330 fixmap_page_table = early_pte_alloc(pmd_off_k(FIXADDR_START),
1331 FIXADDR_START, _PAGE_KERNEL_TABLE);
1332#endif 1323#endif
1324
1325 early_pte_alloc(pmd_off_k(FIXADDR_START), FIXADDR_START,
1326 _PAGE_KERNEL_TABLE);
1333} 1327}
1334 1328
1335static void __init map_lowmem(void) 1329static void __init map_lowmem(void)
@@ -1349,13 +1343,20 @@ static void __init map_lowmem(void)
1349 if (start >= end) 1343 if (start >= end)
1350 break; 1344 break;
1351 1345
1352 if (end < kernel_x_start || start >= kernel_x_end) { 1346 if (end < kernel_x_start) {
1353 map.pfn = __phys_to_pfn(start); 1347 map.pfn = __phys_to_pfn(start);
1354 map.virtual = __phys_to_virt(start); 1348 map.virtual = __phys_to_virt(start);
1355 map.length = end - start; 1349 map.length = end - start;
1356 map.type = MT_MEMORY_RWX; 1350 map.type = MT_MEMORY_RWX;
1357 1351
1358 create_mapping(&map); 1352 create_mapping(&map);
1353 } else if (start >= kernel_x_end) {
1354 map.pfn = __phys_to_pfn(start);
1355 map.virtual = __phys_to_virt(start);
1356 map.length = end - start;
1357 map.type = MT_MEMORY_RW;
1358
1359 create_mapping(&map);
1359 } else { 1360 } else {
1360 /* This better cover the entire kernel */ 1361 /* This better cover the entire kernel */
1361 if (start < kernel_x_start) { 1362 if (start < kernel_x_start) {
diff --git a/arch/arm/mm/pageattr.c b/arch/arm/mm/pageattr.c
new file mode 100644
index 000000000000..004e35cdcfff
--- /dev/null
+++ b/arch/arm/mm/pageattr.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
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 version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#include <linux/mm.h>
14#include <linux/module.h>
15
16#include <asm/pgtable.h>
17#include <asm/tlbflush.h>
18
19struct page_change_data {
20 pgprot_t set_mask;
21 pgprot_t clear_mask;
22};
23
24static int change_page_range(pte_t *ptep, pgtable_t token, unsigned long addr,
25 void *data)
26{
27 struct page_change_data *cdata = data;
28 pte_t pte = *ptep;
29
30 pte = clear_pte_bit(pte, cdata->clear_mask);
31 pte = set_pte_bit(pte, cdata->set_mask);
32
33 set_pte_ext(ptep, pte, 0);
34 return 0;
35}
36
37static int change_memory_common(unsigned long addr, int numpages,
38 pgprot_t set_mask, pgprot_t clear_mask)
39{
40 unsigned long start = addr;
41 unsigned long size = PAGE_SIZE*numpages;
42 unsigned long end = start + size;
43 int ret;
44 struct page_change_data data;
45
46 if (!IS_ALIGNED(addr, PAGE_SIZE)) {
47 start &= PAGE_MASK;
48 end = start + size;
49 WARN_ON_ONCE(1);
50 }
51
52 if (!is_module_address(start) || !is_module_address(end - 1))
53 return -EINVAL;
54
55 data.set_mask = set_mask;
56 data.clear_mask = clear_mask;
57
58 ret = apply_to_page_range(&init_mm, start, size, change_page_range,
59 &data);
60
61 flush_tlb_kernel_range(start, end);
62 return ret;
63}
64
65int set_memory_ro(unsigned long addr, int numpages)
66{
67 return change_memory_common(addr, numpages,
68 __pgprot(L_PTE_RDONLY),
69 __pgprot(0));
70}
71
72int set_memory_rw(unsigned long addr, int numpages)
73{
74 return change_memory_common(addr, numpages,
75 __pgprot(0),
76 __pgprot(L_PTE_RDONLY));
77}
78
79int set_memory_nx(unsigned long addr, int numpages)
80{
81 return change_memory_common(addr, numpages,
82 __pgprot(L_PTE_XN),
83 __pgprot(0));
84}
85
86int set_memory_x(unsigned long addr, int numpages)
87{
88 return change_memory_common(addr, numpages,
89 __pgprot(0),
90 __pgprot(L_PTE_XN));
91}
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 22ac2a6fbfe3..8b4ee5e81c14 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -591,9 +591,10 @@ __krait_proc_info:
591 /* 591 /*
592 * Some Krait processors don't indicate support for SDIV and UDIV 592 * Some Krait processors don't indicate support for SDIV and UDIV
593 * instructions in the ARM instruction set, even though they actually 593 * instructions in the ARM instruction set, even though they actually
594 * do support them. 594 * do support them. They also don't indicate support for fused multiply
595 * instructions even though they actually do support them.
595 */ 596 */
596 __v7_proc __v7_setup, hwcaps = HWCAP_IDIV 597 __v7_proc __v7_setup, hwcaps = HWCAP_IDIV | HWCAP_VFPv4
597 .size __krait_proc_info, . - __krait_proc_info 598 .size __krait_proc_info, . - __krait_proc_info
598 599
599 /* 600 /*
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c
index 4e729f055a81..ec717c190e2c 100644
--- a/arch/arm/nwfpe/fpmodule.c
+++ b/arch/arm/nwfpe/fpmodule.c
@@ -86,20 +86,20 @@ extern void nwfpe_enter(void);
86static int __init fpe_init(void) 86static int __init fpe_init(void)
87{ 87{
88 if (sizeof(FPA11) > sizeof(union fp_state)) { 88 if (sizeof(FPA11) > sizeof(union fp_state)) {
89 printk(KERN_ERR "nwfpe: bad structure size\n"); 89 pr_err("nwfpe: bad structure size\n");
90 return -EINVAL; 90 return -EINVAL;
91 } 91 }
92 92
93 if (sizeof(FPREG) != 12) { 93 if (sizeof(FPREG) != 12) {
94 printk(KERN_ERR "nwfpe: bad register size\n"); 94 pr_err("nwfpe: bad register size\n");
95 return -EINVAL; 95 return -EINVAL;
96 } 96 }
97 if (fpe_type[0] && strcmp(fpe_type, "nwfpe")) 97 if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
98 return 0; 98 return 0;
99 99
100 /* Display title, version and copyright information. */ 100 /* Display title, version and copyright information. */
101 printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 (" 101 pr_info("NetWinder Floating Point Emulator V0.97 ("
102 NWFPE_BITS " precision)\n"); 102 NWFPE_BITS " precision)\n");
103 103
104 thread_register_notifier(&nwfpe_notifier_block); 104 thread_register_notifier(&nwfpe_notifier_block);
105 105
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index cda654cbf2c2..f74a8f7e5f84 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -197,6 +197,12 @@ look_for_VFP_exceptions:
197 tst r5, #FPSCR_IXE 197 tst r5, #FPSCR_IXE
198 bne process_exception 198 bne process_exception
199 199
200 tst r5, #FPSCR_LENGTH_MASK
201 beq skip
202 orr r1, r1, #FPEXC_DEX
203 b process_exception
204skip:
205
200 @ Fall into hand on to next handler - appropriate coproc instr 206 @ Fall into hand on to next handler - appropriate coproc instr
201 @ not recognised by VFP 207 @ not recognised by VFP
202 208
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 2f37e1d6cb45..f6e4d56eda00 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -738,63 +738,73 @@ static int __init vfp_init(void)
738 vfp_vector = vfp_null_entry; 738 vfp_vector = vfp_null_entry;
739 739
740 pr_info("VFP support v0.3: "); 740 pr_info("VFP support v0.3: ");
741 if (VFP_arch) 741 if (VFP_arch) {
742 pr_cont("not present\n"); 742 pr_cont("not present\n");
743 else if (vfpsid & FPSID_NODOUBLE) { 743 return 0;
744 pr_cont("no double precision support\n"); 744 /* Extract the architecture on CPUID scheme */
745 } else { 745 } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
746 hotcpu_notifier(vfp_hotplug, 0); 746 VFP_arch = vfpsid & FPSID_CPUID_ARCH_MASK;
747 747 VFP_arch >>= FPSID_ARCH_BIT;
748 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
749 pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n",
750 (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
751 (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT,
752 (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
753 (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
754 (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
755
756 vfp_vector = vfp_support_entry;
757
758 thread_register_notifier(&vfp_notifier_block);
759 vfp_pm_init();
760
761 /*
762 * We detected VFP, and the support code is
763 * in place; report VFP support to userspace.
764 */
765 elf_hwcap |= HWCAP_VFP;
766#ifdef CONFIG_VFPv3
767 if (VFP_arch >= 2) {
768 elf_hwcap |= HWCAP_VFPv3;
769
770 /*
771 * Check for VFPv3 D16 and VFPv4 D16. CPUs in
772 * this configuration only have 16 x 64bit
773 * registers.
774 */
775 if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
776 elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */
777 else
778 elf_hwcap |= HWCAP_VFPD32;
779 }
780#endif
781 /* 748 /*
782 * Check for the presence of the Advanced SIMD 749 * Check for the presence of the Advanced SIMD
783 * load/store instructions, integer and single 750 * load/store instructions, integer and single
784 * precision floating point operations. Only check 751 * precision floating point operations. Only check
785 * for NEON if the hardware has the MVFR registers. 752 * for NEON if the hardware has the MVFR registers.
786 */ 753 */
787 if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { 754 if (IS_ENABLED(CONFIG_NEON) &&
788#ifdef CONFIG_NEON 755 (fmrx(MVFR1) & 0x000fff00) == 0x00011100)
789 if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) 756 elf_hwcap |= HWCAP_NEON;
790 elf_hwcap |= HWCAP_NEON; 757
791#endif 758 if (IS_ENABLED(CONFIG_VFPv3)) {
792#ifdef CONFIG_VFPv3 759 u32 mvfr0 = fmrx(MVFR0);
760 if (((mvfr0 & MVFR0_DP_MASK) >> MVFR0_DP_BIT) == 0x2 ||
761 ((mvfr0 & MVFR0_SP_MASK) >> MVFR0_SP_BIT) == 0x2) {
762 elf_hwcap |= HWCAP_VFPv3;
763 /*
764 * Check for VFPv3 D16 and VFPv4 D16. CPUs in
765 * this configuration only have 16 x 64bit
766 * registers.
767 */
768 if ((mvfr0 & MVFR0_A_SIMD_MASK) == 1)
769 /* also v4-D16 */
770 elf_hwcap |= HWCAP_VFPv3D16;
771 else
772 elf_hwcap |= HWCAP_VFPD32;
773 }
774
793 if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) 775 if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
794 elf_hwcap |= HWCAP_VFPv4; 776 elf_hwcap |= HWCAP_VFPv4;
795#endif
796 } 777 }
778 /* Extract the architecture version on pre-cpuid scheme */
779 } else {
780 if (vfpsid & FPSID_NODOUBLE) {
781 pr_cont("no double precision support\n");
782 return 0;
783 }
784
785 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT;
797 } 786 }
787
788 hotcpu_notifier(vfp_hotplug, 0);
789
790 vfp_vector = vfp_support_entry;
791
792 thread_register_notifier(&vfp_notifier_block);
793 vfp_pm_init();
794
795 /*
796 * We detected VFP, and the support code is
797 * in place; report VFP support to userspace.
798 */
799 elf_hwcap |= HWCAP_VFP;
800
801 pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n",
802 (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
803 VFP_arch,
804 (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
805 (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
806 (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
807
798 return 0; 808 return 0;
799} 809}
800 810
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index 4f96c1617aae..f0465ba0f221 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -290,7 +290,7 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
290 u32 z, a; 290 u32 z, a;
291 291
292 if ((significand & 0xc0000000) != 0x40000000) { 292 if ((significand & 0xc0000000) != 0x40000000) {
293 printk(KERN_WARNING "VFP: estimate_sqrt: invalid significand\n"); 293 pr_warn("VFP: estimate_sqrt: invalid significand\n");
294 } 294 }
295 295
296 a = significand << 1; 296 a = significand << 1;
diff --git a/arch/arm/xen/Makefile b/arch/arm/xen/Makefile
index 1f85bfe6b470..12969523414c 100644
--- a/arch/arm/xen/Makefile
+++ b/arch/arm/xen/Makefile
@@ -1 +1 @@
obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o mm32.o obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 0e15f011f9c8..c7ca936ebd99 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -261,11 +261,6 @@ static int __init xen_guest_init(void)
261 261
262 xen_setup_features(); 262 xen_setup_features();
263 263
264 if (!xen_feature(XENFEAT_grant_map_identity)) {
265 pr_warn("Please upgrade your Xen.\n"
266 "If your platform has any non-coherent DMA devices, they won't work properly.\n");
267 }
268
269 if (xen_feature(XENFEAT_dom0)) 264 if (xen_feature(XENFEAT_dom0))
270 xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED; 265 xen_start_info->flags |= SIF_INITDOMAIN|SIF_PRIVILEGED;
271 else 266 else
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index b0e77de99148..351b24a979d4 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -1,6 +1,10 @@
1#include <linux/cpu.h>
2#include <linux/dma-mapping.h>
1#include <linux/bootmem.h> 3#include <linux/bootmem.h>
2#include <linux/gfp.h> 4#include <linux/gfp.h>
5#include <linux/highmem.h>
3#include <linux/export.h> 6#include <linux/export.h>
7#include <linux/of_address.h>
4#include <linux/slab.h> 8#include <linux/slab.h>
5#include <linux/types.h> 9#include <linux/types.h>
6#include <linux/dma-mapping.h> 10#include <linux/dma-mapping.h>
@@ -8,6 +12,7 @@
8#include <linux/swiotlb.h> 12#include <linux/swiotlb.h>
9 13
10#include <xen/xen.h> 14#include <xen/xen.h>
15#include <xen/interface/grant_table.h>
11#include <xen/interface/memory.h> 16#include <xen/interface/memory.h>
12#include <xen/swiotlb-xen.h> 17#include <xen/swiotlb-xen.h>
13 18
@@ -16,6 +21,114 @@
16#include <asm/xen/hypercall.h> 21#include <asm/xen/hypercall.h>
17#include <asm/xen/interface.h> 22#include <asm/xen/interface.h>
18 23
24enum dma_cache_op {
25 DMA_UNMAP,
26 DMA_MAP,
27};
28static bool hypercall_cflush = false;
29
30/* functions called by SWIOTLB */
31
32static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
33 size_t size, enum dma_data_direction dir, enum dma_cache_op op)
34{
35 struct gnttab_cache_flush cflush;
36 unsigned long pfn;
37 size_t left = size;
38
39 pfn = (handle >> PAGE_SHIFT) + offset / PAGE_SIZE;
40 offset %= PAGE_SIZE;
41
42 do {
43 size_t len = left;
44
45 /* buffers in highmem or foreign pages cannot cross page
46 * boundaries */
47 if (len + offset > PAGE_SIZE)
48 len = PAGE_SIZE - offset;
49
50 cflush.op = 0;
51 cflush.a.dev_bus_addr = pfn << PAGE_SHIFT;
52 cflush.offset = offset;
53 cflush.length = len;
54
55 if (op == DMA_UNMAP && dir != DMA_TO_DEVICE)
56 cflush.op = GNTTAB_CACHE_INVAL;
57 if (op == DMA_MAP) {
58 if (dir == DMA_FROM_DEVICE)
59 cflush.op = GNTTAB_CACHE_INVAL;
60 else
61 cflush.op = GNTTAB_CACHE_CLEAN;
62 }
63 if (cflush.op)
64 HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1);
65
66 offset = 0;
67 pfn++;
68 left -= len;
69 } while (left);
70}
71
72static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
73 size_t size, enum dma_data_direction dir)
74{
75 dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_UNMAP);
76}
77
78static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
79 size_t size, enum dma_data_direction dir)
80{
81 dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, DMA_MAP);
82}
83
84void __xen_dma_map_page(struct device *hwdev, struct page *page,
85 dma_addr_t dev_addr, unsigned long offset, size_t size,
86 enum dma_data_direction dir, struct dma_attrs *attrs)
87{
88 if (is_device_dma_coherent(hwdev))
89 return;
90 if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
91 return;
92
93 __xen_dma_page_cpu_to_dev(hwdev, dev_addr, size, dir);
94}
95
96void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
97 size_t size, enum dma_data_direction dir,
98 struct dma_attrs *attrs)
99
100{
101 if (is_device_dma_coherent(hwdev))
102 return;
103 if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
104 return;
105
106 __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
107}
108
109void __xen_dma_sync_single_for_cpu(struct device *hwdev,
110 dma_addr_t handle, size_t size, enum dma_data_direction dir)
111{
112 if (is_device_dma_coherent(hwdev))
113 return;
114 __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
115}
116
117void __xen_dma_sync_single_for_device(struct device *hwdev,
118 dma_addr_t handle, size_t size, enum dma_data_direction dir)
119{
120 if (is_device_dma_coherent(hwdev))
121 return;
122 __xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
123}
124
125bool xen_arch_need_swiotlb(struct device *dev,
126 unsigned long pfn,
127 unsigned long mfn)
128{
129 return (!hypercall_cflush && (pfn != mfn) && !is_device_dma_coherent(dev));
130}
131
19int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order, 132int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
20 unsigned int address_bits, 133 unsigned int address_bits,
21 dma_addr_t *dma_handle) 134 dma_addr_t *dma_handle)
@@ -56,10 +169,18 @@ static struct dma_map_ops xen_swiotlb_dma_ops = {
56 169
57int __init xen_mm_init(void) 170int __init xen_mm_init(void)
58{ 171{
172 struct gnttab_cache_flush cflush;
59 if (!xen_initial_domain()) 173 if (!xen_initial_domain())
60 return 0; 174 return 0;
61 xen_swiotlb_init(1, false); 175 xen_swiotlb_init(1, false);
62 xen_dma_ops = &xen_swiotlb_dma_ops; 176 xen_dma_ops = &xen_swiotlb_dma_ops;
177
178 cflush.op = 0;
179 cflush.a.dev_bus_addr = 0;
180 cflush.offset = 0;
181 cflush.length = 0;
182 if (HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, &cflush, 1) != -ENOSYS)
183 hypercall_cflush = true;
63 return 0; 184 return 0;
64} 185}
65arch_initcall(xen_mm_init); 186arch_initcall(xen_mm_init);
diff --git a/arch/arm/xen/mm32.c b/arch/arm/xen/mm32.c
deleted file mode 100644
index 3b99860fd7ae..000000000000
--- a/arch/arm/xen/mm32.c
+++ /dev/null
@@ -1,202 +0,0 @@
1#include <linux/cpu.h>
2#include <linux/dma-mapping.h>
3#include <linux/gfp.h>
4#include <linux/highmem.h>
5
6#include <xen/features.h>
7
8static DEFINE_PER_CPU(unsigned long, xen_mm32_scratch_virt);
9static DEFINE_PER_CPU(pte_t *, xen_mm32_scratch_ptep);
10
11static int alloc_xen_mm32_scratch_page(int cpu)
12{
13 struct page *page;
14 unsigned long virt;
15 pmd_t *pmdp;
16 pte_t *ptep;
17
18 if (per_cpu(xen_mm32_scratch_ptep, cpu) != NULL)
19 return 0;
20
21 page = alloc_page(GFP_KERNEL);
22 if (page == NULL) {
23 pr_warn("Failed to allocate xen_mm32_scratch_page for cpu %d\n", cpu);
24 return -ENOMEM;
25 }
26
27 virt = (unsigned long)__va(page_to_phys(page));
28 pmdp = pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt);
29 ptep = pte_offset_kernel(pmdp, virt);
30
31 per_cpu(xen_mm32_scratch_virt, cpu) = virt;
32 per_cpu(xen_mm32_scratch_ptep, cpu) = ptep;
33
34 return 0;
35}
36
37static int xen_mm32_cpu_notify(struct notifier_block *self,
38 unsigned long action, void *hcpu)
39{
40 int cpu = (long)hcpu;
41 switch (action) {
42 case CPU_UP_PREPARE:
43 if (alloc_xen_mm32_scratch_page(cpu))
44 return NOTIFY_BAD;
45 break;
46 default:
47 break;
48 }
49 return NOTIFY_OK;
50}
51
52static struct notifier_block xen_mm32_cpu_notifier = {
53 .notifier_call = xen_mm32_cpu_notify,
54};
55
56static void* xen_mm32_remap_page(dma_addr_t handle)
57{
58 unsigned long virt = get_cpu_var(xen_mm32_scratch_virt);
59 pte_t *ptep = __get_cpu_var(xen_mm32_scratch_ptep);
60
61 *ptep = pfn_pte(handle >> PAGE_SHIFT, PAGE_KERNEL);
62 local_flush_tlb_kernel_page(virt);
63
64 return (void*)virt;
65}
66
67static void xen_mm32_unmap(void *vaddr)
68{
69 put_cpu_var(xen_mm32_scratch_virt);
70}
71
72
73/* functions called by SWIOTLB */
74
75static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
76 size_t size, enum dma_data_direction dir,
77 void (*op)(const void *, size_t, int))
78{
79 unsigned long pfn;
80 size_t left = size;
81
82 pfn = (handle >> PAGE_SHIFT) + offset / PAGE_SIZE;
83 offset %= PAGE_SIZE;
84
85 do {
86 size_t len = left;
87 void *vaddr;
88
89 if (!pfn_valid(pfn))
90 {
91 /* Cannot map the page, we don't know its physical address.
92 * Return and hope for the best */
93 if (!xen_feature(XENFEAT_grant_map_identity))
94 return;
95 vaddr = xen_mm32_remap_page(handle) + offset;
96 op(vaddr, len, dir);
97 xen_mm32_unmap(vaddr - offset);
98 } else {
99 struct page *page = pfn_to_page(pfn);
100
101 if (PageHighMem(page)) {
102 if (len + offset > PAGE_SIZE)
103 len = PAGE_SIZE - offset;
104
105 if (cache_is_vipt_nonaliasing()) {
106 vaddr = kmap_atomic(page);
107 op(vaddr + offset, len, dir);
108 kunmap_atomic(vaddr);
109 } else {
110 vaddr = kmap_high_get(page);
111 if (vaddr) {
112 op(vaddr + offset, len, dir);
113 kunmap_high(page);
114 }
115 }
116 } else {
117 vaddr = page_address(page) + offset;
118 op(vaddr, len, dir);
119 }
120 }
121
122 offset = 0;
123 pfn++;
124 left -= len;
125 } while (left);
126}
127
128static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
129 size_t size, enum dma_data_direction dir)
130{
131 /* Cannot use __dma_page_dev_to_cpu because we don't have a
132 * struct page for handle */
133
134 if (dir != DMA_TO_DEVICE)
135 outer_inv_range(handle, handle + size);
136
137 dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, dmac_unmap_area);
138}
139
140static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
141 size_t size, enum dma_data_direction dir)
142{
143
144 dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, dmac_map_area);
145
146 if (dir == DMA_FROM_DEVICE) {
147 outer_inv_range(handle, handle + size);
148 } else {
149 outer_clean_range(handle, handle + size);
150 }
151}
152
153void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
154 size_t size, enum dma_data_direction dir,
155 struct dma_attrs *attrs)
156
157{
158 if (!__generic_dma_ops(hwdev)->unmap_page)
159 return;
160 if (dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
161 return;
162
163 __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
164}
165
166void xen_dma_sync_single_for_cpu(struct device *hwdev,
167 dma_addr_t handle, size_t size, enum dma_data_direction dir)
168{
169 if (!__generic_dma_ops(hwdev)->sync_single_for_cpu)
170 return;
171 __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
172}
173
174void xen_dma_sync_single_for_device(struct device *hwdev,
175 dma_addr_t handle, size_t size, enum dma_data_direction dir)
176{
177 if (!__generic_dma_ops(hwdev)->sync_single_for_device)
178 return;
179 __xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
180}
181
182int __init xen_mm32_init(void)
183{
184 int cpu;
185
186 if (!xen_initial_domain())
187 return 0;
188
189 register_cpu_notifier(&xen_mm32_cpu_notifier);
190 get_online_cpus();
191 for_each_online_cpu(cpu) {
192 if (alloc_xen_mm32_scratch_page(cpu)) {
193 put_online_cpus();
194 unregister_cpu_notifier(&xen_mm32_cpu_notifier);
195 return -ENOMEM;
196 }
197 }
198 put_online_cpus();
199
200 return 0;
201}
202arch_initcall(xen_mm32_init);
diff --git a/arch/arm64/include/asm/device.h b/arch/arm64/include/asm/device.h
index cf98b362094b..243ef256b8c9 100644
--- a/arch/arm64/include/asm/device.h
+++ b/arch/arm64/include/asm/device.h
@@ -21,6 +21,7 @@ struct dev_archdata {
21#ifdef CONFIG_IOMMU_API 21#ifdef CONFIG_IOMMU_API
22 void *iommu; /* private IOMMU data */ 22 void *iommu; /* private IOMMU data */
23#endif 23#endif
24 bool dma_coherent;
24}; 25};
25 26
26struct pdev_archdata { 27struct pdev_archdata {
diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index adeae3f6f0fc..d34189bceff7 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -54,11 +54,18 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
54 54
55static inline int set_arch_dma_coherent_ops(struct device *dev) 55static inline int set_arch_dma_coherent_ops(struct device *dev)
56{ 56{
57 dev->archdata.dma_coherent = true;
57 set_dma_ops(dev, &coherent_swiotlb_dma_ops); 58 set_dma_ops(dev, &coherent_swiotlb_dma_ops);
58 return 0; 59 return 0;
59} 60}
60#define set_arch_dma_coherent_ops set_arch_dma_coherent_ops 61#define set_arch_dma_coherent_ops set_arch_dma_coherent_ops
61 62
63/* do not use this function in a driver */
64static inline bool is_device_dma_coherent(struct device *dev)
65{
66 return dev->archdata.dma_coherent;
67}
68
62#include <asm-generic/dma-mapping-common.h> 69#include <asm-generic/dma-mapping-common.h>
63 70
64static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 71static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
diff --git a/arch/arm64/include/asm/xen/page-coherent.h b/arch/arm64/include/asm/xen/page-coherent.h
index dde3fc9c49f0..2052102b4e02 100644
--- a/arch/arm64/include/asm/xen/page-coherent.h
+++ b/arch/arm64/include/asm/xen/page-coherent.h
@@ -1,43 +1 @@
1#ifndef _ASM_ARM64_XEN_PAGE_COHERENT_H #include <../../arm/include/asm/xen/page-coherent.h>
2#define _ASM_ARM64_XEN_PAGE_COHERENT_H
3
4#include <asm/page.h>
5#include <linux/dma-attrs.h>
6#include <linux/dma-mapping.h>
7
8static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
9 dma_addr_t *dma_handle, gfp_t flags,
10 struct dma_attrs *attrs)
11{
12 return __generic_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, attrs);
13}
14
15static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
16 void *cpu_addr, dma_addr_t dma_handle,
17 struct dma_attrs *attrs)
18{
19 __generic_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
20}
21
22static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
23 unsigned long offset, size_t size, enum dma_data_direction dir,
24 struct dma_attrs *attrs)
25{
26}
27
28static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
29 size_t size, enum dma_data_direction dir,
30 struct dma_attrs *attrs)
31{
32}
33
34static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
35 dma_addr_t handle, size_t size, enum dma_data_direction dir)
36{
37}
38
39static inline void xen_dma_sync_single_for_device(struct device *hwdev,
40 dma_addr_t handle, size_t size, enum dma_data_direction dir)
41{
42}
43#endif /* _ASM_ARM64_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 663da771580a..3425f311c49e 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -511,7 +511,7 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
511 511
512static int psci_suspend_finisher(unsigned long index) 512static int psci_suspend_finisher(unsigned long index)
513{ 513{
514 struct psci_power_state *state = __get_cpu_var(psci_power_state); 514 struct psci_power_state *state = __this_cpu_read(psci_power_state);
515 515
516 return psci_ops.cpu_suspend(state[index - 1], 516 return psci_ops.cpu_suspend(state[index - 1],
517 virt_to_phys(cpu_resume)); 517 virt_to_phys(cpu_resume));
@@ -520,7 +520,7 @@ static int psci_suspend_finisher(unsigned long index)
520static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) 520static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
521{ 521{
522 int ret; 522 int ret;
523 struct psci_power_state *state = __get_cpu_var(psci_power_state); 523 struct psci_power_state *state = __this_cpu_read(psci_power_state);
524 /* 524 /*
525 * idle state index 0 corresponds to wfi, should never be called 525 * idle state index 0 corresponds to wfi, should never be called
526 * from the cpu_suspend operations 526 * from the cpu_suspend operations
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index f5e18bf3275e..e5fc463b36d0 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -2,7 +2,9 @@
2 2
3platforms += alchemy 3platforms += alchemy
4platforms += ar7 4platforms += ar7
5platforms += ath25
5platforms += ath79 6platforms += ath79
7platforms += bcm3384
6platforms += bcm47xx 8platforms += bcm47xx
7platforms += bcm63xx 9platforms += bcm63xx
8platforms += cavium-octeon 10platforms += cavium-octeon
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9536ef912f59..3289969ee423 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -53,6 +53,7 @@ config MIPS
53 select HAVE_CC_STACKPROTECTOR 53 select HAVE_CC_STACKPROTECTOR
54 select CPU_PM if CPU_IDLE 54 select CPU_PM if CPU_IDLE
55 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 55 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
56 select ARCH_BINFMT_ELF_STATE
56 57
57menu "Machine selection" 58menu "Machine selection"
58 59
@@ -62,7 +63,7 @@ choice
62 63
63config MIPS_ALCHEMY 64config MIPS_ALCHEMY
64 bool "Alchemy processor based machines" 65 bool "Alchemy processor based machines"
65 select 64BIT_PHYS_ADDR 66 select ARCH_PHYS_ADDR_T_64BIT
66 select CEVT_R4K 67 select CEVT_R4K
67 select CSRC_R4K 68 select CSRC_R4K
68 select IRQ_CPU 69 select IRQ_CPU
@@ -96,6 +97,20 @@ config AR7
96 Support for the Texas Instruments AR7 System-on-a-Chip 97 Support for the Texas Instruments AR7 System-on-a-Chip
97 family: TNETD7100, 7200 and 7300. 98 family: TNETD7100, 7200 and 7300.
98 99
100config ATH25
101 bool "Atheros AR231x/AR531x SoC support"
102 select CEVT_R4K
103 select CSRC_R4K
104 select DMA_NONCOHERENT
105 select IRQ_CPU
106 select IRQ_DOMAIN
107 select SYS_HAS_CPU_MIPS32_R1
108 select SYS_SUPPORTS_BIG_ENDIAN
109 select SYS_SUPPORTS_32BIT_KERNEL
110 select SYS_HAS_EARLY_PRINTK
111 help
112 Support for Atheros AR231x and Atheros AR531x based boards
113
99config ATH79 114config ATH79
100 bool "Atheros AR71XX/AR724X/AR913X based boards" 115 bool "Atheros AR71XX/AR724X/AR913X based boards"
101 select ARCH_REQUIRE_GPIOLIB 116 select ARCH_REQUIRE_GPIOLIB
@@ -115,6 +130,32 @@ config ATH79
115 help 130 help
116 Support for the Atheros AR71XX/AR724X/AR913X SoCs. 131 Support for the Atheros AR71XX/AR724X/AR913X SoCs.
117 132
133config BCM3384
134 bool "Broadcom BCM3384 based boards"
135 select BOOT_RAW
136 select NO_EXCEPT_FILL
137 select USE_OF
138 select CEVT_R4K
139 select CSRC_R4K
140 select SYNC_R4K
141 select COMMON_CLK
142 select DMA_NONCOHERENT
143 select IRQ_CPU
144 select SYS_SUPPORTS_32BIT_KERNEL
145 select SYS_SUPPORTS_BIG_ENDIAN
146 select SYS_SUPPORTS_HIGHMEM
147 select SYS_HAS_CPU_BMIPS5000
148 select SWAP_IO_SPACE
149 select USB_EHCI_BIG_ENDIAN_DESC
150 select USB_EHCI_BIG_ENDIAN_MMIO
151 select USB_OHCI_BIG_ENDIAN_DESC
152 select USB_OHCI_BIG_ENDIAN_MMIO
153 help
154 Support for BCM3384 based boards. BCM3384/BCM33843 is a cable modem
155 chipset with a Linux application processor that is often used to
156 provide Samba services, a CUPS print server, and/or advanced routing
157 features.
158
118config BCM47XX 159config BCM47XX
119 bool "Broadcom BCM47XX based boards" 160 bool "Broadcom BCM47XX based boards"
120 select ARCH_WANT_OPTIONAL_GPIOLIB 161 select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -269,6 +310,8 @@ config LANTIQ
269 select USE_OF 310 select USE_OF
270 select PINCTRL 311 select PINCTRL
271 select PINCTRL_LANTIQ 312 select PINCTRL_LANTIQ
313 select ARCH_HAS_RESET_CONTROLLER
314 select RESET_CONTROLLER
272 315
273config LASAT 316config LASAT
274 bool "LASAT Networks platforms" 317 bool "LASAT Networks platforms"
@@ -315,17 +358,18 @@ config MIPS_MALTA
315 select BOOT_RAW 358 select BOOT_RAW
316 select CEVT_R4K 359 select CEVT_R4K
317 select CSRC_R4K 360 select CSRC_R4K
318 select CSRC_GIC 361 select CLKSRC_MIPS_GIC
319 select DMA_MAYBE_COHERENT 362 select DMA_MAYBE_COHERENT
320 select GENERIC_ISA_DMA 363 select GENERIC_ISA_DMA
321 select HAVE_PCSPKR_PLATFORM 364 select HAVE_PCSPKR_PLATFORM
322 select IRQ_CPU 365 select IRQ_CPU
323 select IRQ_GIC 366 select MIPS_GIC
324 select HW_HAS_PCI 367 select HW_HAS_PCI
325 select I8253 368 select I8253
326 select I8259 369 select I8259
327 select MIPS_BONITO64 370 select MIPS_BONITO64
328 select MIPS_CPU_SCACHE 371 select MIPS_CPU_SCACHE
372 select MIPS_L1_CACHE_SHIFT_6
329 select PCI_GT64XXX_PCI0 373 select PCI_GT64XXX_PCI0
330 select MIPS_MSC 374 select MIPS_MSC
331 select SWAP_IO_SPACE 375 select SWAP_IO_SPACE
@@ -340,6 +384,7 @@ config MIPS_MALTA
340 select SYS_SUPPORTS_64BIT_KERNEL 384 select SYS_SUPPORTS_64BIT_KERNEL
341 select SYS_SUPPORTS_BIG_ENDIAN 385 select SYS_SUPPORTS_BIG_ENDIAN
342 select SYS_SUPPORTS_LITTLE_ENDIAN 386 select SYS_SUPPORTS_LITTLE_ENDIAN
387 select SYS_SUPPORTS_MICROMIPS
343 select SYS_SUPPORTS_MIPS_CMP 388 select SYS_SUPPORTS_MIPS_CMP
344 select SYS_SUPPORTS_MIPS_CPS 389 select SYS_SUPPORTS_MIPS_CPS
345 select SYS_SUPPORTS_MIPS16 390 select SYS_SUPPORTS_MIPS16
@@ -357,12 +402,12 @@ config MIPS_SEAD3
357 select BUILTIN_DTB 402 select BUILTIN_DTB
358 select CEVT_R4K 403 select CEVT_R4K
359 select CSRC_R4K 404 select CSRC_R4K
360 select CSRC_GIC 405 select CLKSRC_MIPS_GIC
361 select CPU_MIPSR2_IRQ_VI 406 select CPU_MIPSR2_IRQ_VI
362 select CPU_MIPSR2_IRQ_EI 407 select CPU_MIPSR2_IRQ_EI
363 select DMA_NONCOHERENT 408 select DMA_NONCOHERENT
364 select IRQ_CPU 409 select IRQ_CPU
365 select IRQ_GIC 410 select MIPS_GIC
366 select LIBFDT 411 select LIBFDT
367 select MIPS_MSC 412 select MIPS_MSC
368 select SYS_HAS_CPU_MIPS32_R1 413 select SYS_HAS_CPU_MIPS32_R1
@@ -726,7 +771,7 @@ config MIKROTIK_RB532
726config CAVIUM_OCTEON_SOC 771config CAVIUM_OCTEON_SOC
727 bool "Cavium Networks Octeon SoC based boards" 772 bool "Cavium Networks Octeon SoC based boards"
728 select CEVT_R4K 773 select CEVT_R4K
729 select 64BIT_PHYS_ADDR 774 select ARCH_PHYS_ADDR_T_64BIT
730 select DMA_COHERENT 775 select DMA_COHERENT
731 select SYS_SUPPORTS_64BIT_KERNEL 776 select SYS_SUPPORTS_64BIT_KERNEL
732 select SYS_SUPPORTS_BIG_ENDIAN 777 select SYS_SUPPORTS_BIG_ENDIAN
@@ -768,7 +813,7 @@ config NLM_XLR_BOARD
768 select SWAP_IO_SPACE 813 select SWAP_IO_SPACE
769 select SYS_SUPPORTS_32BIT_KERNEL 814 select SYS_SUPPORTS_32BIT_KERNEL
770 select SYS_SUPPORTS_64BIT_KERNEL 815 select SYS_SUPPORTS_64BIT_KERNEL
771 select 64BIT_PHYS_ADDR 816 select ARCH_PHYS_ADDR_T_64BIT
772 select SYS_SUPPORTS_BIG_ENDIAN 817 select SYS_SUPPORTS_BIG_ENDIAN
773 select SYS_SUPPORTS_HIGHMEM 818 select SYS_SUPPORTS_HIGHMEM
774 select DMA_COHERENT 819 select DMA_COHERENT
@@ -794,7 +839,7 @@ config NLM_XLP_BOARD
794 select HW_HAS_PCI 839 select HW_HAS_PCI
795 select SYS_SUPPORTS_32BIT_KERNEL 840 select SYS_SUPPORTS_32BIT_KERNEL
796 select SYS_SUPPORTS_64BIT_KERNEL 841 select SYS_SUPPORTS_64BIT_KERNEL
797 select 64BIT_PHYS_ADDR 842 select ARCH_PHYS_ADDR_T_64BIT
798 select SYS_SUPPORTS_BIG_ENDIAN 843 select SYS_SUPPORTS_BIG_ENDIAN
799 select SYS_SUPPORTS_LITTLE_ENDIAN 844 select SYS_SUPPORTS_LITTLE_ENDIAN
800 select SYS_SUPPORTS_HIGHMEM 845 select SYS_SUPPORTS_HIGHMEM
@@ -835,6 +880,7 @@ config MIPS_PARAVIRT
835endchoice 880endchoice
836 881
837source "arch/mips/alchemy/Kconfig" 882source "arch/mips/alchemy/Kconfig"
883source "arch/mips/ath25/Kconfig"
838source "arch/mips/ath79/Kconfig" 884source "arch/mips/ath79/Kconfig"
839source "arch/mips/bcm47xx/Kconfig" 885source "arch/mips/bcm47xx/Kconfig"
840source "arch/mips/bcm63xx/Kconfig" 886source "arch/mips/bcm63xx/Kconfig"
@@ -907,10 +953,6 @@ config CEVT_GT641XX
907config CEVT_R4K 953config CEVT_R4K
908 bool 954 bool
909 955
910config CEVT_GIC
911 select MIPS_CM
912 bool
913
914config CEVT_SB1250 956config CEVT_SB1250
915 bool 957 bool
916 958
@@ -926,10 +968,6 @@ config CSRC_IOASIC
926config CSRC_R4K 968config CSRC_R4K
927 bool 969 bool
928 970
929config CSRC_GIC
930 select MIPS_CM
931 bool
932
933config CSRC_SB1250 971config CSRC_SB1250
934 bool 972 bool
935 973
@@ -941,7 +979,7 @@ config FW_CFE
941 bool 979 bool
942 980
943config ARCH_DMA_ADDR_T_64BIT 981config ARCH_DMA_ADDR_T_64BIT
944 def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT 982 def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT
945 983
946config DMA_MAYBE_COHERENT 984config DMA_MAYBE_COHERENT
947 select DMA_NONCOHERENT 985 select DMA_NONCOHERENT
@@ -975,6 +1013,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU
975 1013
976config I8259 1014config I8259
977 bool 1015 bool
1016 select IRQ_DOMAIN
978 1017
979config MIPS_BONITO64 1018config MIPS_BONITO64
980 bool 1019 bool
@@ -1055,6 +1094,7 @@ config MIPS_HUGE_TLB_SUPPORT
1055 1094
1056config IRQ_CPU 1095config IRQ_CPU
1057 bool 1096 bool
1097 select IRQ_DOMAIN
1058 1098
1059config IRQ_CPU_RM7K 1099config IRQ_CPU_RM7K
1060 bool 1100 bool
@@ -1071,10 +1111,6 @@ config IRQ_TXX9
1071config IRQ_GT641XX 1111config IRQ_GT641XX
1072 bool 1112 bool
1073 1113
1074config IRQ_GIC
1075 select MIPS_CM
1076 bool
1077
1078config PCI_GT64XXX_PCI0 1114config PCI_GT64XXX_PCI0
1079 bool 1115 bool
1080 1116
@@ -1574,6 +1610,7 @@ config CPU_LOONGSON1
1574 select CPU_HAS_PREFETCH 1610 select CPU_HAS_PREFETCH
1575 select CPU_SUPPORTS_32BIT_KERNEL 1611 select CPU_SUPPORTS_32BIT_KERNEL
1576 select CPU_SUPPORTS_HIGHMEM 1612 select CPU_SUPPORTS_HIGHMEM
1613 select CPU_SUPPORTS_CPUFREQ
1577 1614
1578config CPU_BMIPS32_3300 1615config CPU_BMIPS32_3300
1579 select SMP_UP if SMP 1616 select SMP_UP if SMP
@@ -1586,12 +1623,14 @@ config CPU_BMIPS4350
1586 1623
1587config CPU_BMIPS4380 1624config CPU_BMIPS4380
1588 bool 1625 bool
1626 select MIPS_L1_CACHE_SHIFT_6
1589 select SYS_SUPPORTS_SMP 1627 select SYS_SUPPORTS_SMP
1590 select SYS_SUPPORTS_HOTPLUG_CPU 1628 select SYS_SUPPORTS_HOTPLUG_CPU
1591 1629
1592config CPU_BMIPS5000 1630config CPU_BMIPS5000
1593 bool 1631 bool
1594 select MIPS_CPU_SCACHE 1632 select MIPS_CPU_SCACHE
1633 select MIPS_L1_CACHE_SHIFT_7
1595 select SYS_SUPPORTS_SMP 1634 select SYS_SUPPORTS_SMP
1596 select SYS_SUPPORTS_HOTPLUG_CPU 1635 select SYS_SUPPORTS_HOTPLUG_CPU
1597 1636
@@ -1886,15 +1925,6 @@ config FORCE_MAX_ZONEORDER
1886 The page size is not necessarily 4KB. Keep this in mind 1925 The page size is not necessarily 4KB. Keep this in mind
1887 when choosing a value for this option. 1926 when choosing a value for this option.
1888 1927
1889config CEVT_GIC
1890 bool "Use GIC global counter for clock events"
1891 depends on IRQ_GIC && !MIPS_SEAD3
1892 help
1893 Use the GIC global counter for the clock events. The R4K clock
1894 event driver is always present, so if the platform ends up not
1895 detecting a GIC, it will fall back to the R4K timer for the
1896 generation of clock events.
1897
1898config BOARD_SCACHE 1928config BOARD_SCACHE
1899 bool 1929 bool
1900 1930
@@ -1908,7 +1938,6 @@ config IP22_CPU_SCACHE
1908config MIPS_CPU_SCACHE 1938config MIPS_CPU_SCACHE
1909 bool 1939 bool
1910 select BOARD_SCACHE 1940 select BOARD_SCACHE
1911 select MIPS_L1_CACHE_SHIFT_6
1912 1941
1913config R5000_CPU_SCACHE 1942config R5000_CPU_SCACHE
1914 bool 1943 bool
@@ -2095,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS
2095 default y 2124 default y
2096 2125
2097 2126
2098config 64BIT_PHYS_ADDR
2099 bool
2100
2101config ARCH_PHYS_ADDR_T_64BIT 2127config ARCH_PHYS_ADDR_T_64BIT
2102 def_bool 64BIT_PHYS_ADDR 2128 bool
2103 2129
2104choice 2130choice
2105 prompt "SmartMIPS or microMIPS ASE support" 2131 prompt "SmartMIPS or microMIPS ASE support"
@@ -2122,7 +2148,7 @@ config CPU_HAS_SMARTMIPS
2122 here. 2148 here.
2123 2149
2124config CPU_MICROMIPS 2150config CPU_MICROMIPS
2125 depends on SYS_SUPPORTS_MICROMIPS 2151 depends on 32BIT && SYS_SUPPORTS_MICROMIPS
2126 bool "microMIPS" 2152 bool "microMIPS"
2127 help 2153 help
2128 When this option is enabled the kernel will be built using the 2154 When this option is enabled the kernel will be built using the
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 3a2b775e8458..88a9f433f6fc 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -122,4 +122,17 @@ config SPINLOCK_TEST
122 help 122 help
123 Add several files to the debugfs to test spinlock speed. 123 Add several files to the debugfs to test spinlock speed.
124 124
125config FP32XX_HYBRID_FPRS
126 bool "Run FP32 & FPXX code with hybrid FPRs"
127 depends on MIPS_O32_FP64_SUPPORT
128 help
129 The hybrid FPR scheme is normally used only when a program needs to
130 execute a mix of FP32 & FP64A code, since the trapping & emulation
131 that it entails is expensive. When enabled, this option will lead
132 to the kernel running programs which use the FP32 & FPXX FP ABIs
133 using the hybrid FPR scheme, which can be useful for debugging
134 purposes.
135
136 If unsure, say N.
137
125endmenu 138endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 58076472bdd8..2563a088d3b8 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -380,6 +380,7 @@ define archhelp
380 echo ' vmlinux.ecoff - ECOFF boot image' 380 echo ' vmlinux.ecoff - ECOFF boot image'
381 echo ' vmlinux.bin - Raw binary boot image' 381 echo ' vmlinux.bin - Raw binary boot image'
382 echo ' vmlinux.srec - SREC boot image' 382 echo ' vmlinux.srec - SREC boot image'
383 echo ' vmlinux.32 - 64-bit boot image wrapped in 32bits (IP22/IP32)'
383 echo ' vmlinuz - Compressed boot(zboot) image' 384 echo ' vmlinuz - Compressed boot(zboot) image'
384 echo ' vmlinuz.ecoff - ECOFF zboot image' 385 echo ' vmlinuz.ecoff - ECOFF zboot image'
385 echo ' vmlinuz.bin - Raw binary zboot image' 386 echo ' vmlinuz.bin - Raw binary zboot image'
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c
index d7557cde271a..203e4403c366 100644
--- a/arch/mips/alchemy/common/clock.c
+++ b/arch/mips/alchemy/common/clock.c
@@ -37,7 +37,6 @@
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/clk-provider.h> 38#include <linux/clk-provider.h>
39#include <linux/clkdev.h> 39#include <linux/clkdev.h>
40#include <linux/clk-private.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/spinlock.h> 41#include <linux/spinlock.h>
43#include <linux/types.h> 42#include <linux/types.h>
@@ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
397 break; 396 break;
398 397
399 /* if this parent is currently unused, remember it. 398 /* if this parent is currently unused, remember it.
400 * XXX: I know it's a layering violation, but it works 399 * XXX: we would actually want clk_has_active_children()
401 * so well.. (if (!clk_has_active_children(pc)) ) 400 * but this is a good-enough approximation for now.
402 */ 401 */
403 if (pc->prepare_count == 0) { 402 if (!__clk_is_prepared(pc)) {
404 if (!free) 403 if (!free)
405 free = pc; 404 free = pc;
406 } 405 }
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
index ea8f41869e56..4e72daf12c32 100644
--- a/arch/mips/alchemy/common/setup.c
+++ b/arch/mips/alchemy/common/setup.c
@@ -70,9 +70,9 @@ void __init plat_mem_setup(void)
70 iomem_resource.end = IOMEM_RESOURCE_END; 70 iomem_resource.end = IOMEM_RESOURCE_END;
71} 71}
72 72
73#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) 73#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
74/* This routine should be valid for all Au1x based boards */ 74/* This routine should be valid for all Au1x based boards */
75phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) 75phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
76{ 76{
77 unsigned long start = ALCHEMY_PCI_MEMWIN_START; 77 unsigned long start = ALCHEMY_PCI_MEMWIN_START;
78 unsigned long end = ALCHEMY_PCI_MEMWIN_END; 78 unsigned long end = ALCHEMY_PCI_MEMWIN_END;
@@ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
83 83
84 /* Check for PCI memory window */ 84 /* Check for PCI memory window */
85 if (phys_addr >= start && (phys_addr + size - 1) <= end) 85 if (phys_addr >= start && (phys_addr + size - 1) <= end)
86 return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); 86 return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr);
87 87
88 /* default nop */ 88 /* default nop */
89 return phys_addr; 89 return phys_addr;
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 7e2356fd5fd6..af2441dbfc12 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
311 &dev_addr[0], &dev_addr[1], 311 &dev_addr[0], &dev_addr[1],
312 &dev_addr[2], &dev_addr[3], 312 &dev_addr[2], &dev_addr[3],
313 &dev_addr[4], &dev_addr[5]) != 6) { 313 &dev_addr[4], &dev_addr[5]) != 6) {
314 pr_warning("cannot parse mac address, " 314 pr_warn("cannot parse mac address, using random address\n");
315 "using random address\n");
316 eth_random_addr(dev_addr); 315 eth_random_addr(dev_addr);
317 } 316 }
318 } else 317 } else
@@ -665,7 +664,7 @@ static int __init ar7_register_devices(void)
665 664
666 res = platform_device_register(&physmap_flash); 665 res = platform_device_register(&physmap_flash);
667 if (res) 666 if (res)
668 pr_warning("unable to register physmap-flash: %d\n", res); 667 pr_warn("unable to register physmap-flash: %d\n", res);
669 668
670 if (ar7_is_titan()) 669 if (ar7_is_titan())
671 titan_fixup_devices(); 670 titan_fixup_devices();
@@ -673,13 +672,13 @@ static int __init ar7_register_devices(void)
673 ar7_device_disable(vlynq_low_data.reset_bit); 672 ar7_device_disable(vlynq_low_data.reset_bit);
674 res = platform_device_register(&vlynq_low); 673 res = platform_device_register(&vlynq_low);
675 if (res) 674 if (res)
676 pr_warning("unable to register vlynq-low: %d\n", res); 675 pr_warn("unable to register vlynq-low: %d\n", res);
677 676
678 if (ar7_has_high_vlynq()) { 677 if (ar7_has_high_vlynq()) {
679 ar7_device_disable(vlynq_high_data.reset_bit); 678 ar7_device_disable(vlynq_high_data.reset_bit);
680 res = platform_device_register(&vlynq_high); 679 res = platform_device_register(&vlynq_high);
681 if (res) 680 if (res)
682 pr_warning("unable to register vlynq-high: %d\n", res); 681 pr_warn("unable to register vlynq-high: %d\n", res);
683 } 682 }
684 683
685 if (ar7_has_high_cpmac()) { 684 if (ar7_has_high_cpmac()) {
@@ -689,9 +688,10 @@ static int __init ar7_register_devices(void)
689 688
690 res = platform_device_register(&cpmac_high); 689 res = platform_device_register(&cpmac_high);
691 if (res) 690 if (res)
692 pr_warning("unable to register cpmac-high: %d\n", res); 691 pr_warn("unable to register cpmac-high: %d\n",
692 res);
693 } else 693 } else
694 pr_warning("unable to add cpmac-high phy: %d\n", res); 694 pr_warn("unable to add cpmac-high phy: %d\n", res);
695 } else 695 } else
696 cpmac_low_data.phy_mask = 0xffffffff; 696 cpmac_low_data.phy_mask = 0xffffffff;
697 697
@@ -700,18 +700,18 @@ static int __init ar7_register_devices(void)
700 cpmac_get_mac(0, cpmac_low_data.dev_addr); 700 cpmac_get_mac(0, cpmac_low_data.dev_addr);
701 res = platform_device_register(&cpmac_low); 701 res = platform_device_register(&cpmac_low);
702 if (res) 702 if (res)
703 pr_warning("unable to register cpmac-low: %d\n", res); 703 pr_warn("unable to register cpmac-low: %d\n", res);
704 } else 704 } else
705 pr_warning("unable to add cpmac-low phy: %d\n", res); 705 pr_warn("unable to add cpmac-low phy: %d\n", res);
706 706
707 detect_leds(); 707 detect_leds();
708 res = platform_device_register(&ar7_gpio_leds); 708 res = platform_device_register(&ar7_gpio_leds);
709 if (res) 709 if (res)
710 pr_warning("unable to register leds: %d\n", res); 710 pr_warn("unable to register leds: %d\n", res);
711 711
712 res = platform_device_register(&ar7_udc); 712 res = platform_device_register(&ar7_udc);
713 if (res) 713 if (res)
714 pr_warning("unable to register usb slave: %d\n", res); 714 pr_warn("unable to register usb slave: %d\n", res);
715 715
716 /* Register watchdog only if enabled in hardware */ 716 /* Register watchdog only if enabled in hardware */
717 bootcr = ioremap_nocache(AR7_REGS_DCL, 4); 717 bootcr = ioremap_nocache(AR7_REGS_DCL, 4);
@@ -726,7 +726,7 @@ static int __init ar7_register_devices(void)
726 ar7_wdt_res.end = ar7_wdt_res.start + 0x20; 726 ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
727 res = platform_device_register(&ar7_wdt); 727 res = platform_device_register(&ar7_wdt);
728 if (res) 728 if (res)
729 pr_warning("unable to register watchdog: %d\n", res); 729 pr_warn("unable to register watchdog: %d\n", res);
730 } 730 }
731 731
732 return 0; 732 return 0;
diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig
new file mode 100644
index 000000000000..fc19dd57e42d
--- /dev/null
+++ b/arch/mips/ath25/Kconfig
@@ -0,0 +1,16 @@
1config SOC_AR5312
2 bool "Atheros AR5312/AR2312+ SoC support"
3 depends on ATH25
4 default y
5
6config SOC_AR2315
7 bool "Atheros AR2315+ SoC support"
8 depends on ATH25
9 default y
10
11config PCI_AR2315
12 bool "Atheros AR2315 PCI controller support"
13 depends on SOC_AR2315
14 select HW_HAS_PCI
15 select PCI
16 default y
diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile
new file mode 100644
index 000000000000..eabad7da446a
--- /dev/null
+++ b/arch/mips/ath25/Makefile
@@ -0,0 +1,16 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2006 FON Technology, SL.
7# Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
8# Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
9#
10
11obj-y += board.o prom.o devices.o
12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14
15obj-$(CONFIG_SOC_AR5312) += ar5312.o
16obj-$(CONFIG_SOC_AR2315) += ar2315.o
diff --git a/arch/mips/ath25/Platform b/arch/mips/ath25/Platform
new file mode 100644
index 000000000000..ef3f81fa080b
--- /dev/null
+++ b/arch/mips/ath25/Platform
@@ -0,0 +1,6 @@
1#
2# Atheros AR531X/AR231X WiSoC
3#
4platform-$(CONFIG_ATH25) += ath25/
5cflags-$(CONFIG_ATH25) += -I$(srctree)/arch/mips/include/asm/mach-ath25
6load-$(CONFIG_ATH25) += 0xffffffff80041000
diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c
new file mode 100644
index 000000000000..2befa7d766a6
--- /dev/null
+++ b/arch/mips/ath25/ar2315.c
@@ -0,0 +1,364 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
10 * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
11 */
12
13/*
14 * Platform devices for Atheros AR2315 SoCs
15 */
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/bitops.h>
20#include <linux/irqdomain.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/reboot.h>
24#include <asm/bootinfo.h>
25#include <asm/reboot.h>
26#include <asm/time.h>
27
28#include <ath25_platform.h>
29
30#include "devices.h"
31#include "ar2315.h"
32#include "ar2315_regs.h"
33
34static void __iomem *ar2315_rst_base;
35static struct irq_domain *ar2315_misc_irq_domain;
36
37static inline u32 ar2315_rst_reg_read(u32 reg)
38{
39 return __raw_readl(ar2315_rst_base + reg);
40}
41
42static inline void ar2315_rst_reg_write(u32 reg, u32 val)
43{
44 __raw_writel(val, ar2315_rst_base + reg);
45}
46
47static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val)
48{
49 u32 ret = ar2315_rst_reg_read(reg);
50
51 ret &= ~mask;
52 ret |= val;
53 ar2315_rst_reg_write(reg, ret);
54}
55
56static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id)
57{
58 ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
59 ar2315_rst_reg_read(AR2315_AHB_ERR1);
60
61 pr_emerg("AHB fatal error\n");
62 machine_restart("AHB error"); /* Catastrophic failure */
63
64 return IRQ_HANDLED;
65}
66
67static struct irqaction ar2315_ahb_err_interrupt = {
68 .handler = ar2315_ahb_err_handler,
69 .name = "ar2315-ahb-error",
70};
71
72static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc)
73{
74 u32 pending = ar2315_rst_reg_read(AR2315_ISR) &
75 ar2315_rst_reg_read(AR2315_IMR);
76 unsigned nr, misc_irq = 0;
77
78 if (pending) {
79 struct irq_domain *domain = irq_get_handler_data(irq);
80
81 nr = __ffs(pending);
82 misc_irq = irq_find_mapping(domain, nr);
83 }
84
85 if (misc_irq) {
86 if (nr == AR2315_MISC_IRQ_GPIO)
87 ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO);
88 else if (nr == AR2315_MISC_IRQ_WATCHDOG)
89 ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD);
90 generic_handle_irq(misc_irq);
91 } else {
92 spurious_interrupt();
93 }
94}
95
96static void ar2315_misc_irq_unmask(struct irq_data *d)
97{
98 ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq));
99}
100
101static void ar2315_misc_irq_mask(struct irq_data *d)
102{
103 ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0);
104}
105
106static struct irq_chip ar2315_misc_irq_chip = {
107 .name = "ar2315-misc",
108 .irq_unmask = ar2315_misc_irq_unmask,
109 .irq_mask = ar2315_misc_irq_mask,
110};
111
112static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq,
113 irq_hw_number_t hw)
114{
115 irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq);
116 return 0;
117}
118
119static struct irq_domain_ops ar2315_misc_irq_domain_ops = {
120 .map = ar2315_misc_irq_map,
121};
122
123/*
124 * Called when an interrupt is received, this function
125 * determines exactly which interrupt it was, and it
126 * invokes the appropriate handler.
127 *
128 * Implicitly, we also define interrupt priority by
129 * choosing which to dispatch first.
130 */
131static void ar2315_irq_dispatch(void)
132{
133 u32 pending = read_c0_status() & read_c0_cause();
134
135 if (pending & CAUSEF_IP3)
136 do_IRQ(AR2315_IRQ_WLAN0);
137#ifdef CONFIG_PCI_AR2315
138 else if (pending & CAUSEF_IP5)
139 do_IRQ(AR2315_IRQ_LCBUS_PCI);
140#endif
141 else if (pending & CAUSEF_IP2)
142 do_IRQ(AR2315_IRQ_MISC);
143 else if (pending & CAUSEF_IP7)
144 do_IRQ(ATH25_IRQ_CPU_CLOCK);
145 else
146 spurious_interrupt();
147}
148
149void __init ar2315_arch_init_irq(void)
150{
151 struct irq_domain *domain;
152 unsigned irq;
153
154 ath25_irq_dispatch = ar2315_irq_dispatch;
155
156 domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT,
157 &ar2315_misc_irq_domain_ops, NULL);
158 if (!domain)
159 panic("Failed to add IRQ domain");
160
161 irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB);
162 setup_irq(irq, &ar2315_ahb_err_interrupt);
163
164 irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler);
165 irq_set_handler_data(AR2315_IRQ_MISC, domain);
166
167 ar2315_misc_irq_domain = domain;
168}
169
170void __init ar2315_init_devices(void)
171{
172 /* Find board configuration */
173 ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE);
174
175 ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0);
176}
177
178static void ar2315_restart(char *command)
179{
180 void (*mips_reset_vec)(void) = (void *)0xbfc00000;
181
182 local_irq_disable();
183
184 /* try reset the system via reset control */
185 ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM);
186
187 /* Cold reset does not work on the AR2315/6, use the GPIO reset bits
188 * a workaround. Give it some time to attempt a gpio based hardware
189 * reset (atheros reference design workaround) */
190
191 /* TODO: implement the GPIO reset workaround */
192
193 /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
194 * workaround. Attempt to jump to the mips reset location -
195 * the boot loader itself might be able to recover the system */
196 mips_reset_vec();
197}
198
199/*
200 * This table is indexed by bits 5..4 of the CLOCKCTL1 register
201 * to determine the predevisor value.
202 */
203static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
204static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 };
205
206static unsigned __init ar2315_sys_clk(u32 clock_ctl)
207{
208 unsigned int pllc_ctrl, cpu_div;
209 unsigned int pllc_out, refdiv, fdiv, divby2;
210 unsigned int clk_div;
211
212 pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL);
213 refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV);
214 refdiv = clockctl1_predivide_table[refdiv];
215 fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV);
216 divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1;
217 pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv;
218
219 /* clkm input selected */
220 switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) {
221 case 0:
222 case 1:
223 clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV);
224 clk_div = pllc_divide_table[clk_div];
225 break;
226 case 2:
227 clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV);
228 clk_div = pllc_divide_table[clk_div];
229 break;
230 default:
231 pllc_out = 40000000;
232 clk_div = 1;
233 break;
234 }
235
236 cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV);
237 cpu_div = cpu_div * 2 ?: 1;
238
239 return pllc_out / (clk_div * cpu_div);
240}
241
242static inline unsigned ar2315_cpu_frequency(void)
243{
244 return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK));
245}
246
247static inline unsigned ar2315_apb_frequency(void)
248{
249 return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK));
250}
251
252void __init ar2315_plat_time_init(void)
253{
254 mips_hpt_frequency = ar2315_cpu_frequency() / 2;
255}
256
257void __init ar2315_plat_mem_setup(void)
258{
259 void __iomem *sdram_base;
260 u32 memsize, memcfg;
261 u32 devid;
262 u32 config;
263
264 /* Detect memory size */
265 sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE,
266 AR2315_SDRAMCTL_SIZE);
267 memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG);
268 memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH);
269 memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH);
270 memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH);
271 memsize <<= 3;
272 add_memory_region(0, memsize, BOOT_MEM_RAM);
273 iounmap(sdram_base);
274
275 ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE);
276
277 /* Detect the hardware based on the device ID */
278 devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP;
279 switch (devid) {
280 case 0x91: /* Need to check */
281 ath25_soc = ATH25_SOC_AR2318;
282 break;
283 case 0x90:
284 ath25_soc = ATH25_SOC_AR2317;
285 break;
286 case 0x87:
287 ath25_soc = ATH25_SOC_AR2316;
288 break;
289 case 0x86:
290 default:
291 ath25_soc = ATH25_SOC_AR2315;
292 break;
293 }
294 ath25_board.devid = devid;
295
296 /* Clear any lingering AHB errors */
297 config = read_c0_config();
298 write_c0_config(config & ~0x3);
299 ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
300 ar2315_rst_reg_read(AR2315_AHB_ERR1);
301 ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE);
302
303 _machine_restart = ar2315_restart;
304}
305
306#ifdef CONFIG_PCI_AR2315
307static struct resource ar2315_pci_res[] = {
308 {
309 .name = "ar2315-pci-ctrl",
310 .flags = IORESOURCE_MEM,
311 .start = AR2315_PCI_BASE,
312 .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1,
313 },
314 {
315 .name = "ar2315-pci-ext",
316 .flags = IORESOURCE_MEM,
317 .start = AR2315_PCI_EXT_BASE,
318 .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1,
319 },
320 {
321 .name = "ar2315-pci",
322 .flags = IORESOURCE_IRQ,
323 .start = AR2315_IRQ_LCBUS_PCI,
324 .end = AR2315_IRQ_LCBUS_PCI,
325 },
326};
327#endif
328
329void __init ar2315_arch_init(void)
330{
331 unsigned irq = irq_create_mapping(ar2315_misc_irq_domain,
332 AR2315_MISC_IRQ_UART0);
333
334 ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency());
335
336#ifdef CONFIG_PCI_AR2315
337 if (ath25_soc == ATH25_SOC_AR2315) {
338 /* Reset PCI DMA logic */
339 ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA);
340 msleep(20);
341 ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0);
342 msleep(20);
343
344 /* Configure endians */
345 ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB |
346 AR2315_CONFIG_PCIAHB_BRIDGE);
347
348 /* Configure as PCI host with DMA */
349 ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM |
350 (AR2315_PCICLK_IN_FREQ_DIV_6 <<
351 AR2315_PCICLK_DIV_S));
352 ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI);
353 ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK |
354 AR2315_IF_MASK, AR2315_IF_PCI |
355 AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR |
356 (AR2315_IF_PCI_CLK_OUTPUT_CLK <<
357 AR2315_IF_PCI_CLK_SHIFT));
358
359 platform_device_register_simple("ar2315-pci", -1,
360 ar2315_pci_res,
361 ARRAY_SIZE(ar2315_pci_res));
362 }
363#endif
364}
diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h
new file mode 100644
index 000000000000..877afe63eed5
--- /dev/null
+++ b/arch/mips/ath25/ar2315.h
@@ -0,0 +1,22 @@
1#ifndef __AR2315_H
2#define __AR2315_H
3
4#ifdef CONFIG_SOC_AR2315
5
6void ar2315_arch_init_irq(void);
7void ar2315_init_devices(void);
8void ar2315_plat_time_init(void);
9void ar2315_plat_mem_setup(void);
10void ar2315_arch_init(void);
11
12#else
13
14static inline void ar2315_arch_init_irq(void) {}
15static inline void ar2315_init_devices(void) {}
16static inline void ar2315_plat_time_init(void) {}
17static inline void ar2315_plat_mem_setup(void) {}
18static inline void ar2315_arch_init(void) {}
19
20#endif
21
22#endif /* __AR2315_H */
diff --git a/arch/mips/ath25/ar2315_regs.h b/arch/mips/ath25/ar2315_regs.h
new file mode 100644
index 000000000000..16e86149cb74
--- /dev/null
+++ b/arch/mips/ath25/ar2315_regs.h
@@ -0,0 +1,410 @@
1/*
2 * Register definitions for AR2315+
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
9 * Copyright (C) 2006 FON Technology, SL.
10 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
11 * Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org>
12 */
13
14#ifndef __ASM_MACH_ATH25_AR2315_REGS_H
15#define __ASM_MACH_ATH25_AR2315_REGS_H
16
17/*
18 * IRQs
19 */
20#define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
21#define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
22#define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
23#define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
24#define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
25
26/*
27 * Miscellaneous interrupts, which share IP2.
28 */
29#define AR2315_MISC_IRQ_UART0 0
30#define AR2315_MISC_IRQ_I2C_RSVD 1
31#define AR2315_MISC_IRQ_SPI 2
32#define AR2315_MISC_IRQ_AHB 3
33#define AR2315_MISC_IRQ_APB 4
34#define AR2315_MISC_IRQ_TIMER 5
35#define AR2315_MISC_IRQ_GPIO 6
36#define AR2315_MISC_IRQ_WATCHDOG 7
37#define AR2315_MISC_IRQ_IR_RSVD 8
38#define AR2315_MISC_IRQ_COUNT 9
39
40/*
41 * Address map
42 */
43#define AR2315_SPI_READ_BASE 0x08000000 /* SPI flash */
44#define AR2315_SPI_READ_SIZE 0x01000000
45#define AR2315_WLAN0_BASE 0x10000000 /* Wireless MMR */
46#define AR2315_PCI_BASE 0x10100000 /* PCI MMR */
47#define AR2315_PCI_SIZE 0x00001000
48#define AR2315_SDRAMCTL_BASE 0x10300000 /* SDRAM MMR */
49#define AR2315_SDRAMCTL_SIZE 0x00000020
50#define AR2315_LOCAL_BASE 0x10400000 /* Local bus MMR */
51#define AR2315_ENET0_BASE 0x10500000 /* Ethernet MMR */
52#define AR2315_RST_BASE 0x11000000 /* Reset control MMR */
53#define AR2315_RST_SIZE 0x00000100
54#define AR2315_UART0_BASE 0x11100000 /* UART MMR */
55#define AR2315_SPI_MMR_BASE 0x11300000 /* SPI flash MMR */
56#define AR2315_SPI_MMR_SIZE 0x00000010
57#define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */
58#define AR2315_PCI_EXT_SIZE 0x40000000
59
60/*
61 * Configuration registers
62 */
63
64/* Cold reset register */
65#define AR2315_COLD_RESET 0x0000
66
67#define AR2315_RESET_COLD_AHB 0x00000001
68#define AR2315_RESET_COLD_APB 0x00000002
69#define AR2315_RESET_COLD_CPU 0x00000004
70#define AR2315_RESET_COLD_CPUWARM 0x00000008
71#define AR2315_RESET_SYSTEM (RESET_COLD_CPU |\
72 RESET_COLD_APB |\
73 RESET_COLD_AHB) /* full system */
74#define AR2317_RESET_SYSTEM 0x00000010
75
76/* Reset register */
77#define AR2315_RESET 0x0004
78
79#define AR2315_RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */
80#define AR2315_RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BB */
81#define AR2315_RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */
82#define AR2315_RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */
83#define AR2315_RESET_MEMCTL 0x00000010 /* warm reset mem control */
84#define AR2315_RESET_LOCAL 0x00000020 /* warm reset local bus */
85#define AR2315_RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */
86#define AR2315_RESET_SPI 0x00000080 /* warm reset SPI iface */
87#define AR2315_RESET_UART0 0x00000100 /* warm reset UART0 */
88#define AR2315_RESET_IR_RSVD 0x00000200 /* warm reset IR iface */
89#define AR2315_RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */
90#define AR2315_RESET_ENET0 0x00000800 /* cold reset ENET0 MAC */
91
92/* AHB master arbitration control */
93#define AR2315_AHB_ARB_CTL 0x0008
94
95#define AR2315_ARB_CPU 0x00000001 /* CPU, default */
96#define AR2315_ARB_WLAN 0x00000002 /* WLAN */
97#define AR2315_ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */
98#define AR2315_ARB_LOCAL 0x00000008 /* Local bus */
99#define AR2315_ARB_PCI 0x00000010 /* PCI bus */
100#define AR2315_ARB_ETHERNET 0x00000020 /* Ethernet */
101#define AR2315_ARB_RETRY 0x00000100 /* Retry policy (debug) */
102
103/* Config Register */
104#define AR2315_ENDIAN_CTL 0x000c
105
106#define AR2315_CONFIG_AHB 0x00000001 /* EC-AHB bridge endian */
107#define AR2315_CONFIG_WLAN 0x00000002 /* WLAN byteswap */
108#define AR2315_CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */
109#define AR2315_CONFIG_PCI 0x00000008 /* PCI byteswap */
110#define AR2315_CONFIG_MEMCTL 0x00000010 /* Mem controller endian */
111#define AR2315_CONFIG_LOCAL 0x00000020 /* Local bus byteswap */
112#define AR2315_CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */
113#define AR2315_CONFIG_MERGE 0x00000200 /* CPU write buffer merge */
114#define AR2315_CONFIG_CPU 0x00000400 /* CPU big endian */
115#define AR2315_CONFIG_BIG 0x00000400
116#define AR2315_CONFIG_PCIAHB 0x00000800
117#define AR2315_CONFIG_PCIAHB_BRIDGE 0x00001000
118#define AR2315_CONFIG_SPI 0x00008000 /* SPI byteswap */
119#define AR2315_CONFIG_CPU_DRAM 0x00010000
120#define AR2315_CONFIG_CPU_PCI 0x00020000
121#define AR2315_CONFIG_CPU_MMR 0x00040000
122
123/* NMI control */
124#define AR2315_NMI_CTL 0x0010
125
126#define AR2315_NMI_EN 1
127
128/* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */
129#define AR2315_SREV 0x0014
130
131#define AR2315_REV_MAJ 0x000000f0
132#define AR2315_REV_MAJ_S 4
133#define AR2315_REV_MIN 0x0000000f
134#define AR2315_REV_MIN_S 0
135#define AR2315_REV_CHIP (AR2315_REV_MAJ | AR2315_REV_MIN)
136
137/* Interface Enable */
138#define AR2315_IF_CTL 0x0018
139
140#define AR2315_IF_MASK 0x00000007
141#define AR2315_IF_DISABLED 0 /* Disable all */
142#define AR2315_IF_PCI 1 /* PCI */
143#define AR2315_IF_TS_LOCAL 2 /* Local bus */
144#define AR2315_IF_ALL 3 /* Emulation only */
145#define AR2315_IF_LOCAL_HOST 0x00000008
146#define AR2315_IF_PCI_HOST 0x00000010
147#define AR2315_IF_PCI_INTR 0x00000020
148#define AR2315_IF_PCI_CLK_MASK 0x00030000
149#define AR2315_IF_PCI_CLK_INPUT 0
150#define AR2315_IF_PCI_CLK_OUTPUT_LOW 1
151#define AR2315_IF_PCI_CLK_OUTPUT_CLK 2
152#define AR2315_IF_PCI_CLK_OUTPUT_HIGH 3
153#define AR2315_IF_PCI_CLK_SHIFT 16
154
155/* APB Interrupt control */
156#define AR2315_ISR 0x0020
157#define AR2315_IMR 0x0024
158#define AR2315_GISR 0x0028
159
160#define AR2315_ISR_UART0 0x00000001 /* high speed UART */
161#define AR2315_ISR_I2C_RSVD 0x00000002 /* I2C bus */
162#define AR2315_ISR_SPI 0x00000004 /* SPI bus */
163#define AR2315_ISR_AHB 0x00000008 /* AHB error */
164#define AR2315_ISR_APB 0x00000010 /* APB error */
165#define AR2315_ISR_TIMER 0x00000020 /* Timer */
166#define AR2315_ISR_GPIO 0x00000040 /* GPIO */
167#define AR2315_ISR_WD 0x00000080 /* Watchdog */
168#define AR2315_ISR_IR_RSVD 0x00000100 /* IR */
169
170#define AR2315_GISR_MISC 0x00000001 /* Misc */
171#define AR2315_GISR_WLAN0 0x00000002 /* WLAN0 */
172#define AR2315_GISR_MPEGTS_RSVD 0x00000004 /* MPEG-TS */
173#define AR2315_GISR_LOCALPCI 0x00000008 /* Local/PCI bus */
174#define AR2315_GISR_WMACPOLL 0x00000010
175#define AR2315_GISR_TIMER 0x00000020
176#define AR2315_GISR_ETHERNET 0x00000040 /* Ethernet */
177
178/* Generic timer */
179#define AR2315_TIMER 0x0030
180#define AR2315_RELOAD 0x0034
181
182/* Watchdog timer */
183#define AR2315_WDT_TIMER 0x0038
184#define AR2315_WDT_CTRL 0x003c
185
186#define AR2315_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */
187#define AR2315_WDT_CTRL_NMI 0x00000001 /* NMI on watchdog */
188#define AR2315_WDT_CTRL_RESET 0x00000002 /* reset on watchdog */
189
190/* CPU Performance Counters */
191#define AR2315_PERFCNT0 0x0048
192#define AR2315_PERFCNT1 0x004c
193
194#define AR2315_PERF0_DATAHIT 0x00000001 /* Count Data Cache Hits */
195#define AR2315_PERF0_DATAMISS 0x00000002 /* Count Data Cache Misses */
196#define AR2315_PERF0_INSTHIT 0x00000004 /* Count Instruction Cache Hits */
197#define AR2315_PERF0_INSTMISS 0x00000008 /* Count Instruction Cache Misses */
198#define AR2315_PERF0_ACTIVE 0x00000010 /* Count Active Processor Cycles */
199#define AR2315_PERF0_WBHIT 0x00000020 /* Count CPU Write Buffer Hits */
200#define AR2315_PERF0_WBMISS 0x00000040 /* Count CPU Write Buffer Misses */
201
202#define AR2315_PERF1_EB_ARDY 0x00000001 /* Count EB_ARdy signal */
203#define AR2315_PERF1_EB_AVALID 0x00000002 /* Count EB_AValid signal */
204#define AR2315_PERF1_EB_WDRDY 0x00000004 /* Count EB_WDRdy signal */
205#define AR2315_PERF1_EB_RDVAL 0x00000008 /* Count EB_RdVal signal */
206#define AR2315_PERF1_VRADDR 0x00000010 /* Count valid read address cycles*/
207#define AR2315_PERF1_VWADDR 0x00000020 /* Count valid write address cycl.*/
208#define AR2315_PERF1_VWDATA 0x00000040 /* Count valid write data cycles */
209
210/* AHB Error Reporting */
211#define AR2315_AHB_ERR0 0x0050 /* error */
212#define AR2315_AHB_ERR1 0x0054 /* haddr */
213#define AR2315_AHB_ERR2 0x0058 /* hwdata */
214#define AR2315_AHB_ERR3 0x005c /* hrdata */
215#define AR2315_AHB_ERR4 0x0060 /* status */
216
217#define AR2315_AHB_ERROR_DET 1 /* AHB Error has been detected, */
218 /* write 1 to clear all bits in ERR0 */
219#define AR2315_AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */
220#define AR2315_AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */
221
222#define AR2315_PROCERR_HMAST 0x0000000f
223#define AR2315_PROCERR_HMAST_DFLT 0
224#define AR2315_PROCERR_HMAST_WMAC 1
225#define AR2315_PROCERR_HMAST_ENET 2
226#define AR2315_PROCERR_HMAST_PCIENDPT 3
227#define AR2315_PROCERR_HMAST_LOCAL 4
228#define AR2315_PROCERR_HMAST_CPU 5
229#define AR2315_PROCERR_HMAST_PCITGT 6
230#define AR2315_PROCERR_HMAST_S 0
231#define AR2315_PROCERR_HWRITE 0x00000010
232#define AR2315_PROCERR_HSIZE 0x00000060
233#define AR2315_PROCERR_HSIZE_S 5
234#define AR2315_PROCERR_HTRANS 0x00000180
235#define AR2315_PROCERR_HTRANS_S 7
236#define AR2315_PROCERR_HBURST 0x00000e00
237#define AR2315_PROCERR_HBURST_S 9
238
239/* Clock Control */
240#define AR2315_PLLC_CTL 0x0064
241#define AR2315_PLLV_CTL 0x0068
242#define AR2315_CPUCLK 0x006c
243#define AR2315_AMBACLK 0x0070
244#define AR2315_SYNCCLK 0x0074
245#define AR2315_DSL_SLEEP_CTL 0x0080
246#define AR2315_DSL_SLEEP_DUR 0x0084
247
248/* PLLc Control fields */
249#define AR2315_PLLC_REF_DIV_M 0x00000003
250#define AR2315_PLLC_REF_DIV_S 0
251#define AR2315_PLLC_FDBACK_DIV_M 0x0000007c
252#define AR2315_PLLC_FDBACK_DIV_S 2
253#define AR2315_PLLC_ADD_FDBACK_DIV_M 0x00000080
254#define AR2315_PLLC_ADD_FDBACK_DIV_S 7
255#define AR2315_PLLC_CLKC_DIV_M 0x0001c000
256#define AR2315_PLLC_CLKC_DIV_S 14
257#define AR2315_PLLC_CLKM_DIV_M 0x00700000
258#define AR2315_PLLC_CLKM_DIV_S 20
259
260/* CPU CLK Control fields */
261#define AR2315_CPUCLK_CLK_SEL_M 0x00000003
262#define AR2315_CPUCLK_CLK_SEL_S 0
263#define AR2315_CPUCLK_CLK_DIV_M 0x0000000c
264#define AR2315_CPUCLK_CLK_DIV_S 2
265
266/* AMBA CLK Control fields */
267#define AR2315_AMBACLK_CLK_SEL_M 0x00000003
268#define AR2315_AMBACLK_CLK_SEL_S 0
269#define AR2315_AMBACLK_CLK_DIV_M 0x0000000c
270#define AR2315_AMBACLK_CLK_DIV_S 2
271
272/* PCI Clock Control */
273#define AR2315_PCICLK 0x00a4
274
275#define AR2315_PCICLK_INPUT_M 0x00000003
276#define AR2315_PCICLK_INPUT_S 0
277#define AR2315_PCICLK_PLLC_CLKM 0
278#define AR2315_PCICLK_PLLC_CLKM1 1
279#define AR2315_PCICLK_PLLC_CLKC 2
280#define AR2315_PCICLK_REF_CLK 3
281#define AR2315_PCICLK_DIV_M 0x0000000c
282#define AR2315_PCICLK_DIV_S 2
283#define AR2315_PCICLK_IN_FREQ 0
284#define AR2315_PCICLK_IN_FREQ_DIV_6 1
285#define AR2315_PCICLK_IN_FREQ_DIV_8 2
286#define AR2315_PCICLK_IN_FREQ_DIV_10 3
287
288/* Observation Control Register */
289#define AR2315_OCR 0x00b0
290
291#define AR2315_OCR_GPIO0_IRIN 0x00000040
292#define AR2315_OCR_GPIO1_IROUT 0x00000080
293#define AR2315_OCR_GPIO3_RXCLR 0x00000200
294
295/* General Clock Control */
296#define AR2315_MISCCLK 0x00b4
297
298#define AR2315_MISCCLK_PLLBYPASS_EN 0x00000001
299#define AR2315_MISCCLK_PROCREFCLK 0x00000002
300
301/*
302 * SDRAM Controller
303 * - No read or write buffers are included.
304 */
305#define AR2315_MEM_CFG 0x0000
306#define AR2315_MEM_CTRL 0x000c
307#define AR2315_MEM_REF 0x0010
308
309#define AR2315_MEM_CFG_DATA_WIDTH_M 0x00006000
310#define AR2315_MEM_CFG_DATA_WIDTH_S 13
311#define AR2315_MEM_CFG_COL_WIDTH_M 0x00001e00
312#define AR2315_MEM_CFG_COL_WIDTH_S 9
313#define AR2315_MEM_CFG_ROW_WIDTH_M 0x000001e0
314#define AR2315_MEM_CFG_ROW_WIDTH_S 5
315#define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018
316#define AR2315_MEM_CFG_BANKADDR_BITS_S 3
317
318/*
319 * Local Bus Interface Registers
320 */
321#define AR2315_LB_CONFIG 0x0000
322
323#define AR2315_LBCONF_OE 0x00000001 /* =1 OE is low-true */
324#define AR2315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */
325#define AR2315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */
326#define AR2315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */
327#define AR2315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */
328#define AR2315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */
329#define AR2315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */
330#define AR2315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */
331#define AR2315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */
332#define AR2315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */
333#define AR2315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */
334#define AR2315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */
335#define AR2315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */
336#define AR2315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */
337#define AR2315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */
338#define AR2315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */
339#define AR2315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */
340#define AR2315_LBCONF_INT 0x00020000 /* =1 Intr is low true */
341#define AR2315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */
342#define AR2315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */
343#define AR2315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */
344#define AR2315_LBCONF_INT_CTR3 0x000c0000 /* GND drive, Vdd drive */
345#define AR2315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */
346#define AR2315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */
347#define AR2315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */
348
349#define AR2315_LB_CLKSEL 0x0004
350
351#define AR2315_LBCLK_EXT 0x00000001 /* use external clk for lb */
352
353#define AR2315_LB_1MS 0x0008
354
355#define AR2315_LB1MS_MASK 0x0003ffff /* # of AHB clk cycles in 1ms */
356
357#define AR2315_LB_MISCCFG 0x000c
358
359#define AR2315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */
360#define AR2315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */
361#define AR2315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */
362#define AR2315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */
363#define AR2315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */
364#define AR2315_LBM_TIMEOUT_M 0x00ffff80
365#define AR2315_LBM_TIMEOUT_S 7
366#define AR2315_LBM_PORTMUX 0x07000000
367
368#define AR2315_LB_RXTSOFF 0x0010
369
370#define AR2315_LB_TX_CHAIN_EN 0x0100
371
372#define AR2315_LB_TXEN_0 0x00000001
373#define AR2315_LB_TXEN_1 0x00000002
374#define AR2315_LB_TXEN_2 0x00000004
375#define AR2315_LB_TXEN_3 0x00000008
376
377#define AR2315_LB_TX_CHAIN_DIS 0x0104
378#define AR2315_LB_TX_DESC_PTR 0x0200
379
380#define AR2315_LB_RX_CHAIN_EN 0x0400
381
382#define AR2315_LB_RXEN 0x00000001
383
384#define AR2315_LB_RX_CHAIN_DIS 0x0404
385#define AR2315_LB_RX_DESC_PTR 0x0408
386
387#define AR2315_LB_INT_STATUS 0x0500
388
389#define AR2315_LB_INT_TX_DESC 0x00000001
390#define AR2315_LB_INT_TX_OK 0x00000002
391#define AR2315_LB_INT_TX_ERR 0x00000004
392#define AR2315_LB_INT_TX_EOF 0x00000008
393#define AR2315_LB_INT_RX_DESC 0x00000010
394#define AR2315_LB_INT_RX_OK 0x00000020
395#define AR2315_LB_INT_RX_ERR 0x00000040
396#define AR2315_LB_INT_RX_EOF 0x00000080
397#define AR2315_LB_INT_TX_TRUNC 0x00000100
398#define AR2315_LB_INT_TX_STARVE 0x00000200
399#define AR2315_LB_INT_LB_TIMEOUT 0x00000400
400#define AR2315_LB_INT_LB_ERR 0x00000800
401#define AR2315_LB_INT_MBOX_WR 0x00001000
402#define AR2315_LB_INT_MBOX_RD 0x00002000
403
404/* Bit definitions for INT MASK are the same as INT_STATUS */
405#define AR2315_LB_INT_MASK 0x0504
406
407#define AR2315_LB_INT_EN 0x0508
408#define AR2315_LB_MBOX 0x0600
409
410#endif /* __ASM_MACH_ATH25_AR2315_REGS_H */
diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c
new file mode 100644
index 000000000000..b6887f75144c
--- /dev/null
+++ b/arch/mips/ath25/ar5312.c
@@ -0,0 +1,393 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
10 * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
11 */
12
13/*
14 * Platform devices for Atheros AR5312 SoCs
15 */
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/bitops.h>
20#include <linux/irqdomain.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/mtd/physmap.h>
24#include <linux/reboot.h>
25#include <asm/bootinfo.h>
26#include <asm/reboot.h>
27#include <asm/time.h>
28
29#include <ath25_platform.h>
30
31#include "devices.h"
32#include "ar5312.h"
33#include "ar5312_regs.h"
34
35static void __iomem *ar5312_rst_base;
36static struct irq_domain *ar5312_misc_irq_domain;
37
38static inline u32 ar5312_rst_reg_read(u32 reg)
39{
40 return __raw_readl(ar5312_rst_base + reg);
41}
42
43static inline void ar5312_rst_reg_write(u32 reg, u32 val)
44{
45 __raw_writel(val, ar5312_rst_base + reg);
46}
47
48static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val)
49{
50 u32 ret = ar5312_rst_reg_read(reg);
51
52 ret &= ~mask;
53 ret |= val;
54 ar5312_rst_reg_write(reg, ret);
55}
56
57static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id)
58{
59 u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1);
60 u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */
61 u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1);
62 u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */
63
64 pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n",
65 proc_addr, proc1, dma_addr, dma1);
66
67 machine_restart("AHB error"); /* Catastrophic failure */
68 return IRQ_HANDLED;
69}
70
71static struct irqaction ar5312_ahb_err_interrupt = {
72 .handler = ar5312_ahb_err_handler,
73 .name = "ar5312-ahb-error",
74};
75
76static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc)
77{
78 u32 pending = ar5312_rst_reg_read(AR5312_ISR) &
79 ar5312_rst_reg_read(AR5312_IMR);
80 unsigned nr, misc_irq = 0;
81
82 if (pending) {
83 struct irq_domain *domain = irq_get_handler_data(irq);
84
85 nr = __ffs(pending);
86 misc_irq = irq_find_mapping(domain, nr);
87 }
88
89 if (misc_irq) {
90 generic_handle_irq(misc_irq);
91 if (nr == AR5312_MISC_IRQ_TIMER)
92 ar5312_rst_reg_read(AR5312_TIMER);
93 } else {
94 spurious_interrupt();
95 }
96}
97
98/* Enable the specified AR5312_MISC_IRQ interrupt */
99static void ar5312_misc_irq_unmask(struct irq_data *d)
100{
101 ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq));
102}
103
104/* Disable the specified AR5312_MISC_IRQ interrupt */
105static void ar5312_misc_irq_mask(struct irq_data *d)
106{
107 ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0);
108 ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */
109}
110
111static struct irq_chip ar5312_misc_irq_chip = {
112 .name = "ar5312-misc",
113 .irq_unmask = ar5312_misc_irq_unmask,
114 .irq_mask = ar5312_misc_irq_mask,
115};
116
117static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq,
118 irq_hw_number_t hw)
119{
120 irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq);
121 return 0;
122}
123
124static struct irq_domain_ops ar5312_misc_irq_domain_ops = {
125 .map = ar5312_misc_irq_map,
126};
127
128static void ar5312_irq_dispatch(void)
129{
130 u32 pending = read_c0_status() & read_c0_cause();
131
132 if (pending & CAUSEF_IP2)
133 do_IRQ(AR5312_IRQ_WLAN0);
134 else if (pending & CAUSEF_IP5)
135 do_IRQ(AR5312_IRQ_WLAN1);
136 else if (pending & CAUSEF_IP6)
137 do_IRQ(AR5312_IRQ_MISC);
138 else if (pending & CAUSEF_IP7)
139 do_IRQ(ATH25_IRQ_CPU_CLOCK);
140 else
141 spurious_interrupt();
142}
143
144void __init ar5312_arch_init_irq(void)
145{
146 struct irq_domain *domain;
147 unsigned irq;
148
149 ath25_irq_dispatch = ar5312_irq_dispatch;
150
151 domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT,
152 &ar5312_misc_irq_domain_ops, NULL);
153 if (!domain)
154 panic("Failed to add IRQ domain");
155
156 irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC);
157 setup_irq(irq, &ar5312_ahb_err_interrupt);
158
159 irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler);
160 irq_set_handler_data(AR5312_IRQ_MISC, domain);
161
162 ar5312_misc_irq_domain = domain;
163}
164
165static struct physmap_flash_data ar5312_flash_data = {
166 .width = 2,
167};
168
169static struct resource ar5312_flash_resource = {
170 .start = AR5312_FLASH_BASE,
171 .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1,
172 .flags = IORESOURCE_MEM,
173};
174
175static struct platform_device ar5312_physmap_flash = {
176 .name = "physmap-flash",
177 .id = 0,
178 .dev.platform_data = &ar5312_flash_data,
179 .resource = &ar5312_flash_resource,
180 .num_resources = 1,
181};
182
183static void __init ar5312_flash_init(void)
184{
185 void __iomem *flashctl_base;
186 u32 ctl;
187
188 flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE,
189 AR5312_FLASHCTL_SIZE);
190
191 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0);
192 ctl &= AR5312_FLASHCTL_MW;
193
194 /* fixup flash width */
195 switch (ctl) {
196 case AR5312_FLASHCTL_MW16:
197 ar5312_flash_data.width = 2;
198 break;
199 case AR5312_FLASHCTL_MW8:
200 default:
201 ar5312_flash_data.width = 1;
202 break;
203 }
204
205 /*
206 * Configure flash bank 0.
207 * Assume 8M window size. Flash will be aliased if it's smaller
208 */
209 ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE;
210 ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S;
211 ctl |= 0x07 << AR5312_FLASHCTL_WST1_S;
212 ctl |= 0x07 << AR5312_FLASHCTL_WST2_S;
213 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0);
214
215 /* Disable other flash banks */
216 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1);
217 ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
218 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1);
219 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2);
220 ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
221 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2);
222
223 iounmap(flashctl_base);
224}
225
226void __init ar5312_init_devices(void)
227{
228 struct ath25_boarddata *config;
229
230 ar5312_flash_init();
231
232 /* Locate board/radio config data */
233 ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE);
234 config = ath25_board.config;
235
236 /* AR2313 has CPU minor rev. 10 */
237 if ((current_cpu_data.processor_id & 0xff) == 0x0a)
238 ath25_soc = ATH25_SOC_AR2313;
239
240 /* AR2312 shares the same Silicon ID as AR5312 */
241 else if (config->flags & BD_ISCASPER)
242 ath25_soc = ATH25_SOC_AR2312;
243
244 /* Everything else is probably AR5312 or compatible */
245 else
246 ath25_soc = ATH25_SOC_AR5312;
247
248 platform_device_register(&ar5312_physmap_flash);
249
250 switch (ath25_soc) {
251 case ATH25_SOC_AR5312:
252 if (!ath25_board.radio)
253 return;
254
255 if (!(config->flags & BD_WLAN0))
256 break;
257
258 ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0);
259 break;
260 case ATH25_SOC_AR2312:
261 case ATH25_SOC_AR2313:
262 if (!ath25_board.radio)
263 return;
264 break;
265 default:
266 break;
267 }
268
269 if (config->flags & BD_WLAN1)
270 ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1);
271}
272
273static void ar5312_restart(char *command)
274{
275 /* reset the system */
276 local_irq_disable();
277 while (1)
278 ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM);
279}
280
281/*
282 * This table is indexed by bits 5..4 of the CLOCKCTL1 register
283 * to determine the predevisor value.
284 */
285static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
286
287static unsigned __init ar5312_cpu_frequency(void)
288{
289 u32 scratch, devid, clock_ctl1;
290 u32 predivide_mask, multiplier_mask, doubler_mask;
291 unsigned predivide_shift, multiplier_shift;
292 unsigned predivide_select, predivisor, multiplier;
293
294 /* Trust the bootrom's idea of cpu frequency. */
295 scratch = ar5312_rst_reg_read(AR5312_SCRATCH);
296 if (scratch)
297 return scratch;
298
299 devid = ar5312_rst_reg_read(AR5312_REV);
300 devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S;
301 if (devid == AR5312_REV_MAJ_AR2313) {
302 predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
303 predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
304 multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
305 multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
306 doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
307 } else { /* AR5312 and AR2312 */
308 predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;
309 predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;
310 multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;
311 multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;
312 doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;
313 }
314
315 /*
316 * Clocking is derived from a fixed 40MHz input clock.
317 *
318 * cpu_freq = input_clock * MULT (where MULT is PLL multiplier)
319 * sys_freq = cpu_freq / 4 (used for APB clock, serial,
320 * flash, Timer, Watchdog Timer)
321 *
322 * cnt_freq = cpu_freq / 2 (use for CPU count/compare)
323 *
324 * So, for example, with a PLL multiplier of 5, we have
325 *
326 * cpu_freq = 200MHz
327 * sys_freq = 50MHz
328 * cnt_freq = 100MHz
329 *
330 * We compute the CPU frequency, based on PLL settings.
331 */
332
333 clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1);
334 predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift;
335 predivisor = clockctl1_predivide_table[predivide_select];
336 multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift;
337
338 if (clock_ctl1 & doubler_mask)
339 multiplier <<= 1;
340
341 return (40000000 / predivisor) * multiplier;
342}
343
344static inline unsigned ar5312_sys_frequency(void)
345{
346 return ar5312_cpu_frequency() / 4;
347}
348
349void __init ar5312_plat_time_init(void)
350{
351 mips_hpt_frequency = ar5312_cpu_frequency() / 2;
352}
353
354void __init ar5312_plat_mem_setup(void)
355{
356 void __iomem *sdram_base;
357 u32 memsize, memcfg, bank0_ac, bank1_ac;
358 u32 devid;
359
360 /* Detect memory size */
361 sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE,
362 AR5312_SDRAMCTL_SIZE);
363 memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1);
364 bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0);
365 bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1);
366 memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) +
367 (bank1_ac ? (1 << (bank1_ac + 1)) : 0);
368 memsize <<= 20;
369 add_memory_region(0, memsize, BOOT_MEM_RAM);
370 iounmap(sdram_base);
371
372 ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE);
373
374 devid = ar5312_rst_reg_read(AR5312_REV);
375 devid >>= AR5312_REV_WMAC_MIN_S;
376 devid &= AR5312_REV_CHIP;
377 ath25_board.devid = (u16)devid;
378
379 /* Clear any lingering AHB errors */
380 ar5312_rst_reg_read(AR5312_PROCADDR);
381 ar5312_rst_reg_read(AR5312_DMAADDR);
382 ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE);
383
384 _machine_restart = ar5312_restart;
385}
386
387void __init ar5312_arch_init(void)
388{
389 unsigned irq = irq_create_mapping(ar5312_misc_irq_domain,
390 AR5312_MISC_IRQ_UART0);
391
392 ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency());
393}
diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h
new file mode 100644
index 000000000000..470abb0052bd
--- /dev/null
+++ b/arch/mips/ath25/ar5312.h
@@ -0,0 +1,22 @@
1#ifndef __AR5312_H
2#define __AR5312_H
3
4#ifdef CONFIG_SOC_AR5312
5
6void ar5312_arch_init_irq(void);
7void ar5312_init_devices(void);
8void ar5312_plat_time_init(void);
9void ar5312_plat_mem_setup(void);
10void ar5312_arch_init(void);
11
12#else
13
14static inline void ar5312_arch_init_irq(void) {}
15static inline void ar5312_init_devices(void) {}
16static inline void ar5312_plat_time_init(void) {}
17static inline void ar5312_plat_mem_setup(void) {}
18static inline void ar5312_arch_init(void) {}
19
20#endif
21
22#endif /* __AR5312_H */
diff --git a/arch/mips/ath25/ar5312_regs.h b/arch/mips/ath25/ar5312_regs.h
new file mode 100644
index 000000000000..4b947f967439
--- /dev/null
+++ b/arch/mips/ath25/ar5312_regs.h
@@ -0,0 +1,224 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
8 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
9 */
10
11#ifndef __ASM_MACH_ATH25_AR5312_REGS_H
12#define __ASM_MACH_ATH25_AR5312_REGS_H
13
14/*
15 * IRQs
16 */
17#define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
18#define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
19#define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
20#define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
21#define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
22
23/*
24 * Miscellaneous interrupts, which share IP6.
25 */
26#define AR5312_MISC_IRQ_TIMER 0
27#define AR5312_MISC_IRQ_AHB_PROC 1
28#define AR5312_MISC_IRQ_AHB_DMA 2
29#define AR5312_MISC_IRQ_GPIO 3
30#define AR5312_MISC_IRQ_UART0 4
31#define AR5312_MISC_IRQ_UART0_DMA 5
32#define AR5312_MISC_IRQ_WATCHDOG 6
33#define AR5312_MISC_IRQ_LOCAL 7
34#define AR5312_MISC_IRQ_SPI 8
35#define AR5312_MISC_IRQ_COUNT 9
36
37/*
38 * Address Map
39 *
40 * The AR5312 supports 2 enet MACS, even though many reference boards only
41 * actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet
42 * PHY or PHY switch. The AR2312 supports 1 enet MAC.
43 */
44#define AR5312_WLAN0_BASE 0x18000000
45#define AR5312_ENET0_BASE 0x18100000
46#define AR5312_ENET1_BASE 0x18200000
47#define AR5312_SDRAMCTL_BASE 0x18300000
48#define AR5312_SDRAMCTL_SIZE 0x00000010
49#define AR5312_FLASHCTL_BASE 0x18400000
50#define AR5312_FLASHCTL_SIZE 0x00000010
51#define AR5312_WLAN1_BASE 0x18500000
52#define AR5312_UART0_BASE 0x1c000000 /* UART MMR */
53#define AR5312_GPIO_BASE 0x1c002000
54#define AR5312_GPIO_SIZE 0x00000010
55#define AR5312_RST_BASE 0x1c003000
56#define AR5312_RST_SIZE 0x00000100
57#define AR5312_FLASH_BASE 0x1e000000
58#define AR5312_FLASH_SIZE 0x00800000
59
60/*
61 * Need these defines to determine true number of ethernet MACs
62 */
63#define AR5312_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */
64#define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */
65#define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */
66
67/* Reset/Timer Block Address Map */
68#define AR5312_TIMER 0x0000 /* countdown timer */
69#define AR5312_RELOAD 0x0004 /* timer reload value */
70#define AR5312_WDT_CTRL 0x0008 /* watchdog cntrl */
71#define AR5312_WDT_TIMER 0x000c /* watchdog timer */
72#define AR5312_ISR 0x0010 /* Intr Status Reg */
73#define AR5312_IMR 0x0014 /* Intr Mask Reg */
74#define AR5312_RESET 0x0020
75#define AR5312_CLOCKCTL1 0x0064
76#define AR5312_SCRATCH 0x006c
77#define AR5312_PROCADDR 0x0070
78#define AR5312_PROC1 0x0074
79#define AR5312_DMAADDR 0x0078
80#define AR5312_DMA1 0x007c
81#define AR5312_ENABLE 0x0080 /* interface enb */
82#define AR5312_REV 0x0090 /* revision */
83
84/* AR5312_WDT_CTRL register bit field definitions */
85#define AR5312_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */
86#define AR5312_WDT_CTRL_NMI 0x00000001
87#define AR5312_WDT_CTRL_RESET 0x00000002
88
89/* AR5312_ISR register bit field definitions */
90#define AR5312_ISR_TIMER 0x00000001
91#define AR5312_ISR_AHBPROC 0x00000002
92#define AR5312_ISR_AHBDMA 0x00000004
93#define AR5312_ISR_GPIO 0x00000008
94#define AR5312_ISR_UART0 0x00000010
95#define AR5312_ISR_UART0DMA 0x00000020
96#define AR5312_ISR_WD 0x00000040
97#define AR5312_ISR_LOCAL 0x00000080
98
99/* AR5312_RESET register bit field definitions */
100#define AR5312_RESET_SYSTEM 0x00000001 /* cold reset full system */
101#define AR5312_RESET_PROC 0x00000002 /* cold reset MIPS core */
102#define AR5312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC/BB */
103#define AR5312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */
104#define AR5312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */
105#define AR5312_RESET_ENET0 0x00000020 /* cold reset ENET0 MAC */
106#define AR5312_RESET_ENET1 0x00000040 /* cold reset ENET1 MAC */
107#define AR5312_RESET_UART0 0x00000100 /* cold reset UART0 */
108#define AR5312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */
109#define AR5312_RESET_APB 0x00000400 /* cold reset APB ar5312 */
110#define AR5312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */
111#define AR5312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */
112#define AR5312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BB */
113#define AR5312_RESET_NMI 0x00010000 /* send an NMI to the CPU */
114#define AR5312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 MAC */
115#define AR5312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 BB */
116#define AR5312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */
117#define AR5312_RESET_WDOG 0x00100000 /* last reset was a wdt */
118
119#define AR5312_RESET_WMAC0_BITS (AR5312_RESET_WLAN0 |\
120 AR5312_RESET_WARM_WLAN0_MAC |\
121 AR5312_RESET_WARM_WLAN0_BB)
122
123#define AR5312_RESET_WMAC1_BITS (AR5312_RESET_WLAN1 |\
124 AR5312_RESET_WARM_WLAN1_MAC |\
125 AR5312_RESET_WARM_WLAN1_BB)
126
127/* AR5312_CLOCKCTL1 register bit field definitions */
128#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
129#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4
130#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
131#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8
132#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000
133
134/* Valid for AR5312 and AR2312 */
135#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
136#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4
137#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
138#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8
139#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000
140
141/* Valid for AR2313 */
142#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000
143#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12
144#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000
145#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16
146#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000
147
148/* AR5312_ENABLE register bit field definitions */
149#define AR5312_ENABLE_WLAN0 0x00000001
150#define AR5312_ENABLE_ENET0 0x00000002
151#define AR5312_ENABLE_ENET1 0x00000004
152#define AR5312_ENABLE_UART_AND_WLAN1_PIO 0x00000008/* UART & WLAN1 PIO */
153#define AR5312_ENABLE_WLAN1_DMA 0x00000010/* WLAN1 DMAs */
154#define AR5312_ENABLE_WLAN1 (AR5312_ENABLE_UART_AND_WLAN1_PIO |\
155 AR5312_ENABLE_WLAN1_DMA)
156
157/* AR5312_REV register bit field definitions */
158#define AR5312_REV_WMAC_MAJ 0x0000f000
159#define AR5312_REV_WMAC_MAJ_S 12
160#define AR5312_REV_WMAC_MIN 0x00000f00
161#define AR5312_REV_WMAC_MIN_S 8
162#define AR5312_REV_MAJ 0x000000f0
163#define AR5312_REV_MAJ_S 4
164#define AR5312_REV_MIN 0x0000000f
165#define AR5312_REV_MIN_S 0
166#define AR5312_REV_CHIP (AR5312_REV_MAJ|AR5312_REV_MIN)
167
168/* Major revision numbers, bits 7..4 of Revision ID register */
169#define AR5312_REV_MAJ_AR5312 0x4
170#define AR5312_REV_MAJ_AR2313 0x5
171
172/* Minor revision numbers, bits 3..0 of Revision ID register */
173#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */
174#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */
175
176/*
177 * ARM Flash Controller -- 3 flash banks with either x8 or x16 devices
178 */
179#define AR5312_FLASHCTL0 0x0000
180#define AR5312_FLASHCTL1 0x0004
181#define AR5312_FLASHCTL2 0x0008
182
183/* AR5312_FLASHCTL register bit field definitions */
184#define AR5312_FLASHCTL_IDCY 0x0000000f /* Idle cycle turnaround time */
185#define AR5312_FLASHCTL_IDCY_S 0
186#define AR5312_FLASHCTL_WST1 0x000003e0 /* Wait state 1 */
187#define AR5312_FLASHCTL_WST1_S 5
188#define AR5312_FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */
189#define AR5312_FLASHCTL_WST2 0x0000f800 /* Wait state 2 */
190#define AR5312_FLASHCTL_WST2_S 11
191#define AR5312_FLASHCTL_AC 0x00070000 /* Flash addr check (added) */
192#define AR5312_FLASHCTL_AC_S 16
193#define AR5312_FLASHCTL_AC_128K 0x00000000
194#define AR5312_FLASHCTL_AC_256K 0x00010000
195#define AR5312_FLASHCTL_AC_512K 0x00020000
196#define AR5312_FLASHCTL_AC_1M 0x00030000
197#define AR5312_FLASHCTL_AC_2M 0x00040000
198#define AR5312_FLASHCTL_AC_4M 0x00050000
199#define AR5312_FLASHCTL_AC_8M 0x00060000
200#define AR5312_FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */
201#define AR5312_FLASHCTL_E 0x00080000 /* Flash bank enable (added) */
202#define AR5312_FLASHCTL_BUSERR 0x01000000 /* Bus transfer error flag */
203#define AR5312_FLASHCTL_WPERR 0x02000000 /* Write protect error flag */
204#define AR5312_FLASHCTL_WP 0x04000000 /* Write protect */
205#define AR5312_FLASHCTL_BM 0x08000000 /* Burst mode */
206#define AR5312_FLASHCTL_MW 0x30000000 /* Mem width */
207#define AR5312_FLASHCTL_MW8 0x00000000 /* Mem width x8 */
208#define AR5312_FLASHCTL_MW16 0x10000000 /* Mem width x16 */
209#define AR5312_FLASHCTL_MW32 0x20000000 /* Mem width x32 (not supp) */
210#define AR5312_FLASHCTL_ATNR 0x00000000 /* Access == no retry */
211#define AR5312_FLASHCTL_ATR 0x80000000 /* Access == retry every */
212#define AR5312_FLASHCTL_ATR4 0xc0000000 /* Access == retry every 4 */
213
214/*
215 * ARM SDRAM Controller -- just enough to determine memory size
216 */
217#define AR5312_MEM_CFG1 0x0004
218
219#define AR5312_MEM_CFG1_AC0_M 0x00000700 /* bank 0: SDRAM addr check */
220#define AR5312_MEM_CFG1_AC0_S 8
221#define AR5312_MEM_CFG1_AC1_M 0x00007000 /* bank 1: SDRAM addr check */
222#define AR5312_MEM_CFG1_AC1_S 12
223
224#endif /* __ASM_MACH_ATH25_AR5312_REGS_H */
diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c
new file mode 100644
index 000000000000..b8bb78282d6a
--- /dev/null
+++ b/arch/mips/ath25/board.c
@@ -0,0 +1,234 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
10 */
11
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <asm/irq_cpu.h>
15#include <asm/reboot.h>
16#include <asm/bootinfo.h>
17#include <asm/time.h>
18
19#include <ath25_platform.h>
20#include "devices.h"
21#include "ar5312.h"
22#include "ar2315.h"
23
24void (*ath25_irq_dispatch)(void);
25
26static inline bool check_radio_magic(const void __iomem *addr)
27{
28 addr += 0x7a; /* offset for flash magic */
29 return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5);
30}
31
32static inline bool check_notempty(const void __iomem *addr)
33{
34 return __raw_readl(addr) != 0xffffffff;
35}
36
37static inline bool check_board_data(const void __iomem *addr, bool broken)
38{
39 /* config magic found */
40 if (__raw_readl(addr) == ATH25_BD_MAGIC)
41 return true;
42
43 if (!broken)
44 return false;
45
46 /* broken board data detected, use radio data to find the
47 * offset, user will fix this */
48
49 if (check_radio_magic(addr + 0x1000))
50 return true;
51 if (check_radio_magic(addr + 0xf8))
52 return true;
53
54 return false;
55}
56
57static const void __iomem * __init find_board_config(const void __iomem *limit,
58 const bool broken)
59{
60 const void __iomem *addr;
61 const void __iomem *begin = limit - 0x1000;
62 const void __iomem *end = limit - 0x30000;
63
64 for (addr = begin; addr >= end; addr -= 0x1000)
65 if (check_board_data(addr, broken))
66 return addr;
67
68 return NULL;
69}
70
71static const void __iomem * __init find_radio_config(const void __iomem *limit,
72 const void __iomem *bcfg)
73{
74 const void __iomem *rcfg, *begin, *end;
75
76 /*
77 * Now find the start of Radio Configuration data, using heuristics:
78 * Search forward from Board Configuration data by 0x1000 bytes
79 * at a time until we find non-0xffffffff.
80 */
81 begin = bcfg + 0x1000;
82 end = limit;
83 for (rcfg = begin; rcfg < end; rcfg += 0x1000)
84 if (check_notempty(rcfg) && check_radio_magic(rcfg))
85 return rcfg;
86
87 /* AR2316 relocates radio config to new location */
88 begin = bcfg + 0xf8;
89 end = limit - 0x1000 + 0xf8;
90 for (rcfg = begin; rcfg < end; rcfg += 0x1000)
91 if (check_notempty(rcfg) && check_radio_magic(rcfg))
92 return rcfg;
93
94 return NULL;
95}
96
97/*
98 * NB: Search region size could be larger than the actual flash size,
99 * but this shouldn't be a problem here, because the flash
100 * will simply be mapped multiple times.
101 */
102int __init ath25_find_config(phys_addr_t base, unsigned long size)
103{
104 const void __iomem *flash_base, *flash_limit;
105 struct ath25_boarddata *config;
106 unsigned int rcfg_size;
107 int broken_boarddata = 0;
108 const void __iomem *bcfg, *rcfg;
109 u8 *board_data;
110 u8 *radio_data;
111 u8 *mac_addr;
112 u32 offset;
113
114 flash_base = ioremap_nocache(base, size);
115 flash_limit = flash_base + size;
116
117 ath25_board.config = NULL;
118 ath25_board.radio = NULL;
119
120 /* Copy the board and radio data to RAM, because accessing the mapped
121 * memory of the flash directly after booting is not safe */
122
123 /* Try to find valid board and radio data */
124 bcfg = find_board_config(flash_limit, false);
125
126 /* If that fails, try to at least find valid radio data */
127 if (!bcfg) {
128 bcfg = find_board_config(flash_limit, true);
129 broken_boarddata = 1;
130 }
131
132 if (!bcfg) {
133 pr_warn("WARNING: No board configuration data found!\n");
134 goto error;
135 }
136
137 board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);
138 ath25_board.config = (struct ath25_boarddata *)board_data;
139 memcpy_fromio(board_data, bcfg, 0x100);
140 if (broken_boarddata) {
141 pr_warn("WARNING: broken board data detected\n");
142 config = ath25_board.config;
143 if (is_zero_ether_addr(config->enet0_mac)) {
144 pr_info("Fixing up empty mac addresses\n");
145 config->reset_config_gpio = 0xffff;
146 config->sys_led_gpio = 0xffff;
147 random_ether_addr(config->wlan0_mac);
148 config->wlan0_mac[0] &= ~0x06;
149 random_ether_addr(config->enet0_mac);
150 random_ether_addr(config->enet1_mac);
151 }
152 }
153
154 /* Radio config starts 0x100 bytes after board config, regardless
155 * of what the physical layout on the flash chip looks like */
156
157 rcfg = find_radio_config(flash_limit, bcfg);
158 if (!rcfg) {
159 pr_warn("WARNING: Could not find Radio Configuration data\n");
160 goto error;
161 }
162
163 radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);
164 ath25_board.radio = radio_data;
165 offset = radio_data - board_data;
166 pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg,
167 offset);
168 rcfg_size = BOARD_CONFIG_BUFSZ - offset;
169 memcpy_fromio(radio_data, rcfg, rcfg_size);
170
171 mac_addr = &radio_data[0x1d * 2];
172 if (is_broadcast_ether_addr(mac_addr)) {
173 pr_info("Radio MAC is blank; using board-data\n");
174 ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac);
175 }
176
177 iounmap(flash_base);
178
179 return 0;
180
181error:
182 iounmap(flash_base);
183 return -ENODEV;
184}
185
186static void ath25_halt(void)
187{
188 local_irq_disable();
189 unreachable();
190}
191
192void __init plat_mem_setup(void)
193{
194 _machine_halt = ath25_halt;
195 pm_power_off = ath25_halt;
196
197 if (is_ar5312())
198 ar5312_plat_mem_setup();
199 else
200 ar2315_plat_mem_setup();
201
202 /* Disable data watchpoints */
203 write_c0_watchlo0(0);
204}
205
206asmlinkage void plat_irq_dispatch(void)
207{
208 ath25_irq_dispatch();
209}
210
211void __init plat_time_init(void)
212{
213 if (is_ar5312())
214 ar5312_plat_time_init();
215 else
216 ar2315_plat_time_init();
217}
218
219unsigned int __cpuinit get_c0_compare_int(void)
220{
221 return CP0_LEGACY_COMPARE_IRQ;
222}
223
224void __init arch_init_irq(void)
225{
226 clear_c0_status(ST0_IM);
227 mips_cpu_irq_init();
228
229 /* Initialize interrupt controllers */
230 if (is_ar5312())
231 ar5312_arch_init_irq();
232 else
233 ar2315_arch_init_irq();
234}
diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c
new file mode 100644
index 000000000000..7a64567d1ac3
--- /dev/null
+++ b/arch/mips/ath25/devices.c
@@ -0,0 +1,125 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/serial_8250.h>
4#include <linux/platform_device.h>
5#include <asm/bootinfo.h>
6
7#include <ath25_platform.h>
8#include "devices.h"
9#include "ar5312.h"
10#include "ar2315.h"
11
12struct ar231x_board_config ath25_board;
13enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN;
14
15static struct resource ath25_wmac0_res[] = {
16 {
17 .name = "wmac0_membase",
18 .flags = IORESOURCE_MEM,
19 },
20 {
21 .name = "wmac0_irq",
22 .flags = IORESOURCE_IRQ,
23 }
24};
25
26static struct resource ath25_wmac1_res[] = {
27 {
28 .name = "wmac1_membase",
29 .flags = IORESOURCE_MEM,
30 },
31 {
32 .name = "wmac1_irq",
33 .flags = IORESOURCE_IRQ,
34 }
35};
36
37static struct platform_device ath25_wmac[] = {
38 {
39 .id = 0,
40 .name = "ar231x-wmac",
41 .resource = ath25_wmac0_res,
42 .num_resources = ARRAY_SIZE(ath25_wmac0_res),
43 .dev.platform_data = &ath25_board,
44 },
45 {
46 .id = 1,
47 .name = "ar231x-wmac",
48 .resource = ath25_wmac1_res,
49 .num_resources = ARRAY_SIZE(ath25_wmac1_res),
50 .dev.platform_data = &ath25_board,
51 },
52};
53
54static const char * const soc_type_strings[] = {
55 [ATH25_SOC_AR5312] = "Atheros AR5312",
56 [ATH25_SOC_AR2312] = "Atheros AR2312",
57 [ATH25_SOC_AR2313] = "Atheros AR2313",
58 [ATH25_SOC_AR2315] = "Atheros AR2315",
59 [ATH25_SOC_AR2316] = "Atheros AR2316",
60 [ATH25_SOC_AR2317] = "Atheros AR2317",
61 [ATH25_SOC_AR2318] = "Atheros AR2318",
62 [ATH25_SOC_UNKNOWN] = "Atheros (unknown)",
63};
64
65const char *get_system_type(void)
66{
67 if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) ||
68 !soc_type_strings[ath25_soc])
69 return soc_type_strings[ATH25_SOC_UNKNOWN];
70 return soc_type_strings[ath25_soc];
71}
72
73void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk)
74{
75 struct uart_port s;
76
77 memset(&s, 0, sizeof(s));
78
79 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP;
80 s.iotype = UPIO_MEM32;
81 s.irq = irq;
82 s.regshift = 2;
83 s.mapbase = mapbase;
84 s.uartclk = uartclk;
85
86 early_serial_setup(&s);
87}
88
89int __init ath25_add_wmac(int nr, u32 base, int irq)
90{
91 struct resource *res;
92
93 ath25_wmac[nr].dev.platform_data = &ath25_board;
94 res = &ath25_wmac[nr].resource[0];
95 res->start = base;
96 res->end = base + 0x10000 - 1;
97 res++;
98 res->start = irq;
99 res->end = irq;
100 return platform_device_register(&ath25_wmac[nr]);
101}
102
103static int __init ath25_register_devices(void)
104{
105 if (is_ar5312())
106 ar5312_init_devices();
107 else
108 ar2315_init_devices();
109
110 return 0;
111}
112
113device_initcall(ath25_register_devices);
114
115static int __init ath25_arch_init(void)
116{
117 if (is_ar5312())
118 ar5312_arch_init();
119 else
120 ar2315_arch_init();
121
122 return 0;
123}
124
125arch_initcall(ath25_arch_init);
diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h
new file mode 100644
index 000000000000..04d414115356
--- /dev/null
+++ b/arch/mips/ath25/devices.h
@@ -0,0 +1,43 @@
1#ifndef __ATH25_DEVICES_H
2#define __ATH25_DEVICES_H
3
4#include <linux/cpu.h>
5
6#define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S)
7
8#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */
9
10enum ath25_soc_type {
11 /* handled by ar5312.c */
12 ATH25_SOC_AR2312,
13 ATH25_SOC_AR2313,
14 ATH25_SOC_AR5312,
15
16 /* handled by ar2315.c */
17 ATH25_SOC_AR2315,
18 ATH25_SOC_AR2316,
19 ATH25_SOC_AR2317,
20 ATH25_SOC_AR2318,
21
22 ATH25_SOC_UNKNOWN
23};
24
25extern enum ath25_soc_type ath25_soc;
26extern struct ar231x_board_config ath25_board;
27extern void (*ath25_irq_dispatch)(void);
28
29int ath25_find_config(phys_addr_t offset, unsigned long size);
30void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk);
31int ath25_add_wmac(int nr, u32 base, int irq);
32
33static inline bool is_ar2315(void)
34{
35 return (current_cpu_data.cputype == CPU_4KEC);
36}
37
38static inline bool is_ar5312(void)
39{
40 return !is_ar2315();
41}
42
43#endif
diff --git a/arch/mips/ath25/early_printk.c b/arch/mips/ath25/early_printk.c
new file mode 100644
index 000000000000..36035b628161
--- /dev/null
+++ b/arch/mips/ath25/early_printk.c
@@ -0,0 +1,44 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
7 */
8
9#include <linux/mm.h>
10#include <linux/io.h>
11#include <linux/serial_reg.h>
12
13#include "devices.h"
14#include "ar2315_regs.h"
15#include "ar5312_regs.h"
16
17static inline void prom_uart_wr(void __iomem *base, unsigned reg,
18 unsigned char ch)
19{
20 __raw_writel(ch, base + 4 * reg);
21}
22
23static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg)
24{
25 return __raw_readl(base + 4 * reg);
26}
27
28void prom_putchar(unsigned char ch)
29{
30 static void __iomem *base;
31
32 if (unlikely(base == NULL)) {
33 if (is_ar2315())
34 base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE));
35 else
36 base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE));
37 }
38
39 while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0)
40 ;
41 prom_uart_wr(base, UART_TX, ch);
42 while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0)
43 ;
44}
diff --git a/arch/mips/ath25/prom.c b/arch/mips/ath25/prom.c
new file mode 100644
index 000000000000..edf82be8870d
--- /dev/null
+++ b/arch/mips/ath25/prom.c
@@ -0,0 +1,26 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright MontaVista Software Inc
7 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
8 * Copyright (C) 2006 FON Technology, SL.
9 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
10 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
11 */
12
13/*
14 * Prom setup file for AR5312/AR231x SoCs
15 */
16
17#include <linux/init.h>
18#include <asm/bootinfo.h>
19
20void __init prom_init(void)
21{
22}
23
24void __init prom_free_prom_memory(void)
25{
26}
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 9c0e1761773f..6adae366f11a 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -359,7 +359,6 @@ void __init arch_init_irq(void)
359 BUG(); 359 BUG();
360 } 360 }
361 361
362 cp0_perfcount_irq = ATH79_MISC_IRQ(5);
363 mips_cpu_irq_init(); 362 mips_cpu_irq_init();
364 ath79_misc_irq_init(); 363 ath79_misc_irq_init();
365 364
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
index e9cbd7c2918f..e1fe63051136 100644
--- a/arch/mips/ath79/prom.c
+++ b/arch/mips/ath79/prom.c
@@ -13,42 +13,24 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/initrd.h>
16 17
17#include <asm/bootinfo.h> 18#include <asm/bootinfo.h>
18#include <asm/addrspace.h> 19#include <asm/addrspace.h>
20#include <asm/fw/fw.h>
19 21
20#include "common.h" 22#include "common.h"
21 23
22static inline int is_valid_ram_addr(void *addr)
23{
24 if (((u32) addr > KSEG0) &&
25 ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
26 return 1;
27
28 if (((u32) addr > KSEG1) &&
29 ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
30 return 1;
31
32 return 0;
33}
34
35static __init void ath79_prom_init_cmdline(int argc, char **argv)
36{
37 int i;
38
39 if (!is_valid_ram_addr(argv))
40 return;
41
42 for (i = 0; i < argc; i++)
43 if (is_valid_ram_addr(argv[i])) {
44 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
45 strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
46 }
47}
48
49void __init prom_init(void) 24void __init prom_init(void)
50{ 25{
51 ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); 26 fw_init_cmdline();
27
28 /* Read the initrd address from the firmware environment */
29 initrd_start = fw_getenvl("initrd_start");
30 if (initrd_start) {
31 initrd_start = KSEG0ADDR(initrd_start);
32 initrd_end = initrd_start + fw_getenvl("initrd_size");
33 }
52} 34}
53 35
54void __init prom_free_prom_memory(void) 36void __init prom_free_prom_memory(void)
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 64807a4809d0..a73c93c3d44a 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -182,6 +182,11 @@ const char *get_system_type(void)
182 return ath79_sys_type; 182 return ath79_sys_type;
183} 183}
184 184
185int get_c0_perfcount_int(void)
186{
187 return ATH79_MISC_IRQ(5);
188}
189
185unsigned int get_c0_compare_int(void) 190unsigned int get_c0_compare_int(void)
186{ 191{
187 return CP0_LEGACY_COMPARE_IRQ; 192 return CP0_LEGACY_COMPARE_IRQ;
diff --git a/arch/mips/bcm3384/Makefile b/arch/mips/bcm3384/Makefile
new file mode 100644
index 000000000000..a393955cba08
--- /dev/null
+++ b/arch/mips/bcm3384/Makefile
@@ -0,0 +1 @@
obj-y += setup.o irq.o dma.o
diff --git a/arch/mips/bcm3384/Platform b/arch/mips/bcm3384/Platform
new file mode 100644
index 000000000000..8e1ca0819e1b
--- /dev/null
+++ b/arch/mips/bcm3384/Platform
@@ -0,0 +1,7 @@
1#
2# Broadcom BCM3384 boards
3#
4platform-$(CONFIG_BCM3384) += bcm3384/
5cflags-$(CONFIG_BCM3384) += \
6 -I$(srctree)/arch/mips/include/asm/mach-bcm3384/
7load-$(CONFIG_BCM3384) := 0xffffffff80010000
diff --git a/arch/mips/bcm3384/dma.c b/arch/mips/bcm3384/dma.c
new file mode 100644
index 000000000000..ea42012fd4f5
--- /dev/null
+++ b/arch/mips/bcm3384/dma.c
@@ -0,0 +1,81 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
7 */
8
9#include <linux/device.h>
10#include <linux/dma-direction.h>
11#include <linux/dma-mapping.h>
12#include <linux/init.h>
13#include <linux/mm.h>
14#include <linux/of.h>
15#include <linux/pci.h>
16#include <linux/types.h>
17#include <dma-coherence.h>
18
19/*
20 * BCM3384 has configurable address translation windows which allow the
21 * peripherals' DMA addresses to be different from the Zephyr-visible
22 * physical addresses. e.g. usb_dma_addr = zephyr_pa ^ 0x08000000
23 *
24 * If our DT "memory" node has a "dma-xor-mask" property we will enable this
25 * translation using the provided offset.
26 */
27static u32 bcm3384_dma_xor_mask;
28static u32 bcm3384_dma_xor_limit = 0xffffffff;
29
30/*
31 * PCI collapses the memory hole at 0x10000000 - 0x1fffffff.
32 * On systems with a dma-xor-mask, this range is guaranteed to live above
33 * the dma-xor-limit.
34 */
35#define BCM3384_MEM_HOLE_PA 0x10000000
36#define BCM3384_MEM_HOLE_SIZE 0x10000000
37
38static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa)
39{
40 if (dev && dev_is_pci(dev) &&
41 pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE))
42 return pa - BCM3384_MEM_HOLE_SIZE;
43 if (pa <= bcm3384_dma_xor_limit)
44 return pa ^ bcm3384_dma_xor_mask;
45 return pa;
46}
47
48dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
49{
50 return bcm3384_phys_to_dma(dev, virt_to_phys(addr));
51}
52
53dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
54{
55 return bcm3384_phys_to_dma(dev, page_to_phys(page));
56}
57
58unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
59{
60 if (dev && dev_is_pci(dev) &&
61 dma_addr >= BCM3384_MEM_HOLE_PA)
62 return dma_addr + BCM3384_MEM_HOLE_SIZE;
63 if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit)
64 return dma_addr ^ bcm3384_dma_xor_mask;
65 return dma_addr;
66}
67
68static int __init bcm3384_init_dma_xor(void)
69{
70 struct device_node *np = of_find_node_by_type(NULL, "memory");
71
72 if (!np)
73 return 0;
74
75 of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask);
76 of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit);
77
78 of_node_put(np);
79 return 0;
80}
81arch_initcall(bcm3384_init_dma_xor);
diff --git a/arch/mips/bcm3384/irq.c b/arch/mips/bcm3384/irq.c
new file mode 100644
index 000000000000..0fb5134fb832
--- /dev/null
+++ b/arch/mips/bcm3384/irq.c
@@ -0,0 +1,193 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Partially based on arch/mips/ralink/irq.c
7 *
8 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
9 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
10 * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
11 */
12
13#include <linux/io.h>
14#include <linux/bitops.h>
15#include <linux/of_platform.h>
16#include <linux/of_address.h>
17#include <linux/of_irq.h>
18#include <linux/irqdomain.h>
19#include <linux/interrupt.h>
20#include <linux/slab.h>
21#include <linux/spinlock.h>
22
23#include <asm/bmips.h>
24#include <asm/irq_cpu.h>
25#include <asm/mipsregs.h>
26
27/* INTC register offsets */
28#define INTC_REG_ENABLE 0x00
29#define INTC_REG_STATUS 0x04
30
31#define MAX_WORDS 2
32#define IRQS_PER_WORD 32
33
34struct bcm3384_intc {
35 int n_words;
36 void __iomem *reg[MAX_WORDS];
37 u32 enable[MAX_WORDS];
38 spinlock_t lock;
39};
40
41static void bcm3384_intc_irq_unmask(struct irq_data *d)
42{
43 struct bcm3384_intc *priv = d->domain->host_data;
44 unsigned long flags;
45 int idx = d->hwirq / IRQS_PER_WORD;
46 int bit = d->hwirq % IRQS_PER_WORD;
47
48 spin_lock_irqsave(&priv->lock, flags);
49 priv->enable[idx] |= BIT(bit);
50 __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
51 spin_unlock_irqrestore(&priv->lock, flags);
52}
53
54static void bcm3384_intc_irq_mask(struct irq_data *d)
55{
56 struct bcm3384_intc *priv = d->domain->host_data;
57 unsigned long flags;
58 int idx = d->hwirq / IRQS_PER_WORD;
59 int bit = d->hwirq % IRQS_PER_WORD;
60
61 spin_lock_irqsave(&priv->lock, flags);
62 priv->enable[idx] &= ~BIT(bit);
63 __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
64 spin_unlock_irqrestore(&priv->lock, flags);
65}
66
67static struct irq_chip bcm3384_intc_irq_chip = {
68 .name = "INTC",
69 .irq_unmask = bcm3384_intc_irq_unmask,
70 .irq_mask = bcm3384_intc_irq_mask,
71 .irq_mask_ack = bcm3384_intc_irq_mask,
72};
73
74unsigned int get_c0_compare_int(void)
75{
76 return CP0_LEGACY_COMPARE_IRQ;
77}
78
79static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
80{
81 struct irq_domain *domain = irq_get_handler_data(irq);
82 struct bcm3384_intc *priv = domain->host_data;
83 unsigned long flags;
84 unsigned int idx;
85
86 for (idx = 0; idx < priv->n_words; idx++) {
87 unsigned long pending;
88 int hwirq;
89
90 spin_lock_irqsave(&priv->lock, flags);
91 pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) &
92 priv->enable[idx];
93 spin_unlock_irqrestore(&priv->lock, flags);
94
95 for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
96 generic_handle_irq(irq_find_mapping(domain,
97 hwirq + idx * IRQS_PER_WORD));
98 }
99 }
100}
101
102asmlinkage void plat_irq_dispatch(void)
103{
104 unsigned long pending =
105 (read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0;
106 int bit;
107
108 for_each_set_bit(bit, &pending, 8)
109 do_IRQ(MIPS_CPU_IRQ_BASE + bit);
110}
111
112static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
113{
114 irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq);
115 return 0;
116}
117
118static const struct irq_domain_ops irq_domain_ops = {
119 .xlate = irq_domain_xlate_onecell,
120 .map = intc_map,
121};
122
123static int __init ioremap_one_pair(struct bcm3384_intc *priv,
124 struct device_node *node,
125 int idx)
126{
127 struct resource res;
128
129 if (of_address_to_resource(node, idx, &res))
130 return 0;
131
132 if (request_mem_region(res.start, resource_size(&res),
133 res.name) < 0)
134 pr_err("Failed to request INTC register region\n");
135
136 priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res));
137 if (!priv->reg[idx])
138 panic("Failed to ioremap INTC register range");
139
140 /* start up with everything masked before we hook the parent IRQ */
141 __raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE);
142 priv->enable[idx] = 0;
143
144 return IRQS_PER_WORD;
145}
146
147static int __init intc_of_init(struct device_node *node,
148 struct device_node *parent)
149{
150 struct irq_domain *domain;
151 unsigned int parent_irq, n_irqs = 0;
152 struct bcm3384_intc *priv;
153
154 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
155 if (!priv)
156 panic("Failed to allocate bcm3384_intc struct");
157
158 spin_lock_init(&priv->lock);
159
160 parent_irq = irq_of_parse_and_map(node, 0);
161 if (!parent_irq)
162 panic("Failed to get INTC IRQ");
163
164 n_irqs += ioremap_one_pair(priv, node, 0);
165 n_irqs += ioremap_one_pair(priv, node, 1);
166
167 if (!n_irqs)
168 panic("Failed to map INTC registers");
169
170 priv->n_words = n_irqs / IRQS_PER_WORD;
171 domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv);
172 if (!domain)
173 panic("Failed to add irqdomain");
174
175 irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler);
176 irq_set_handler_data(parent_irq, domain);
177
178 return 0;
179}
180
181static struct of_device_id of_irq_ids[] __initdata = {
182 { .compatible = "mti,cpu-interrupt-controller",
183 .data = mips_cpu_intc_init },
184 { .compatible = "brcm,bcm3384-intc",
185 .data = intc_of_init },
186 {},
187};
188
189void __init arch_init_irq(void)
190{
191 bmips_tp1_irqs = 0;
192 of_irq_init(of_irq_ids);
193}
diff --git a/arch/mips/bcm3384/setup.c b/arch/mips/bcm3384/setup.c
new file mode 100644
index 000000000000..d84b8400b874
--- /dev/null
+++ b/arch/mips/bcm3384/setup.c
@@ -0,0 +1,97 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
8 */
9
10#include <linux/init.h>
11#include <linux/bootmem.h>
12#include <linux/clk-provider.h>
13#include <linux/ioport.h>
14#include <linux/of.h>
15#include <linux/of_fdt.h>
16#include <linux/of_platform.h>
17#include <linux/smp.h>
18#include <asm/addrspace.h>
19#include <asm/bmips.h>
20#include <asm/bootinfo.h>
21#include <asm/prom.h>
22#include <asm/smp-ops.h>
23#include <asm/time.h>
24
25void __init prom_init(void)
26{
27 register_bmips_smp_ops();
28}
29
30void __init prom_free_prom_memory(void)
31{
32}
33
34const char *get_system_type(void)
35{
36 return "BCM3384";
37}
38
39void __init plat_time_init(void)
40{
41 struct device_node *np;
42 u32 freq;
43
44 np = of_find_node_by_name(NULL, "cpus");
45 if (!np)
46 panic("missing 'cpus' DT node");
47 if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
48 panic("missing 'mips-hpt-frequency' property");
49 of_node_put(np);
50
51 mips_hpt_frequency = freq;
52}
53
54void __init plat_mem_setup(void)
55{
56 void *dtb = __dtb_start;
57
58 set_io_port_base(0);
59 ioport_resource.start = 0;
60 ioport_resource.end = ~0;
61
62 /* intended to somewhat resemble ARM; see Documentation/arm/Booting */
63 if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
64 dtb = phys_to_virt(fw_arg2);
65
66 __dt_setup_arch(dtb);
67
68 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
69}
70
71void __init device_tree_init(void)
72{
73 struct device_node *np;
74
75 unflatten_and_copy_device_tree();
76
77 /* Disable SMP boot unless both CPUs are listed in DT and !disabled */
78 np = of_find_node_by_name(NULL, "cpus");
79 if (np && of_get_available_child_count(np) <= 1)
80 bmips_smp_enabled = 0;
81 of_node_put(np);
82}
83
84int __init plat_of_setup(void)
85{
86 return __dt_register_buses("brcm,bcm3384", "simple-bus");
87}
88
89arch_initcall(plat_of_setup);
90
91static int __init plat_dev_init(void)
92{
93 of_clk_init(NULL);
94 return 0;
95}
96
97device_initcall(plat_dev_init);
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h
index f1cc9d0495d8..ea909a56a3ee 100644
--- a/arch/mips/bcm47xx/bcm47xx_private.h
+++ b/arch/mips/bcm47xx/bcm47xx_private.h
@@ -6,12 +6,18 @@
6/* prom.c */ 6/* prom.c */
7void __init bcm47xx_prom_highmem_init(void); 7void __init bcm47xx_prom_highmem_init(void);
8 8
9/* sprom.c */
10void bcm47xx_sprom_register_fallbacks(void);
11
9/* buttons.c */ 12/* buttons.c */
10int __init bcm47xx_buttons_register(void); 13int __init bcm47xx_buttons_register(void);
11 14
12/* leds.c */ 15/* leds.c */
13void __init bcm47xx_leds_register(void); 16void __init bcm47xx_leds_register(void);
14 17
18/* setup.c */
19void __init bcm47xx_bus_setup(void);
20
15/* workarounds.c */ 21/* workarounds.c */
16void __init bcm47xx_workarounds(void); 22void __init bcm47xx_workarounds(void);
17 23
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
index e0585b76ec19..21b4497f09be 100644
--- a/arch/mips/bcm47xx/irq.c
+++ b/arch/mips/bcm47xx/irq.c
@@ -22,6 +22,8 @@
22 * 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 675 Mass Ave, Cambridge, MA 02139, USA.
23 */ 23 */
24 24
25#include "bcm47xx_private.h"
26
25#include <linux/types.h> 27#include <linux/types.h>
26#include <linux/interrupt.h> 28#include <linux/interrupt.h>
27#include <linux/irq.h> 29#include <linux/irq.h>
@@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7)
65 67
66void __init arch_init_irq(void) 68void __init arch_init_irq(void)
67{ 69{
70 /*
71 * This is the first arch callback after mm_init (we can use kmalloc),
72 * so let's finish bus initialization now.
73 */
74 bcm47xx_bus_setup();
75
68#ifdef CONFIG_BCM47XX_BCMA 76#ifdef CONFIG_BCM47XX_BCMA
69 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { 77 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
70 bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, 78 bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 2bed73a684ae..c5c381c43f17 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -13,24 +13,35 @@
13 13
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/ssb/ssb.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/string.h> 17#include <linux/string.h>
19#include <asm/addrspace.h> 18#include <linux/mtd/mtd.h>
20#include <bcm47xx_nvram.h> 19#include <bcm47xx_nvram.h>
21#include <asm/mach-bcm47xx/bcm47xx.h> 20
21#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
22#define NVRAM_SPACE 0x8000
23
24#define FLASH_MIN 0x00020000 /* Minimum flash size */
25
26struct nvram_header {
27 u32 magic;
28 u32 len;
29 u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
30 u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
31 u32 config_ncdl; /* ncdl values for memc */
32};
22 33
23static char nvram_buf[NVRAM_SPACE]; 34static char nvram_buf[NVRAM_SPACE];
24static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; 35static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
25 36
26static u32 find_nvram_size(u32 end) 37static u32 find_nvram_size(void __iomem *end)
27{ 38{
28 struct nvram_header *header; 39 struct nvram_header __iomem *header;
29 int i; 40 int i;
30 41
31 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { 42 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
32 header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); 43 header = (struct nvram_header *)(end - nvram_sizes[i]);
33 if (header->magic == NVRAM_HEADER) 44 if (header->magic == NVRAM_MAGIC)
34 return nvram_sizes[i]; 45 return nvram_sizes[i];
35 } 46 }
36 47
@@ -38,36 +49,40 @@ static u32 find_nvram_size(u32 end)
38} 49}
39 50
40/* Probe for NVRAM header */ 51/* Probe for NVRAM header */
41static int nvram_find_and_copy(u32 base, u32 lim) 52static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
42{ 53{
43 struct nvram_header *header; 54 struct nvram_header __iomem *header;
44 int i; 55 int i;
45 u32 off; 56 u32 off;
46 u32 *src, *dst; 57 u32 *src, *dst;
47 u32 size; 58 u32 size;
48 59
60 if (nvram_buf[0]) {
61 pr_warn("nvram already initialized\n");
62 return -EEXIST;
63 }
64
49 /* TODO: when nvram is on nand flash check for bad blocks first. */ 65 /* TODO: when nvram is on nand flash check for bad blocks first. */
50 off = FLASH_MIN; 66 off = FLASH_MIN;
51 while (off <= lim) { 67 while (off <= lim) {
52 /* Windowed flash access */ 68 /* Windowed flash access */
53 size = find_nvram_size(base + off); 69 size = find_nvram_size(iobase + off);
54 if (size) { 70 if (size) {
55 header = (struct nvram_header *)KSEG1ADDR(base + off - 71 header = (struct nvram_header *)(iobase + off - size);
56 size);
57 goto found; 72 goto found;
58 } 73 }
59 off <<= 1; 74 off <<= 1;
60 } 75 }
61 76
62 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ 77 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
63 header = (struct nvram_header *) KSEG1ADDR(base + 4096); 78 header = (struct nvram_header *)(iobase + 4096);
64 if (header->magic == NVRAM_HEADER) { 79 if (header->magic == NVRAM_MAGIC) {
65 size = NVRAM_SPACE; 80 size = NVRAM_SPACE;
66 goto found; 81 goto found;
67 } 82 }
68 83
69 header = (struct nvram_header *) KSEG1ADDR(base + 1024); 84 header = (struct nvram_header *)(iobase + 1024);
70 if (header->magic == NVRAM_HEADER) { 85 if (header->magic == NVRAM_MAGIC) {
71 size = NVRAM_SPACE; 86 size = NVRAM_SPACE;
72 goto found; 87 goto found;
73 } 88 }
@@ -94,71 +109,73 @@ found:
94 return 0; 109 return 0;
95} 110}
96 111
97#ifdef CONFIG_BCM47XX_SSB 112/*
98static int nvram_init_ssb(void) 113 * On bcm47xx we need access to the NVRAM very early, so we can't use mtd
114 * subsystem to access flash. We can't even use platform device / driver to
115 * store memory offset.
116 * To handle this we provide following symbol. It's supposed to be called as
117 * soon as we get info about flash device, before any NVRAM entry is needed.
118 */
119int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
99{ 120{
100 struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; 121 void __iomem *iobase;
101 u32 base; 122 int err;
102 u32 lim;
103
104 if (mcore->pflash.present) {
105 base = mcore->pflash.window;
106 lim = mcore->pflash.window_size;
107 } else {
108 pr_err("Couldn't find supported flash memory\n");
109 return -ENXIO;
110 }
111 123
112 return nvram_find_and_copy(base, lim); 124 iobase = ioremap_nocache(base, lim);
113} 125 if (!iobase)
114#endif 126 return -ENOMEM;
115 127
116#ifdef CONFIG_BCM47XX_BCMA 128 err = nvram_find_and_copy(iobase, lim);
117static int nvram_init_bcma(void) 129
118{ 130 iounmap(iobase);
119 struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc;
120 u32 base;
121 u32 lim;
122
123#ifdef CONFIG_BCMA_NFLASH
124 if (cc->nflash.boot) {
125 base = BCMA_SOC_FLASH1;
126 lim = BCMA_SOC_FLASH1_SZ;
127 } else
128#endif
129 if (cc->pflash.present) {
130 base = cc->pflash.window;
131 lim = cc->pflash.window_size;
132#ifdef CONFIG_BCMA_SFLASH
133 } else if (cc->sflash.present) {
134 base = cc->sflash.window;
135 lim = cc->sflash.size;
136#endif
137 } else {
138 pr_err("Couldn't find supported flash memory\n");
139 return -ENXIO;
140 }
141 131
142 return nvram_find_and_copy(base, lim); 132 return err;
143} 133}
144#endif
145 134
146static int nvram_init(void) 135static int nvram_init(void)
147{ 136{
148 switch (bcm47xx_bus_type) { 137#ifdef CONFIG_MTD
149#ifdef CONFIG_BCM47XX_SSB 138 struct mtd_info *mtd;
150 case BCM47XX_BUS_TYPE_SSB: 139 struct nvram_header header;
151 return nvram_init_ssb(); 140 size_t bytes_read;
152#endif 141 int err, i;
153#ifdef CONFIG_BCM47XX_BCMA 142
154 case BCM47XX_BUS_TYPE_BCMA: 143 mtd = get_mtd_device_nm("nvram");
155 return nvram_init_bcma(); 144 if (IS_ERR(mtd))
156#endif 145 return -ENODEV;
146
147 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
148 loff_t from = mtd->size - nvram_sizes[i];
149
150 if (from < 0)
151 continue;
152
153 err = mtd_read(mtd, from, sizeof(header), &bytes_read,
154 (uint8_t *)&header);
155 if (!err && header.magic == NVRAM_MAGIC) {
156 u8 *dst = (uint8_t *)nvram_buf;
157 size_t len = header.len;
158
159 if (header.len > NVRAM_SPACE) {
160 pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
161 header.len, NVRAM_SPACE);
162 len = NVRAM_SPACE;
163 }
164
165 err = mtd_read(mtd, from, len, &bytes_read, dst);
166 if (err)
167 return err;
168 memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read);
169
170 return 0;
171 }
157 } 172 }
173#endif
174
158 return -ENXIO; 175 return -ENXIO;
159} 176}
160 177
161int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) 178int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
162{ 179{
163 char *var, *value, *end, *eq; 180 char *var, *value, *end, *eq;
164 int err; 181 int err;
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index c00585d915bc..e43b5046cb30 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void)
102} 102}
103 103
104#ifdef CONFIG_BCM47XX_SSB 104#ifdef CONFIG_BCM47XX_SSB
105static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
106{
107 char prefix[10];
108
109 if (bus->bustype == SSB_BUSTYPE_PCI) {
110 memset(out, 0, sizeof(struct ssb_sprom));
111 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
112 bus->host_pci->bus->number + 1,
113 PCI_SLOT(bus->host_pci->devfn));
114 bcm47xx_fill_sprom(out, prefix, false);
115 return 0;
116 } else {
117 printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
118 return -EINVAL;
119 }
120}
121
122static int bcm47xx_get_invariants(struct ssb_bus *bus, 105static int bcm47xx_get_invariants(struct ssb_bus *bus,
123 struct ssb_init_invariants *iv) 106 struct ssb_init_invariants *iv)
124{ 107{
@@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void)
144 char buf[100]; 127 char buf[100];
145 struct ssb_mipscore *mcore; 128 struct ssb_mipscore *mcore;
146 129
147 err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
148 if (err)
149 printk(KERN_WARNING "bcm47xx: someone else already registered"
150 " a ssb SPROM callback handler (err %d)\n", err);
151
152 err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, 130 err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
153 bcm47xx_get_invariants); 131 bcm47xx_get_invariants);
154 if (err) 132 if (err)
@@ -171,56 +149,21 @@ static void __init bcm47xx_register_ssb(void)
171#endif 149#endif
172 150
173#ifdef CONFIG_BCM47XX_BCMA 151#ifdef CONFIG_BCM47XX_BCMA
174static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
175{
176 char prefix[10];
177 struct bcma_device *core;
178
179 switch (bus->hosttype) {
180 case BCMA_HOSTTYPE_PCI:
181 memset(out, 0, sizeof(struct ssb_sprom));
182 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
183 bus->host_pci->bus->number + 1,
184 PCI_SLOT(bus->host_pci->devfn));
185 bcm47xx_fill_sprom(out, prefix, false);
186 return 0;
187 case BCMA_HOSTTYPE_SOC:
188 memset(out, 0, sizeof(struct ssb_sprom));
189 core = bcma_find_core(bus, BCMA_CORE_80211);
190 if (core) {
191 snprintf(prefix, sizeof(prefix), "sb/%u/",
192 core->core_index);
193 bcm47xx_fill_sprom(out, prefix, true);
194 } else {
195 bcm47xx_fill_sprom(out, NULL, false);
196 }
197 return 0;
198 default:
199 pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
200 return -EINVAL;
201 }
202}
203
204static void __init bcm47xx_register_bcma(void) 152static void __init bcm47xx_register_bcma(void)
205{ 153{
206 int err; 154 int err;
207 155
208 err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
209 if (err)
210 pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
211
212 err = bcma_host_soc_register(&bcm47xx_bus.bcma); 156 err = bcma_host_soc_register(&bcm47xx_bus.bcma);
213 if (err) 157 if (err)
214 panic("Failed to register BCMA bus (err %d)", err); 158 panic("Failed to register BCMA bus (err %d)", err);
215
216 err = bcma_host_soc_init(&bcm47xx_bus.bcma);
217 if (err)
218 panic("Failed to initialize BCMA bus (err %d)", err);
219
220 bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
221} 159}
222#endif 160#endif
223 161
162/*
163 * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed
164 * to detect memory and record it with add_memory_region.
165 * Any extra initializaion performed here must not use kmalloc or bootmem.
166 */
224void __init plat_mem_setup(void) 167void __init plat_mem_setup(void)
225{ 168{
226 struct cpuinfo_mips *c = &current_cpu_data; 169 struct cpuinfo_mips *c = &current_cpu_data;
@@ -229,6 +172,7 @@ void __init plat_mem_setup(void)
229 printk(KERN_INFO "bcm47xx: using bcma bus\n"); 172 printk(KERN_INFO "bcm47xx: using bcma bus\n");
230#ifdef CONFIG_BCM47XX_BCMA 173#ifdef CONFIG_BCM47XX_BCMA
231 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; 174 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
175 bcm47xx_sprom_register_fallbacks();
232 bcm47xx_register_bcma(); 176 bcm47xx_register_bcma();
233 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); 177 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
234#ifdef CONFIG_HIGHMEM 178#ifdef CONFIG_HIGHMEM
@@ -239,6 +183,7 @@ void __init plat_mem_setup(void)
239 printk(KERN_INFO "bcm47xx: using ssb bus\n"); 183 printk(KERN_INFO "bcm47xx: using ssb bus\n");
240#ifdef CONFIG_BCM47XX_SSB 184#ifdef CONFIG_BCM47XX_SSB
241 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; 185 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
186 bcm47xx_sprom_register_fallbacks();
242 bcm47xx_register_ssb(); 187 bcm47xx_register_ssb();
243 bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); 188 bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
244#endif 189#endif
@@ -247,6 +192,28 @@ void __init plat_mem_setup(void)
247 _machine_restart = bcm47xx_machine_restart; 192 _machine_restart = bcm47xx_machine_restart;
248 _machine_halt = bcm47xx_machine_halt; 193 _machine_halt = bcm47xx_machine_halt;
249 pm_power_off = bcm47xx_machine_halt; 194 pm_power_off = bcm47xx_machine_halt;
195}
196
197/*
198 * This finishes bus initialization doing things that were not possible without
199 * kmalloc. Make sure to call it late enough (after mm_init).
200 */
201void __init bcm47xx_bus_setup(void)
202{
203#ifdef CONFIG_BCM47XX_BCMA
204 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
205 int err;
206
207 err = bcma_host_soc_init(&bcm47xx_bus.bcma);
208 if (err)
209 panic("Failed to initialize BCMA bus (err %d)", err);
210
211 bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo,
212 NULL);
213 }
214#endif
215
216 /* With bus initialized we can access NVRAM and detect the board */
250 bcm47xx_board_detect(); 217 bcm47xx_board_detect();
251 mips_set_machine_name(bcm47xx_board_get_name()); 218 mips_set_machine_name(bcm47xx_board_get_name());
252} 219}
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
index 41226b68de3d..2eff7fe99c6b 100644
--- a/arch/mips/bcm47xx/sprom.c
+++ b/arch/mips/bcm47xx/sprom.c
@@ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name,
136 *leddc_off_time = (val >> 16) & 0xff; 136 *leddc_off_time = (val >> 16) & 0xff;
137} 137}
138 138
139static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
140{
141 if (strchr(buf, ':'))
142 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
143 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
144 &macaddr[5]);
145 else if (strchr(buf, '-'))
146 sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
147 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
148 &macaddr[5]);
149 else
150 pr_warn("Can not parse mac address: %s\n", buf);
151}
152
139static void nvram_read_macaddr(const char *prefix, const char *name, 153static void nvram_read_macaddr(const char *prefix, const char *name,
140 u8 val[6], bool fallback) 154 u8 val[6], bool fallback)
141{ 155{
@@ -801,3 +815,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
801 nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); 815 nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
802} 816}
803#endif 817#endif
818
819#if defined(CONFIG_BCM47XX_SSB)
820static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
821{
822 char prefix[10];
823
824 if (bus->bustype == SSB_BUSTYPE_PCI) {
825 memset(out, 0, sizeof(struct ssb_sprom));
826 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
827 bus->host_pci->bus->number + 1,
828 PCI_SLOT(bus->host_pci->devfn));
829 bcm47xx_fill_sprom(out, prefix, false);
830 return 0;
831 } else {
832 pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
833 return -EINVAL;
834 }
835}
836#endif
837
838#if defined(CONFIG_BCM47XX_BCMA)
839static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
840{
841 char prefix[10];
842 struct bcma_device *core;
843
844 switch (bus->hosttype) {
845 case BCMA_HOSTTYPE_PCI:
846 memset(out, 0, sizeof(struct ssb_sprom));
847 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
848 bus->host_pci->bus->number + 1,
849 PCI_SLOT(bus->host_pci->devfn));
850 bcm47xx_fill_sprom(out, prefix, false);
851 return 0;
852 case BCMA_HOSTTYPE_SOC:
853 memset(out, 0, sizeof(struct ssb_sprom));
854 core = bcma_find_core(bus, BCMA_CORE_80211);
855 if (core) {
856 snprintf(prefix, sizeof(prefix), "sb/%u/",
857 core->core_index);
858 bcm47xx_fill_sprom(out, prefix, true);
859 } else {
860 bcm47xx_fill_sprom(out, NULL, false);
861 }
862 return 0;
863 default:
864 pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
865 return -EINVAL;
866 }
867}
868#endif
869
870/*
871 * On bcm47xx we need to register SPROM fallback handler very early, so we can't
872 * use anything like platform device / driver for this.
873 */
874void bcm47xx_sprom_register_fallbacks(void)
875{
876#if defined(CONFIG_BCM47XX_SSB)
877 if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb))
878 pr_warn("Failed to registered ssb SPROM handler\n");
879#endif
880
881#if defined(CONFIG_BCM47XX_BCMA)
882 if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
883 pr_warn("Failed to registered bcma SPROM handler\n");
884#endif
885}
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 536f64443031..307ec8b8e41c 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -263,7 +263,7 @@ static unsigned int detect_memory_size(void)
263 263
264 if (BCMCPU_IS_6345()) { 264 if (BCMCPU_IS_6345()) {
265 val = bcm_sdram_readl(SDRAM_MBASE_REG); 265 val = bcm_sdram_readl(SDRAM_MBASE_REG);
266 return (val * 8 * 1024 * 1024); 266 return val * 8 * 1024 * 1024;
267 } 267 }
268 268
269 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { 269 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index ca9c90e2cabf..4f49fa477f14 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -1,3 +1,4 @@
1dtb-$(CONFIG_BCM3384) += bcm93384wvg.dtb
1dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb 2dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb
2dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb 3dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb
3dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb 4dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb
diff --git a/arch/mips/boot/dts/bcm3384.dtsi b/arch/mips/boot/dts/bcm3384.dtsi
new file mode 100644
index 000000000000..21b074a99c94
--- /dev/null
+++ b/arch/mips/boot/dts/bcm3384.dtsi
@@ -0,0 +1,109 @@
1/ {
2 #address-cells = <1>;
3 #size-cells = <1>;
4 compatible = "brcm,bcm3384", "brcm,bcm33843";
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 /* On BMIPS5000 this is 1/8th of the CPU core clock */
11 mips-hpt-frequency = <100000000>;
12
13 cpu@0 {
14 compatible = "brcm,bmips5000";
15 device_type = "cpu";
16 reg = <0>;
17 };
18
19 cpu@1 {
20 compatible = "brcm,bmips5000";
21 device_type = "cpu";
22 reg = <1>;
23 };
24 };
25
26 clocks {
27 #address-cells = <1>;
28 #size-cells = <0>;
29
30 periph_clk: periph_clk@0 {
31 compatible = "fixed-clock";
32 #clock-cells = <0>;
33 clock-frequency = <54000000>;
34 };
35 };
36
37 aliases {
38 uart0 = &uart0;
39 };
40
41 cpu_intc: cpu_intc@0 {
42 #address-cells = <0>;
43 compatible = "mti,cpu-interrupt-controller";
44
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 };
48
49 periph_intc: periph_intc@14e00038 {
50 compatible = "brcm,bcm3384-intc";
51 reg = <0x14e00038 0x8 0x14e00340 0x8>;
52
53 interrupt-controller;
54 #interrupt-cells = <1>;
55
56 interrupt-parent = <&cpu_intc>;
57 interrupts = <4>;
58 };
59
60 zmips_intc: zmips_intc@104b0060 {
61 compatible = "brcm,bcm3384-intc";
62 reg = <0x104b0060 0x8>;
63
64 interrupt-controller;
65 #interrupt-cells = <1>;
66
67 interrupt-parent = <&periph_intc>;
68 interrupts = <29>;
69 };
70
71 iop_intc: iop_intc@14e00058 {
72 compatible = "brcm,bcm3384-intc";
73 reg = <0x14e00058 0x8>;
74
75 interrupt-controller;
76 #interrupt-cells = <1>;
77
78 interrupt-parent = <&cpu_intc>;
79 interrupts = <6>;
80 };
81
82 uart0: serial@14e00520 {
83 compatible = "brcm,bcm6345-uart";
84 reg = <0x14e00520 0x18>;
85 interrupt-parent = <&periph_intc>;
86 interrupts = <2>;
87 clocks = <&periph_clk>;
88 status = "disabled";
89 };
90
91 ehci0: usb@15400300 {
92 compatible = "brcm,bcm3384-ehci", "generic-ehci";
93 reg = <0x15400300 0x100>;
94 big-endian;
95 interrupt-parent = <&periph_intc>;
96 interrupts = <41>;
97 status = "disabled";
98 };
99
100 ohci0: usb@15400400 {
101 compatible = "brcm,bcm3384-ohci", "generic-ohci";
102 reg = <0x15400400 0x100>;
103 big-endian;
104 no-big-frame-no;
105 interrupt-parent = <&periph_intc>;
106 interrupts = <40>;
107 status = "disabled";
108 };
109};
diff --git a/arch/mips/boot/dts/bcm93384wvg.dts b/arch/mips/boot/dts/bcm93384wvg.dts
new file mode 100644
index 000000000000..831741179212
--- /dev/null
+++ b/arch/mips/boot/dts/bcm93384wvg.dts
@@ -0,0 +1,32 @@
1/dts-v1/;
2
3/include/ "bcm3384.dtsi"
4
5/ {
6 compatible = "brcm,bcm93384wvg", "brcm,bcm3384";
7 model = "Broadcom BCM93384WVG";
8
9 chosen {
10 bootargs = "console=ttyS0,115200";
11 stdout-path = &uart0;
12 };
13
14 memory@0 {
15 device_type = "memory";
16 reg = <0x0 0x04000000>;
17 dma-xor-mask = <0x08000000>;
18 dma-xor-limit = <0x0fffffff>;
19 };
20};
21
22&uart0 {
23 status = "okay";
24};
25
26&ehci0 {
27 status = "okay";
28};
29
30&ohci0 {
31 status = "okay";
32};
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 02f244475207..3778655c4a37 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -262,8 +262,8 @@ char *octeon_swiotlb;
262void __init plat_swiotlb_setup(void) 262void __init plat_swiotlb_setup(void)
263{ 263{
264 int i; 264 int i;
265 phys_t max_addr; 265 phys_addr_t max_addr;
266 phys_t addr_size; 266 phys_addr_t addr_size;
267 size_t swiotlbsize; 267 size_t swiotlbsize;
268 unsigned long swiotlb_nslabs; 268 unsigned long swiotlb_nslabs;
269 269
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c
index f4c1b36fdf65..e15b049b3bd7 100644
--- a/arch/mips/cavium-octeon/executive/octeon-model.c
+++ b/arch/mips/cavium-octeon/executive/octeon-model.c
@@ -28,22 +28,23 @@
28#include <asm/octeon/octeon.h> 28#include <asm/octeon/octeon.h>
29 29
30/** 30/**
31 * Given the chip processor ID from COP0, this function returns a 31 * Read a byte of fuse data
32 * string representing the chip model number. The string is of the 32 * @byte_addr: address to read
33 * form CNXXXXpX.X-FREQ-SUFFIX.
34 * - XXXX = The chip model number
35 * - X.X = Chip pass number
36 * - FREQ = Current frequency in Mhz
37 * - SUFFIX = NSP, EXP, SCP, SSP, or CP
38 *
39 * @chip_id: Chip ID
40 * 33 *
41 * Returns Model string 34 * Returns fuse value: 0 or 1
42 */ 35 */
43const char *octeon_model_get_string(uint32_t chip_id) 36static uint8_t __init cvmx_fuse_read_byte(int byte_addr)
44{ 37{
45 static char buffer[32]; 38 union cvmx_mio_fus_rcmd read_cmd;
46 return octeon_model_get_string_buffer(chip_id, buffer); 39
40 read_cmd.u64 = 0;
41 read_cmd.s.addr = byte_addr;
42 read_cmd.s.pend = 1;
43 cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
44 while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
45 && read_cmd.s.pend)
46 ;
47 return read_cmd.s.dat;
47} 48}
48 49
49/* 50/*
@@ -51,7 +52,8 @@ const char *octeon_model_get_string(uint32_t chip_id)
51 * as running early in u-boot static/global variables don't work when 52 * as running early in u-boot static/global variables don't work when
52 * running from flash. 53 * running from flash.
53 */ 54 */
54const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) 55static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
56 char *buffer)
55{ 57{
56 const char *family; 58 const char *family;
57 const char *core_model; 59 const char *core_model;
@@ -407,3 +409,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
407 sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); 409 sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
408 return buffer; 410 return buffer;
409} 411}
412
413/**
414 * Given the chip processor ID from COP0, this function returns a
415 * string representing the chip model number. The string is of the
416 * form CNXXXXpX.X-FREQ-SUFFIX.
417 * - XXXX = The chip model number
418 * - X.X = Chip pass number
419 * - FREQ = Current frequency in Mhz
420 * - SUFFIX = NSP, EXP, SCP, SSP, or CP
421 *
422 * @chip_id: Chip ID
423 *
424 * Returns Model string
425 */
426const char *__init octeon_model_get_string(uint32_t chip_id)
427{
428 static char buffer[32];
429 return octeon_model_get_string_buffer(chip_id, buffer);
430}
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 5ebdb32d9a2b..94f888d3384e 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -1092,7 +1092,7 @@ static int __init edac_devinit(void)
1092 name = edac_device_names[i]; 1092 name = edac_device_names[i];
1093 dev = platform_device_register_simple(name, -1, NULL, 0); 1093 dev = platform_device_register_simple(name, -1, NULL, 0);
1094 if (IS_ERR(dev)) { 1094 if (IS_ERR(dev)) {
1095 pr_err("Registation of %s failed!\n", name); 1095 pr_err("Registration of %s failed!\n", name);
1096 err = PTR_ERR(dev); 1096 err = PTR_ERR(dev);
1097 } 1097 }
1098 } 1098 }
@@ -1103,7 +1103,7 @@ static int __init edac_devinit(void)
1103 dev = platform_device_register_simple("octeon_lmc_edac", 1103 dev = platform_device_register_simple("octeon_lmc_edac",
1104 i, NULL, 0); 1104 i, NULL, 0);
1105 if (IS_ERR(dev)) { 1105 if (IS_ERR(dev)) {
1106 pr_err("Registation of octeon_lmc_edac %d failed!\n", i); 1106 pr_err("Registration of octeon_lmc_edac %d failed!\n", i);
1107 err = PTR_ERR(dev); 1107 err = PTR_ERR(dev);
1108 } 1108 }
1109 } 1109 }
diff --git a/arch/mips/configs/bcm3384_defconfig b/arch/mips/configs/bcm3384_defconfig
new file mode 100644
index 000000000000..88711c28ff32
--- /dev/null
+++ b/arch/mips/configs/bcm3384_defconfig
@@ -0,0 +1,78 @@
1CONFIG_BCM3384=y
2CONFIG_HIGHMEM=y
3CONFIG_SMP=y
4CONFIG_NR_CPUS=4
5# CONFIG_SECCOMP is not set
6CONFIG_MIPS_O32_FP64_SUPPORT=y
7# CONFIG_LOCALVERSION_AUTO is not set
8# CONFIG_SWAP is not set
9CONFIG_NO_HZ=y
10CONFIG_BLK_DEV_INITRD=y
11# CONFIG_RD_GZIP is not set
12CONFIG_EXPERT=y
13# CONFIG_VM_EVENT_COUNTERS is not set
14# CONFIG_SLUB_DEBUG is not set
15# CONFIG_BLK_DEV_BSG is not set
16# CONFIG_IOSCHED_DEADLINE is not set
17# CONFIG_IOSCHED_CFQ is not set
18CONFIG_NET=y
19CONFIG_PACKET=y
20CONFIG_PACKET_DIAG=y
21CONFIG_UNIX=y
22CONFIG_INET=y
23# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
24# CONFIG_INET_XFRM_MODE_TUNNEL is not set
25# CONFIG_INET_XFRM_MODE_BEET is not set
26# CONFIG_INET_LRO is not set
27# CONFIG_INET_DIAG is not set
28CONFIG_CFG80211=y
29CONFIG_NL80211_TESTMODE=y
30CONFIG_MAC80211=y
31CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
32CONFIG_DEVTMPFS=y
33CONFIG_DEVTMPFS_MOUNT=y
34# CONFIG_STANDALONE is not set
35# CONFIG_PREVENT_FIRMWARE_BUILD is not set
36CONFIG_MTD=y
37CONFIG_MTD_CFI=y
38CONFIG_MTD_CFI_INTELEXT=y
39CONFIG_MTD_CFI_AMDSTD=y
40CONFIG_MTD_PHYSMAP=y
41# CONFIG_BLK_DEV is not set
42CONFIG_SCSI=y
43CONFIG_BLK_DEV_SD=y
44# CONFIG_SCSI_LOWLEVEL is not set
45CONFIG_NETDEVICES=y
46CONFIG_USB_USBNET=y
47# CONFIG_INPUT is not set
48# CONFIG_SERIO is not set
49# CONFIG_VT is not set
50# CONFIG_DEVKMEM is not set
51CONFIG_SERIAL_EARLYCON_FORCE=y
52CONFIG_SERIAL_BCM63XX=y
53CONFIG_SERIAL_BCM63XX_CONSOLE=y
54# CONFIG_HW_RANDOM is not set
55# CONFIG_HWMON is not set
56CONFIG_USB=y
57CONFIG_USB_EHCI_HCD=y
58# CONFIG_USB_EHCI_TT_NEWSCHED is not set
59CONFIG_USB_EHCI_HCD_PLATFORM=y
60CONFIG_USB_OHCI_HCD=y
61CONFIG_USB_OHCI_HCD_PLATFORM=y
62CONFIG_USB_STORAGE=y
63CONFIG_EXT4_FS=y
64CONFIG_EXT4_FS_POSIX_ACL=y
65CONFIG_EXT4_FS_SECURITY=y
66# CONFIG_DNOTIFY is not set
67CONFIG_FUSE_FS=y
68CONFIG_VFAT_FS=y
69CONFIG_PROC_KCORE=y
70CONFIG_TMPFS=y
71CONFIG_NFS_FS=y
72CONFIG_CIFS=y
73CONFIG_NLS_CODEPAGE_437=y
74CONFIG_NLS_ASCII=y
75CONFIG_NLS_ISO8859_1=y
76CONFIG_DEBUG_FS=y
77CONFIG_MAGIC_SYSRQ=y
78# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c
index ffd0345780ae..6ecda64ad184 100644
--- a/arch/mips/fw/lib/cmdline.c
+++ b/arch/mips/fw/lib/cmdline.c
@@ -68,7 +68,7 @@ char *fw_getenv(char *envname)
68 result = fw_envp(index + 1); 68 result = fw_envp(index + 1);
69 break; 69 break;
70 } else if (fw_envp(index)[i] == '=') { 70 } else if (fw_envp(index)[i] == '=') {
71 result = (fw_envp(index + 1) + i); 71 result = fw_envp(index) + i + 1;
72 break; 72 break;
73 } 73 }
74 } 74 }
@@ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname)
88{ 88{
89 unsigned long envl = 0UL; 89 unsigned long envl = 0UL;
90 char *str; 90 char *str;
91 long val;
92 int tmp; 91 int tmp;
93 92
94 str = fw_getenv(envname); 93 str = fw_getenv(envname);
95 if (str) { 94 if (str) {
96 tmp = kstrtol(str, 0, &val); 95 tmp = kstrtoul(str, 0, &envl);
97 envl = (unsigned long)val; 96 if (tmp)
97 envl = 0;
98 } 98 }
99 99
100 return envl; 100 return envl;
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 6dd6bfc607e9..857da84cfc92 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -17,6 +17,7 @@
17#include <linux/irqflags.h> 17#include <linux/irqflags.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <asm/barrier.h> 19#include <asm/barrier.h>
20#include <asm/compiler.h>
20#include <asm/cpu-features.h> 21#include <asm/cpu-features.h>
21#include <asm/cmpxchg.h> 22#include <asm/cmpxchg.h>
22#include <asm/war.h> 23#include <asm/war.h>
@@ -40,95 +41,97 @@
40 */ 41 */
41#define atomic_set(v, i) ((v)->counter = (i)) 42#define atomic_set(v, i) ((v)->counter = (i))
42 43
43#define ATOMIC_OP(op, c_op, asm_op) \ 44#define ATOMIC_OP(op, c_op, asm_op) \
44static __inline__ void atomic_##op(int i, atomic_t * v) \ 45static __inline__ void atomic_##op(int i, atomic_t * v) \
45{ \ 46{ \
46 if (kernel_uses_llsc && R10000_LLSC_WAR) { \ 47 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
47 int temp; \ 48 int temp; \
48 \ 49 \
49 __asm__ __volatile__( \ 50 __asm__ __volatile__( \
50 " .set arch=r4000 \n" \ 51 " .set arch=r4000 \n" \
51 "1: ll %0, %1 # atomic_" #op " \n" \ 52 "1: ll %0, %1 # atomic_" #op " \n" \
52 " " #asm_op " %0, %2 \n" \ 53 " " #asm_op " %0, %2 \n" \
53 " sc %0, %1 \n" \ 54 " sc %0, %1 \n" \
54 " beqzl %0, 1b \n" \ 55 " beqzl %0, 1b \n" \
55 " .set mips0 \n" \ 56 " .set mips0 \n" \
56 : "=&r" (temp), "+m" (v->counter) \ 57 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
57 : "Ir" (i)); \ 58 : "Ir" (i)); \
58 } else if (kernel_uses_llsc) { \ 59 } else if (kernel_uses_llsc) { \
59 int temp; \ 60 int temp; \
60 \ 61 \
61 do { \ 62 do { \
62 __asm__ __volatile__( \ 63 __asm__ __volatile__( \
63 " .set arch=r4000 \n" \ 64 " .set arch=r4000 \n" \
64 " ll %0, %1 # atomic_" #op "\n" \ 65 " ll %0, %1 # atomic_" #op "\n" \
65 " " #asm_op " %0, %2 \n" \ 66 " " #asm_op " %0, %2 \n" \
66 " sc %0, %1 \n" \ 67 " sc %0, %1 \n" \
67 " .set mips0 \n" \ 68 " .set mips0 \n" \
68 : "=&r" (temp), "+m" (v->counter) \ 69 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
69 : "Ir" (i)); \ 70 : "Ir" (i)); \
70 } while (unlikely(!temp)); \ 71 } while (unlikely(!temp)); \
71 } else { \ 72 } else { \
72 unsigned long flags; \ 73 unsigned long flags; \
73 \ 74 \
74 raw_local_irq_save(flags); \ 75 raw_local_irq_save(flags); \
75 v->counter c_op i; \ 76 v->counter c_op i; \
76 raw_local_irq_restore(flags); \ 77 raw_local_irq_restore(flags); \
77 } \ 78 } \
78} \
79
80#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
81static __inline__ int atomic_##op##_return(int i, atomic_t * v) \
82{ \
83 int result; \
84 \
85 smp_mb__before_llsc(); \
86 \
87 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
88 int temp; \
89 \
90 __asm__ __volatile__( \
91 " .set arch=r4000 \n" \
92 "1: ll %1, %2 # atomic_" #op "_return \n" \
93 " " #asm_op " %0, %1, %3 \n" \
94 " sc %0, %2 \n" \
95 " beqzl %0, 1b \n" \
96 " " #asm_op " %0, %1, %3 \n" \
97 " .set mips0 \n" \
98 : "=&r" (result), "=&r" (temp), "+m" (v->counter) \
99 : "Ir" (i)); \
100 } else if (kernel_uses_llsc) { \
101 int temp; \
102 \
103 do { \
104 __asm__ __volatile__( \
105 " .set arch=r4000 \n" \
106 " ll %1, %2 # atomic_" #op "_return \n" \
107 " " #asm_op " %0, %1, %3 \n" \
108 " sc %0, %2 \n" \
109 " .set mips0 \n" \
110 : "=&r" (result), "=&r" (temp), "+m" (v->counter) \
111 : "Ir" (i)); \
112 } while (unlikely(!result)); \
113 \
114 result = temp; result c_op i; \
115 } else { \
116 unsigned long flags; \
117 \
118 raw_local_irq_save(flags); \
119 result = v->counter; \
120 result c_op i; \
121 v->counter = result; \
122 raw_local_irq_restore(flags); \
123 } \
124 \
125 smp_llsc_mb(); \
126 \
127 return result; \
128} 79}
129 80
130#define ATOMIC_OPS(op, c_op, asm_op) \ 81#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
131 ATOMIC_OP(op, c_op, asm_op) \ 82static __inline__ int atomic_##op##_return(int i, atomic_t * v) \
83{ \
84 int result; \
85 \
86 smp_mb__before_llsc(); \
87 \
88 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
89 int temp; \
90 \
91 __asm__ __volatile__( \
92 " .set arch=r4000 \n" \
93 "1: ll %1, %2 # atomic_" #op "_return \n" \
94 " " #asm_op " %0, %1, %3 \n" \
95 " sc %0, %2 \n" \
96 " beqzl %0, 1b \n" \
97 " " #asm_op " %0, %1, %3 \n" \
98 " .set mips0 \n" \
99 : "=&r" (result), "=&r" (temp), \
100 "+" GCC_OFF12_ASM() (v->counter) \
101 : "Ir" (i)); \
102 } else if (kernel_uses_llsc) { \
103 int temp; \
104 \
105 do { \
106 __asm__ __volatile__( \
107 " .set arch=r4000 \n" \
108 " ll %1, %2 # atomic_" #op "_return \n" \
109 " " #asm_op " %0, %1, %3 \n" \
110 " sc %0, %2 \n" \
111 " .set mips0 \n" \
112 : "=&r" (result), "=&r" (temp), \
113 "+" GCC_OFF12_ASM() (v->counter) \
114 : "Ir" (i)); \
115 } while (unlikely(!result)); \
116 \
117 result = temp; result c_op i; \
118 } else { \
119 unsigned long flags; \
120 \
121 raw_local_irq_save(flags); \
122 result = v->counter; \
123 result c_op i; \
124 v->counter = result; \
125 raw_local_irq_restore(flags); \
126 } \
127 \
128 smp_llsc_mb(); \
129 \
130 return result; \
131}
132
133#define ATOMIC_OPS(op, c_op, asm_op) \
134 ATOMIC_OP(op, c_op, asm_op) \
132 ATOMIC_OP_RETURN(op, c_op, asm_op) 135 ATOMIC_OP_RETURN(op, c_op, asm_op)
133 136
134ATOMIC_OPS(add, +=, addu) 137ATOMIC_OPS(add, +=, addu)
@@ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
167 " .set reorder \n" 170 " .set reorder \n"
168 "1: \n" 171 "1: \n"
169 " .set mips0 \n" 172 " .set mips0 \n"
170 : "=&r" (result), "=&r" (temp), "+m" (v->counter) 173 : "=&r" (result), "=&r" (temp),
171 : "Ir" (i), "m" (v->counter) 174 "+" GCC_OFF12_ASM() (v->counter)
175 : "Ir" (i), GCC_OFF12_ASM() (v->counter)
172 : "memory"); 176 : "memory");
173 } else if (kernel_uses_llsc) { 177 } else if (kernel_uses_llsc) {
174 int temp; 178 int temp;
@@ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
185 " .set reorder \n" 189 " .set reorder \n"
186 "1: \n" 190 "1: \n"
187 " .set mips0 \n" 191 " .set mips0 \n"
188 : "=&r" (result), "=&r" (temp), "+m" (v->counter) 192 : "=&r" (result), "=&r" (temp),
193 "+" GCC_OFF12_ASM() (v->counter)
189 : "Ir" (i)); 194 : "Ir" (i));
190 } else { 195 } else {
191 unsigned long flags; 196 unsigned long flags;
@@ -315,96 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
315 */ 320 */
316#define atomic64_set(v, i) ((v)->counter = (i)) 321#define atomic64_set(v, i) ((v)->counter = (i))
317 322
318#define ATOMIC64_OP(op, c_op, asm_op) \ 323#define ATOMIC64_OP(op, c_op, asm_op) \
319static __inline__ void atomic64_##op(long i, atomic64_t * v) \ 324static __inline__ void atomic64_##op(long i, atomic64_t * v) \
320{ \ 325{ \
321 if (kernel_uses_llsc && R10000_LLSC_WAR) { \ 326 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
322 long temp; \ 327 long temp; \
323 \ 328 \
324 __asm__ __volatile__( \ 329 __asm__ __volatile__( \
325 " .set arch=r4000 \n" \ 330 " .set arch=r4000 \n" \
326 "1: lld %0, %1 # atomic64_" #op " \n" \ 331 "1: lld %0, %1 # atomic64_" #op " \n" \
327 " " #asm_op " %0, %2 \n" \ 332 " " #asm_op " %0, %2 \n" \
328 " scd %0, %1 \n" \ 333 " scd %0, %1 \n" \
329 " beqzl %0, 1b \n" \ 334 " beqzl %0, 1b \n" \
330 " .set mips0 \n" \ 335 " .set mips0 \n" \
331 : "=&r" (temp), "+m" (v->counter) \ 336 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
332 : "Ir" (i)); \ 337 : "Ir" (i)); \
333 } else if (kernel_uses_llsc) { \ 338 } else if (kernel_uses_llsc) { \
334 long temp; \ 339 long temp; \
335 \ 340 \
336 do { \ 341 do { \
337 __asm__ __volatile__( \ 342 __asm__ __volatile__( \
338 " .set arch=r4000 \n" \ 343 " .set arch=r4000 \n" \
339 " lld %0, %1 # atomic64_" #op "\n" \ 344 " lld %0, %1 # atomic64_" #op "\n" \
340 " " #asm_op " %0, %2 \n" \ 345 " " #asm_op " %0, %2 \n" \
341 " scd %0, %1 \n" \ 346 " scd %0, %1 \n" \
342 " .set mips0 \n" \ 347 " .set mips0 \n" \
343 : "=&r" (temp), "+m" (v->counter) \ 348 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
344 : "Ir" (i)); \ 349 : "Ir" (i)); \
345 } while (unlikely(!temp)); \ 350 } while (unlikely(!temp)); \
346 } else { \ 351 } else { \
347 unsigned long flags; \ 352 unsigned long flags; \
348 \ 353 \
349 raw_local_irq_save(flags); \ 354 raw_local_irq_save(flags); \
350 v->counter c_op i; \ 355 v->counter c_op i; \
351 raw_local_irq_restore(flags); \ 356 raw_local_irq_restore(flags); \
352 } \ 357 } \
353} \ 358}
354 359
355#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ 360#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \
356static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ 361static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
357{ \ 362{ \
358 long result; \ 363 long result; \
359 \ 364 \
360 smp_mb__before_llsc(); \ 365 smp_mb__before_llsc(); \
361 \ 366 \
362 if (kernel_uses_llsc && R10000_LLSC_WAR) { \ 367 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
363 long temp; \ 368 long temp; \
364 \ 369 \
365 __asm__ __volatile__( \ 370 __asm__ __volatile__( \
366 " .set arch=r4000 \n" \ 371 " .set arch=r4000 \n" \
367 "1: lld %1, %2 # atomic64_" #op "_return\n" \ 372 "1: lld %1, %2 # atomic64_" #op "_return\n" \
368 " " #asm_op " %0, %1, %3 \n" \ 373 " " #asm_op " %0, %1, %3 \n" \
369 " scd %0, %2 \n" \ 374 " scd %0, %2 \n" \
370 " beqzl %0, 1b \n" \ 375 " beqzl %0, 1b \n" \
371 " " #asm_op " %0, %1, %3 \n" \ 376 " " #asm_op " %0, %1, %3 \n" \
372 " .set mips0 \n" \ 377 " .set mips0 \n" \
373 : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ 378 : "=&r" (result), "=&r" (temp), \
374 : "Ir" (i)); \ 379 "+" GCC_OFF12_ASM() (v->counter) \
375 } else if (kernel_uses_llsc) { \ 380 : "Ir" (i)); \
376 long temp; \ 381 } else if (kernel_uses_llsc) { \
377 \ 382 long temp; \
378 do { \ 383 \
379 __asm__ __volatile__( \ 384 do { \
380 " .set arch=r4000 \n" \ 385 __asm__ __volatile__( \
381 " lld %1, %2 # atomic64_" #op "_return\n" \ 386 " .set arch=r4000 \n" \
382 " " #asm_op " %0, %1, %3 \n" \ 387 " lld %1, %2 # atomic64_" #op "_return\n" \
383 " scd %0, %2 \n" \ 388 " " #asm_op " %0, %1, %3 \n" \
384 " .set mips0 \n" \ 389 " scd %0, %2 \n" \
385 : "=&r" (result), "=&r" (temp), "=m" (v->counter) \ 390 " .set mips0 \n" \
386 : "Ir" (i), "m" (v->counter) \ 391 : "=&r" (result), "=&r" (temp), \
387 : "memory"); \ 392 "=" GCC_OFF12_ASM() (v->counter) \
388 } while (unlikely(!result)); \ 393 : "Ir" (i), GCC_OFF12_ASM() (v->counter) \
389 \ 394 : "memory"); \
390 result = temp; result c_op i; \ 395 } while (unlikely(!result)); \
391 } else { \ 396 \
392 unsigned long flags; \ 397 result = temp; result c_op i; \
393 \ 398 } else { \
394 raw_local_irq_save(flags); \ 399 unsigned long flags; \
395 result = v->counter; \ 400 \
396 result c_op i; \ 401 raw_local_irq_save(flags); \
397 v->counter = result; \ 402 result = v->counter; \
398 raw_local_irq_restore(flags); \ 403 result c_op i; \
399 } \ 404 v->counter = result; \
400 \ 405 raw_local_irq_restore(flags); \
401 smp_llsc_mb(); \ 406 } \
402 \ 407 \
403 return result; \ 408 smp_llsc_mb(); \
409 \
410 return result; \
404} 411}
405 412
406#define ATOMIC64_OPS(op, c_op, asm_op) \ 413#define ATOMIC64_OPS(op, c_op, asm_op) \
407 ATOMIC64_OP(op, c_op, asm_op) \ 414 ATOMIC64_OP(op, c_op, asm_op) \
408 ATOMIC64_OP_RETURN(op, c_op, asm_op) 415 ATOMIC64_OP_RETURN(op, c_op, asm_op)
409 416
410ATOMIC64_OPS(add, +=, daddu) 417ATOMIC64_OPS(add, +=, daddu)
@@ -415,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu)
415#undef ATOMIC64_OP 422#undef ATOMIC64_OP
416 423
417/* 424/*
418 * atomic64_sub_if_positive - conditionally subtract integer from atomic variable 425 * atomic64_sub_if_positive - conditionally subtract integer from atomic
426 * variable
419 * @i: integer value to subtract 427 * @i: integer value to subtract
420 * @v: pointer of type atomic64_t 428 * @v: pointer of type atomic64_t
421 * 429 *
@@ -443,8 +451,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
443 " .set reorder \n" 451 " .set reorder \n"
444 "1: \n" 452 "1: \n"
445 " .set mips0 \n" 453 " .set mips0 \n"
446 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 454 : "=&r" (result), "=&r" (temp),
447 : "Ir" (i), "m" (v->counter) 455 "=" GCC_OFF12_ASM() (v->counter)
456 : "Ir" (i), GCC_OFF12_ASM() (v->counter)
448 : "memory"); 457 : "memory");
449 } else if (kernel_uses_llsc) { 458 } else if (kernel_uses_llsc) {
450 long temp; 459 long temp;
@@ -461,7 +470,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
461 " .set reorder \n" 470 " .set reorder \n"
462 "1: \n" 471 "1: \n"
463 " .set mips0 \n" 472 " .set mips0 \n"
464 : "=&r" (result), "=&r" (temp), "+m" (v->counter) 473 : "=&r" (result), "=&r" (temp),
474 "+" GCC_OFF12_ASM() (v->counter)
465 : "Ir" (i)); 475 : "Ir" (i));
466 } else { 476 } else {
467 unsigned long flags; 477 unsigned long flags;
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index bae6b0fa8ab5..6663bcca9d0c 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -17,6 +17,7 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <asm/barrier.h> 18#include <asm/barrier.h>
19#include <asm/byteorder.h> /* sigh ... */ 19#include <asm/byteorder.h> /* sigh ... */
20#include <asm/compiler.h>
20#include <asm/cpu-features.h> 21#include <asm/cpu-features.h>
21#include <asm/sgidefs.h> 22#include <asm/sgidefs.h>
22#include <asm/war.h> 23#include <asm/war.h>
@@ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
78 " " __SC "%0, %1 \n" 79 " " __SC "%0, %1 \n"
79 " beqzl %0, 1b \n" 80 " beqzl %0, 1b \n"
80 " .set mips0 \n" 81 " .set mips0 \n"
81 : "=&r" (temp), "=m" (*m) 82 : "=&r" (temp), "=" GCC_OFF12_ASM() (*m)
82 : "ir" (1UL << bit), "m" (*m)); 83 : "ir" (1UL << bit), GCC_OFF12_ASM() (*m));
83#ifdef CONFIG_CPU_MIPSR2 84#ifdef CONFIG_CPU_MIPSR2
84 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 85 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
85 do { 86 do {
@@ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
87 " " __LL "%0, %1 # set_bit \n" 88 " " __LL "%0, %1 # set_bit \n"
88 " " __INS "%0, %3, %2, 1 \n" 89 " " __INS "%0, %3, %2, 1 \n"
89 " " __SC "%0, %1 \n" 90 " " __SC "%0, %1 \n"
90 : "=&r" (temp), "+m" (*m) 91 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
91 : "ir" (bit), "r" (~0)); 92 : "ir" (bit), "r" (~0));
92 } while (unlikely(!temp)); 93 } while (unlikely(!temp));
93#endif /* CONFIG_CPU_MIPSR2 */ 94#endif /* CONFIG_CPU_MIPSR2 */
@@ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
99 " or %0, %2 \n" 100 " or %0, %2 \n"
100 " " __SC "%0, %1 \n" 101 " " __SC "%0, %1 \n"
101 " .set mips0 \n" 102 " .set mips0 \n"
102 : "=&r" (temp), "+m" (*m) 103 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
103 : "ir" (1UL << bit)); 104 : "ir" (1UL << bit));
104 } while (unlikely(!temp)); 105 } while (unlikely(!temp));
105 } else 106 } else
@@ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
130 " " __SC "%0, %1 \n" 131 " " __SC "%0, %1 \n"
131 " beqzl %0, 1b \n" 132 " beqzl %0, 1b \n"
132 " .set mips0 \n" 133 " .set mips0 \n"
133 : "=&r" (temp), "+m" (*m) 134 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
134 : "ir" (~(1UL << bit))); 135 : "ir" (~(1UL << bit)));
135#ifdef CONFIG_CPU_MIPSR2 136#ifdef CONFIG_CPU_MIPSR2
136 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 137 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
@@ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
139 " " __LL "%0, %1 # clear_bit \n" 140 " " __LL "%0, %1 # clear_bit \n"
140 " " __INS "%0, $0, %2, 1 \n" 141 " " __INS "%0, $0, %2, 1 \n"
141 " " __SC "%0, %1 \n" 142 " " __SC "%0, %1 \n"
142 : "=&r" (temp), "+m" (*m) 143 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
143 : "ir" (bit)); 144 : "ir" (bit));
144 } while (unlikely(!temp)); 145 } while (unlikely(!temp));
145#endif /* CONFIG_CPU_MIPSR2 */ 146#endif /* CONFIG_CPU_MIPSR2 */
@@ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
151 " and %0, %2 \n" 152 " and %0, %2 \n"
152 " " __SC "%0, %1 \n" 153 " " __SC "%0, %1 \n"
153 " .set mips0 \n" 154 " .set mips0 \n"
154 : "=&r" (temp), "+m" (*m) 155 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
155 : "ir" (~(1UL << bit))); 156 : "ir" (~(1UL << bit)));
156 } while (unlikely(!temp)); 157 } while (unlikely(!temp));
157 } else 158 } else
@@ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
196 " " __SC "%0, %1 \n" 197 " " __SC "%0, %1 \n"
197 " beqzl %0, 1b \n" 198 " beqzl %0, 1b \n"
198 " .set mips0 \n" 199 " .set mips0 \n"
199 : "=&r" (temp), "+m" (*m) 200 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
200 : "ir" (1UL << bit)); 201 : "ir" (1UL << bit));
201 } else if (kernel_uses_llsc) { 202 } else if (kernel_uses_llsc) {
202 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 203 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
209 " xor %0, %2 \n" 210 " xor %0, %2 \n"
210 " " __SC "%0, %1 \n" 211 " " __SC "%0, %1 \n"
211 " .set mips0 \n" 212 " .set mips0 \n"
212 : "=&r" (temp), "+m" (*m) 213 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
213 : "ir" (1UL << bit)); 214 : "ir" (1UL << bit));
214 } while (unlikely(!temp)); 215 } while (unlikely(!temp));
215 } else 216 } else
@@ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr,
244 " beqzl %2, 1b \n" 245 " beqzl %2, 1b \n"
245 " and %2, %0, %3 \n" 246 " and %2, %0, %3 \n"
246 " .set mips0 \n" 247 " .set mips0 \n"
247 : "=&r" (temp), "+m" (*m), "=&r" (res) 248 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
248 : "r" (1UL << bit) 249 : "r" (1UL << bit)
249 : "memory"); 250 : "memory");
250 } else if (kernel_uses_llsc) { 251 } else if (kernel_uses_llsc) {
@@ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr,
258 " or %2, %0, %3 \n" 259 " or %2, %0, %3 \n"
259 " " __SC "%2, %1 \n" 260 " " __SC "%2, %1 \n"
260 " .set mips0 \n" 261 " .set mips0 \n"
261 : "=&r" (temp), "+m" (*m), "=&r" (res) 262 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
262 : "r" (1UL << bit) 263 : "r" (1UL << bit)
263 : "memory"); 264 : "memory");
264 } while (unlikely(!res)); 265 } while (unlikely(!res));
@@ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
312 " or %2, %0, %3 \n" 313 " or %2, %0, %3 \n"
313 " " __SC "%2, %1 \n" 314 " " __SC "%2, %1 \n"
314 " .set mips0 \n" 315 " .set mips0 \n"
315 : "=&r" (temp), "+m" (*m), "=&r" (res) 316 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
316 : "r" (1UL << bit) 317 : "r" (1UL << bit)
317 : "memory"); 318 : "memory");
318 } while (unlikely(!res)); 319 } while (unlikely(!res));
@@ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr,
354 " beqzl %2, 1b \n" 355 " beqzl %2, 1b \n"
355 " and %2, %0, %3 \n" 356 " and %2, %0, %3 \n"
356 " .set mips0 \n" 357 " .set mips0 \n"
357 : "=&r" (temp), "+m" (*m), "=&r" (res) 358 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
358 : "r" (1UL << bit) 359 : "r" (1UL << bit)
359 : "memory"); 360 : "memory");
360#ifdef CONFIG_CPU_MIPSR2 361#ifdef CONFIG_CPU_MIPSR2
@@ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr,
368 " " __EXT "%2, %0, %3, 1 \n" 369 " " __EXT "%2, %0, %3, 1 \n"
369 " " __INS "%0, $0, %3, 1 \n" 370 " " __INS "%0, $0, %3, 1 \n"
370 " " __SC "%0, %1 \n" 371 " " __SC "%0, %1 \n"
371 : "=&r" (temp), "+m" (*m), "=&r" (res) 372 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
372 : "ir" (bit) 373 : "ir" (bit)
373 : "memory"); 374 : "memory");
374 } while (unlikely(!temp)); 375 } while (unlikely(!temp));
@@ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr,
385 " xor %2, %3 \n" 386 " xor %2, %3 \n"
386 " " __SC "%2, %1 \n" 387 " " __SC "%2, %1 \n"
387 " .set mips0 \n" 388 " .set mips0 \n"
388 : "=&r" (temp), "+m" (*m), "=&r" (res) 389 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
389 : "r" (1UL << bit) 390 : "r" (1UL << bit)
390 : "memory"); 391 : "memory");
391 } while (unlikely(!res)); 392 } while (unlikely(!res));
@@ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr,
427 " beqzl %2, 1b \n" 428 " beqzl %2, 1b \n"
428 " and %2, %0, %3 \n" 429 " and %2, %0, %3 \n"
429 " .set mips0 \n" 430 " .set mips0 \n"
430 : "=&r" (temp), "+m" (*m), "=&r" (res) 431 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
431 : "r" (1UL << bit) 432 : "r" (1UL << bit)
432 : "memory"); 433 : "memory");
433 } else if (kernel_uses_llsc) { 434 } else if (kernel_uses_llsc) {
@@ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr,
441 " xor %2, %0, %3 \n" 442 " xor %2, %0, %3 \n"
442 " " __SC "\t%2, %1 \n" 443 " " __SC "\t%2, %1 \n"
443 " .set mips0 \n" 444 " .set mips0 \n"
444 : "=&r" (temp), "+m" (*m), "=&r" (res) 445 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
445 : "r" (1UL << bit) 446 : "r" (1UL << bit)
446 : "memory"); 447 : "memory");
447 } while (unlikely(!res)); 448 } while (unlikely(!res));
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
index cbaccebf5065..30939b02e3ff 100644
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end;
84extern int bmips_smp_enabled; 84extern int bmips_smp_enabled;
85extern int bmips_cpu_offset; 85extern int bmips_cpu_offset;
86extern cpumask_t bmips_booted_mask; 86extern cpumask_t bmips_booted_mask;
87extern unsigned long bmips_tp1_irqs;
87 88
88extern void bmips_ebase_setup(void); 89extern void bmips_ebase_setup(void);
89extern asmlinkage void plat_wired_tlb_setup(void); 90extern asmlinkage void plat_wired_tlb_setup(void);
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 1f7ca8b00404..b603804caac5 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -70,10 +70,7 @@ enum loongson_machine_type {
70 MACH_DEXXON_GDIUM2F10, 70 MACH_DEXXON_GDIUM2F10,
71 MACH_LEMOTE_NAS, 71 MACH_LEMOTE_NAS,
72 MACH_LEMOTE_LL2F, 72 MACH_LEMOTE_LL2F,
73 MACH_LEMOTE_A1004, 73 MACH_LOONGSON_GENERIC,
74 MACH_LEMOTE_A1101,
75 MACH_LEMOTE_A1201,
76 MACH_LEMOTE_A1205,
77 MACH_LOONGSON_END 74 MACH_LOONGSON_END
78}; 75};
79 76
@@ -101,16 +98,16 @@ extern unsigned long mips_machtype;
101struct boot_mem_map { 98struct boot_mem_map {
102 int nr_map; 99 int nr_map;
103 struct boot_mem_map_entry { 100 struct boot_mem_map_entry {
104 phys_t addr; /* start of memory segment */ 101 phys_addr_t addr; /* start of memory segment */
105 phys_t size; /* size of memory segment */ 102 phys_addr_t size; /* size of memory segment */
106 long type; /* type of memory segment */ 103 long type; /* type of memory segment */
107 } map[BOOT_MEM_MAP_MAX]; 104 } map[BOOT_MEM_MAP_MAX];
108}; 105};
109 106
110extern struct boot_mem_map boot_mem_map; 107extern struct boot_mem_map boot_mem_map;
111 108
112extern void add_memory_region(phys_t start, phys_t size, long type); 109extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
113extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max); 110extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
114 111
115extern void prom_init(void); 112extern void prom_init(void);
116extern void prom_free_prom_memory(void); 113extern void prom_free_prom_memory(void);
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h
index 778e32d817bc..4809c29a4890 100644
--- a/arch/mips/include/asm/clock.h
+++ b/arch/mips/include/asm/clock.h
@@ -35,9 +35,6 @@ struct clk {
35#define CLK_ALWAYS_ENABLED (1 << 0) 35#define CLK_ALWAYS_ENABLED (1 << 0)
36#define CLK_RATE_PROPAGATES (1 << 1) 36#define CLK_RATE_PROPAGATES (1 << 1)
37 37
38/* Should be defined by processor-specific code */
39void arch_init_clk_ops(struct clk_ops **, int type);
40
41int clk_init(void); 38int clk_init(void);
42 39
43int __clk_enable(struct clk *); 40int __clk_enable(struct clk *);
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index eefcaa363a87..28b1edf19501 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -10,6 +10,7 @@
10 10
11#include <linux/bug.h> 11#include <linux/bug.h>
12#include <linux/irqflags.h> 12#include <linux/irqflags.h>
13#include <asm/compiler.h>
13#include <asm/war.h> 14#include <asm/war.h>
14 15
15static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) 16static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
@@ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
30 " sc %2, %1 \n" 31 " sc %2, %1 \n"
31 " beqzl %2, 1b \n" 32 " beqzl %2, 1b \n"
32 " .set mips0 \n" 33 " .set mips0 \n"
33 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 34 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy)
34 : "R" (*m), "Jr" (val) 35 : GCC_OFF12_ASM() (*m), "Jr" (val)
35 : "memory"); 36 : "memory");
36 } else if (kernel_uses_llsc) { 37 } else if (kernel_uses_llsc) {
37 unsigned long dummy; 38 unsigned long dummy;
@@ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
45 " .set arch=r4000 \n" 46 " .set arch=r4000 \n"
46 " sc %2, %1 \n" 47 " sc %2, %1 \n"
47 " .set mips0 \n" 48 " .set mips0 \n"
48 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 49 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m),
49 : "R" (*m), "Jr" (val) 50 "=&r" (dummy)
51 : GCC_OFF12_ASM() (*m), "Jr" (val)
50 : "memory"); 52 : "memory");
51 } while (unlikely(!dummy)); 53 } while (unlikely(!dummy));
52 } else { 54 } else {
@@ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
80 " scd %2, %1 \n" 82 " scd %2, %1 \n"
81 " beqzl %2, 1b \n" 83 " beqzl %2, 1b \n"
82 " .set mips0 \n" 84 " .set mips0 \n"
83 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 85 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy)
84 : "R" (*m), "Jr" (val) 86 : GCC_OFF12_ASM() (*m), "Jr" (val)
85 : "memory"); 87 : "memory");
86 } else if (kernel_uses_llsc) { 88 } else if (kernel_uses_llsc) {
87 unsigned long dummy; 89 unsigned long dummy;
@@ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
93 " move %2, %z4 \n" 95 " move %2, %z4 \n"
94 " scd %2, %1 \n" 96 " scd %2, %1 \n"
95 " .set mips0 \n" 97 " .set mips0 \n"
96 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 98 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m),
97 : "R" (*m), "Jr" (val) 99 "=&r" (dummy)
100 : GCC_OFF12_ASM() (*m), "Jr" (val)
98 : "memory"); 101 : "memory");
99 } while (unlikely(!dummy)); 102 } while (unlikely(!dummy));
100 } else { 103 } else {
@@ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
155 " beqzl $1, 1b \n" \ 158 " beqzl $1, 1b \n" \
156 "2: \n" \ 159 "2: \n" \
157 " .set pop \n" \ 160 " .set pop \n" \
158 : "=&r" (__ret), "=R" (*m) \ 161 : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \
159 : "R" (*m), "Jr" (old), "Jr" (new) \ 162 : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \
160 : "memory"); \ 163 : "memory"); \
161 } else if (kernel_uses_llsc) { \ 164 } else if (kernel_uses_llsc) { \
162 __asm__ __volatile__( \ 165 __asm__ __volatile__( \
@@ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
172 " beqz $1, 1b \n" \ 175 " beqz $1, 1b \n" \
173 " .set pop \n" \ 176 " .set pop \n" \
174 "2: \n" \ 177 "2: \n" \
175 : "=&r" (__ret), "=R" (*m) \ 178 : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \
176 : "R" (*m), "Jr" (old), "Jr" (new) \ 179 : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \
177 : "memory"); \ 180 : "memory"); \
178 } else { \ 181 } else { \
179 unsigned long __flags; \ 182 unsigned long __flags; \
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h
index 71f5c5cfc58a..c73815e0123a 100644
--- a/arch/mips/include/asm/compiler.h
+++ b/arch/mips/include/asm/compiler.h
@@ -16,4 +16,12 @@
16#define GCC_REG_ACCUM "accum" 16#define GCC_REG_ACCUM "accum"
17#endif 17#endif
18 18
19#ifndef CONFIG_CPU_MICROMIPS
20#define GCC_OFF12_ASM() "R"
21#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
22#define GCC_OFF12_ASM() "ZC"
23#else
24#error "microMIPS compilation unsupported with GCC older than 4.9"
25#endif
26
19#endif /* _ASM_COMPILER_H */ 27#endif /* _ASM_COMPILER_H */
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 3325f3eb248c..2897cfafcaf0 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -344,4 +344,8 @@
344# define cpu_has_msa 0 344# define cpu_has_msa 0
345#endif 345#endif
346 346
347#ifndef cpu_has_fre
348# define cpu_has_fre (cpu_data[0].options & MIPS_CPU_FRE)
349#endif
350
347#endif /* __ASM_CPU_FEATURES_H */ 351#endif /* __ASM_CPU_FEATURES_H */
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index dfdc77ed1839..33866fce4d63 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -142,6 +142,7 @@
142#define PRID_IMP_BMIPS3300_BUG 0x0000 142#define PRID_IMP_BMIPS3300_BUG 0x0000
143#define PRID_IMP_BMIPS43XX 0xa000 143#define PRID_IMP_BMIPS43XX 0xa000
144#define PRID_IMP_BMIPS5000 0x5a00 144#define PRID_IMP_BMIPS5000 0x5a00
145#define PRID_IMP_BMIPS5200 0x5b00
145 146
146#define PRID_REV_BMIPS4380_LO 0x0040 147#define PRID_REV_BMIPS4380_LO 0x0040
147#define PRID_REV_BMIPS4380_HI 0x006f 148#define PRID_REV_BMIPS4380_HI 0x006f
@@ -368,6 +369,7 @@ enum cpu_type_enum {
368#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ 369#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */
369#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ 370#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */
370#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ 371#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */
372#define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */
371 373
372/* 374/*
373 * CPU ASE encodings 375 * CPU ASE encodings
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h
index 4da0c1fe30d9..ae6fedcb0060 100644
--- a/arch/mips/include/asm/edac.h
+++ b/arch/mips/include/asm/edac.h
@@ -1,6 +1,8 @@
1#ifndef ASM_EDAC_H 1#ifndef ASM_EDAC_H
2#define ASM_EDAC_H 2#define ASM_EDAC_H
3 3
4#include <asm/compiler.h>
5
4/* ECC atomic, DMA, SMP and interrupt safe scrub function */ 6/* ECC atomic, DMA, SMP and interrupt safe scrub function */
5 7
6static inline void atomic_scrub(void *va, u32 size) 8static inline void atomic_scrub(void *va, u32 size)
@@ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size)
24 " sc %0, %1 \n" 26 " sc %0, %1 \n"
25 " beqz %0, 1b \n" 27 " beqz %0, 1b \n"
26 " .set mips0 \n" 28 " .set mips0 \n"
27 : "=&r" (temp), "=m" (*virt_addr) 29 : "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr)
28 : "m" (*virt_addr)); 30 : GCC_OFF12_ASM() (*virt_addr));
29 31
30 virt_addr++; 32 virt_addr++;
31 } 33 }
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index 1d38fe0edd2d..eb4d95de619c 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -8,6 +8,8 @@
8#ifndef _ASM_ELF_H 8#ifndef _ASM_ELF_H
9#define _ASM_ELF_H 9#define _ASM_ELF_H
10 10
11#include <linux/fs.h>
12#include <uapi/linux/elf.h>
11 13
12/* ELF header e_flags defines. */ 14/* ELF header e_flags defines. */
13/* MIPS architecture level. */ 15/* MIPS architecture level. */
@@ -28,6 +30,7 @@
28#define PT_MIPS_REGINFO 0x70000000 30#define PT_MIPS_REGINFO 0x70000000
29#define PT_MIPS_RTPROC 0x70000001 31#define PT_MIPS_RTPROC 0x70000001
30#define PT_MIPS_OPTIONS 0x70000002 32#define PT_MIPS_OPTIONS 0x70000002
33#define PT_MIPS_ABIFLAGS 0x70000003
31 34
32/* Flags in the e_flags field of the header */ 35/* Flags in the e_flags field of the header */
33#define EF_MIPS_NOREORDER 0x00000001 36#define EF_MIPS_NOREORDER 0x00000001
@@ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
174typedef double elf_fpreg_t; 177typedef double elf_fpreg_t;
175typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 178typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
176 179
180struct mips_elf_abiflags_v0 {
181 uint16_t version; /* Version of flags structure */
182 uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */
183 uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below,
184 1-n otherwise */
185 uint8_t gpr_size; /* The size of general purpose registers */
186 uint8_t cpr1_size; /* The size of co-processor 1 registers */
187 uint8_t cpr2_size; /* The size of co-processor 2 registers */
188 uint8_t fp_abi; /* The floating-point ABI */
189 uint32_t isa_ext; /* Mask of processor-specific extensions */
190 uint32_t ases; /* Mask of ASEs used */
191 uint32_t flags1; /* Mask of general flags */
192 uint32_t flags2;
193};
194
195#define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */
196#define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */
197#define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */
198#define MIPS_ABI_FP_SOFT 3 /* -msoft-float */
199#define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */
200#define MIPS_ABI_FP_XX 5 /* -mfpxx */
201#define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */
202#define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */
203
177#ifdef CONFIG_32BIT 204#ifdef CONFIG_32BIT
178 205
179/* 206/*
@@ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32;
262 289
263#ifdef CONFIG_32BIT 290#ifdef CONFIG_32BIT
264 291
265#define SET_PERSONALITY(ex) \ 292#define SET_PERSONALITY2(ex, state) \
266do { \ 293do { \
267 if ((ex).e_flags & EF_MIPS_FP64) \
268 clear_thread_flag(TIF_32BIT_FPREGS); \
269 else \
270 set_thread_flag(TIF_32BIT_FPREGS); \
271 \
272 if (personality(current->personality) != PER_LINUX) \ 294 if (personality(current->personality) != PER_LINUX) \
273 set_personality(PER_LINUX); \ 295 set_personality(PER_LINUX); \
274 \ 296 \
297 mips_set_personality_fp(state); \
298 \
275 current->thread.abi = &mips_abi; \ 299 current->thread.abi = &mips_abi; \
276} while (0) 300} while (0)
277 301
@@ -291,44 +315,44 @@ do { \
291#endif 315#endif
292 316
293#ifdef CONFIG_MIPS32_O32 317#ifdef CONFIG_MIPS32_O32
294#define __SET_PERSONALITY32_O32(ex) \ 318#define __SET_PERSONALITY32_O32(ex, state) \
295 do { \ 319 do { \
296 set_thread_flag(TIF_32BIT_REGS); \ 320 set_thread_flag(TIF_32BIT_REGS); \
297 set_thread_flag(TIF_32BIT_ADDR); \ 321 set_thread_flag(TIF_32BIT_ADDR); \
298 \ 322 \
299 if (!((ex).e_flags & EF_MIPS_FP64)) \ 323 mips_set_personality_fp(state); \
300 set_thread_flag(TIF_32BIT_FPREGS); \
301 \ 324 \
302 current->thread.abi = &mips_abi_32; \ 325 current->thread.abi = &mips_abi_32; \
303 } while (0) 326 } while (0)
304#else 327#else
305#define __SET_PERSONALITY32_O32(ex) \ 328#define __SET_PERSONALITY32_O32(ex, state) \
306 do { } while (0) 329 do { } while (0)
307#endif 330#endif
308 331
309#ifdef CONFIG_MIPS32_COMPAT 332#ifdef CONFIG_MIPS32_COMPAT
310#define __SET_PERSONALITY32(ex) \ 333#define __SET_PERSONALITY32(ex, state) \
311do { \ 334do { \
312 if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ 335 if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
313 ((ex).e_flags & EF_MIPS_ABI) == 0) \ 336 ((ex).e_flags & EF_MIPS_ABI) == 0) \
314 __SET_PERSONALITY32_N32(); \ 337 __SET_PERSONALITY32_N32(); \
315 else \ 338 else \
316 __SET_PERSONALITY32_O32(ex); \ 339 __SET_PERSONALITY32_O32(ex, state); \
317} while (0) 340} while (0)
318#else 341#else
319#define __SET_PERSONALITY32(ex) do { } while (0) 342#define __SET_PERSONALITY32(ex, state) do { } while (0)
320#endif 343#endif
321 344
322#define SET_PERSONALITY(ex) \ 345#define SET_PERSONALITY2(ex, state) \
323do { \ 346do { \
324 unsigned int p; \ 347 unsigned int p; \
325 \ 348 \
326 clear_thread_flag(TIF_32BIT_REGS); \ 349 clear_thread_flag(TIF_32BIT_REGS); \
327 clear_thread_flag(TIF_32BIT_FPREGS); \ 350 clear_thread_flag(TIF_32BIT_FPREGS); \
351 clear_thread_flag(TIF_HYBRID_FPREGS); \
328 clear_thread_flag(TIF_32BIT_ADDR); \ 352 clear_thread_flag(TIF_32BIT_ADDR); \
329 \ 353 \
330 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ 354 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
331 __SET_PERSONALITY32(ex); \ 355 __SET_PERSONALITY32(ex, state); \
332 else \ 356 else \
333 current->thread.abi = &mips_abi; \ 357 current->thread.abi = &mips_abi; \
334 \ 358 \
@@ -390,4 +414,24 @@ struct mm_struct;
390extern unsigned long arch_randomize_brk(struct mm_struct *mm); 414extern unsigned long arch_randomize_brk(struct mm_struct *mm);
391#define arch_randomize_brk arch_randomize_brk 415#define arch_randomize_brk arch_randomize_brk
392 416
417struct arch_elf_state {
418 int fp_abi;
419 int interp_fp_abi;
420 int overall_abi;
421};
422
423#define INIT_ARCH_ELF_STATE { \
424 .fp_abi = -1, \
425 .interp_fp_abi = -1, \
426 .overall_abi = -1, \
427}
428
429extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
430 bool is_interp, struct arch_elf_state *state);
431
432extern int arch_check_elf(void *ehdr, bool has_interpreter,
433 struct arch_elf_state *state);
434
435extern void mips_set_personality_fp(struct arch_elf_state *state);
436
393#endif /* _ASM_ELF_H */ 437#endif /* _ASM_ELF_H */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index dd562414cd5e..994d21939676 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *);
36 36
37/* 37/*
38 * This enum specifies a mode in which we want the FPU to operate, for cores 38 * This enum specifies a mode in which we want the FPU to operate, for cores
39 * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT 39 * which implement the Status.FR bit. Note that the bottom bit of the value
40 * purposefully have the values 0 & 1 respectively, so that an integer value 40 * purposefully matches the desired value of the Status.FR bit.
41 * of Status.FR can be trivially casted to the corresponding enum fpu_mode.
42 */ 41 */
43enum fpu_mode { 42enum fpu_mode {
44 FPU_32BIT = 0, /* FR = 0 */ 43 FPU_32BIT = 0, /* FR = 0 */
45 FPU_64BIT, /* FR = 1 */ 44 FPU_64BIT, /* FR = 1, FRE = 0 */
46 FPU_AS_IS, 45 FPU_AS_IS,
46 FPU_HYBRID, /* FR = 1, FRE = 1 */
47
48#define FPU_FR_MASK 0x1
47}; 49};
48 50
49static inline int __enable_fpu(enum fpu_mode mode) 51static inline int __enable_fpu(enum fpu_mode mode)
@@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode)
57 enable_fpu_hazard(); 59 enable_fpu_hazard();
58 return 0; 60 return 0;
59 61
62 case FPU_HYBRID:
63 if (!cpu_has_fre)
64 return SIGFPE;
65
66 /* set FRE */
67 write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE);
68 goto fr_common;
69
60 case FPU_64BIT: 70 case FPU_64BIT:
61#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) 71#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT))
62 /* we only have a 32-bit FPU */ 72 /* we only have a 32-bit FPU */
@@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode)
64#endif 74#endif
65 /* fall through */ 75 /* fall through */
66 case FPU_32BIT: 76 case FPU_32BIT:
77 /* clear FRE */
78 write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE);
79fr_common:
67 /* set CU1 & change FR appropriately */ 80 /* set CU1 & change FR appropriately */
68 fr = (int)mode; 81 fr = (int)mode & FPU_FR_MASK;
69 change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); 82 change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0));
70 enable_fpu_hazard(); 83 enable_fpu_hazard();
71 84
@@ -102,13 +115,17 @@ static inline int __own_fpu(void)
102 enum fpu_mode mode; 115 enum fpu_mode mode;
103 int ret; 116 int ret;
104 117
105 mode = !test_thread_flag(TIF_32BIT_FPREGS); 118 if (test_thread_flag(TIF_HYBRID_FPREGS))
119 mode = FPU_HYBRID;
120 else
121 mode = !test_thread_flag(TIF_32BIT_FPREGS);
122
106 ret = __enable_fpu(mode); 123 ret = __enable_fpu(mode);
107 if (ret) 124 if (ret)
108 return ret; 125 return ret;
109 126
110 KSTK_STATUS(current) |= ST0_CU1; 127 KSTK_STATUS(current) |= ST0_CU1;
111 if (mode == FPU_64BIT) 128 if (mode == FPU_64BIT || mode == FPU_HYBRID)
112 KSTK_STATUS(current) |= ST0_FR; 129 KSTK_STATUS(current) |= ST0_FR;
113 else /* mode == FPU_32BIT */ 130 else /* mode == FPU_32BIT */
114 KSTK_STATUS(current) &= ~ST0_FR; 131 KSTK_STATUS(current) &= ~ST0_FR;
@@ -166,8 +183,24 @@ static inline int init_fpu(void)
166 183
167 if (cpu_has_fpu) { 184 if (cpu_has_fpu) {
168 ret = __own_fpu(); 185 ret = __own_fpu();
169 if (!ret) 186 if (!ret) {
187 unsigned int config5 = read_c0_config5();
188
189 /*
190 * Ensure FRE is clear whilst running _init_fpu, since
191 * single precision FP instructions are used. If FRE
192 * was set then we'll just end up initialising all 32
193 * 64b registers.
194 */
195 write_c0_config5(config5 & ~MIPS_CONF5_FRE);
196 enable_fpu_hazard();
197
170 _init_fpu(); 198 _init_fpu();
199
200 /* Restore FRE */
201 write_c0_config5(config5);
202 enable_fpu_hazard();
203 }
171 } else 204 } else
172 fpu_emulator_init_fpu(); 205 fpu_emulator_init_fpu();
173 206
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
index 194cda0396a3..ef9987a61d88 100644
--- a/arch/mips/include/asm/futex.h
+++ b/arch/mips/include/asm/futex.h
@@ -14,6 +14,7 @@
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <asm/asm-eva.h> 15#include <asm/asm-eva.h>
16#include <asm/barrier.h> 16#include <asm/barrier.h>
17#include <asm/compiler.h>
17#include <asm/errno.h> 18#include <asm/errno.h>
18#include <asm/war.h> 19#include <asm/war.h>
19 20
@@ -32,6 +33,7 @@
32 " beqzl $1, 1b \n" \ 33 " beqzl $1, 1b \n" \
33 __WEAK_LLSC_MB \ 34 __WEAK_LLSC_MB \
34 "3: \n" \ 35 "3: \n" \
36 " .insn \n" \
35 " .set pop \n" \ 37 " .set pop \n" \
36 " .set mips0 \n" \ 38 " .set mips0 \n" \
37 " .section .fixup,\"ax\" \n" \ 39 " .section .fixup,\"ax\" \n" \
@@ -42,8 +44,10 @@
42 " "__UA_ADDR "\t1b, 4b \n" \ 44 " "__UA_ADDR "\t1b, 4b \n" \
43 " "__UA_ADDR "\t2b, 4b \n" \ 45 " "__UA_ADDR "\t2b, 4b \n" \
44 " .previous \n" \ 46 " .previous \n" \
45 : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ 47 : "=r" (ret), "=&r" (oldval), \
46 : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ 48 "=" GCC_OFF12_ASM() (*uaddr) \
49 : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \
50 "i" (-EFAULT) \
47 : "memory"); \ 51 : "memory"); \
48 } else if (cpu_has_llsc) { \ 52 } else if (cpu_has_llsc) { \
49 __asm__ __volatile__( \ 53 __asm__ __volatile__( \
@@ -58,6 +62,7 @@
58 " beqz $1, 1b \n" \ 62 " beqz $1, 1b \n" \
59 __WEAK_LLSC_MB \ 63 __WEAK_LLSC_MB \
60 "3: \n" \ 64 "3: \n" \
65 " .insn \n" \
61 " .set pop \n" \ 66 " .set pop \n" \
62 " .set mips0 \n" \ 67 " .set mips0 \n" \
63 " .section .fixup,\"ax\" \n" \ 68 " .section .fixup,\"ax\" \n" \
@@ -68,8 +73,10 @@
68 " "__UA_ADDR "\t1b, 4b \n" \ 73 " "__UA_ADDR "\t1b, 4b \n" \
69 " "__UA_ADDR "\t2b, 4b \n" \ 74 " "__UA_ADDR "\t2b, 4b \n" \
70 " .previous \n" \ 75 " .previous \n" \
71 : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ 76 : "=r" (ret), "=&r" (oldval), \
72 : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ 77 "=" GCC_OFF12_ASM() (*uaddr) \
78 : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \
79 "i" (-EFAULT) \
73 : "memory"); \ 80 : "memory"); \
74 } else \ 81 } else \
75 ret = -ENOSYS; \ 82 ret = -ENOSYS; \
@@ -157,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
157 " beqzl $1, 1b \n" 164 " beqzl $1, 1b \n"
158 __WEAK_LLSC_MB 165 __WEAK_LLSC_MB
159 "3: \n" 166 "3: \n"
167 " .insn \n"
160 " .set pop \n" 168 " .set pop \n"
161 " .section .fixup,\"ax\" \n" 169 " .section .fixup,\"ax\" \n"
162 "4: li %0, %6 \n" 170 "4: li %0, %6 \n"
@@ -166,8 +174,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
166 " "__UA_ADDR "\t1b, 4b \n" 174 " "__UA_ADDR "\t1b, 4b \n"
167 " "__UA_ADDR "\t2b, 4b \n" 175 " "__UA_ADDR "\t2b, 4b \n"
168 " .previous \n" 176 " .previous \n"
169 : "+r" (ret), "=&r" (val), "=R" (*uaddr) 177 : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr)
170 : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) 178 : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
179 "i" (-EFAULT)
171 : "memory"); 180 : "memory");
172 } else if (cpu_has_llsc) { 181 } else if (cpu_has_llsc) {
173 __asm__ __volatile__( 182 __asm__ __volatile__(
@@ -184,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
184 " beqz $1, 1b \n" 193 " beqz $1, 1b \n"
185 __WEAK_LLSC_MB 194 __WEAK_LLSC_MB
186 "3: \n" 195 "3: \n"
196 " .insn \n"
187 " .set pop \n" 197 " .set pop \n"
188 " .section .fixup,\"ax\" \n" 198 " .section .fixup,\"ax\" \n"
189 "4: li %0, %6 \n" 199 "4: li %0, %6 \n"
@@ -193,8 +203,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
193 " "__UA_ADDR "\t1b, 4b \n" 203 " "__UA_ADDR "\t1b, 4b \n"
194 " "__UA_ADDR "\t2b, 4b \n" 204 " "__UA_ADDR "\t2b, 4b \n"
195 " .previous \n" 205 " .previous \n"
196 : "+r" (ret), "=&r" (val), "=R" (*uaddr) 206 : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr)
197 : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) 207 : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
208 "i" (-EFAULT)
198 : "memory"); 209 : "memory");
199 } else 210 } else
200 return -ENOSYS; 211 return -ENOSYS;
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
deleted file mode 100644
index d7699cf7e135..000000000000
--- a/arch/mips/include/asm/gic.h
+++ /dev/null
@@ -1,384 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000, 07 MIPS Technologies, Inc.
7 *
8 * GIC Register Definitions
9 *
10 */
11#ifndef _ASM_GICREGS_H
12#define _ASM_GICREGS_H
13
14#include <linux/bitmap.h>
15#include <linux/threads.h>
16
17#include <irq.h>
18
19#undef GICISBYTELITTLEENDIAN
20
21/* Constants */
22#define GIC_POL_POS 1
23#define GIC_POL_NEG 0
24#define GIC_TRIG_EDGE 1
25#define GIC_TRIG_LEVEL 0
26
27#define MSK(n) ((1 << (n)) - 1)
28#define REG32(addr) (*(volatile unsigned int *) (addr))
29#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS)
30#define REGP(base, phys) REG32((unsigned long)(base) + (phys))
31
32/* Accessors */
33#define GIC_REG(segment, offset) \
34 REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
35#define GIC_REG_ADDR(segment, offset) \
36 REG32(_gic_base + segment##_##SECTION_OFS + offset)
37
38#define GIC_ABS_REG(segment, offset) \
39 (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
40#define GIC_REG_ABS_ADDR(segment, offset) \
41 (_gic_base + segment##_##SECTION_OFS + offset)
42
43#ifdef GICISBYTELITTLEENDIAN
44#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
45#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data))
46#else
47#define GICREAD(reg, data) ((data) = (reg))
48#define GICWRITE(reg, data) ((reg) = (data))
49#endif
50#define GICBIS(reg, mask, bits) \
51 do { u32 data; \
52 GICREAD(reg, data); \
53 data &= ~(mask); \
54 data |= ((bits) & (mask)); \
55 GICWRITE((reg), data); \
56 } while (0)
57
58
59/* GIC Address Space */
60#define SHARED_SECTION_OFS 0x0000
61#define SHARED_SECTION_SIZE 0x8000
62#define VPE_LOCAL_SECTION_OFS 0x8000
63#define VPE_LOCAL_SECTION_SIZE 0x4000
64#define VPE_OTHER_SECTION_OFS 0xc000
65#define VPE_OTHER_SECTION_SIZE 0x4000
66#define USM_VISIBLE_SECTION_OFS 0x10000
67#define USM_VISIBLE_SECTION_SIZE 0x10000
68
69/* Register Map for Shared Section */
70
71#define GIC_SH_CONFIG_OFS 0x0000
72
73/* Shared Global Counter */
74#define GIC_SH_COUNTER_31_00_OFS 0x0010
75#define GIC_SH_COUNTER_63_32_OFS 0x0014
76#define GIC_SH_REVISIONID_OFS 0x0020
77
78/* Interrupt Polarity */
79#define GIC_SH_POL_31_0_OFS 0x0100
80#define GIC_SH_POL_63_32_OFS 0x0104
81#define GIC_SH_POL_95_64_OFS 0x0108
82#define GIC_SH_POL_127_96_OFS 0x010c
83#define GIC_SH_POL_159_128_OFS 0x0110
84#define GIC_SH_POL_191_160_OFS 0x0114
85#define GIC_SH_POL_223_192_OFS 0x0118
86#define GIC_SH_POL_255_224_OFS 0x011c
87
88/* Edge/Level Triggering */
89#define GIC_SH_TRIG_31_0_OFS 0x0180
90#define GIC_SH_TRIG_63_32_OFS 0x0184
91#define GIC_SH_TRIG_95_64_OFS 0x0188
92#define GIC_SH_TRIG_127_96_OFS 0x018c
93#define GIC_SH_TRIG_159_128_OFS 0x0190
94#define GIC_SH_TRIG_191_160_OFS 0x0194
95#define GIC_SH_TRIG_223_192_OFS 0x0198
96#define GIC_SH_TRIG_255_224_OFS 0x019c
97
98/* Dual Edge Triggering */
99#define GIC_SH_DUAL_31_0_OFS 0x0200
100#define GIC_SH_DUAL_63_32_OFS 0x0204
101#define GIC_SH_DUAL_95_64_OFS 0x0208
102#define GIC_SH_DUAL_127_96_OFS 0x020c
103#define GIC_SH_DUAL_159_128_OFS 0x0210
104#define GIC_SH_DUAL_191_160_OFS 0x0214
105#define GIC_SH_DUAL_223_192_OFS 0x0218
106#define GIC_SH_DUAL_255_224_OFS 0x021c
107
108/* Set/Clear corresponding bit in Edge Detect Register */
109#define GIC_SH_WEDGE_OFS 0x0280
110
111/* Reset Mask - Disables Interrupt */
112#define GIC_SH_RMASK_31_0_OFS 0x0300
113#define GIC_SH_RMASK_63_32_OFS 0x0304
114#define GIC_SH_RMASK_95_64_OFS 0x0308
115#define GIC_SH_RMASK_127_96_OFS 0x030c
116#define GIC_SH_RMASK_159_128_OFS 0x0310
117#define GIC_SH_RMASK_191_160_OFS 0x0314
118#define GIC_SH_RMASK_223_192_OFS 0x0318
119#define GIC_SH_RMASK_255_224_OFS 0x031c
120
121/* Set Mask (WO) - Enables Interrupt */
122#define GIC_SH_SMASK_31_0_OFS 0x0380
123#define GIC_SH_SMASK_63_32_OFS 0x0384
124#define GIC_SH_SMASK_95_64_OFS 0x0388
125#define GIC_SH_SMASK_127_96_OFS 0x038c
126#define GIC_SH_SMASK_159_128_OFS 0x0390
127#define GIC_SH_SMASK_191_160_OFS 0x0394
128#define GIC_SH_SMASK_223_192_OFS 0x0398
129#define GIC_SH_SMASK_255_224_OFS 0x039c
130
131/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
132#define GIC_SH_MASK_31_0_OFS 0x0400
133#define GIC_SH_MASK_63_32_OFS 0x0404
134#define GIC_SH_MASK_95_64_OFS 0x0408
135#define GIC_SH_MASK_127_96_OFS 0x040c
136#define GIC_SH_MASK_159_128_OFS 0x0410
137#define GIC_SH_MASK_191_160_OFS 0x0414
138#define GIC_SH_MASK_223_192_OFS 0x0418
139#define GIC_SH_MASK_255_224_OFS 0x041c
140
141/* Pending Global Interrupts (RO) */
142#define GIC_SH_PEND_31_0_OFS 0x0480
143#define GIC_SH_PEND_63_32_OFS 0x0484
144#define GIC_SH_PEND_95_64_OFS 0x0488
145#define GIC_SH_PEND_127_96_OFS 0x048c
146#define GIC_SH_PEND_159_128_OFS 0x0490
147#define GIC_SH_PEND_191_160_OFS 0x0494
148#define GIC_SH_PEND_223_192_OFS 0x0498
149#define GIC_SH_PEND_255_224_OFS 0x049c
150
151#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
152
153/* Maps Interrupt X to a Pin */
154#define GIC_SH_MAP_TO_PIN(intr) \
155 (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr))
156
157#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
158
159/* Maps Interrupt X to a VPE */
160#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
161 (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4))
162#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
163
164/* Convert an interrupt number to a byte offset/bit for multi-word registers */
165#define GIC_INTR_OFS(intr) (((intr) / 32)*4)
166#define GIC_INTR_BIT(intr) ((intr) % 32)
167
168/* Polarity : Reset Value is always 0 */
169#define GIC_SH_SET_POLARITY_OFS 0x0100
170#define GIC_SET_POLARITY(intr, pol) \
171 GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
172 GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
173 (pol) << GIC_INTR_BIT(intr))
174
175/* Triggering : Reset Value is always 0 */
176#define GIC_SH_SET_TRIGGER_OFS 0x0180
177#define GIC_SET_TRIGGER(intr, trig) \
178 GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
179 GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
180 (trig) << GIC_INTR_BIT(intr))
181
182/* Mask manipulation */
183#define GIC_SH_SMASK_OFS 0x0380
184#define GIC_SET_INTR_MASK(intr) \
185 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \
186 GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
187#define GIC_SH_RMASK_OFS 0x0300
188#define GIC_CLR_INTR_MASK(intr) \
189 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \
190 GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
191
192/* Register Map for Local Section */
193#define GIC_VPE_CTL_OFS 0x0000
194#define GIC_VPE_PEND_OFS 0x0004
195#define GIC_VPE_MASK_OFS 0x0008
196#define GIC_VPE_RMASK_OFS 0x000c
197#define GIC_VPE_SMASK_OFS 0x0010
198#define GIC_VPE_WD_MAP_OFS 0x0040
199#define GIC_VPE_COMPARE_MAP_OFS 0x0044
200#define GIC_VPE_TIMER_MAP_OFS 0x0048
201#define GIC_VPE_PERFCTR_MAP_OFS 0x0050
202#define GIC_VPE_SWINT0_MAP_OFS 0x0054
203#define GIC_VPE_SWINT1_MAP_OFS 0x0058
204#define GIC_VPE_OTHER_ADDR_OFS 0x0080
205#define GIC_VPE_WD_CONFIG0_OFS 0x0090
206#define GIC_VPE_WD_COUNT0_OFS 0x0094
207#define GIC_VPE_WD_INITIAL0_OFS 0x0098
208#define GIC_VPE_COMPARE_LO_OFS 0x00a0
209#define GIC_VPE_COMPARE_HI_OFS 0x00a4
210
211#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
212#define GIC_VPE_EIC_SS(intr) \
213 (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr))
214
215#define GIC_VPE_EIC_VEC_BASE 0x0800
216#define GIC_VPE_EIC_VEC(intr) \
217 (GIC_VPE_EIC_VEC_BASE + (4 * intr))
218
219#define GIC_VPE_TENABLE_NMI_OFS 0x1000
220#define GIC_VPE_TENABLE_YQ_OFS 0x1004
221#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080
222#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084
223
224/* User Mode Visible Section Register Map */
225#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000
226#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004
227
228/* Masks */
229#define GIC_SH_CONFIG_COUNTSTOP_SHF 28
230#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
231
232#define GIC_SH_CONFIG_COUNTBITS_SHF 24
233#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
234
235#define GIC_SH_CONFIG_NUMINTRS_SHF 16
236#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
237
238#define GIC_SH_CONFIG_NUMVPES_SHF 0
239#define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF)
240
241#define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31))
242#define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31))
243
244#define GIC_MAP_TO_PIN_SHF 31
245#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF)
246#define GIC_MAP_TO_NMI_SHF 30
247#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF)
248#define GIC_MAP_TO_YQ_SHF 29
249#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF)
250#define GIC_MAP_SHF 0
251#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF)
252
253/* GIC_VPE_CTL Masks */
254#define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2
255#define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF)
256#define GIC_VPE_CTL_TIMER_RTBL_SHF 1
257#define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF)
258#define GIC_VPE_CTL_EIC_MODE_SHF 0
259#define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
260
261/* GIC_VPE_PEND Masks */
262#define GIC_VPE_PEND_WD_SHF 0
263#define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF)
264#define GIC_VPE_PEND_CMP_SHF 1
265#define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF)
266#define GIC_VPE_PEND_TIMER_SHF 2
267#define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF)
268#define GIC_VPE_PEND_PERFCOUNT_SHF 3
269#define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF)
270#define GIC_VPE_PEND_SWINT0_SHF 4
271#define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
272#define GIC_VPE_PEND_SWINT1_SHF 5
273#define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
274
275/* GIC_VPE_RMASK Masks */
276#define GIC_VPE_RMASK_WD_SHF 0
277#define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF)
278#define GIC_VPE_RMASK_CMP_SHF 1
279#define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF)
280#define GIC_VPE_RMASK_TIMER_SHF 2
281#define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF)
282#define GIC_VPE_RMASK_PERFCNT_SHF 3
283#define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF)
284#define GIC_VPE_RMASK_SWINT0_SHF 4
285#define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
286#define GIC_VPE_RMASK_SWINT1_SHF 5
287#define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
288
289/* GIC_VPE_SMASK Masks */
290#define GIC_VPE_SMASK_WD_SHF 0
291#define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF)
292#define GIC_VPE_SMASK_CMP_SHF 1
293#define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF)
294#define GIC_VPE_SMASK_TIMER_SHF 2
295#define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF)
296#define GIC_VPE_SMASK_PERFCNT_SHF 3
297#define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF)
298#define GIC_VPE_SMASK_SWINT0_SHF 4
299#define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
300#define GIC_VPE_SMASK_SWINT1_SHF 5
301#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
302
303/*
304 * Set the Mapping of Interrupt X to a VPE.
305 */
306#define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \
307 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \
308 GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
309
310/*
311 * Interrupt Meta-data specification. The ipiflag helps
312 * in building ipi_map.
313 */
314struct gic_intr_map {
315 unsigned int cpunum; /* Directed to this CPU */
316#define GIC_UNUSED 0xdead /* Dummy data */
317 unsigned int pin; /* Directed to this Pin */
318 unsigned int polarity; /* Polarity : +/- */
319 unsigned int trigtype; /* Trigger : Edge/Levl */
320 unsigned int flags; /* Misc flags */
321#define GIC_FLAG_TRANSPARENT 0x01
322};
323
324/*
325 * This is only used in EIC mode. This helps to figure out which
326 * shared interrupts we need to process when we get a vector interrupt.
327 */
328#define GIC_MAX_SHARED_INTR 0x5
329struct gic_shared_intr_map {
330 unsigned int num_shared_intr;
331 unsigned int intr_list[GIC_MAX_SHARED_INTR];
332 unsigned int local_intr_mask;
333};
334
335/* GIC nomenclature for Core Interrupt Pins. */
336#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
337#define GIC_CPU_INT1 1 /* . */
338#define GIC_CPU_INT2 2 /* . */
339#define GIC_CPU_INT3 3 /* . */
340#define GIC_CPU_INT4 4 /* . */
341#define GIC_CPU_INT5 5 /* Core Interrupt 7 */
342
343/* Local GIC interrupts. */
344#define GIC_INT_TMR (GIC_CPU_INT5)
345#define GIC_INT_PERFCTR (GIC_CPU_INT5)
346
347/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
348#define GIC_CPU_TO_VEC_OFFSET (2)
349
350/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
351#define GIC_PIN_TO_VEC_OFFSET (1)
352
353#include <linux/clocksource.h>
354#include <linux/irq.h>
355
356extern unsigned int gic_present;
357extern unsigned int gic_frequency;
358extern unsigned long _gic_base;
359extern unsigned int gic_irq_base;
360extern unsigned int gic_irq_flags[];
361extern struct gic_shared_intr_map gic_shared_intr_map[];
362
363extern void gic_init(unsigned long gic_base_addr,
364 unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
365 unsigned int intrmap_size, unsigned int irqbase);
366extern void gic_clocksource_init(unsigned int);
367extern unsigned int gic_compare_int (void);
368extern cycle_t gic_read_count(void);
369extern cycle_t gic_read_compare(void);
370extern void gic_write_compare(cycle_t cnt);
371extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
372extern void gic_send_ipi(unsigned int intr);
373extern unsigned int plat_ipi_call_int_xlate(unsigned int);
374extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
375extern void gic_bind_eic_interrupt(int irq, int set);
376extern unsigned int gic_get_timer_pending(void);
377extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src);
378extern unsigned int gic_get_int(void);
379extern void gic_enable_interrupt(int irq_vec);
380extern void gic_disable_interrupt(int irq_vec);
381extern void gic_irq_ack(struct irq_data *d);
382extern void gic_finish_irq(struct irq_data *d);
383extern void gic_platform_init(int irqs, struct irq_chip *irq_controller);
384#endif /* _ASM_GICREGS_H */
diff --git a/arch/mips/include/asm/hpet.h b/arch/mips/include/asm/hpet.h
new file mode 100644
index 000000000000..18a8f778bfaa
--- /dev/null
+++ b/arch/mips/include/asm/hpet.h
@@ -0,0 +1,73 @@
1#ifndef _ASM_HPET_H
2#define _ASM_HPET_H
3
4#ifdef CONFIG_RS780_HPET
5
6#define HPET_MMAP_SIZE 1024
7
8#define HPET_ID 0x000
9#define HPET_PERIOD 0x004
10#define HPET_CFG 0x010
11#define HPET_STATUS 0x020
12#define HPET_COUNTER 0x0f0
13
14#define HPET_Tn_CFG(n) (0x100 + 0x20 * n)
15#define HPET_Tn_CMP(n) (0x108 + 0x20 * n)
16#define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n)
17
18#define HPET_T0_IRS 0x001
19#define HPET_T1_IRS 0x002
20#define HPET_T3_IRS 0x004
21
22#define HPET_T0_CFG 0x100
23#define HPET_T0_CMP 0x108
24#define HPET_T0_ROUTE 0x110
25#define HPET_T1_CFG 0x120
26#define HPET_T1_CMP 0x128
27#define HPET_T1_ROUTE 0x130
28#define HPET_T2_CFG 0x140
29#define HPET_T2_CMP 0x148
30#define HPET_T2_ROUTE 0x150
31
32#define HPET_ID_REV 0x000000ff
33#define HPET_ID_NUMBER 0x00001f00
34#define HPET_ID_64BIT 0x00002000
35#define HPET_ID_LEGSUP 0x00008000
36#define HPET_ID_VENDOR 0xffff0000
37#define HPET_ID_NUMBER_SHIFT 8
38#define HPET_ID_VENDOR_SHIFT 16
39
40#define HPET_CFG_ENABLE 0x001
41#define HPET_CFG_LEGACY 0x002
42#define HPET_LEGACY_8254 2
43#define HPET_LEGACY_RTC 8
44
45#define HPET_TN_LEVEL 0x0002
46#define HPET_TN_ENABLE 0x0004
47#define HPET_TN_PERIODIC 0x0008
48#define HPET_TN_PERIODIC_CAP 0x0010
49#define HPET_TN_64BIT_CAP 0x0020
50#define HPET_TN_SETVAL 0x0040
51#define HPET_TN_32BIT 0x0100
52#define HPET_TN_ROUTE 0x3e00
53#define HPET_TN_FSB 0x4000
54#define HPET_TN_FSB_CAP 0x8000
55#define HPET_TN_ROUTE_SHIFT 9
56
57/* Max HPET Period is 10^8 femto sec as in HPET spec */
58#define HPET_MAX_PERIOD 100000000UL
59/*
60 * Min HPET period is 10^5 femto sec just for safety. If it is less than this,
61 * then 32 bit HPET counter wrapsaround in less than 0.5 sec.
62 */
63#define HPET_MIN_PERIOD 100000UL
64
65#define HPET_ADDR 0x20000
66#define HPET_MMIO_ADDR 0x90000e0000020000
67#define HPET_FREQ 14318780
68#define HPET_COMPARE_VAL ((HPET_FREQ + HZ / 2) / HZ)
69#define HPET_T0_IRQ 0
70
71extern void __init setup_hpet_timer(void);
72#endif /* CONFIG_RS780_HPET */
73#endif /* _ASM_HPET_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 933b50e125a0..9e777cd42b67 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address)
167 */ 167 */
168#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) 168#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
169 169
170extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); 170extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
171extern void __iounmap(const volatile void __iomem *addr); 171extern void __iounmap(const volatile void __iomem *addr);
172 172
173#ifndef CONFIG_PCI 173#ifndef CONFIG_PCI
@@ -175,7 +175,7 @@ struct pci_dev;
175static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} 175static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
176#endif 176#endif
177 177
178static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, 178static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size,
179 unsigned long flags) 179 unsigned long flags)
180{ 180{
181 void __iomem *addr = plat_ioremap(offset, size, flags); 181 void __iomem *addr = plat_ioremap(offset, size, flags);
@@ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
183 if (addr) 183 if (addr)
184 return addr; 184 return addr;
185 185
186#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) 186#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
187 187
188 if (cpu_has_64bit_addresses) { 188 if (cpu_has_64bit_addresses) {
189 u64 base = UNCAC_BASE; 189 u64 base = UNCAC_BASE;
@@ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
197 return (void __iomem *) (unsigned long) (base + offset); 197 return (void __iomem *) (unsigned long) (base + offset);
198 } else if (__builtin_constant_p(offset) && 198 } else if (__builtin_constant_p(offset) &&
199 __builtin_constant_p(size) && __builtin_constant_p(flags)) { 199 __builtin_constant_p(size) && __builtin_constant_p(flags)) {
200 phys_t phys_addr, last_addr; 200 phys_addr_t phys_addr, last_addr;
201 201
202 phys_addr = fixup_bigphys_addr(offset, size); 202 phys_addr = fixup_bigphys_addr(offset, size);
203 203
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 39f07aec640c..5a4e1bb8fb1b 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -48,4 +48,7 @@ extern int cp0_compare_irq;
48extern int cp0_compare_irq_shift; 48extern int cp0_compare_irq_shift;
49extern int cp0_perfcount_irq; 49extern int cp0_perfcount_irq;
50 50
51void arch_trigger_all_cpu_backtrace(bool);
52#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
53
51#endif /* _ASM_IRQ_H */ 54#endif /* _ASM_IRQ_H */
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h
index 3f11fdb3ed8c..39a160bb41dc 100644
--- a/arch/mips/include/asm/irq_cpu.h
+++ b/arch/mips/include/asm/irq_cpu.h
@@ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void);
19 19
20#ifdef CONFIG_IRQ_DOMAIN 20#ifdef CONFIG_IRQ_DOMAIN
21struct device_node; 21struct device_node;
22extern int mips_cpu_intc_init(struct device_node *of_node, 22extern int mips_cpu_irq_of_init(struct device_node *of_node,
23 struct device_node *parent); 23 struct device_node *parent);
24#endif 24#endif
25 25
26#endif /* _ASM_IRQ_CPU_H */ 26#endif /* _ASM_IRQ_CPU_H */
diff --git a/arch/mips/include/asm/mach-ath25/ath25_platform.h b/arch/mips/include/asm/mach-ath25/ath25_platform.h
new file mode 100644
index 000000000000..4f4ee4f9e5ec
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h
@@ -0,0 +1,73 @@
1#ifndef __ASM_MACH_ATH25_PLATFORM_H
2#define __ASM_MACH_ATH25_PLATFORM_H
3
4#include <linux/etherdevice.h>
5
6/*
7 * This is board-specific data that is stored in a "fixed" location in flash.
8 * It is shared across operating systems, so it should not be changed lightly.
9 * The main reason we need it is in order to extract the ethernet MAC
10 * address(es).
11 */
12struct ath25_boarddata {
13 u32 magic; /* board data is valid */
14#define ATH25_BD_MAGIC 0x35333131 /* "5311", for all 531x/231x platforms */
15 u16 cksum; /* checksum (starting with BD_REV 2) */
16 u16 rev; /* revision of this struct */
17#define BD_REV 4
18 char board_name[64]; /* Name of board */
19 u16 major; /* Board major number */
20 u16 minor; /* Board minor number */
21 u32 flags; /* Board configuration */
22#define BD_ENET0 0x00000001 /* ENET0 is stuffed */
23#define BD_ENET1 0x00000002 /* ENET1 is stuffed */
24#define BD_UART1 0x00000004 /* UART1 is stuffed */
25#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */
26#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */
27#define BD_SYSLED 0x00000020 /* System LED stuffed */
28#define BD_EXTUARTCLK 0x00000040 /* External UART clock */
29#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */
30#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */
31#define BD_WLAN0 0x00000200 /* Enable WLAN0 */
32#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ mem_cap for testing */
33#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */
34#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */
35#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */
36#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */
37#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */
38#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */
39#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */
40 u16 reset_config_gpio; /* Reset factory GPIO pin */
41 u16 sys_led_gpio; /* System LED GPIO pin */
42
43 u32 cpu_freq; /* CPU core frequency in Hz */
44 u32 sys_freq; /* System frequency in Hz */
45 u32 cnt_freq; /* Calculated C0_COUNT frequency */
46
47 u8 wlan0_mac[ETH_ALEN];
48 u8 enet0_mac[ETH_ALEN];
49 u8 enet1_mac[ETH_ALEN];
50
51 u16 pci_id; /* Pseudo PCIID for common code */
52 u16 mem_cap; /* cap bank1 in MB */
53
54 /* version 3 */
55 u8 wlan1_mac[ETH_ALEN]; /* (ar5212) */
56};
57
58#define BOARD_CONFIG_BUFSZ 0x1000
59
60/*
61 * Platform device information for the Wireless MAC
62 */
63struct ar231x_board_config {
64 u16 devid;
65
66 /* board config data */
67 struct ath25_boarddata *config;
68
69 /* radio calibration data */
70 const char *radio;
71};
72
73#endif /* __ASM_MACH_ATH25_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
new file mode 100644
index 000000000000..ade0356df257
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
@@ -0,0 +1,64 @@
1/*
2 * Atheros AR231x/AR531x SoC specific CPU feature overrides
3 *
4 * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
5 *
6 * This file was derived from: include/asm-mips/cpu-features.h
7 * Copyright (C) 2003, 2004 Ralf Baechle
8 * Copyright (C) 2004 Maciej W. Rozycki
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 *
14 */
15#ifndef __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H
16#define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H
17
18/*
19 * The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core.
20 */
21#define cpu_has_tlb 1
22#define cpu_has_4kex 1
23#define cpu_has_3k_cache 0
24#define cpu_has_4k_cache 1
25#define cpu_has_tx39_cache 0
26#define cpu_has_sb1_cache 0
27#define cpu_has_fpu 0
28#define cpu_has_32fpr 0
29#define cpu_has_counter 1
30#define cpu_has_ejtag 1
31
32#if !defined(CONFIG_SOC_AR5312)
33# define cpu_has_llsc 1
34#else
35/*
36 * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the
37 * ll/sc instructions.
38 */
39# define cpu_has_llsc 0
40#endif
41
42#define cpu_has_mips16 0
43#define cpu_has_mdmx 0
44#define cpu_has_mips3d 0
45#define cpu_has_smartmips 0
46
47#define cpu_has_mips32r1 1
48
49#if !defined(CONFIG_SOC_AR5312)
50# define cpu_has_mips32r2 1
51#endif
52
53#define cpu_has_mips64r1 0
54#define cpu_has_mips64r2 0
55
56#define cpu_has_dsp 0
57#define cpu_has_mipsmt 0
58
59#define cpu_has_64bits 0
60#define cpu_has_64bit_zero_reg 0
61#define cpu_has_64bit_gp_regs 0
62#define cpu_has_64bit_addresses 0
63
64#endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h
new file mode 100644
index 000000000000..d8009c93a465
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h
@@ -0,0 +1,82 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
7 * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
8 *
9 */
10#ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H
11#define __ASM_MACH_ATH25_DMA_COHERENCE_H
12
13#include <linux/device.h>
14
15/*
16 * We need some arbitrary non-zero value to be programmed to the BAR1 register
17 * of PCI host controller to enable DMA. The same value should be used as the
18 * offset to calculate the physical address of DMA buffer for PCI devices.
19 */
20#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000
21
22static inline dma_addr_t ath25_dev_offset(struct device *dev)
23{
24#ifdef CONFIG_PCI
25 extern struct bus_type pci_bus_type;
26
27 if (dev && dev->bus == &pci_bus_type)
28 return AR2315_PCI_HOST_SDRAM_BASEADDR;
29#endif
30 return 0;
31}
32
33static inline dma_addr_t
34plat_map_dma_mem(struct device *dev, void *addr, size_t size)
35{
36 return virt_to_phys(addr) + ath25_dev_offset(dev);
37}
38
39static inline dma_addr_t
40plat_map_dma_mem_page(struct device *dev, struct page *page)
41{
42 return page_to_phys(page) + ath25_dev_offset(dev);
43}
44
45static inline unsigned long
46plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
47{
48 return dma_addr - ath25_dev_offset(dev);
49}
50
51static inline void
52plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size,
53 enum dma_data_direction direction)
54{
55}
56
57static inline int plat_dma_supported(struct device *dev, u64 mask)
58{
59 return 1;
60}
61
62static inline void plat_extra_sync_for_device(struct device *dev)
63{
64}
65
66static inline int plat_dma_mapping_error(struct device *dev,
67 dma_addr_t dma_addr)
68{
69 return 0;
70}
71
72static inline int plat_device_is_coherent(struct device *dev)
73{
74#ifdef CONFIG_DMA_COHERENT
75 return 1;
76#endif
77#ifdef CONFIG_DMA_NONCOHERENT
78 return 0;
79#endif
80}
81
82#endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-ath25/gpio.h b/arch/mips/include/asm/mach-ath25/gpio.h
new file mode 100644
index 000000000000..713564b8e8ef
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/gpio.h
@@ -0,0 +1,16 @@
1#ifndef __ASM_MACH_ATH25_GPIO_H
2#define __ASM_MACH_ATH25_GPIO_H
3
4#include <asm-generic/gpio.h>
5
6#define gpio_get_value __gpio_get_value
7#define gpio_set_value __gpio_set_value
8#define gpio_cansleep __gpio_cansleep
9#define gpio_to_irq __gpio_to_irq
10
11static inline int irq_to_gpio(unsigned irq)
12{
13 return -EINVAL;
14}
15
16#endif /* __ASM_MACH_ATH25_GPIO_H */
diff --git a/arch/mips/include/asm/mach-ath25/war.h b/arch/mips/include/asm/mach-ath25/war.h
new file mode 100644
index 000000000000..e3a5250ebd67
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/war.h
@@ -0,0 +1,25 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
7 */
8#ifndef __ASM_MACH_ATH25_WAR_H
9#define __ASM_MACH_ATH25_WAR_H
10
11#define R4600_V1_INDEX_ICACHEOP_WAR 0
12#define R4600_V1_HIT_CACHEOP_WAR 0
13#define R4600_V2_HIT_CACHEOP_WAR 0
14#define R5432_CP0_INTERRUPT_WAR 0
15#define BCM1250_M3_WAR 0
16#define SIBYTE_1956_WAR 0
17#define MIPS4K_ICACHE_REFILL_WAR 0
18#define MIPS_CACHE_SYNC_WAR 0
19#define TX49XX_ICACHE_INDEX_INV_WAR 0
20#define RM9000_CDEX_SMP_WAR 0
21#define ICACHE_REFILLS_WORKAROUND_WAR 0
22#define R10000_LLSC_WAR 0
23#define MIPS34K_MISSED_ITLB_WAR 0
24
25#endif /* __ASM_MACH_ATH25_WAR_H */
diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h
index 75a94ad3ac91..99fea1fbb4f5 100644
--- a/arch/mips/include/asm/mach-au1x00/ioremap.h
+++ b/arch/mips/include/asm/mach-au1x00/ioremap.h
@@ -11,10 +11,10 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13 13
14#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) 14#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
15extern phys_t __fixup_bigphys_addr(phys_t, phys_t); 15extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t);
16#else 16#else
17static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) 17static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
18{ 18{
19 return phys_addr; 19 return phys_addr;
20} 20}
@@ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
23/* 23/*
24 * Allow physical addresses to be fixed up to help 36-bit peripherals. 24 * Allow physical addresses to be fixed up to help 36-bit peripherals.
25 */ 25 */
26static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 26static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
27{ 27{
28 return __fixup_bigphys_addr(phys_addr, size); 28 return __fixup_bigphys_addr(phys_addr, size);
29} 29}
30 30
31static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 31static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
32 unsigned long flags) 32 unsigned long flags)
33{ 33{
34 return NULL; 34 return NULL;
diff --git a/arch/mips/include/asm/mach-bcm3384/dma-coherence.h b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h
new file mode 100644
index 000000000000..a3be8e50e1f0
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
3 * Copyright (C) 2009 Broadcom Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
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
15#ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H
16#define __ASM_MACH_BCM3384_DMA_COHERENCE_H
17
18struct device;
19
20extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size);
21extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page);
22extern unsigned long plat_dma_addr_to_phys(struct device *dev,
23 dma_addr_t dma_addr);
24
25static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
26 size_t size, enum dma_data_direction direction)
27{
28}
29
30static inline int plat_dma_supported(struct device *dev, u64 mask)
31{
32 /*
33 * we fall back to GFP_DMA when the mask isn't all 1s,
34 * so we can't guarantee allocations that must be
35 * within a tighter range than GFP_DMA..
36 */
37 if (mask < DMA_BIT_MASK(24))
38 return 0;
39
40 return 1;
41}
42
43static inline int plat_device_is_coherent(struct device *dev)
44{
45 return 0;
46}
47
48#endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-bcm3384/war.h b/arch/mips/include/asm/mach-bcm3384/war.h
new file mode 100644
index 000000000000..59d7599059b0
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm3384/war.h
@@ -0,0 +1,24 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
7 */
8#ifndef __ASM_MIPS_MACH_BCM3384_WAR_H
9#define __ASM_MIPS_MACH_BCM3384_WAR_H
10
11#define R4600_V1_INDEX_ICACHEOP_WAR 0
12#define R4600_V1_HIT_CACHEOP_WAR 0
13#define R4600_V2_HIT_CACHEOP_WAR 0
14#define R5432_CP0_INTERRUPT_WAR 0
15#define BCM1250_M3_WAR 0
16#define SIBYTE_1956_WAR 0
17#define MIPS4K_ICACHE_REFILL_WAR 0
18#define MIPS_CACHE_SYNC_WAR 0
19#define TX49XX_ICACHE_INDEX_INV_WAR 0
20#define ICACHE_REFILLS_WORKAROUND_WAR 0
21#define R10000_LLSC_WAR 0
22#define MIPS34K_MISSED_ITLB_WAR 0
23
24#endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
index 36a3fc1aa3ae..ee59ffe99922 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
@@ -14,40 +14,8 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16 16
17struct nvram_header { 17int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
18 u32 magic; 18int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
19 u32 len;
20 u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
21 u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
22 u32 config_ncdl; /* ncdl values for memc */
23};
24
25#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
26#define NVRAM_VERSION 1
27#define NVRAM_HEADER_SIZE 20
28#define NVRAM_SPACE 0x8000
29
30#define FLASH_MIN 0x00020000 /* Minimum flash size */
31
32#define NVRAM_MAX_VALUE_LEN 255
33#define NVRAM_MAX_PARAM_LEN 64
34
35extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len);
36
37static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
38{
39 if (strchr(buf, ':'))
40 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
41 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
42 &macaddr[5]);
43 else if (strchr(buf, '-'))
44 sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
45 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
46 &macaddr[5]);
47 else
48 printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
49}
50
51int bcm47xx_nvram_gpio_pin(const char *name); 19int bcm47xx_nvram_gpio_pin(const char *name);
52 20
53#endif /* __BCM47XX_NVRAM_H */ 21#endif /* __BCM47XX_NVRAM_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
index ff15e3b14e7a..aea6e64b828f 100644
--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -3,12 +3,12 @@
3 3
4#include <bcm63xx_cpu.h> 4#include <bcm63xx_cpu.h>
5 5
6static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 6static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
7{ 7{
8 return phys_addr; 8 return phys_addr;
9} 9}
10 10
11static inline int is_bcm63xx_internal_registers(phys_t offset) 11static inline int is_bcm63xx_internal_registers(phys_addr_t offset)
12{ 12{
13 switch (bcm63xx_get_cpu_id()) { 13 switch (bcm63xx_get_cpu_id()) {
14 case BCM3368_CPU_ID: 14 case BCM3368_CPU_ID:
@@ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset)
32 return 0; 32 return 0;
33} 33}
34 34
35static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 35static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
36 unsigned long flags) 36 unsigned long flags)
37{ 37{
38 if (is_bcm63xx_internal_registers(offset)) 38 if (is_bcm63xx_internal_registers(offset))
diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h
index b379938d47f0..513371f7c39c 100644
--- a/arch/mips/include/asm/mach-generic/ioremap.h
+++ b/arch/mips/include/asm/mach-generic/ioremap.h
@@ -15,12 +15,12 @@
15 * Allow physical addresses to be fixed up to help peripherals located 15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version. 16 * outside the low 32-bit range -- generic pass-through version.
17 */ 17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 18static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
19{ 19{
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 23static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
24 unsigned long flags) 24 unsigned long flags)
25{ 25{
26 return NULL; 26 return NULL;
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h
index 139cd200e79d..050e18bb1a04 100644
--- a/arch/mips/include/asm/mach-generic/irq.h
+++ b/arch/mips/include/asm/mach-generic/irq.h
@@ -36,4 +36,10 @@
36 36
37#endif /* CONFIG_IRQ_CPU */ 37#endif /* CONFIG_IRQ_CPU */
38 38
39#ifdef CONFIG_MIPS_GIC
40#ifndef MIPS_GIC_IRQ_BASE
41#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
42#endif
43#endif /* CONFIG_MIPS_GIC */
44
39#endif /* __ASM_MACH_GENERIC_IRQ_H */ 45#endif /* __ASM_MACH_GENERIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
index f196cceb7322..4e5ae6523cb4 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void);
48extern unsigned char ltq_boot_select(void); 48extern unsigned char ltq_boot_select(void);
49/* find out what caused the last cpu reset */ 49/* find out what caused the last cpu reset */
50extern int ltq_reset_cause(void); 50extern int ltq_reset_cause(void);
51/* find out the soc type */
52extern int ltq_soc_type(void);
51 53
52#define IOPORT_RESOURCE_START 0x10000000 54#define IOPORT_RESOURCE_START 0x10000000
53#define IOPORT_RESOURCE_END 0xffffffff 55#define IOPORT_RESOURCE_END 0xffffffff
diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h
index 3388fc53599e..fa802926523f 100644
--- a/arch/mips/include/asm/mach-loongson/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson/boot_param.h
@@ -10,7 +10,8 @@
10#define VIDEO_ROM 7 10#define VIDEO_ROM 7
11#define ADAPTER_ROM 8 11#define ADAPTER_ROM 8
12#define ACPI_TABLE 9 12#define ACPI_TABLE 9
13#define MAX_MEMORY_TYPE 10 13#define SMBIOS_TABLE 10
14#define MAX_MEMORY_TYPE 11
14 15
15#define LOONGSON3_BOOT_MEM_MAP_MAX 128 16#define LOONGSON3_BOOT_MEM_MAP_MAX 128
16struct efi_memory_map_loongson { 17struct efi_memory_map_loongson {
@@ -42,15 +43,49 @@ struct efi_cpuinfo_loongson {
42 u32 processor_id; /* PRID, e.g. 6305, 6306 */ 43 u32 processor_id; /* PRID, e.g. 6305, 6306 */
43 u32 cputype; /* Loongson_3A/3B, etc. */ 44 u32 cputype; /* Loongson_3A/3B, etc. */
44 u32 total_node; /* num of total numa nodes */ 45 u32 total_node; /* num of total numa nodes */
45 u32 cpu_startup_core_id; /* Core id */ 46 u16 cpu_startup_core_id; /* Boot core id */
47 u16 reserved_cores_mask;
46 u32 cpu_clock_freq; /* cpu_clock */ 48 u32 cpu_clock_freq; /* cpu_clock */
47 u32 nr_cpus; 49 u32 nr_cpus;
48} __packed; 50} __packed;
49 51
52#define MAX_UARTS 64
53struct uart_device {
54 u32 iotype; /* see include/linux/serial_core.h */
55 u32 uartclk;
56 u32 int_offset;
57 u64 uart_base;
58} __packed;
59
60#define MAX_SENSORS 64
61#define SENSOR_TEMPER 0x00000001
62#define SENSOR_VOLTAGE 0x00000002
63#define SENSOR_FAN 0x00000004
64struct sensor_device {
65 char name[32]; /* a formal name */
66 char label[64]; /* a flexible description */
67 u32 type; /* SENSOR_* */
68 u32 id; /* instance id of a sensor-class */
69 u32 fan_policy; /* see loongson_hwmon.h */
70 u32 fan_percent;/* only for constant speed policy */
71 u64 base_addr; /* base address of device registers */
72} __packed;
73
50struct system_loongson { 74struct system_loongson {
51 u16 vers; /* version of system_loongson */ 75 u16 vers; /* version of system_loongson */
52 u32 ccnuma_smp; /* 0: no numa; 1: has numa */ 76 u32 ccnuma_smp; /* 0: no numa; 1: has numa */
53 u32 sing_double_channel; /* 1:single; 2:double */ 77 u32 sing_double_channel; /* 1:single; 2:double */
78 u32 nr_uarts;
79 struct uart_device uarts[MAX_UARTS];
80 u32 nr_sensors;
81 struct sensor_device sensors[MAX_SENSORS];
82 char has_ec;
83 char ec_name[32];
84 u64 ec_base_addr;
85 char has_tcm;
86 char tcm_name[32];
87 u64 tcm_base_addr;
88 u64 workarounds; /* see workarounds.h */
54} __packed; 89} __packed;
55 90
56struct irq_source_routing_table { 91struct irq_source_routing_table {
@@ -149,6 +184,8 @@ struct loongson_system_configuration {
149 u32 nr_nodes; 184 u32 nr_nodes;
150 int cores_per_node; 185 int cores_per_node;
151 int cores_per_package; 186 int cores_per_package;
187 u16 boot_cpu_id;
188 u16 reserved_cpus_mask;
152 enum loongson_cpu_type cputype; 189 enum loongson_cpu_type cputype;
153 u64 ht_control_base; 190 u64 ht_control_base;
154 u64 pci_mem_start_addr; 191 u64 pci_mem_start_addr;
@@ -159,9 +196,15 @@ struct loongson_system_configuration {
159 u64 suspend_addr; 196 u64 suspend_addr;
160 u64 vgabios_addr; 197 u64 vgabios_addr;
161 u32 dma_mask_bits; 198 u32 dma_mask_bits;
199 char ecname[32];
200 u32 nr_uarts;
201 struct uart_device uarts[MAX_UARTS];
202 u32 nr_sensors;
203 struct sensor_device sensors[MAX_SENSORS];
204 u64 workarounds;
162}; 205};
163 206
164extern struct efi_memory_map_loongson *loongson_memmap; 207extern struct efi_memory_map_loongson *loongson_memmap;
165extern struct loongson_system_configuration loongson_sysconf; 208extern struct loongson_system_configuration loongson_sysconf;
166extern int cpuhotplug_workaround; 209
167#endif 210#endif
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
index 6a902751cc7f..a90534161bd2 100644
--- a/arch/mips/include/asm/mach-loongson/dma-coherence.h
+++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
@@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
23 size_t size) 23 size_t size)
24{ 24{
25#ifdef CONFIG_CPU_LOONGSON3 25#ifdef CONFIG_CPU_LOONGSON3
26 return virt_to_phys(addr); 26 return phys_to_dma(dev, virt_to_phys(addr));
27#else 27#else
28 return virt_to_phys(addr) | 0x80000000; 28 return virt_to_phys(addr) | 0x80000000;
29#endif 29#endif
@@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
33 struct page *page) 33 struct page *page)
34{ 34{
35#ifdef CONFIG_CPU_LOONGSON3 35#ifdef CONFIG_CPU_LOONGSON3
36 return page_to_phys(page); 36 return phys_to_dma(dev, page_to_phys(page));
37#else 37#else
38 return page_to_phys(page) | 0x80000000; 38 return page_to_phys(page) | 0x80000000;
39#endif 39#endif
@@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
43 dma_addr_t dma_addr) 43 dma_addr_t dma_addr)
44{ 44{
45#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) 45#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
46 return dma_addr; 46 return dma_to_phys(dev, dma_addr);
47#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) 47#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
48 return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); 48 return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
49#else 49#else
diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h
index 34560bda6626..a281cca5f2fb 100644
--- a/arch/mips/include/asm/mach-loongson/irq.h
+++ b/arch/mips/include/asm/mach-loongson/irq.h
@@ -32,8 +32,7 @@
32#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) 32#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a)
33#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) 33#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18)
34 34
35#define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */ 35#define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */
36#define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */
37 36
38#endif 37#endif
39 38
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index 92bf76c21441..5459ac09679f 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void);
35extern void __init prom_init_machtype(void); 35extern void __init prom_init_machtype(void);
36extern void __init prom_init_env(void); 36extern void __init prom_init_env(void);
37#ifdef CONFIG_LOONGSON_UART_BASE 37#ifdef CONFIG_LOONGSON_UART_BASE
38extern unsigned long _loongson_uart_base, loongson_uart_base; 38extern unsigned long _loongson_uart_base[], loongson_uart_base[];
39extern void prom_init_loongson_uart_base(void); 39extern void prom_init_loongson_uart_base(void);
40#endif 40#endif
41 41
diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h
new file mode 100644
index 000000000000..4431fc54a36c
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h
@@ -0,0 +1,55 @@
1#ifndef __LOONGSON_HWMON_H_
2#define __LOONGSON_HWMON_H_
3
4#include <linux/types.h>
5
6#define MIN_TEMP 0
7#define MAX_TEMP 255
8#define NOT_VALID_TEMP 999
9
10typedef int (*get_temp_fun)(int);
11extern int loongson3_cpu_temp(int);
12
13/* 0:Max speed, 1:Manual, 2:Auto */
14enum fan_control_mode {
15 FAN_FULL_MODE = 0,
16 FAN_MANUAL_MODE = 1,
17 FAN_AUTO_MODE = 2,
18 FAN_MODE_END
19};
20
21struct temp_range {
22 u8 low;
23 u8 high;
24 u8 level;
25};
26
27#define CONSTANT_SPEED_POLICY 0 /* at constent speed */
28#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */
29#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */
30
31#define MAX_STEP_NUM 16
32#define MAX_FAN_LEVEL 255
33
34/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */
35struct loongson_fan_policy {
36 u8 type;
37
38 /* percent only used when type is CONSTANT_SPEED_POLICY */
39 u8 percent;
40
41 /* period between two check. (Unit: S) */
42 u8 adjust_period;
43
44 /* fan adjust usually depend on a temprature input */
45 get_temp_fun depend_temp;
46
47 /* up_step/down_step used when type is STEP_SPEED_POLICY */
48 u8 up_step_num;
49 u8 down_step_num;
50 struct temp_range up_step[MAX_STEP_NUM];
51 struct temp_range down_step[MAX_STEP_NUM];
52 struct delayed_work work;
53};
54
55#endif /* __LOONGSON_HWMON_H_*/
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
index 228e37847a36..cb2b60249cd2 100644
--- a/arch/mips/include/asm/mach-loongson/machine.h
+++ b/arch/mips/include/asm/mach-loongson/machine.h
@@ -26,7 +26,7 @@
26 26
27#ifdef CONFIG_LOONGSON_MACH3X 27#ifdef CONFIG_LOONGSON_MACH3X
28 28
29#define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 29#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
30 30
31#endif /* CONFIG_LOONGSON_MACH3X */ 31#endif /* CONFIG_LOONGSON_MACH3X */
32 32
diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h
index 5598ba77d2ef..0d8f3b55bdbc 100644
--- a/arch/mips/include/asm/mach-loongson/topology.h
+++ b/arch/mips/include/asm/mach-loongson/topology.h
@@ -3,7 +3,7 @@
3 3
4#ifdef CONFIG_NUMA 4#ifdef CONFIG_NUMA
5 5
6#define cpu_to_node(cpu) ((cpu) >> 2) 6#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2)
7#define parent_node(node) (node) 7#define parent_node(node) (node)
8#define cpumask_of_node(node) (&__node_data[(node)]->cpumask) 8#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
9 9
diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h
new file mode 100644
index 000000000000..e180c1422eae
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/workarounds.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_
2#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_
3
4#define WORKAROUND_CPUFREQ 0x00000001
5#define WORKAROUND_CPUHOTPLUG 0x00000002
6
7#endif
diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h
new file mode 100644
index 000000000000..e7765ce30bcf
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/cpufreq.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * Loongson 1 CPUFreq platform support.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12
13#ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H
14#define __ASM_MACH_LOONGSON1_CPUFREQ_H
15
16struct plat_ls1x_cpufreq {
17 const char *clk_name; /* CPU clk */
18 const char *osc_clk_name; /* OSC clk */
19 unsigned int max_freq; /* in kHz */
20 unsigned int min_freq; /* in kHz */
21};
22
23#endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */
diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h
index 5c437c2ba6b3..20e0c2b155dd 100644
--- a/arch/mips/include/asm/mach-loongson1/loongson1.h
+++ b/arch/mips/include/asm/mach-loongson1/loongson1.h
@@ -16,6 +16,7 @@
16#define DEFAULT_MEMSIZE 256 /* If no memsize provided */ 16#define DEFAULT_MEMSIZE 256 /* If no memsize provided */
17 17
18/* Loongson 1 Register Bases */ 18/* Loongson 1 Register Bases */
19#define LS1X_MUX_BASE 0x1fd00420
19#define LS1X_INTC_BASE 0x1fd01040 20#define LS1X_INTC_BASE 0x1fd01040
20#define LS1X_EHCI_BASE 0x1fe00000 21#define LS1X_EHCI_BASE 0x1fe00000
21#define LS1X_OHCI_BASE 0x1fe08000 22#define LS1X_OHCI_BASE 0x1fe08000
@@ -31,7 +32,10 @@
31#define LS1X_I2C0_BASE 0x1fe58000 32#define LS1X_I2C0_BASE 0x1fe58000
32#define LS1X_I2C1_BASE 0x1fe68000 33#define LS1X_I2C1_BASE 0x1fe68000
33#define LS1X_I2C2_BASE 0x1fe70000 34#define LS1X_I2C2_BASE 0x1fe70000
34#define LS1X_PWM_BASE 0x1fe5c000 35#define LS1X_PWM0_BASE 0x1fe5c000
36#define LS1X_PWM1_BASE 0x1fe5c010
37#define LS1X_PWM2_BASE 0x1fe5c020
38#define LS1X_PWM3_BASE 0x1fe5c030
35#define LS1X_WDT_BASE 0x1fe5c060 39#define LS1X_WDT_BASE 0x1fe5c060
36#define LS1X_RTC_BASE 0x1fe64000 40#define LS1X_RTC_BASE 0x1fe64000
37#define LS1X_AC97_BASE 0x1fe74000 41#define LS1X_AC97_BASE 0x1fe74000
@@ -39,6 +43,8 @@
39#define LS1X_CLK_BASE 0x1fe78030 43#define LS1X_CLK_BASE 0x1fe78030
40 44
41#include <regs-clk.h> 45#include <regs-clk.h>
46#include <regs-mux.h>
47#include <regs-pwm.h>
42#include <regs-wdt.h> 48#include <regs-wdt.h>
43 49
44#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ 50#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h
index 30c13e508fff..47de55e0c835 100644
--- a/arch/mips/include/asm/mach-loongson1/platform.h
+++ b/arch/mips/include/asm/mach-loongson1/platform.h
@@ -13,10 +13,12 @@
13 13
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15 15
16extern struct platform_device ls1x_uart_device; 16extern struct platform_device ls1x_uart_pdev;
17extern struct platform_device ls1x_eth0_device; 17extern struct platform_device ls1x_cpufreq_pdev;
18extern struct platform_device ls1x_ehci_device; 18extern struct platform_device ls1x_eth0_pdev;
19extern struct platform_device ls1x_rtc_device; 19extern struct platform_device ls1x_eth1_pdev;
20extern struct platform_device ls1x_ehci_pdev;
21extern struct platform_device ls1x_rtc_pdev;
20 22
21extern void __init ls1x_clk_init(void); 23extern void __init ls1x_clk_init(void);
22extern void __init ls1x_serial_setup(struct platform_device *pdev); 24extern void __init ls1x_serial_setup(struct platform_device *pdev);
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h
index fb6a3ff9318f..ee2445b10fc3 100644
--- a/arch/mips/include/asm/mach-loongson1/regs-clk.h
+++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h
@@ -20,15 +20,32 @@
20 20
21/* Clock PLL Divisor Register Bits */ 21/* Clock PLL Divisor Register Bits */
22#define DIV_DC_EN (0x1 << 31) 22#define DIV_DC_EN (0x1 << 31)
23#define DIV_DC_RST (0x1 << 30)
23#define DIV_CPU_EN (0x1 << 25) 24#define DIV_CPU_EN (0x1 << 25)
25#define DIV_CPU_RST (0x1 << 24)
24#define DIV_DDR_EN (0x1 << 19) 26#define DIV_DDR_EN (0x1 << 19)
27#define DIV_DDR_RST (0x1 << 18)
28#define RST_DC_EN (0x1 << 5)
29#define RST_DC (0x1 << 4)
30#define RST_DDR_EN (0x1 << 3)
31#define RST_DDR (0x1 << 2)
32#define RST_CPU_EN (0x1 << 1)
33#define RST_CPU 0x1
25 34
26#define DIV_DC_SHIFT 26 35#define DIV_DC_SHIFT 26
27#define DIV_CPU_SHIFT 20 36#define DIV_CPU_SHIFT 20
28#define DIV_DDR_SHIFT 14 37#define DIV_DDR_SHIFT 14
29 38
30#define DIV_DC_WIDTH 5 39#define DIV_DC_WIDTH 4
31#define DIV_CPU_WIDTH 5 40#define DIV_CPU_WIDTH 4
32#define DIV_DDR_WIDTH 5 41#define DIV_DDR_WIDTH 4
42
43#define BYPASS_DC_SHIFT 12
44#define BYPASS_DDR_SHIFT 10
45#define BYPASS_CPU_SHIFT 8
46
47#define BYPASS_DC_WIDTH 1
48#define BYPASS_DDR_WIDTH 1
49#define BYPASS_CPU_WIDTH 1
33 50
34#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ 51#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h
new file mode 100644
index 000000000000..fb1e36efaa19
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/regs-mux.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * Loongson 1 MUX Register Definitions.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H
13#define __ASM_MACH_LOONGSON1_REGS_MUX_H
14
15#define LS1X_MUX_REG(x) \
16 ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x)))
17
18#define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0)
19#define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4)
20
21/* MUX CTRL0 Register Bits */
22#define UART0_USE_PWM23 (0x1 << 28)
23#define UART0_USE_PWM01 (0x1 << 27)
24#define UART1_USE_LCD0_5_6_11 (0x1 << 26)
25#define I2C2_USE_CAN1 (0x1 << 25)
26#define I2C1_USE_CAN0 (0x1 << 24)
27#define NAND3_USE_UART5 (0x1 << 23)
28#define NAND3_USE_UART4 (0x1 << 22)
29#define NAND3_USE_UART1_DAT (0x1 << 21)
30#define NAND3_USE_UART1_CTS (0x1 << 20)
31#define NAND3_USE_PWM23 (0x1 << 19)
32#define NAND3_USE_PWM01 (0x1 << 18)
33#define NAND2_USE_UART5 (0x1 << 17)
34#define NAND2_USE_UART4 (0x1 << 16)
35#define NAND2_USE_UART1_DAT (0x1 << 15)
36#define NAND2_USE_UART1_CTS (0x1 << 14)
37#define NAND2_USE_PWM23 (0x1 << 13)
38#define NAND2_USE_PWM01 (0x1 << 12)
39#define NAND1_USE_UART5 (0x1 << 11)
40#define NAND1_USE_UART4 (0x1 << 10)
41#define NAND1_USE_UART1_DAT (0x1 << 9)
42#define NAND1_USE_UART1_CTS (0x1 << 8)
43#define NAND1_USE_PWM23 (0x1 << 7)
44#define NAND1_USE_PWM01 (0x1 << 6)
45#define GMAC1_USE_UART1 (0x1 << 4)
46#define GMAC1_USE_UART0 (0x1 << 3)
47#define LCD_USE_UART0_DAT (0x1 << 2)
48#define LCD_USE_UART15 (0x1 << 1)
49#define LCD_USE_UART0 0x1
50
51/* MUX CTRL1 Register Bits */
52#define USB_RESET (0x1 << 31)
53#define SPI1_CS_USE_PWM01 (0x1 << 24)
54#define SPI1_USE_CAN (0x1 << 23)
55#define DISABLE_DDR_CONFSPACE (0x1 << 20)
56#define DDR32TO16EN (0x1 << 16)
57#define GMAC1_SHUT (0x1 << 13)
58#define GMAC0_SHUT (0x1 << 12)
59#define USB_SHUT (0x1 << 11)
60#define UART1_3_USE_CAN1 (0x1 << 5)
61#define UART1_2_USE_CAN0 (0x1 << 4)
62#define GMAC1_USE_TXCLK (0x1 << 3)
63#define GMAC0_USE_TXCLK (0x1 << 2)
64#define GMAC1_USE_PWM23 (0x1 << 1)
65#define GMAC0_USE_PWM01 0x1
66
67#endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h
new file mode 100644
index 000000000000..99f2bcc586f0
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/regs-pwm.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * Loongson 1 PWM Register Definitions.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H
13#define __ASM_MACH_LOONGSON1_REGS_PWM_H
14
15/* Loongson 1 PWM Timer Register Definitions */
16#define PWM_CNT 0x0
17#define PWM_HRC 0x4
18#define PWM_LRC 0x8
19#define PWM_CTRL 0xc
20
21/* PWM Control Register Bits */
22#define CNT_RST (0x1 << 7)
23#define INT_SR (0x1 << 6)
24#define INT_EN (0x1 << 5)
25#define PWM_SINGLE (0x1 << 4)
26#define PWM_OE (0x1 << 3)
27#define CNT_EN 0x1
28
29#endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h
index 6574568c2084..c39ee982ad3b 100644
--- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h
+++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> 2 * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
3 * 3 *
4 * Loongson 1 watchdog register definitions. 4 * Loongson 1 Watchdog Register Definitions.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
@@ -12,11 +12,8 @@
12#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H 12#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H
13#define __ASM_MACH_LOONGSON1_REGS_WDT_H 13#define __ASM_MACH_LOONGSON1_REGS_WDT_H
14 14
15#define LS1X_WDT_REG(x) \ 15#define WDT_EN 0x0
16 ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) 16#define WDT_TIMER 0x4
17 17#define WDT_SET 0x8
18#define LS1X_WDT_EN LS1X_WDT_REG(0x0)
19#define LS1X_WDT_SET LS1X_WDT_REG(0x4)
20#define LS1X_WDT_TIMER LS1X_WDT_REG(0x8)
21 18
22#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ 19#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */
diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h
index f2c13d211abb..47cfe64efbb0 100644
--- a/arch/mips/include/asm/mach-malta/irq.h
+++ b/arch/mips/include/asm/mach-malta/irq.h
@@ -2,7 +2,6 @@
2#define __ASM_MACH_MIPS_IRQ_H 2#define __ASM_MACH_MIPS_IRQ_H
3 3
4 4
5#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
6#define NR_IRQS 256 5#define NR_IRQS 256
7 6
8#include_next <irq.h> 7#include_next <irq.h>
diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h
index fc946c835995..2e54b4bff5cf 100644
--- a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h
+++ b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h
@@ -49,6 +49,7 @@
49 49
50#include <linux/types.h> 50#include <linux/types.h>
51 51
52#include <asm/compiler.h>
52#include <asm/war.h> 53#include <asm/war.h>
53 54
54#ifndef R10000_LLSC_WAR 55#ifndef R10000_LLSC_WAR
@@ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr,
84 " "__beqz"%0, 1b \n" 85 " "__beqz"%0, 1b \n"
85 " nop \n" 86 " nop \n"
86 " .set pop \n" 87 " .set pop \n"
87 : "=&r" (temp), "=m" (*addr) 88 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
88 : "ir" (~mask), "ir" (value), "m" (*addr)); 89 : "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr));
89} 90}
90 91
91/* 92/*
@@ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr,
105 " "__beqz"%0, 1b \n" 106 " "__beqz"%0, 1b \n"
106 " nop \n" 107 " nop \n"
107 " .set pop \n" 108 " .set pop \n"
108 : "=&r" (temp), "=m" (*addr) 109 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
109 : "ir" (mask), "m" (*addr)); 110 : "ir" (mask), GCC_OFF12_ASM() (*addr));
110} 111}
111 112
112/* 113/*
@@ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr,
126 " "__beqz"%0, 1b \n" 127 " "__beqz"%0, 1b \n"
127 " nop \n" 128 " nop \n"
128 " .set pop \n" 129 " .set pop \n"
129 : "=&r" (temp), "=m" (*addr) 130 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
130 : "ir" (~mask), "m" (*addr)); 131 : "ir" (~mask), GCC_OFF12_ASM() (*addr));
131} 132}
132 133
133/* 134/*
@@ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr,
147 " "__beqz"%0, 1b \n" 148 " "__beqz"%0, 1b \n"
148 " nop \n" 149 " nop \n"
149 " .set pop \n" 150 " .set pop \n"
150 : "=&r" (temp), "=m" (*addr) 151 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
151 : "ir" (mask), "m" (*addr)); 152 : "ir" (mask), GCC_OFF12_ASM() (*addr));
152} 153}
153 154
154/* 155/*
@@ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr)
219 " .set arch=r4000 \n" \ 220 " .set arch=r4000 \n" \
220 "1: ll %0, %1 #custom_read_reg32 \n" \ 221 "1: ll %0, %1 #custom_read_reg32 \n" \
221 " .set pop \n" \ 222 " .set pop \n" \
222 : "=r" (tmp), "=m" (*address) \ 223 : "=r" (tmp), "=" GCC_OFF12_ASM() (*address) \
223 : "m" (*address)) 224 : GCC_OFF12_ASM() (*address))
224 225
225#define custom_write_reg32(address, tmp) \ 226#define custom_write_reg32(address, tmp) \
226 __asm__ __volatile__( \ 227 __asm__ __volatile__( \
@@ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr)
230 " "__beqz"%0, 1b \n" \ 231 " "__beqz"%0, 1b \n" \
231 " nop \n" \ 232 " nop \n" \
232 " .set pop \n" \ 233 " .set pop \n" \
233 : "=&r" (tmp), "=m" (*address) \ 234 : "=&r" (tmp), "=" GCC_OFF12_ASM() (*address) \
234 : "0" (tmp), "m" (*address)) 235 : "0" (tmp), GCC_OFF12_ASM() (*address))
235 236
236#endif /* __ASM_REGOPS_H__ */ 237#endif /* __ASM_REGOPS_H__ */
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
index 6f9b24f51157..1976fb815fd1 100644
--- a/arch/mips/include/asm/mach-ralink/mt7620.h
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
@@ -13,6 +13,13 @@
13#ifndef _MT7620_REGS_H_ 13#ifndef _MT7620_REGS_H_
14#define _MT7620_REGS_H_ 14#define _MT7620_REGS_H_
15 15
16enum mt762x_soc_type {
17 MT762X_SOC_UNKNOWN = 0,
18 MT762X_SOC_MT7620A,
19 MT762X_SOC_MT7620N,
20 MT762X_SOC_MT7628AN,
21};
22
16#define MT7620_SYSC_BASE 0x10000000 23#define MT7620_SYSC_BASE 0x10000000
17 24
18#define SYSC_REG_CHIP_NAME0 0x00 25#define SYSC_REG_CHIP_NAME0 0x00
@@ -25,11 +32,9 @@
25#define SYSC_REG_CPLL_CONFIG0 0x54 32#define SYSC_REG_CPLL_CONFIG0 0x54
26#define SYSC_REG_CPLL_CONFIG1 0x58 33#define SYSC_REG_CPLL_CONFIG1 0x58
27 34
28#define MT7620N_CHIP_NAME0 0x33365452 35#define MT7620_CHIP_NAME0 0x3637544d
29#define MT7620N_CHIP_NAME1 0x20203235 36#define MT7620_CHIP_NAME1 0x20203032
30 37#define MT7628_CHIP_NAME1 0x20203832
31#define MT7620A_CHIP_NAME0 0x3637544d
32#define MT7620A_CHIP_NAME1 0x20203032
33 38
34#define SYSCFG0_XTAL_FREQ_SEL BIT(6) 39#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
35 40
@@ -74,6 +79,9 @@
74#define SYSCFG0_DRAM_TYPE_DDR1 1 79#define SYSCFG0_DRAM_TYPE_DDR1 1
75#define SYSCFG0_DRAM_TYPE_DDR2 2 80#define SYSCFG0_DRAM_TYPE_DDR2 2
76 81
82#define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0
83#define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1
84
77#define MT7620_DRAM_BASE 0x0 85#define MT7620_DRAM_BASE 0x0
78#define MT7620_SDRAM_SIZE_MIN 2 86#define MT7620_SDRAM_SIZE_MIN 2
79#define MT7620_SDRAM_SIZE_MAX 64 87#define MT7620_SDRAM_SIZE_MAX 64
@@ -82,7 +90,6 @@
82#define MT7620_DDR2_SIZE_MIN 32 90#define MT7620_DDR2_SIZE_MIN 32
83#define MT7620_DDR2_SIZE_MAX 256 91#define MT7620_DDR2_SIZE_MAX 256
84 92
85#define MT7620_GPIO_MODE_I2C BIT(0)
86#define MT7620_GPIO_MODE_UART0_SHIFT 2 93#define MT7620_GPIO_MODE_UART0_SHIFT 2
87#define MT7620_GPIO_MODE_UART0_MASK 0x7 94#define MT7620_GPIO_MODE_UART0_MASK 0x7
88#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) 95#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT)
@@ -94,15 +101,40 @@
94#define MT7620_GPIO_MODE_GPIO_UARTF 0x5 101#define MT7620_GPIO_MODE_GPIO_UARTF 0x5
95#define MT7620_GPIO_MODE_GPIO_I2S 0x6 102#define MT7620_GPIO_MODE_GPIO_I2S 0x6
96#define MT7620_GPIO_MODE_GPIO 0x7 103#define MT7620_GPIO_MODE_GPIO 0x7
97#define MT7620_GPIO_MODE_UART1 BIT(5) 104
98#define MT7620_GPIO_MODE_MDIO BIT(8) 105#define MT7620_GPIO_MODE_NAND 0
99#define MT7620_GPIO_MODE_RGMII1 BIT(9) 106#define MT7620_GPIO_MODE_SD 1
100#define MT7620_GPIO_MODE_RGMII2 BIT(10) 107#define MT7620_GPIO_MODE_ND_SD_GPIO 2
101#define MT7620_GPIO_MODE_SPI BIT(11) 108#define MT7620_GPIO_MODE_ND_SD_MASK 0x3
102#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) 109#define MT7620_GPIO_MODE_ND_SD_SHIFT 18
103#define MT7620_GPIO_MODE_WLED BIT(13) 110
104#define MT7620_GPIO_MODE_JTAG BIT(15) 111#define MT7620_GPIO_MODE_PCIE_RST 0
105#define MT7620_GPIO_MODE_EPHY BIT(15) 112#define MT7620_GPIO_MODE_PCIE_REF 1
106#define MT7620_GPIO_MODE_WDT BIT(22) 113#define MT7620_GPIO_MODE_PCIE_GPIO 2
114#define MT7620_GPIO_MODE_PCIE_MASK 0x3
115#define MT7620_GPIO_MODE_PCIE_SHIFT 16
116
117#define MT7620_GPIO_MODE_WDT_RST 0
118#define MT7620_GPIO_MODE_WDT_REF 1
119#define MT7620_GPIO_MODE_WDT_GPIO 2
120#define MT7620_GPIO_MODE_WDT_MASK 0x3
121#define MT7620_GPIO_MODE_WDT_SHIFT 21
122
123#define MT7620_GPIO_MODE_I2C 0
124#define MT7620_GPIO_MODE_UART1 5
125#define MT7620_GPIO_MODE_MDIO 8
126#define MT7620_GPIO_MODE_RGMII1 9
127#define MT7620_GPIO_MODE_RGMII2 10
128#define MT7620_GPIO_MODE_SPI 11
129#define MT7620_GPIO_MODE_SPI_REF_CLK 12
130#define MT7620_GPIO_MODE_WLED 13
131#define MT7620_GPIO_MODE_JTAG 15
132#define MT7620_GPIO_MODE_EPHY 15
133#define MT7620_GPIO_MODE_PA 20
134
135static inline int mt7620_get_eco(void)
136{
137 return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
138}
107 139
108#endif 140#endif
diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h
new file mode 100644
index 000000000000..be106cb2e26d
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/pinmux.h
@@ -0,0 +1,55 @@
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 version 2 as
4 * publishhed by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _RT288X_PINMUX_H__
10#define _RT288X_PINMUX_H__
11
12#define FUNC(name, value, pin_first, pin_count) \
13 { name, value, pin_first, pin_count }
14
15#define GRP(_name, _func, _mask, _shift) \
16 { .name = _name, .mask = _mask, .shift = _shift, \
17 .func = _func, .gpio = _mask, \
18 .func_count = ARRAY_SIZE(_func) }
19
20#define GRP_G(_name, _func, _mask, _gpio, _shift) \
21 { .name = _name, .mask = _mask, .shift = _shift, \
22 .func = _func, .gpio = _gpio, \
23 .func_count = ARRAY_SIZE(_func) }
24
25struct rt2880_pmx_group;
26
27struct rt2880_pmx_func {
28 const char *name;
29 const char value;
30
31 int pin_first;
32 int pin_count;
33 int *pins;
34
35 int *groups;
36 int group_count;
37
38 int enabled;
39};
40
41struct rt2880_pmx_group {
42 const char *name;
43 int enabled;
44
45 const u32 shift;
46 const char mask;
47 const char gpio;
48
49 struct rt2880_pmx_func *func;
50 int func_count;
51};
52
53extern struct rt2880_pmx_group *rt2880_pinmux_data;
54
55#endif
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h
index 5a508f9f9432..bd93014490df 100644
--- a/arch/mips/include/asm/mach-ralink/ralink_regs.h
+++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h
@@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg)
26 return __raw_readl(rt_sysc_membase + reg); 26 return __raw_readl(rt_sysc_membase + reg);
27} 27}
28 28
29static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg)
30{
31 u32 val = rt_sysc_r32(reg) & ~clr;
32
33 __raw_writel(val | set, rt_sysc_membase + reg);
34}
35
29static inline void rt_memc_w32(u32 val, unsigned reg) 36static inline void rt_memc_w32(u32 val, unsigned reg)
30{ 37{
31 __raw_writel(val, rt_memc_membase + reg); 38 __raw_writel(val, rt_memc_membase + reg);
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h
index 069bf37a6010..96f731bac79a 100644
--- a/arch/mips/include/asm/mach-ralink/rt305x.h
+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
@@ -125,24 +125,29 @@ static inline int soc_is_rt5350(void)
125#define RT305X_GPIO_GE0_TXD0 40 125#define RT305X_GPIO_GE0_TXD0 40
126#define RT305X_GPIO_GE0_RXCLK 51 126#define RT305X_GPIO_GE0_RXCLK 51
127 127
128#define RT305X_GPIO_MODE_I2C BIT(0)
129#define RT305X_GPIO_MODE_SPI BIT(1)
130#define RT305X_GPIO_MODE_UART0_SHIFT 2 128#define RT305X_GPIO_MODE_UART0_SHIFT 2
131#define RT305X_GPIO_MODE_UART0_MASK 0x7 129#define RT305X_GPIO_MODE_UART0_MASK 0x7
132#define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) 130#define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT)
133#define RT305X_GPIO_MODE_UARTF 0x0 131#define RT305X_GPIO_MODE_UARTF 0
134#define RT305X_GPIO_MODE_PCM_UARTF 0x1 132#define RT305X_GPIO_MODE_PCM_UARTF 1
135#define RT305X_GPIO_MODE_PCM_I2S 0x2 133#define RT305X_GPIO_MODE_PCM_I2S 2
136#define RT305X_GPIO_MODE_I2S_UARTF 0x3 134#define RT305X_GPIO_MODE_I2S_UARTF 3
137#define RT305X_GPIO_MODE_PCM_GPIO 0x4 135#define RT305X_GPIO_MODE_PCM_GPIO 4
138#define RT305X_GPIO_MODE_GPIO_UARTF 0x5 136#define RT305X_GPIO_MODE_GPIO_UARTF 5
139#define RT305X_GPIO_MODE_GPIO_I2S 0x6 137#define RT305X_GPIO_MODE_GPIO_I2S 6
140#define RT305X_GPIO_MODE_GPIO 0x7 138#define RT305X_GPIO_MODE_GPIO 7
141#define RT305X_GPIO_MODE_UART1 BIT(5) 139
142#define RT305X_GPIO_MODE_JTAG BIT(6) 140#define RT305X_GPIO_MODE_I2C 0
143#define RT305X_GPIO_MODE_MDIO BIT(7) 141#define RT305X_GPIO_MODE_SPI 1
144#define RT305X_GPIO_MODE_SDRAM BIT(8) 142#define RT305X_GPIO_MODE_UART1 5
145#define RT305X_GPIO_MODE_RGMII BIT(9) 143#define RT305X_GPIO_MODE_JTAG 6
144#define RT305X_GPIO_MODE_MDIO 7
145#define RT305X_GPIO_MODE_SDRAM 8
146#define RT305X_GPIO_MODE_RGMII 9
147#define RT5350_GPIO_MODE_PHY_LED 14
148#define RT5350_GPIO_MODE_SPI_CS1 21
149#define RT3352_GPIO_MODE_LNA 18
150#define RT3352_GPIO_MODE_PA 20
146 151
147#define RT3352_SYSC_REG_SYSCFG0 0x010 152#define RT3352_SYSC_REG_SYSCFG0 0x010
148#define RT3352_SYSC_REG_SYSCFG1 0x014 153#define RT3352_SYSC_REG_SYSCFG1 0x014
diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h
index 058382f37f92..0fbe6f9257cd 100644
--- a/arch/mips/include/asm/mach-ralink/rt3883.h
+++ b/arch/mips/include/asm/mach-ralink/rt3883.h
@@ -112,8 +112,6 @@
112#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) 112#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19)
113#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) 113#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18)
114 114
115#define RT3883_GPIO_MODE_I2C BIT(0)
116#define RT3883_GPIO_MODE_SPI BIT(1)
117#define RT3883_GPIO_MODE_UART0_SHIFT 2 115#define RT3883_GPIO_MODE_UART0_SHIFT 2
118#define RT3883_GPIO_MODE_UART0_MASK 0x7 116#define RT3883_GPIO_MODE_UART0_MASK 0x7
119#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) 117#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT)
@@ -125,11 +123,15 @@
125#define RT3883_GPIO_MODE_GPIO_UARTF 0x5 123#define RT3883_GPIO_MODE_GPIO_UARTF 0x5
126#define RT3883_GPIO_MODE_GPIO_I2S 0x6 124#define RT3883_GPIO_MODE_GPIO_I2S 0x6
127#define RT3883_GPIO_MODE_GPIO 0x7 125#define RT3883_GPIO_MODE_GPIO 0x7
128#define RT3883_GPIO_MODE_UART1 BIT(5) 126
129#define RT3883_GPIO_MODE_JTAG BIT(6) 127#define RT3883_GPIO_MODE_I2C 0
130#define RT3883_GPIO_MODE_MDIO BIT(7) 128#define RT3883_GPIO_MODE_SPI 1
131#define RT3883_GPIO_MODE_GE1 BIT(9) 129#define RT3883_GPIO_MODE_UART1 5
132#define RT3883_GPIO_MODE_GE2 BIT(10) 130#define RT3883_GPIO_MODE_JTAG 6
131#define RT3883_GPIO_MODE_MDIO 7
132#define RT3883_GPIO_MODE_GE1 9
133#define RT3883_GPIO_MODE_GE2 10
134
133#define RT3883_GPIO_MODE_PCI_SHIFT 11 135#define RT3883_GPIO_MODE_PCI_SHIFT 11
134#define RT3883_GPIO_MODE_PCI_MASK 0x7 136#define RT3883_GPIO_MODE_PCI_MASK 0x7
135#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) 137#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT)
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h
index d8106f75b9af..5d154cfbcf4c 100644
--- a/arch/mips/include/asm/mach-sead3/irq.h
+++ b/arch/mips/include/asm/mach-sead3/irq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_MACH_MIPS_IRQ_H 1#ifndef __ASM_MACH_MIPS_IRQ_H
2#define __ASM_MACH_MIPS_IRQ_H 2#define __ASM_MACH_MIPS_IRQ_H
3 3
4#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
5#define NR_IRQS 256 4#define NR_IRQS 256
6 5
7 6
diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h
index 93c6c04ffda3..0874cd2b06d7 100644
--- a/arch/mips/include/asm/mach-tx39xx/ioremap.h
+++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h
@@ -15,12 +15,12 @@
15 * Allow physical addresses to be fixed up to help peripherals located 15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version. 16 * outside the low 32-bit range -- generic pass-through version.
17 */ 17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 18static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
19{ 19{
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 23static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
24 unsigned long flags) 24 unsigned long flags)
25{ 25{
26#define TXX9_DIRECTMAP_BASE 0xff000000ul 26#define TXX9_DIRECTMAP_BASE 0xff000000ul
diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h
index 1e7beae72229..4b6a8441b25f 100644
--- a/arch/mips/include/asm/mach-tx49xx/ioremap.h
+++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h
@@ -15,12 +15,12 @@
15 * Allow physical addresses to be fixed up to help peripherals located 15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version. 16 * outside the low 32-bit range -- generic pass-through version.
17 */ 17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 18static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
19{ 19{
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 23static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
24 unsigned long flags) 24 unsigned long flags)
25{ 25{
26#ifdef CONFIG_64BIT 26#ifdef CONFIG_64BIT
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index e330732ddf98..987ff580466b 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -10,7 +10,7 @@
10#ifndef _MIPS_MALTAINT_H 10#ifndef _MIPS_MALTAINT_H
11#define _MIPS_MALTAINT_H 11#define _MIPS_MALTAINT_H
12 12
13#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) 13#include <linux/irqchip/mips-gic.h>
14 14
15/* 15/*
16 * Interrupts 0..15 are used for Malta ISA compatible interrupts 16 * Interrupts 0..15 are used for Malta ISA compatible interrupts
@@ -22,29 +22,28 @@
22#define MIPSCPU_INT_SW1 1 22#define MIPSCPU_INT_SW1 1
23#define MIPSCPU_INT_MB0 2 23#define MIPSCPU_INT_MB0 2
24#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 24#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0
25#define MIPSCPU_INT_GIC MIPSCPU_INT_MB0 /* GIC chained interrupt */
25#define MIPSCPU_INT_MB1 3 26#define MIPSCPU_INT_MB1 3
26#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 27#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1
27#define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */
28#define MIPSCPU_INT_MB2 4 28#define MIPSCPU_INT_MB2 4
29#define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */
30#define MIPSCPU_INT_MB3 5 29#define MIPSCPU_INT_MB3 5
31#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 30#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3
32#define MIPSCPU_INT_MB4 6 31#define MIPSCPU_INT_MB4 6
33#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 32#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4
34 33
35/* 34/*
36 * Interrupts 64..127 are used for Soc-it Classic interrupts 35 * Interrupts 96..127 are used for Soc-it Classic interrupts
37 */ 36 */
38#define MSC01C_INT_BASE 64 37#define MSC01C_INT_BASE 96
39 38
40/* SOC-it Classic interrupt offsets */ 39/* SOC-it Classic interrupt offsets */
41#define MSC01C_INT_TMR 0 40#define MSC01C_INT_TMR 0
42#define MSC01C_INT_PCI 1 41#define MSC01C_INT_PCI 1
43 42
44/* 43/*
45 * Interrupts 64..127 are used for Soc-it EIC interrupts 44 * Interrupts 96..127 are used for Soc-it EIC interrupts
46 */ 45 */
47#define MSC01E_INT_BASE 64 46#define MSC01E_INT_BASE 96
48 47
49/* SOC-it EIC interrupt offsets */ 48/* SOC-it EIC interrupt offsets */
50#define MSC01E_INT_SW0 1 49#define MSC01E_INT_SW0 1
@@ -63,14 +62,7 @@
63#define MSC01E_INT_PERFCTR 10 62#define MSC01E_INT_PERFCTR 10
64#define MSC01E_INT_CPUCTR 11 63#define MSC01E_INT_CPUCTR 11
65 64
66/* External Interrupts used for IPI */ 65/* GIC external interrupts */
67#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 66#define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3)
68#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
69#define GIC_IPI_EXT_INTR_RESCHED_VPE1 18
70#define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19
71#define GIC_IPI_EXT_INTR_RESCHED_VPE2 20
72#define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21
73#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22
74#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23
75 67
76#endif /* !(_MIPS_MALTAINT_H) */ 68#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h
index 6b17aaf7d901..8932c7de0419 100644
--- a/arch/mips/include/asm/mips-boards/sead3int.h
+++ b/arch/mips/include/asm/mips-boards/sead3int.h
@@ -10,10 +10,23 @@
10#ifndef _MIPS_SEAD3INT_H 10#ifndef _MIPS_SEAD3INT_H
11#define _MIPS_SEAD3INT_H 11#define _MIPS_SEAD3INT_H
12 12
13#include <linux/irqchip/mips-gic.h>
14
13/* SEAD-3 GIC address space definitions. */ 15/* SEAD-3 GIC address space definitions. */
14#define GIC_BASE_ADDR 0x1b1c0000 16#define GIC_BASE_ADDR 0x1b1c0000
15#define GIC_ADDRSPACE_SZ (128 * 1024) 17#define GIC_ADDRSPACE_SZ (128 * 1024)
16 18
17#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) 19/* CPU interrupt offsets */
20#define CPU_INT_GIC 2
21#define CPU_INT_EHCI 2
22#define CPU_INT_UART0 4
23#define CPU_INT_UART1 4
24#define CPU_INT_NET 6
25
26/* GIC interrupt offsets */
27#define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0)
28#define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2)
29#define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3)
30#define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5)
18 31
19#endif /* !(_MIPS_SEAD3INT_H) */ 32#endif /* !(_MIPS_SEAD3INT_H) */
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 6a9d2dd005ca..b95a827d763e 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -30,7 +30,7 @@ extern void __iomem *mips_cm_l2sync_base;
30 * different way by defining a function with the same prototype except for the 30 * different way by defining a function with the same prototype except for the
31 * name mips_cm_phys_base (without underscores). 31 * name mips_cm_phys_base (without underscores).
32 */ 32 */
33extern phys_t __mips_cm_phys_base(void); 33extern phys_addr_t __mips_cm_phys_base(void);
34 34
35/** 35/**
36 * mips_cm_probe - probe for a Coherence Manager 36 * mips_cm_probe - probe for a Coherence Manager
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index e139a534e0fd..1cebe8c79051 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -25,7 +25,7 @@ extern void __iomem *mips_cpc_base;
25 * memory mapped registers. This is platform dependant & must therefore be 25 * memory mapped registers. This is platform dependant & must therefore be
26 * implemented per-platform. 26 * implemented per-platform.
27 */ 27 */
28extern phys_t mips_cpc_default_phys_base(void); 28extern phys_addr_t mips_cpc_default_phys_base(void);
29 29
30/** 30/**
31 * mips_cpc_phys_base - retrieve the physical base address of the CPC 31 * mips_cpc_phys_base - retrieve the physical base address of the CPC
@@ -35,7 +35,7 @@ extern phys_t mips_cpc_default_phys_base(void);
35 * is present. It may be overriden by individual platforms which determine 35 * is present. It may be overriden by individual platforms which determine
36 * this address in a different way. 36 * this address in a different way.
37 */ 37 */
38extern phys_t __weak mips_cpc_phys_base(void); 38extern phys_addr_t __weak mips_cpc_phys_base(void);
39 39
40/** 40/**
41 * mips_cpc_probe - probe for a Cluster Power Controller 41 * mips_cpc_probe - probe for a Cluster Power Controller
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 22a135ac91de..5e4aef304b02 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -653,6 +653,9 @@
653#define MIPS_CONF5_NF (_ULCAST_(1) << 0) 653#define MIPS_CONF5_NF (_ULCAST_(1) << 0)
654#define MIPS_CONF5_UFR (_ULCAST_(1) << 2) 654#define MIPS_CONF5_UFR (_ULCAST_(1) << 2)
655#define MIPS_CONF5_MRP (_ULCAST_(1) << 3) 655#define MIPS_CONF5_MRP (_ULCAST_(1) << 3)
656#define MIPS_CONF5_MVH (_ULCAST_(1) << 5)
657#define MIPS_CONF5_FRE (_ULCAST_(1) << 8)
658#define MIPS_CONF5_UFE (_ULCAST_(1) << 9)
656#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) 659#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27)
657#define MIPS_CONF5_EVA (_ULCAST_(1) << 28) 660#define MIPS_CONF5_EVA (_ULCAST_(1) << 28)
658#define MIPS_CONF5_CV (_ULCAST_(1) << 29) 661#define MIPS_CONF5_CV (_ULCAST_(1) << 29)
@@ -694,6 +697,7 @@
694#define MIPS_FPIR_W (_ULCAST_(1) << 20) 697#define MIPS_FPIR_W (_ULCAST_(1) << 20)
695#define MIPS_FPIR_L (_ULCAST_(1) << 21) 698#define MIPS_FPIR_L (_ULCAST_(1) << 21)
696#define MIPS_FPIR_F64 (_ULCAST_(1) << 22) 699#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
700#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
697 701
698/* 702/*
699 * Bits in the MIPS32 Memory Segmentation registers. 703 * Bits in the MIPS32 Memory Segmentation registers.
@@ -994,6 +998,39 @@ do { \
994 local_irq_restore(__flags); \ 998 local_irq_restore(__flags); \
995} while (0) 999} while (0)
996 1000
1001#define __readx_32bit_c0_register(source) \
1002({ \
1003 unsigned int __res; \
1004 \
1005 __asm__ __volatile__( \
1006 " .set push \n" \
1007 " .set noat \n" \
1008 " .set mips32r2 \n" \
1009 " .insn \n" \
1010 " # mfhc0 $1, %1 \n" \
1011 " .word (0x40410000 | ((%1 & 0x1f) << 11)) \n" \
1012 " move %0, $1 \n" \
1013 " .set pop \n" \
1014 : "=r" (__res) \
1015 : "i" (source)); \
1016 __res; \
1017})
1018
1019#define __writex_32bit_c0_register(register, value) \
1020do { \
1021 __asm__ __volatile__( \
1022 " .set push \n" \
1023 " .set noat \n" \
1024 " .set mips32r2 \n" \
1025 " move $1, %0 \n" \
1026 " # mthc0 $1, %1 \n" \
1027 " .insn \n" \
1028 " .word (0x40c10000 | ((%1 & 0x1f) << 11)) \n" \
1029 " .set pop \n" \
1030 : \
1031 : "r" (value), "i" (register)); \
1032} while (0)
1033
997#define read_c0_index() __read_32bit_c0_register($0, 0) 1034#define read_c0_index() __read_32bit_c0_register($0, 0)
998#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) 1035#define write_c0_index(val) __write_32bit_c0_register($0, 0, val)
999 1036
@@ -1003,9 +1040,15 @@ do { \
1003#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) 1040#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
1004#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) 1041#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
1005 1042
1043#define readx_c0_entrylo0() __readx_32bit_c0_register(2)
1044#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val)
1045
1006#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) 1046#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
1007#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) 1047#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
1008 1048
1049#define readx_c0_entrylo1() __readx_32bit_c0_register(3)
1050#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val)
1051
1009#define read_c0_conf() __read_32bit_c0_register($3, 0) 1052#define read_c0_conf() __read_32bit_c0_register($3, 0)
1010#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) 1053#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
1011 1054
diff --git a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
index 024a71b2bff9..75739c83f07e 100644
--- a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
+++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
@@ -76,6 +76,8 @@
76 76
77#include <linux/prefetch.h> 77#include <linux/prefetch.h>
78 78
79#include <asm/compiler.h>
80
79#include <asm/octeon/cvmx-fpa.h> 81#include <asm/octeon/cvmx-fpa.h>
80/** 82/**
81 * By default we disable the max depth support. Most programs 83 * By default we disable the max depth support. Most programs
@@ -273,7 +275,7 @@ static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
273 " lbu %[ticket], %[now_serving]\n" 275 " lbu %[ticket], %[now_serving]\n"
274 "4:\n" 276 "4:\n"
275 ".set pop\n" : 277 ".set pop\n" :
276 [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), 278 [ticket_ptr] "=" GCC_OFF12_ASM()(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]),
277 [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), 279 [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp),
278 [my_ticket] "=r"(my_ticket) 280 [my_ticket] "=r"(my_ticket)
279 ); 281 );
diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h
index 4b4d0ecfd9eb..2188e65afb86 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow.h
@@ -1066,7 +1066,7 @@ static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
1066 uint64_t switch_complete; 1066 uint64_t switch_complete;
1067 CVMX_MF_CHORD(switch_complete); 1067 CVMX_MF_CHORD(switch_complete);
1068 if (!switch_complete) 1068 if (!switch_complete)
1069 pr_warning("%s called with tag switch in progress\n", function); 1069 pr_warn("%s called with tag switch in progress\n", function);
1070} 1070}
1071 1071
1072/** 1072/**
@@ -1084,8 +1084,7 @@ static inline void cvmx_pow_tag_sw_wait(void)
1084 if (unlikely(switch_complete)) 1084 if (unlikely(switch_complete))
1085 break; 1085 break;
1086 if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { 1086 if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
1087 pr_warning("Tag switch is taking a long time, " 1087 pr_warn("Tag switch is taking a long time, possible deadlock\n");
1088 "possible deadlock\n");
1089 start_cycle = -MAX_CYCLES - 1; 1088 start_cycle = -MAX_CYCLES - 1;
1090 } 1089 }
1091 } 1090 }
@@ -1296,19 +1295,16 @@ static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
1296 __cvmx_pow_warn_if_pending_switch(__func__); 1295 __cvmx_pow_warn_if_pending_switch(__func__);
1297 current_tag = cvmx_pow_get_current_tag(); 1296 current_tag = cvmx_pow_get_current_tag();
1298 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1297 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1299 pr_warning("%s called with NULL_NULL tag\n", 1298 pr_warn("%s called with NULL_NULL tag\n", __func__);
1300 __func__);
1301 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1299 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1302 pr_warning("%s called with NULL tag\n", __func__); 1300 pr_warn("%s called with NULL tag\n", __func__);
1303 if ((current_tag.s.type == tag_type) 1301 if ((current_tag.s.type == tag_type)
1304 && (current_tag.s.tag == tag)) 1302 && (current_tag.s.tag == tag))
1305 pr_warning("%s called to perform a tag switch to the " 1303 pr_warn("%s called to perform a tag switch to the same tag\n",
1306 "same tag\n", 1304 __func__);
1307 __func__);
1308 if (tag_type == CVMX_POW_TAG_TYPE_NULL) 1305 if (tag_type == CVMX_POW_TAG_TYPE_NULL)
1309 pr_warning("%s called to perform a tag switch to " 1306 pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n",
1310 "NULL. Use cvmx_pow_tag_sw_null() instead\n", 1307 __func__);
1311 __func__);
1312 } 1308 }
1313 1309
1314 /* 1310 /*
@@ -1407,23 +1403,19 @@ static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
1407 __cvmx_pow_warn_if_pending_switch(__func__); 1403 __cvmx_pow_warn_if_pending_switch(__func__);
1408 current_tag = cvmx_pow_get_current_tag(); 1404 current_tag = cvmx_pow_get_current_tag();
1409 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1405 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1410 pr_warning("%s called with NULL_NULL tag\n", 1406 pr_warn("%s called with NULL_NULL tag\n", __func__);
1411 __func__);
1412 if ((current_tag.s.type == tag_type) 1407 if ((current_tag.s.type == tag_type)
1413 && (current_tag.s.tag == tag)) 1408 && (current_tag.s.tag == tag))
1414 pr_warning("%s called to perform a tag switch to " 1409 pr_warn("%s called to perform a tag switch to the same tag\n",
1415 "the same tag\n", 1410 __func__);
1416 __func__);
1417 if (tag_type == CVMX_POW_TAG_TYPE_NULL) 1411 if (tag_type == CVMX_POW_TAG_TYPE_NULL)
1418 pr_warning("%s called to perform a tag switch to " 1412 pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n",
1419 "NULL. Use cvmx_pow_tag_sw_null() instead\n", 1413 __func__);
1420 __func__);
1421 if (wqp != cvmx_phys_to_ptr(0x80)) 1414 if (wqp != cvmx_phys_to_ptr(0x80))
1422 if (wqp != cvmx_pow_get_current_wqp()) 1415 if (wqp != cvmx_pow_get_current_wqp())
1423 pr_warning("%s passed WQE(%p) doesn't match " 1416 pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n",
1424 "the address in the POW(%p)\n", 1417 __func__, wqp,
1425 __func__, wqp, 1418 cvmx_pow_get_current_wqp());
1426 cvmx_pow_get_current_wqp());
1427 } 1419 }
1428 1420
1429 /* 1421 /*
@@ -1507,12 +1499,10 @@ static inline void cvmx_pow_tag_sw_null_nocheck(void)
1507 __cvmx_pow_warn_if_pending_switch(__func__); 1499 __cvmx_pow_warn_if_pending_switch(__func__);
1508 current_tag = cvmx_pow_get_current_tag(); 1500 current_tag = cvmx_pow_get_current_tag();
1509 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1501 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1510 pr_warning("%s called with NULL_NULL tag\n", 1502 pr_warn("%s called with NULL_NULL tag\n", __func__);
1511 __func__);
1512 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1503 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1513 pr_warning("%s called when we already have a " 1504 pr_warn("%s called when we already have a NULL tag\n",
1514 "NULL tag\n", 1505 __func__);
1515 __func__);
1516 } 1506 }
1517 1507
1518 tag_req.u64 = 0; 1508 tag_req.u64 = 0;
@@ -1725,17 +1715,14 @@ static inline void cvmx_pow_tag_sw_desched_nocheck(
1725 __cvmx_pow_warn_if_pending_switch(__func__); 1715 __cvmx_pow_warn_if_pending_switch(__func__);
1726 current_tag = cvmx_pow_get_current_tag(); 1716 current_tag = cvmx_pow_get_current_tag();
1727 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1717 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1728 pr_warning("%s called with NULL_NULL tag\n", 1718 pr_warn("%s called with NULL_NULL tag\n", __func__);
1729 __func__);
1730 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1719 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1731 pr_warning("%s called with NULL tag. Deschedule not " 1720 pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n",
1732 "allowed from NULL state\n", 1721 __func__);
1733 __func__);
1734 if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) 1722 if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
1735 && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) 1723 && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
1736 pr_warning("%s called where neither the before or " 1724 pr_warn("%s called where neither the before or after tag is ATOMIC\n",
1737 "after tag is ATOMIC\n", 1725 __func__);
1738 __func__);
1739 } 1726 }
1740 1727
1741 tag_req.u64 = 0; 1728 tag_req.u64 = 0;
@@ -1832,12 +1819,10 @@ static inline void cvmx_pow_desched(uint64_t no_sched)
1832 __cvmx_pow_warn_if_pending_switch(__func__); 1819 __cvmx_pow_warn_if_pending_switch(__func__);
1833 current_tag = cvmx_pow_get_current_tag(); 1820 current_tag = cvmx_pow_get_current_tag();
1834 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1821 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1835 pr_warning("%s called with NULL_NULL tag\n", 1822 pr_warn("%s called with NULL_NULL tag\n", __func__);
1836 __func__);
1837 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1823 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1838 pr_warning("%s called with NULL tag. Deschedule not " 1824 pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n",
1839 "expected from NULL state\n", 1825 __func__);
1840 __func__);
1841 } 1826 }
1842 1827
1843 /* Need to make sure any writes to the work queue entry are complete */ 1828 /* Need to make sure any writes to the work queue entry are complete */
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index f991e7701d3d..33db1c806b01 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -451,67 +451,4 @@ static inline uint32_t cvmx_octeon_num_cores(void)
451 return cvmx_pop(ciu_fuse); 451 return cvmx_pop(ciu_fuse);
452} 452}
453 453
454/**
455 * Read a byte of fuse data
456 * @byte_addr: address to read
457 *
458 * Returns fuse value: 0 or 1
459 */
460static uint8_t cvmx_fuse_read_byte(int byte_addr)
461{
462 union cvmx_mio_fus_rcmd read_cmd;
463
464 read_cmd.u64 = 0;
465 read_cmd.s.addr = byte_addr;
466 read_cmd.s.pend = 1;
467 cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
468 while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
469 && read_cmd.s.pend)
470 ;
471 return read_cmd.s.dat;
472}
473
474/**
475 * Read a single fuse bit
476 *
477 * @fuse: Fuse number (0-1024)
478 *
479 * Returns fuse value: 0 or 1
480 */
481static inline int cvmx_fuse_read(int fuse)
482{
483 return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1;
484}
485
486static inline int cvmx_octeon_model_CN36XX(void)
487{
488 return OCTEON_IS_MODEL(OCTEON_CN38XX)
489 && !cvmx_octeon_is_pass1()
490 && cvmx_fuse_read(264);
491}
492
493static inline int cvmx_octeon_zip_present(void)
494{
495 return octeon_has_feature(OCTEON_FEATURE_ZIP);
496}
497
498static inline int cvmx_octeon_dfa_present(void)
499{
500 if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
501 && !OCTEON_IS_MODEL(OCTEON_CN31XX)
502 && !OCTEON_IS_MODEL(OCTEON_CN58XX))
503 return 0;
504 else if (OCTEON_IS_MODEL(OCTEON_CN3020))
505 return 0;
506 else if (cvmx_octeon_is_pass1())
507 return 1;
508 else
509 return !cvmx_fuse_read(120);
510}
511
512static inline int cvmx_octeon_crypto_present(void)
513{
514 return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
515}
516
517#endif /* __CVMX_H__ */ 454#endif /* __CVMX_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
index 90e05a8d4b15..c4fe81f47f53 100644
--- a/arch/mips/include/asm/octeon/octeon-feature.h
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -86,8 +86,6 @@ enum octeon_feature {
86 OCTEON_MAX_FEATURE 86 OCTEON_MAX_FEATURE
87}; 87};
88 88
89static inline int cvmx_fuse_read(int fuse);
90
91/** 89/**
92 * Determine if the current Octeon supports a specific feature. These 90 * Determine if the current Octeon supports a specific feature. These
93 * checks have been optimized to be fairly quick, but they should still 91 * checks have been optimized to be fairly quick, but they should still
@@ -105,33 +103,6 @@ static inline int octeon_has_feature(enum octeon_feature feature)
105 case OCTEON_FEATURE_SAAD: 103 case OCTEON_FEATURE_SAAD:
106 return !OCTEON_IS_MODEL(OCTEON_CN3XXX); 104 return !OCTEON_IS_MODEL(OCTEON_CN3XXX);
107 105
108 case OCTEON_FEATURE_ZIP:
109 if (OCTEON_IS_MODEL(OCTEON_CN30XX)
110 || OCTEON_IS_MODEL(OCTEON_CN50XX)
111 || OCTEON_IS_MODEL(OCTEON_CN52XX))
112 return 0;
113 else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
114 return 1;
115 else
116 return !cvmx_fuse_read(121);
117
118 case OCTEON_FEATURE_CRYPTO:
119 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
120 union cvmx_mio_fus_dat2 fus_2;
121 fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
122 if (fus_2.s.nocrypto || fus_2.s.nomul) {
123 return 0;
124 } else if (!fus_2.s.dorm_crypto) {
125 return 1;
126 } else {
127 union cvmx_rnm_ctl_status st;
128 st.u64 = cvmx_read_csr(CVMX_RNM_CTL_STATUS);
129 return st.s.eer_val;
130 }
131 } else {
132 return !cvmx_fuse_read(90);
133 }
134
135 case OCTEON_FEATURE_DORM_CRYPTO: 106 case OCTEON_FEATURE_DORM_CRYPTO:
136 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { 107 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
137 union cvmx_mio_fus_dat2 fus_2; 108 union cvmx_mio_fus_dat2 fus_2;
@@ -188,29 +159,6 @@ static inline int octeon_has_feature(enum octeon_feature feature)
188 && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) 159 && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
189 && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); 160 && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X);
190 161
191 case OCTEON_FEATURE_DFA:
192 if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
193 && !OCTEON_IS_MODEL(OCTEON_CN31XX)
194 && !OCTEON_IS_MODEL(OCTEON_CN58XX))
195 return 0;
196 else if (OCTEON_IS_MODEL(OCTEON_CN3020))
197 return 0;
198 else
199 return !cvmx_fuse_read(120);
200
201 case OCTEON_FEATURE_HFA:
202 if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
203 return 0;
204 else
205 return !cvmx_fuse_read(90);
206
207 case OCTEON_FEATURE_DFM:
208 if (!(OCTEON_IS_MODEL(OCTEON_CN63XX)
209 || OCTEON_IS_MODEL(OCTEON_CN66XX)))
210 return 0;
211 else
212 return !cvmx_fuse_read(90);
213
214 case OCTEON_FEATURE_MDIO_CLAUSE_45: 162 case OCTEON_FEATURE_MDIO_CLAUSE_45:
215 return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) 163 return !(OCTEON_IS_MODEL(OCTEON_CN3XXX)
216 || OCTEON_IS_MODEL(OCTEON_CN58XX) 164 || OCTEON_IS_MODEL(OCTEON_CN58XX)
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index e2c122c6a657..e8a1c2fd52cd 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -326,8 +326,7 @@ static inline int __octeon_is_model_runtime__(uint32_t model)
326#define OCTEON_IS_COMMON_BINARY() 1 326#define OCTEON_IS_COMMON_BINARY() 1
327#undef OCTEON_MODEL 327#undef OCTEON_MODEL
328 328
329const char *octeon_model_get_string(uint32_t chip_id); 329const char *__init octeon_model_get_string(uint32_t chip_id);
330const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);
331 330
332/* 331/*
333 * Return the octeon family, i.e., ProcessorID of the PrID register. 332 * Return the octeon family, i.e., ProcessorID of the PrID register.
diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h
index 2474fc5d1751..af81ab0da55f 100644
--- a/arch/mips/include/asm/paccess.h
+++ b/arch/mips/include/asm/paccess.h
@@ -56,6 +56,7 @@ struct __large_pstruct { unsigned long buf[100]; };
56 "1:\t" insn "\t%1,%2\n\t" \ 56 "1:\t" insn "\t%1,%2\n\t" \
57 "move\t%0,$0\n" \ 57 "move\t%0,$0\n" \
58 "2:\n\t" \ 58 "2:\n\t" \
59 ".insn\n\t" \
59 ".section\t.fixup,\"ax\"\n" \ 60 ".section\t.fixup,\"ax\"\n" \
60 "3:\tli\t%0,%3\n\t" \ 61 "3:\tli\t%0,%3\n\t" \
61 "move\t%1,$0\n\t" \ 62 "move\t%1,$0\n\t" \
@@ -94,6 +95,7 @@ extern void __get_dbe_unknown(void);
94 "1:\t" insn "\t%1,%2\n\t" \ 95 "1:\t" insn "\t%1,%2\n\t" \
95 "move\t%0,$0\n" \ 96 "move\t%0,$0\n" \
96 "2:\n\t" \ 97 "2:\n\t" \
98 ".insn\n\t" \
97 ".section\t.fixup,\"ax\"\n" \ 99 ".section\t.fixup,\"ax\"\n" \
98 "3:\tli\t%0,%3\n\t" \ 100 "3:\tli\t%0,%3\n\t" \
99 "j\t2b\n\t" \ 101 "j\t2b\n\t" \
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 3be81803595d..154b70a10483 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -116,7 +116,7 @@ extern void copy_user_highpage(struct page *to, struct page *from,
116/* 116/*
117 * These are used to make use of C type-checking.. 117 * These are used to make use of C type-checking..
118 */ 118 */
119#ifdef CONFIG_64BIT_PHYS_ADDR 119#ifdef CONFIG_PHYS_ADDR_T_64BIT
120 #ifdef CONFIG_CPU_MIPS32 120 #ifdef CONFIG_CPU_MIPS32
121 typedef struct { unsigned long pte_low, pte_high; } pte_t; 121 typedef struct { unsigned long pte_low, pte_high; } pte_t;
122 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) 122 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 974b0e308963..69529624a005 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -84,7 +84,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
84 const struct resource *rsrc, resource_size_t *start, 84 const struct resource *rsrc, resource_size_t *start,
85 resource_size_t *end) 85 resource_size_t *end)
86{ 86{
87 phys_t size = resource_size(rsrc); 87 phys_addr_t size = resource_size(rsrc);
88 88
89 *start = fixup_bigphys_addr(rsrc->start, size); 89 *start = fixup_bigphys_addr(rsrc->start, size);
90 *end = rsrc->start + size; 90 *end = rsrc->start + size;
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index cd7d6064bcbe..68984b612f9d 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -69,7 +69,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
69# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) 69# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
70#endif 70#endif
71 71
72#ifdef CONFIG_64BIT_PHYS_ADDR 72#ifdef CONFIG_PHYS_ADDR_T_64BIT
73#define pte_ERROR(e) \ 73#define pte_ERROR(e) \
74 printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) 74 printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
75#else 75#else
@@ -103,7 +103,7 @@ static inline void pmd_clear(pmd_t *pmdp)
103 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); 103 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
104} 104}
105 105
106#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 106#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
107#define pte_page(x) pfn_to_page(pte_pfn(x)) 107#define pte_page(x) pfn_to_page(pte_pfn(x))
108#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) 108#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6))
109static inline pte_t 109static inline pte_t
@@ -126,7 +126,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
126#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) 126#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT))
127#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) 127#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
128#endif 128#endif
129#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ 129#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
130 130
131#define __pgd_offset(address) pgd_index(address) 131#define __pgd_offset(address) pgd_index(address)
132#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) 132#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
@@ -155,73 +155,75 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
155#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 155#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
156 156
157/* Swap entries must have VALID bit cleared. */ 157/* Swap entries must have VALID bit cleared. */
158#define __swp_type(x) (((x).val >> 10) & 0x1f) 158#define __swp_type(x) (((x).val >> 10) & 0x1f)
159#define __swp_offset(x) ((x).val >> 15) 159#define __swp_offset(x) ((x).val >> 15)
160#define __swp_entry(type,offset) \ 160#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 10) | ((offset) << 15) })
161 ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) 161#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
162#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
162 163
163/* 164/*
164 * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: 165 * Encode and decode a nonlinear file mapping entry
165 */ 166 */
166#define PTE_FILE_MAX_BITS 28 167#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \
167 168 (((_pte).pte >> 2 ) & 0x38) | \
168#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ 169 (((_pte).pte >> 10) << 6 ))
169 (((_pte).pte >> 2 ) & 0x38) | \
170 (((_pte).pte >> 10) << 6 ))
171 170
172#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ 171#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \
173 (((off) & 0x38) << 2 ) | \ 172 (((off) & 0x38) << 2 ) | \
174 (((off) >> 6 ) << 10) | \ 173 (((off) >> 6 ) << 10) | \
175 _PAGE_FILE }) 174 _PAGE_FILE })
176 175
176/*
177 * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range:
178 */
179#define PTE_FILE_MAX_BITS 28
177#else 180#else
178 181
182#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
183
179/* Swap entries must have VALID and GLOBAL bits cleared. */ 184/* Swap entries must have VALID and GLOBAL bits cleared. */
180#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 185#define __swp_type(x) (((x).val >> 2) & 0x1f)
181#define __swp_type(x) (((x).val >> 2) & 0x1f) 186#define __swp_offset(x) ((x).val >> 7)
182#define __swp_offset(x) ((x).val >> 7) 187#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) })
183#define __swp_entry(type,offset) \ 188#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
184 ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) 189#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
185#else
186#define __swp_type(x) (((x).val >> 8) & 0x1f)
187#define __swp_offset(x) ((x).val >> 13)
188#define __swp_entry(type,offset) \
189 ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
190#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
191 190
192#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
193/* 191/*
194 * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... 192 * Bits 0 and 1 of pte_high are taken, use the rest for the page offset...
195 */ 193 */
196#define PTE_FILE_MAX_BITS 30 194#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
197 195#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
198#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
199#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
200 196
197#define PTE_FILE_MAX_BITS 30
201#else 198#else
202/* 199/*
203 * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range: 200 * Constraints:
201 * _PAGE_PRESENT at bit 0
202 * _PAGE_MODIFIED at bit 4
203 * _PAGE_GLOBAL at bit 6
204 * _PAGE_VALID at bit 7
204 */ 205 */
205#define PTE_FILE_MAX_BITS 28 206#define __swp_type(x) (((x).val >> 8) & 0x1f)
207#define __swp_offset(x) ((x).val >> 13)
208#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
209#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
210#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
206 211
207#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ 212/*
208 (((_pte).pte >> 2) & 0x8) | \ 213 * Encode and decode a nonlinear file mapping entry
209 (((_pte).pte >> 8) << 4)) 214 */
215#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \
216 (((_pte).pte >> 2) & 0x8) | \
217 (((_pte).pte >> 8) << 4))
210 218
211#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ 219#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \
212 (((off) & 0x8) << 2) | \ 220 (((off) & 0x8) << 2) | \
213 (((off) >> 4) << 8) | \ 221 (((off) >> 4) << 8) | \
214 _PAGE_FILE }) 222 _PAGE_FILE })
215#endif
216 223
217#endif 224#define PTE_FILE_MAX_BITS 28
225#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
218 226
219#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 227#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */
220#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
221#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
222#else
223#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
224#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
225#endif
226 228
227#endif /* _ASM_PGTABLE_32_H */ 229#endif /* _ASM_PGTABLE_32_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index e747bfa0be7e..ca11f14f40a3 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -32,39 +32,41 @@
32 * unpredictable things. The code (when it is written) to deal with 32 * unpredictable things. The code (when it is written) to deal with
33 * this problem will be in the update_mmu_cache() code for the r4k. 33 * this problem will be in the update_mmu_cache() code for the r4k.
34 */ 34 */
35#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 35#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
36 36
37/* 37/*
38 * The following bits are directly used by the TLB hardware 38 * The following bits are directly used by the TLB hardware
39 */ 39 */
40#define _PAGE_R4KBUG (1 << 0) /* workaround for r4k bug */ 40#define _PAGE_GLOBAL_SHIFT 0
41#define _PAGE_GLOBAL (1 << 0) 41#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
42#define _PAGE_VALID_SHIFT 1 42#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)
43#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) 43#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
44#define _PAGE_SILENT_READ (1 << 1) /* synonym */ 44#define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1)
45#define _PAGE_DIRTY_SHIFT 2 45#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
46#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) /* The MIPS dirty bit */ 46#define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1)
47#define _PAGE_SILENT_WRITE (1 << 2) 47#define _CACHE_MASK (7 << _CACHE_SHIFT)
48#define _CACHE_SHIFT 3
49#define _CACHE_MASK (7 << 3)
50 48
51/* 49/*
52 * The following bits are implemented in software 50 * The following bits are implemented in software
53 * 51 *
54 * _PAGE_FILE semantics: set:pagecache unset:swap 52 * _PAGE_FILE semantics: set:pagecache unset:swap
55 */ 53 */
56#define _PAGE_PRESENT_SHIFT 6 54#define _PAGE_PRESENT_SHIFT (_CACHE_SHIFT + 3)
57#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) 55#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
58#define _PAGE_READ_SHIFT 7 56#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1)
59#define _PAGE_READ (1 << _PAGE_READ_SHIFT) 57#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
60#define _PAGE_WRITE_SHIFT 8 58#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
61#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) 59#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
62#define _PAGE_ACCESSED_SHIFT 9 60#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
63#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) 61#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
64#define _PAGE_MODIFIED_SHIFT 10 62#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
65#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) 63#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
66 64
67#define _PAGE_FILE (1 << 10) 65#define _PAGE_SILENT_READ _PAGE_VALID
66#define _PAGE_SILENT_WRITE _PAGE_DIRTY
67#define _PAGE_FILE _PAGE_MODIFIED
68
69#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
68 70
69#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 71#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
70 72
@@ -172,7 +174,7 @@
172 174
173#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) 175#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
174 176
175#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */ 177#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */
176 178
177#ifndef _PFN_SHIFT 179#ifndef _PFN_SHIFT
178#define _PFN_SHIFT PAGE_SHIFT 180#define _PFN_SHIFT PAGE_SHIFT
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index d6d1928539b1..62a6ba383d4f 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -125,7 +125,7 @@ do { \
125extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, 125extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
126 pte_t pteval); 126 pte_t pteval);
127 127
128#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 128#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
129 129
130#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) 130#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
131#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) 131#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT)
@@ -227,7 +227,7 @@ extern pgd_t swapper_pg_dir[];
227 * The following only work if pte_present() is true. 227 * The following only work if pte_present() is true.
228 * Undefined behaviour if not.. 228 * Undefined behaviour if not..
229 */ 229 */
230#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 230#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
231static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } 231static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; }
232static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } 232static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; }
233static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } 233static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
@@ -297,13 +297,13 @@ static inline pte_t pte_wrprotect(pte_t pte)
297 297
298static inline pte_t pte_mkclean(pte_t pte) 298static inline pte_t pte_mkclean(pte_t pte)
299{ 299{
300 pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); 300 pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
301 return pte; 301 return pte;
302} 302}
303 303
304static inline pte_t pte_mkold(pte_t pte) 304static inline pte_t pte_mkold(pte_t pte)
305{ 305{
306 pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); 306 pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
307 return pte; 307 return pte;
308} 308}
309 309
@@ -382,13 +382,13 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
382 */ 382 */
383#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) 383#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
384 384
385#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 385#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
386static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 386static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
387{ 387{
388 pte.pte_low &= _PAGE_CHG_MASK; 388 pte.pte_low &= _PAGE_CHG_MASK;
389 pte.pte_high &= ~0x3f; 389 pte.pte_high &= (_PFN_MASK | _CACHE_MASK);
390 pte.pte_low |= pgprot_val(newprot); 390 pte.pte_low |= pgprot_val(newprot);
391 pte.pte_high |= pgprot_val(newprot) & 0x3f; 391 pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK);
392 return pte; 392 return pte;
393} 393}
394#else 394#else
@@ -419,7 +419,7 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
419 419
420#define kern_addr_valid(addr) (1) 420#define kern_addr_valid(addr) (1)
421 421
422#ifdef CONFIG_64BIT_PHYS_ADDR 422#ifdef CONFIG_PHYS_ADDR_T_64BIT
423extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); 423extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
424 424
425static inline int io_remap_pfn_range(struct vm_area_struct *vma, 425static inline int io_remap_pfn_range(struct vm_area_struct *vma,
@@ -428,7 +428,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
428 unsigned long size, 428 unsigned long size,
429 pgprot_t prot) 429 pgprot_t prot)
430{ 430{
431 phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); 431 phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
432 return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); 432 return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
433} 433}
434#define io_remap_pfn_range io_remap_pfn_range 434#define io_remap_pfn_range io_remap_pfn_range
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
index a9494c0141fb..eaa26270a5e5 100644
--- a/arch/mips/include/asm/prom.h
+++ b/arch/mips/include/asm/prom.h
@@ -22,6 +22,7 @@ extern void device_tree_init(void);
22struct boot_param_header; 22struct boot_param_header;
23 23
24extern void __dt_setup_arch(void *bph); 24extern void __dt_setup_arch(void *bph);
25extern int __dt_register_buses(const char *bus0, const char *bus1);
25 26
26#define dt_setup_arch(sym) \ 27#define dt_setup_arch(sym) \
27({ \ 28({ \
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index cd6e0afc6833..e293a8d89a6d 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -47,79 +47,20 @@ extern void (*r4k_blast_icache)(void);
47 47
48#ifdef CONFIG_MIPS_MT 48#ifdef CONFIG_MIPS_MT
49 49
50/*
51 * Optionally force single-threaded execution during I-cache flushes.
52 */
53#define PROTECT_CACHE_FLUSHES 1
54
55#ifdef PROTECT_CACHE_FLUSHES
56
57extern int mt_protiflush;
58extern int mt_protdflush;
59extern void mt_cflush_lockdown(void);
60extern void mt_cflush_release(void);
61
62#define BEGIN_MT_IPROT \
63 unsigned long flags = 0; \
64 unsigned long mtflags = 0; \
65 if(mt_protiflush) { \
66 local_irq_save(flags); \
67 ehb(); \
68 mtflags = dvpe(); \
69 mt_cflush_lockdown(); \
70 }
71
72#define END_MT_IPROT \
73 if(mt_protiflush) { \
74 mt_cflush_release(); \
75 evpe(mtflags); \
76 local_irq_restore(flags); \
77 }
78
79#define BEGIN_MT_DPROT \
80 unsigned long flags = 0; \
81 unsigned long mtflags = 0; \
82 if(mt_protdflush) { \
83 local_irq_save(flags); \
84 ehb(); \
85 mtflags = dvpe(); \
86 mt_cflush_lockdown(); \
87 }
88
89#define END_MT_DPROT \
90 if(mt_protdflush) { \
91 mt_cflush_release(); \
92 evpe(mtflags); \
93 local_irq_restore(flags); \
94 }
95
96#else
97
98#define BEGIN_MT_IPROT
99#define BEGIN_MT_DPROT
100#define END_MT_IPROT
101#define END_MT_DPROT
102
103#endif /* PROTECT_CACHE_FLUSHES */
104
105#define __iflush_prologue \ 50#define __iflush_prologue \
106 unsigned long redundance; \ 51 unsigned long redundance; \
107 extern int mt_n_iflushes; \ 52 extern int mt_n_iflushes; \
108 BEGIN_MT_IPROT \
109 for (redundance = 0; redundance < mt_n_iflushes; redundance++) { 53 for (redundance = 0; redundance < mt_n_iflushes; redundance++) {
110 54
111#define __iflush_epilogue \ 55#define __iflush_epilogue \
112 END_MT_IPROT \
113 } 56 }
114 57
115#define __dflush_prologue \ 58#define __dflush_prologue \
116 unsigned long redundance; \ 59 unsigned long redundance; \
117 extern int mt_n_dflushes; \ 60 extern int mt_n_dflushes; \
118 BEGIN_MT_DPROT \
119 for (redundance = 0; redundance < mt_n_dflushes; redundance++) { 61 for (redundance = 0; redundance < mt_n_dflushes; redundance++) {
120 62
121#define __dflush_epilogue \ 63#define __dflush_epilogue \
122 END_MT_DPROT \
123 } 64 }
124 65
125#define __inv_dflush_prologue __dflush_prologue 66#define __inv_dflush_prologue __dflush_prologue
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h
index 78d201fb6c87..c6d06d383ef9 100644
--- a/arch/mips/include/asm/spinlock.h
+++ b/arch/mips/include/asm/spinlock.h
@@ -12,6 +12,7 @@
12#include <linux/compiler.h> 12#include <linux/compiler.h>
13 13
14#include <asm/barrier.h> 14#include <asm/barrier.h>
15#include <asm/compiler.h>
15#include <asm/war.h> 16#include <asm/war.h>
16 17
17/* 18/*
@@ -88,7 +89,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
88 " subu %[ticket], %[ticket], 1 \n" 89 " subu %[ticket], %[ticket], 1 \n"
89 " .previous \n" 90 " .previous \n"
90 " .set pop \n" 91 " .set pop \n"
91 : [ticket_ptr] "+m" (lock->lock), 92 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
92 [serving_now_ptr] "+m" (lock->h.serving_now), 93 [serving_now_ptr] "+m" (lock->h.serving_now),
93 [ticket] "=&r" (tmp), 94 [ticket] "=&r" (tmp),
94 [my_ticket] "=&r" (my_ticket) 95 [my_ticket] "=&r" (my_ticket)
@@ -121,7 +122,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
121 " subu %[ticket], %[ticket], 1 \n" 122 " subu %[ticket], %[ticket], 1 \n"
122 " .previous \n" 123 " .previous \n"
123 " .set pop \n" 124 " .set pop \n"
124 : [ticket_ptr] "+m" (lock->lock), 125 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
125 [serving_now_ptr] "+m" (lock->h.serving_now), 126 [serving_now_ptr] "+m" (lock->h.serving_now),
126 [ticket] "=&r" (tmp), 127 [ticket] "=&r" (tmp),
127 [my_ticket] "=&r" (my_ticket) 128 [my_ticket] "=&r" (my_ticket)
@@ -163,7 +164,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
163 " li %[ticket], 0 \n" 164 " li %[ticket], 0 \n"
164 " .previous \n" 165 " .previous \n"
165 " .set pop \n" 166 " .set pop \n"
166 : [ticket_ptr] "+m" (lock->lock), 167 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
167 [ticket] "=&r" (tmp), 168 [ticket] "=&r" (tmp),
168 [my_ticket] "=&r" (tmp2), 169 [my_ticket] "=&r" (tmp2),
169 [now_serving] "=&r" (tmp3) 170 [now_serving] "=&r" (tmp3)
@@ -187,7 +188,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
187 " li %[ticket], 0 \n" 188 " li %[ticket], 0 \n"
188 " .previous \n" 189 " .previous \n"
189 " .set pop \n" 190 " .set pop \n"
190 : [ticket_ptr] "+m" (lock->lock), 191 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
191 [ticket] "=&r" (tmp), 192 [ticket] "=&r" (tmp),
192 [my_ticket] "=&r" (tmp2), 193 [my_ticket] "=&r" (tmp2),
193 [now_serving] "=&r" (tmp3) 194 [now_serving] "=&r" (tmp3)
@@ -234,8 +235,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
234 " beqzl %1, 1b \n" 235 " beqzl %1, 1b \n"
235 " nop \n" 236 " nop \n"
236 " .set reorder \n" 237 " .set reorder \n"
237 : "=m" (rw->lock), "=&r" (tmp) 238 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
238 : "m" (rw->lock) 239 : GCC_OFF12_ASM() (rw->lock)
239 : "memory"); 240 : "memory");
240 } else { 241 } else {
241 do { 242 do {
@@ -244,8 +245,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
244 " bltz %1, 1b \n" 245 " bltz %1, 1b \n"
245 " addu %1, 1 \n" 246 " addu %1, 1 \n"
246 "2: sc %1, %0 \n" 247 "2: sc %1, %0 \n"
247 : "=m" (rw->lock), "=&r" (tmp) 248 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
248 : "m" (rw->lock) 249 : GCC_OFF12_ASM() (rw->lock)
249 : "memory"); 250 : "memory");
250 } while (unlikely(!tmp)); 251 } while (unlikely(!tmp));
251 } 252 }
@@ -268,8 +269,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
268 " sub %1, 1 \n" 269 " sub %1, 1 \n"
269 " sc %1, %0 \n" 270 " sc %1, %0 \n"
270 " beqzl %1, 1b \n" 271 " beqzl %1, 1b \n"
271 : "=m" (rw->lock), "=&r" (tmp) 272 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
272 : "m" (rw->lock) 273 : GCC_OFF12_ASM() (rw->lock)
273 : "memory"); 274 : "memory");
274 } else { 275 } else {
275 do { 276 do {
@@ -277,8 +278,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
277 "1: ll %1, %2 # arch_read_unlock \n" 278 "1: ll %1, %2 # arch_read_unlock \n"
278 " sub %1, 1 \n" 279 " sub %1, 1 \n"
279 " sc %1, %0 \n" 280 " sc %1, %0 \n"
280 : "=m" (rw->lock), "=&r" (tmp) 281 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
281 : "m" (rw->lock) 282 : GCC_OFF12_ASM() (rw->lock)
282 : "memory"); 283 : "memory");
283 } while (unlikely(!tmp)); 284 } while (unlikely(!tmp));
284 } 285 }
@@ -298,8 +299,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
298 " beqzl %1, 1b \n" 299 " beqzl %1, 1b \n"
299 " nop \n" 300 " nop \n"
300 " .set reorder \n" 301 " .set reorder \n"
301 : "=m" (rw->lock), "=&r" (tmp) 302 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
302 : "m" (rw->lock) 303 : GCC_OFF12_ASM() (rw->lock)
303 : "memory"); 304 : "memory");
304 } else { 305 } else {
305 do { 306 do {
@@ -308,8 +309,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
308 " bnez %1, 1b \n" 309 " bnez %1, 1b \n"
309 " lui %1, 0x8000 \n" 310 " lui %1, 0x8000 \n"
310 "2: sc %1, %0 \n" 311 "2: sc %1, %0 \n"
311 : "=m" (rw->lock), "=&r" (tmp) 312 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
312 : "m" (rw->lock) 313 : GCC_OFF12_ASM() (rw->lock)
313 : "memory"); 314 : "memory");
314 } while (unlikely(!tmp)); 315 } while (unlikely(!tmp));
315 } 316 }
@@ -348,8 +349,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
348 __WEAK_LLSC_MB 349 __WEAK_LLSC_MB
349 " li %2, 1 \n" 350 " li %2, 1 \n"
350 "2: \n" 351 "2: \n"
351 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 352 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
352 : "m" (rw->lock) 353 : GCC_OFF12_ASM() (rw->lock)
353 : "memory"); 354 : "memory");
354 } else { 355 } else {
355 __asm__ __volatile__( 356 __asm__ __volatile__(
@@ -365,8 +366,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
365 __WEAK_LLSC_MB 366 __WEAK_LLSC_MB
366 " li %2, 1 \n" 367 " li %2, 1 \n"
367 "2: \n" 368 "2: \n"
368 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 369 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
369 : "m" (rw->lock) 370 : GCC_OFF12_ASM() (rw->lock)
370 : "memory"); 371 : "memory");
371 } 372 }
372 373
@@ -392,8 +393,8 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
392 " li %2, 1 \n" 393 " li %2, 1 \n"
393 " .set reorder \n" 394 " .set reorder \n"
394 "2: \n" 395 "2: \n"
395 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 396 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
396 : "m" (rw->lock) 397 : GCC_OFF12_ASM() (rw->lock)
397 : "memory"); 398 : "memory");
398 } else { 399 } else {
399 do { 400 do {
@@ -405,8 +406,9 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
405 " sc %1, %0 \n" 406 " sc %1, %0 \n"
406 " li %2, 1 \n" 407 " li %2, 1 \n"
407 "2: \n" 408 "2: \n"
408 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 409 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp),
409 : "m" (rw->lock) 410 "=&r" (ret)
411 : GCC_OFF12_ASM() (rw->lock)
410 : "memory"); 412 : "memory");
411 } while (unlikely(!tmp)); 413 } while (unlikely(!tmp));
412 414
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 7de865805deb..99eea59604e9 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void)
116#define TIF_LOAD_WATCH 25 /* If set, load watch registers */ 116#define TIF_LOAD_WATCH 25 /* If set, load watch registers */
117#define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ 117#define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */
118#define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ 118#define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */
119#define TIF_HYBRID_FPREGS 28 /* 64b FP registers, odd singles in bits 63:32 of even doubles */
119#define TIF_USEDMSA 29 /* MSA has been used this quantum */ 120#define TIF_USEDMSA 29 /* MSA has been used this quantum */
120#define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ 121#define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */
121#define TIF_SYSCALL_TRACE 31 /* syscall trace active */ 122#define TIF_SYSCALL_TRACE 31 /* syscall trace active */
@@ -135,6 +136,7 @@ static inline struct thread_info *current_thread_info(void)
135#define _TIF_FPUBOUND (1<<TIF_FPUBOUND) 136#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
136#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) 137#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
137#define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS) 138#define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS)
139#define _TIF_HYBRID_FPREGS (1<<TIF_HYBRID_FPREGS)
138#define _TIF_USEDMSA (1<<TIF_USEDMSA) 140#define _TIF_USEDMSA (1<<TIF_USEDMSA)
139#define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE) 141#define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE)
140#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) 142#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index 8f3047d611ee..8ab2874225c4 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -46,19 +46,17 @@ extern unsigned int mips_hpt_frequency;
46 * so it lives here. 46 * so it lives here.
47 */ 47 */
48extern int (*perf_irq)(void); 48extern int (*perf_irq)(void);
49extern int __weak get_c0_perfcount_int(void);
49 50
50/* 51/*
51 * Initialize the calling CPU's compare interrupt as clockevent device 52 * Initialize the calling CPU's compare interrupt as clockevent device
52 */ 53 */
53extern unsigned int __weak get_c0_compare_int(void); 54extern unsigned int __weak get_c0_compare_int(void);
54extern int r4k_clockevent_init(void); 55extern int r4k_clockevent_init(void);
55extern int gic_clockevent_init(void);
56 56
57static inline int mips_clockevent_init(void) 57static inline int mips_clockevent_init(void)
58{ 58{
59#if defined(CONFIG_CEVT_GIC) 59#ifdef CONFIG_CEVT_R4K
60 return (gic_clockevent_init() | r4k_clockevent_init());
61#elif defined(CONFIG_CEVT_R4K)
62 return r4k_clockevent_init(); 60 return r4k_clockevent_init();
63#else 61#else
64 return -ENXIO; 62 return -ENXIO;
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
index a845aafedee4..148d42a17f30 100644
--- a/arch/mips/include/asm/types.h
+++ b/arch/mips/include/asm/types.h
@@ -11,23 +11,7 @@
11#ifndef _ASM_TYPES_H 11#ifndef _ASM_TYPES_H
12#define _ASM_TYPES_H 12#define _ASM_TYPES_H
13 13
14# include <asm-generic/int-ll64.h> 14#include <asm-generic/int-ll64.h>
15#include <uapi/asm/types.h> 15#include <uapi/asm/types.h>
16 16
17/*
18 * These aren't exported outside the kernel to avoid name space clashes
19 */
20#ifndef __ASSEMBLY__
21
22/*
23 * Don't use phys_t. You've been warned.
24 */
25#ifdef CONFIG_64BIT_PHYS_ADDR
26typedef unsigned long long phys_t;
27#else
28typedef unsigned long phys_t;
29#endif
30
31#endif /* __ASSEMBLY__ */
32
33#endif /* _ASM_TYPES_H */ 17#endif /* _ASM_TYPES_H */
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 22a5624e2fd2..bf8b32450ef6 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -1325,33 +1325,6 @@ strncpy_from_user(char *__to, const char __user *__from, long __len)
1325 return res; 1325 return res;
1326} 1326}
1327 1327
1328/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
1329static inline long __strlen_user(const char __user *s)
1330{
1331 long res;
1332
1333 if (segment_eq(get_fs(), get_ds())) {
1334 __asm__ __volatile__(
1335 "move\t$4, %1\n\t"
1336 __MODULE_JAL(__strlen_kernel_nocheck_asm)
1337 "move\t%0, $2"
1338 : "=r" (res)
1339 : "r" (s)
1340 : "$2", "$4", __UA_t0, "$31");
1341 } else {
1342 might_fault();
1343 __asm__ __volatile__(
1344 "move\t$4, %1\n\t"
1345 __MODULE_JAL(__strlen_user_nocheck_asm)
1346 "move\t%0, $2"
1347 : "=r" (res)
1348 : "r" (s)
1349 : "$2", "$4", __UA_t0, "$31");
1350 }
1351
1352 return res;
1353}
1354
1355/* 1328/*
1356 * strlen_user: - Get the size of a string in user space. 1329 * strlen_user: - Get the size of a string in user space.
1357 * @str: The string to measure. 1330 * @str: The string to measure.
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 708c5d414905..fc1cdd25fcda 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -136,9 +136,11 @@ Ip_u1s2(_lui);
136Ip_u2s3u1(_lw); 136Ip_u2s3u1(_lw);
137Ip_u3u1u2(_lwx); 137Ip_u3u1u2(_lwx);
138Ip_u1u2u3(_mfc0); 138Ip_u1u2u3(_mfc0);
139Ip_u1u2u3(_mfhc0);
139Ip_u1(_mfhi); 140Ip_u1(_mfhi);
140Ip_u1(_mflo); 141Ip_u1(_mflo);
141Ip_u1u2u3(_mtc0); 142Ip_u1u2u3(_mtc0);
143Ip_u1u2u3(_mthc0);
142Ip_u3u1u2(_mul); 144Ip_u3u1u2(_mul);
143Ip_u3u1u2(_or); 145Ip_u3u1u2(_or);
144Ip_u2u1u3(_ori); 146Ip_u2u1u3(_ori);
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h
index 4bfdb9d4c186..89c22433b1c6 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -108,9 +108,10 @@ enum rt_op {
108 */ 108 */
109enum cop_op { 109enum cop_op {
110 mfc_op = 0x00, dmfc_op = 0x01, 110 mfc_op = 0x00, dmfc_op = 0x01,
111 cfc_op = 0x02, mfhc_op = 0x03, 111 cfc_op = 0x02, mfhc0_op = 0x02,
112 mtc_op = 0x04, dmtc_op = 0x05, 112 mfhc_op = 0x03, mtc_op = 0x04,
113 ctc_op = 0x06, mthc_op = 0x07, 113 dmtc_op = 0x05, ctc_op = 0x06,
114 mthc0_op = 0x06, mthc_op = 0x07,
114 bc_op = 0x08, cop_op = 0x10, 115 bc_op = 0x08, cop_op = 0x10,
115 copm_op = 0x18 116 copm_op = 0x18
116}; 117};
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 76eafcb79c89..ef796f97b996 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -32,7 +32,7 @@ static void __init jz4740_detect_mem(void)
32{ 32{
33 void __iomem *jz_emc_base; 33 void __iomem *jz_emc_base;
34 u32 ctrl, bus, bank, rows, cols; 34 u32 ctrl, bus, bank, rows, cols;
35 phys_t size; 35 phys_addr_t size;
36 36
37 jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); 37 jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100);
38 ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); 38 ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL);
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 008a2fed0584..92987d1bbe5f 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -4,9 +4,10 @@
4 4
5extra-y := head.o vmlinux.lds 5extra-y := head.o vmlinux.lds
6 6
7obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ 7obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \
8 prom.o ptrace.o reset.o setup.o signal.o syscall.o \ 8 process.o prom.o ptrace.o reset.o setup.o signal.o \
9 time.o topology.o traps.o unaligned.o watch.o vdso.o 9 syscall.o time.o topology.o traps.o unaligned.o watch.o \
10 vdso.o
10 11
11ifdef CONFIG_FUNCTION_TRACER 12ifdef CONFIG_FUNCTION_TRACER
12CFLAGS_REMOVE_ftrace.o = -pg 13CFLAGS_REMOVE_ftrace.o = -pg
@@ -18,12 +19,10 @@ endif
18obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o 19obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
19obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 20obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
20obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o 21obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
21obj-$(CONFIG_CEVT_GIC) += cevt-gic.o
22obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o 22obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
23obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o 23obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
24obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o 24obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
25obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o 25obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
26obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
27obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o 26obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
28obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o 27obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
29obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o 28obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
@@ -68,7 +67,6 @@ obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
68obj-$(CONFIG_MIPS_MSC) += irq-msc01.o 67obj-$(CONFIG_MIPS_MSC) += irq-msc01.o
69obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o 68obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o
70obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o 69obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o
71obj-$(CONFIG_IRQ_GIC) += irq-gic.o
72 70
73obj-$(CONFIG_KPROBES) += kprobes.o 71obj-$(CONFIG_KPROBES) += kprobes.o
74obj-$(CONFIG_32BIT) += scall32-o32.o 72obj-$(CONFIG_32BIT) += scall32-o32.o
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c
deleted file mode 100644
index 6093716980b9..000000000000
--- a/arch/mips/kernel/cevt-gic.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2013 Imagination Technologies Ltd.
7 */
8#include <linux/clockchips.h>
9#include <linux/interrupt.h>
10#include <linux/percpu.h>
11#include <linux/smp.h>
12#include <linux/irq.h>
13
14#include <asm/time.h>
15#include <asm/gic.h>
16#include <asm/mips-boards/maltaint.h>
17
18DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
19int gic_timer_irq_installed;
20
21
22static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
23{
24 u64 cnt;
25 int res;
26
27 cnt = gic_read_count();
28 cnt += (u64)delta;
29 gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
30 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
31 return res;
32}
33
34void gic_set_clock_mode(enum clock_event_mode mode,
35 struct clock_event_device *evt)
36{
37 /* Nothing to do ... */
38}
39
40irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
41{
42 struct clock_event_device *cd;
43 int cpu = smp_processor_id();
44
45 gic_write_compare(gic_read_compare());
46 cd = &per_cpu(gic_clockevent_device, cpu);
47 cd->event_handler(cd);
48 return IRQ_HANDLED;
49}
50
51struct irqaction gic_compare_irqaction = {
52 .handler = gic_compare_interrupt,
53 .flags = IRQF_PERCPU | IRQF_TIMER,
54 .name = "timer",
55};
56
57
58void gic_event_handler(struct clock_event_device *dev)
59{
60}
61
62int gic_clockevent_init(void)
63{
64 unsigned int cpu = smp_processor_id();
65 struct clock_event_device *cd;
66 unsigned int irq;
67
68 if (!cpu_has_counter || !gic_frequency)
69 return -ENXIO;
70
71 irq = MIPS_GIC_IRQ_BASE;
72
73 cd = &per_cpu(gic_clockevent_device, cpu);
74
75 cd->name = "MIPS GIC";
76 cd->features = CLOCK_EVT_FEAT_ONESHOT |
77 CLOCK_EVT_FEAT_C3STOP;
78
79 clockevent_set_clock(cd, gic_frequency);
80
81 /* Calculate the min / max delta */
82 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
83 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
84
85 cd->rating = 300;
86 cd->irq = irq;
87 cd->cpumask = cpumask_of(cpu);
88 cd->set_next_event = gic_next_event;
89 cd->set_mode = gic_set_clock_mode;
90 cd->event_handler = gic_event_handler;
91
92 clockevents_register_device(cd);
93
94 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002);
95 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK);
96
97 if (gic_timer_irq_installed)
98 return 0;
99
100 gic_timer_irq_installed = 1;
101
102 setup_irq(irq, &gic_compare_irqaction);
103 irq_set_handler(irq, handle_percpu_irq);
104 return 0;
105}
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index bc127e22fdab..6acaad0480af 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -11,10 +11,10 @@
11#include <linux/percpu.h> 11#include <linux/percpu.h>
12#include <linux/smp.h> 12#include <linux/smp.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/irqchip/mips-gic.h>
14 15
15#include <asm/time.h> 16#include <asm/time.h>
16#include <asm/cevt-r4k.h> 17#include <asm/cevt-r4k.h>
17#include <asm/gic.h>
18 18
19static int mips_next_event(unsigned long delta, 19static int mips_next_event(unsigned long delta,
20 struct clock_event_device *evt) 20 struct clock_event_device *evt)
@@ -85,8 +85,8 @@ void mips_event_handler(struct clock_event_device *dev)
85 */ 85 */
86static int c0_compare_int_pending(void) 86static int c0_compare_int_pending(void)
87{ 87{
88#ifdef CONFIG_IRQ_GIC 88#ifdef CONFIG_MIPS_GIC
89 if (cpu_has_veic) 89 if (gic_present)
90 return gic_get_timer_pending(); 90 return gic_get_timer_pending();
91#endif 91#endif
92 return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); 92 return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index dc49cf30c2db..5342674842f5 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -69,6 +69,63 @@ static int __init htw_disable(char *s)
69 69
70__setup("nohtw", htw_disable); 70__setup("nohtw", htw_disable);
71 71
72static int mips_ftlb_disabled;
73static int mips_has_ftlb_configured;
74
75static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);
76
77static int __init ftlb_disable(char *s)
78{
79 unsigned int config4, mmuextdef;
80
81 /*
82 * If the core hasn't done any FTLB configuration, there is nothing
83 * for us to do here.
84 */
85 if (!mips_has_ftlb_configured)
86 return 1;
87
88 /* Disable it in the boot cpu */
89 set_ftlb_enable(&cpu_data[0], 0);
90
91 back_to_back_c0_hazard();
92
93 config4 = read_c0_config4();
94
95 /* Check that FTLB has been disabled */
96 mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
97 /* MMUSIZEEXT == VTLB ON, FTLB OFF */
98 if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) {
99 /* This should never happen */
100 pr_warn("FTLB could not be disabled!\n");
101 return 1;
102 }
103
104 mips_ftlb_disabled = 1;
105 mips_has_ftlb_configured = 0;
106
107 /*
108 * noftlb is mainly used for debug purposes so print
109 * an informative message instead of using pr_debug()
110 */
111 pr_info("FTLB has been disabled\n");
112
113 /*
114 * Some of these bits are duplicated in the decode_config4.
115 * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case
116 * once FTLB has been disabled so undo what decode_config4 did.
117 */
118 cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways *
119 cpu_data[0].tlbsizeftlbsets;
120 cpu_data[0].tlbsizeftlbsets = 0;
121 cpu_data[0].tlbsizeftlbways = 0;
122
123 return 1;
124}
125
126__setup("noftlb", ftlb_disable);
127
128
72static inline void check_errata(void) 129static inline void check_errata(void)
73{ 130{
74 struct cpuinfo_mips *c = &current_cpu_data; 131 struct cpuinfo_mips *c = &current_cpu_data;
@@ -140,7 +197,7 @@ static inline unsigned long cpu_get_fpu_id(void)
140 */ 197 */
141static inline int __cpu_has_fpu(void) 198static inline int __cpu_has_fpu(void)
142{ 199{
143 return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); 200 return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
144} 201}
145 202
146static inline unsigned long cpu_get_msa_id(void) 203static inline unsigned long cpu_get_msa_id(void)
@@ -399,6 +456,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
399 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; 456 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
400 /* fall through */ 457 /* fall through */
401 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: 458 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
459 if (mips_ftlb_disabled)
460 break;
402 newcf4 = (config4 & ~ftlb_page) | 461 newcf4 = (config4 & ~ftlb_page) |
403 (page_size_ftlb(mmuextdef) << 462 (page_size_ftlb(mmuextdef) <<
404 MIPS_CONF4_FTLBPAGESIZE_SHIFT); 463 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
@@ -418,6 +477,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
418 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> 477 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
419 MIPS_CONF4_FTLBWAYS_SHIFT) + 2; 478 MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
420 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; 479 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
480 mips_has_ftlb_configured = 1;
421 break; 481 break;
422 } 482 }
423 } 483 }
@@ -432,7 +492,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
432 unsigned int config5; 492 unsigned int config5;
433 493
434 config5 = read_c0_config5(); 494 config5 = read_c0_config5();
435 config5 &= ~MIPS_CONF5_UFR; 495 config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
436 write_c0_config5(config5); 496 write_c0_config5(config5);
437 497
438 if (config5 & MIPS_CONF5_EVA) 498 if (config5 & MIPS_CONF5_EVA)
@@ -453,8 +513,8 @@ static void decode_configs(struct cpuinfo_mips *c)
453 513
454 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 514 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
455 515
456 /* Enable FTLB if present */ 516 /* Enable FTLB if present and not disabled */
457 set_ftlb_enable(c, 1); 517 set_ftlb_enable(c, !mips_ftlb_disabled);
458 518
459 ok = decode_config0(c); /* Read Config registers. */ 519 ok = decode_config0(c); /* Read Config registers. */
460 BUG_ON(!ok); /* Arch spec violation! */ 520 BUG_ON(!ok); /* Arch spec violation! */
@@ -1058,6 +1118,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
1058 break; 1118 break;
1059 } 1119 }
1060 case PRID_IMP_BMIPS5000: 1120 case PRID_IMP_BMIPS5000:
1121 case PRID_IMP_BMIPS5200:
1061 c->cputype = CPU_BMIPS5000; 1122 c->cputype = CPU_BMIPS5000;
1062 __cpu_name[cpu] = "Broadcom BMIPS5000"; 1123 __cpu_name[cpu] = "Broadcom BMIPS5000";
1063 set_elf_platform(cpu, "bmips5000"); 1124 set_elf_platform(cpu, "bmips5000");
@@ -1288,6 +1349,8 @@ void cpu_probe(void)
1288 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { 1349 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
1289 if (c->fpu_id & MIPS_FPIR_3D) 1350 if (c->fpu_id & MIPS_FPIR_3D)
1290 c->ases |= MIPS_ASE_MIPS3D; 1351 c->ases |= MIPS_ASE_MIPS3D;
1352 if (c->fpu_id & MIPS_FPIR_FREP)
1353 c->options |= MIPS_CPU_FRE;
1291 } 1354 }
1292 } 1355 }
1293 1356
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c
index f291cf99b03a..6fe7790e5868 100644
--- a/arch/mips/kernel/crash_dump.c
+++ b/arch/mips/kernel/crash_dump.c
@@ -38,7 +38,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
38 kunmap_atomic(vaddr); 38 kunmap_atomic(vaddr);
39 } else { 39 } else {
40 if (!kdump_buf_page) { 40 if (!kdump_buf_page) {
41 pr_warning("Kdump: Kdump buffer page not allocated\n"); 41 pr_warn("Kdump: Kdump buffer page not allocated\n");
42 42
43 return -EFAULT; 43 return -EFAULT;
44 } 44 }
@@ -57,7 +57,7 @@ static int __init kdump_buf_page_init(void)
57 57
58 kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); 58 kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
59 if (!kdump_buf_page) { 59 if (!kdump_buf_page) {
60 pr_warning("Kdump: Failed to allocate kdump buffer page\n"); 60 pr_warn("Kdump: Failed to allocate kdump buffer page\n");
61 ret = -ENOMEM; 61 ret = -ENOMEM;
62 } 62 }
63 63
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c
deleted file mode 100644
index e02620901117..000000000000
--- a/arch/mips/kernel/csrc-gic.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */
8#include <linux/init.h>
9#include <linux/time.h>
10
11#include <asm/gic.h>
12
13static cycle_t gic_hpt_read(struct clocksource *cs)
14{
15 return gic_read_count();
16}
17
18static struct clocksource gic_clocksource = {
19 .name = "GIC",
20 .read = gic_hpt_read,
21 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
22};
23
24void __init gic_clocksource_init(unsigned int frequency)
25{
26 unsigned int config, bits;
27
28 /* Calculate the clocksource mask. */
29 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
30 bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
31 (GIC_SH_CONFIG_COUNTBITS_SHF - 2));
32
33 /* Set clocksource mask. */
34 gic_clocksource.mask = CLOCKSOURCE_MASK(bits);
35
36 /* Calculate a somewhat reasonable rating value. */
37 gic_clocksource.rating = 200 + frequency / 10000000;
38
39 clocksource_register_hz(&gic_clocksource, frequency);
40}
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
new file mode 100644
index 000000000000..c92b15df6893
--- /dev/null
+++ b/arch/mips/kernel/elf.c
@@ -0,0 +1,191 @@
1/*
2 * Copyright (C) 2014 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/elf.h>
12#include <linux/sched.h>
13
14enum {
15 FP_ERROR = -1,
16 FP_DOUBLE_64A = -2,
17};
18
19int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
20 bool is_interp, struct arch_elf_state *state)
21{
22 struct elfhdr *ehdr = _ehdr;
23 struct elf_phdr *phdr = _phdr;
24 struct mips_elf_abiflags_v0 abiflags;
25 int ret;
26
27 if (config_enabled(CONFIG_64BIT) &&
28 (ehdr->e_ident[EI_CLASS] != ELFCLASS32))
29 return 0;
30 if (phdr->p_type != PT_MIPS_ABIFLAGS)
31 return 0;
32 if (phdr->p_filesz < sizeof(abiflags))
33 return -EINVAL;
34
35 ret = kernel_read(elf, phdr->p_offset, (char *)&abiflags,
36 sizeof(abiflags));
37 if (ret < 0)
38 return ret;
39 if (ret != sizeof(abiflags))
40 return -EIO;
41
42 /* Record the required FP ABIs for use by mips_check_elf */
43 if (is_interp)
44 state->interp_fp_abi = abiflags.fp_abi;
45 else
46 state->fp_abi = abiflags.fp_abi;
47
48 return 0;
49}
50
51static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi)
52{
53 /* If the ABI requirement is provided, simply return that */
54 if (in_abi != -1)
55 return in_abi;
56
57 /* If the EF_MIPS_FP64 flag was set, return MIPS_ABI_FP_64 */
58 if (ehdr->e_flags & EF_MIPS_FP64)
59 return MIPS_ABI_FP_64;
60
61 /* Default to MIPS_ABI_FP_DOUBLE */
62 return MIPS_ABI_FP_DOUBLE;
63}
64
65int arch_check_elf(void *_ehdr, bool has_interpreter,
66 struct arch_elf_state *state)
67{
68 struct elfhdr *ehdr = _ehdr;
69 unsigned fp_abi, interp_fp_abi, abi0, abi1;
70
71 /* Ignore non-O32 binaries */
72 if (config_enabled(CONFIG_64BIT) &&
73 (ehdr->e_ident[EI_CLASS] != ELFCLASS32))
74 return 0;
75
76 fp_abi = get_fp_abi(ehdr, state->fp_abi);
77
78 if (has_interpreter) {
79 interp_fp_abi = get_fp_abi(ehdr, state->interp_fp_abi);
80
81 abi0 = min(fp_abi, interp_fp_abi);
82 abi1 = max(fp_abi, interp_fp_abi);
83 } else {
84 abi0 = abi1 = fp_abi;
85 }
86
87 state->overall_abi = FP_ERROR;
88
89 if (abi0 == abi1) {
90 state->overall_abi = abi0;
91 } else if (abi0 == MIPS_ABI_FP_ANY) {
92 state->overall_abi = abi1;
93 } else if (abi0 == MIPS_ABI_FP_DOUBLE) {
94 switch (abi1) {
95 case MIPS_ABI_FP_XX:
96 state->overall_abi = MIPS_ABI_FP_DOUBLE;
97 break;
98
99 case MIPS_ABI_FP_64A:
100 state->overall_abi = FP_DOUBLE_64A;
101 break;
102 }
103 } else if (abi0 == MIPS_ABI_FP_SINGLE ||
104 abi0 == MIPS_ABI_FP_SOFT) {
105 /* Cannot link with other ABIs */
106 } else if (abi0 == MIPS_ABI_FP_OLD_64) {
107 switch (abi1) {
108 case MIPS_ABI_FP_XX:
109 case MIPS_ABI_FP_64:
110 case MIPS_ABI_FP_64A:
111 state->overall_abi = MIPS_ABI_FP_64;
112 break;
113 }
114 } else if (abi0 == MIPS_ABI_FP_XX ||
115 abi0 == MIPS_ABI_FP_64 ||
116 abi0 == MIPS_ABI_FP_64A) {
117 state->overall_abi = MIPS_ABI_FP_64;
118 }
119
120 switch (state->overall_abi) {
121 case MIPS_ABI_FP_64:
122 case MIPS_ABI_FP_64A:
123 case FP_DOUBLE_64A:
124 if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
125 return -ELIBBAD;
126 break;
127
128 case FP_ERROR:
129 return -ELIBBAD;
130 }
131
132 return 0;
133}
134
135void mips_set_personality_fp(struct arch_elf_state *state)
136{
137 if (config_enabled(CONFIG_FP32XX_HYBRID_FPRS)) {
138 /*
139 * Use hybrid FPRs for all code which can correctly execute
140 * with that mode.
141 */
142 switch (state->overall_abi) {
143 case MIPS_ABI_FP_DOUBLE:
144 case MIPS_ABI_FP_SINGLE:
145 case MIPS_ABI_FP_SOFT:
146 case MIPS_ABI_FP_XX:
147 case MIPS_ABI_FP_ANY:
148 /* FR=1, FRE=1 */
149 clear_thread_flag(TIF_32BIT_FPREGS);
150 set_thread_flag(TIF_HYBRID_FPREGS);
151 return;
152 }
153 }
154
155 switch (state->overall_abi) {
156 case MIPS_ABI_FP_DOUBLE:
157 case MIPS_ABI_FP_SINGLE:
158 case MIPS_ABI_FP_SOFT:
159 /* FR=0 */
160 set_thread_flag(TIF_32BIT_FPREGS);
161 clear_thread_flag(TIF_HYBRID_FPREGS);
162 break;
163
164 case FP_DOUBLE_64A:
165 /* FR=1, FRE=1 */
166 clear_thread_flag(TIF_32BIT_FPREGS);
167 set_thread_flag(TIF_HYBRID_FPREGS);
168 break;
169
170 case MIPS_ABI_FP_64:
171 case MIPS_ABI_FP_64A:
172 /* FR=1, FRE=0 */
173 clear_thread_flag(TIF_32BIT_FPREGS);
174 clear_thread_flag(TIF_HYBRID_FPREGS);
175 break;
176
177 case MIPS_ABI_FP_XX:
178 case MIPS_ABI_FP_ANY:
179 if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
180 set_thread_flag(TIF_32BIT_FPREGS);
181 else
182 clear_thread_flag(TIF_32BIT_FPREGS);
183
184 clear_thread_flag(TIF_HYBRID_FPREGS);
185 break;
186
187 default:
188 case FP_ERROR:
189 BUG();
190 }
191}
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 50b364897dda..a74ec3ae557c 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/ioport.h> 13#include <linux/ioport.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/irqdomain.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/spinlock.h> 17#include <linux/spinlock.h>
17#include <linux/syscore_ops.h> 18#include <linux/syscore_ops.h>
@@ -308,6 +309,19 @@ static struct resource pic2_io_resource = {
308 .flags = IORESOURCE_BUSY 309 .flags = IORESOURCE_BUSY
309}; 310};
310 311
312static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq,
313 irq_hw_number_t hw)
314{
315 irq_set_chip_and_handler(virq, &i8259A_chip, handle_level_irq);
316 irq_set_probe(virq);
317 return 0;
318}
319
320static struct irq_domain_ops i8259A_ops = {
321 .map = i8259A_irq_domain_map,
322 .xlate = irq_domain_xlate_onecell,
323};
324
311/* 325/*
312 * On systems with i8259-style interrupt controllers we assume for 326 * On systems with i8259-style interrupt controllers we assume for
313 * driver compatibility reasons interrupts 0 - 15 to be the i8259 327 * driver compatibility reasons interrupts 0 - 15 to be the i8259
@@ -315,17 +329,17 @@ static struct resource pic2_io_resource = {
315 */ 329 */
316void __init init_i8259_irqs(void) 330void __init init_i8259_irqs(void)
317{ 331{
318 int i; 332 struct irq_domain *domain;
319 333
320 insert_resource(&ioport_resource, &pic1_io_resource); 334 insert_resource(&ioport_resource, &pic1_io_resource);
321 insert_resource(&ioport_resource, &pic2_io_resource); 335 insert_resource(&ioport_resource, &pic2_io_resource);
322 336
323 init_8259A(0); 337 init_8259A(0);
324 338
325 for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { 339 domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0,
326 irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); 340 &i8259A_ops, NULL);
327 irq_set_probe(i); 341 if (!domain)
328 } 342 panic("Failed to add i8259 IRQ domain");
329 343
330 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); 344 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
331} 345}
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
deleted file mode 100644
index 9e9d8b9a5b97..000000000000
--- a/arch/mips/kernel/irq-gic.c
+++ /dev/null
@@ -1,402 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
8 */
9#include <linux/bitmap.h>
10#include <linux/init.h>
11#include <linux/smp.h>
12#include <linux/irq.h>
13#include <linux/clocksource.h>
14
15#include <asm/io.h>
16#include <asm/gic.h>
17#include <asm/setup.h>
18#include <asm/traps.h>
19#include <linux/hardirq.h>
20#include <asm-generic/bitops/find.h>
21
22unsigned int gic_frequency;
23unsigned int gic_present;
24unsigned long _gic_base;
25unsigned int gic_irq_base;
26unsigned int gic_irq_flags[GIC_NUM_INTRS];
27
28/* The index into this array is the vector # of the interrupt. */
29struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS];
30
31struct gic_pcpu_mask {
32 DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
33};
34
35struct gic_pending_regs {
36 DECLARE_BITMAP(pending, GIC_NUM_INTRS);
37};
38
39struct gic_intrmask_regs {
40 DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
41};
42
43static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
44static struct gic_pending_regs pending_regs[NR_CPUS];
45static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
46
47#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC)
48cycle_t gic_read_count(void)
49{
50 unsigned int hi, hi2, lo;
51
52 do {
53 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
54 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
55 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
56 } while (hi2 != hi);
57
58 return (((cycle_t) hi) << 32) + lo;
59}
60
61void gic_write_compare(cycle_t cnt)
62{
63 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
64 (int)(cnt >> 32));
65 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
66 (int)(cnt & 0xffffffff));
67}
68
69void gic_write_cpu_compare(cycle_t cnt, int cpu)
70{
71 unsigned long flags;
72
73 local_irq_save(flags);
74
75 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
76 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
77 (int)(cnt >> 32));
78 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
79 (int)(cnt & 0xffffffff));
80
81 local_irq_restore(flags);
82}
83
84cycle_t gic_read_compare(void)
85{
86 unsigned int hi, lo;
87
88 GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi);
89 GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo);
90
91 return (((cycle_t) hi) << 32) + lo;
92}
93#endif
94
95unsigned int gic_get_timer_pending(void)
96{
97 unsigned int vpe_pending;
98
99 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
100 GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending);
101 return (vpe_pending & GIC_VPE_PEND_TIMER_MSK);
102}
103
104void gic_bind_eic_interrupt(int irq, int set)
105{
106 /* Convert irq vector # to hw int # */
107 irq -= GIC_PIN_TO_VEC_OFFSET;
108
109 /* Set irq to use shadow set */
110 GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set);
111}
112
113void gic_send_ipi(unsigned int intr)
114{
115 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
116}
117
118static void gic_eic_irq_dispatch(void)
119{
120 unsigned int cause = read_c0_cause();
121 int irq;
122
123 irq = (cause & ST0_IM) >> STATUSB_IP2;
124 if (irq == 0)
125 irq = -1;
126
127 if (irq >= 0)
128 do_IRQ(gic_irq_base + irq);
129 else
130 spurious_interrupt();
131}
132
133static void __init vpe_local_setup(unsigned int numvpes)
134{
135 unsigned long timer_intr = GIC_INT_TMR;
136 unsigned long perf_intr = GIC_INT_PERFCTR;
137 unsigned int vpe_ctl;
138 int i;
139
140 if (cpu_has_veic) {
141 /*
142 * GIC timer interrupt -> CPU HW Int X (vector X+2) ->
143 * map to pin X+2-1 (since GIC adds 1)
144 */
145 timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
146 /*
147 * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) ->
148 * map to pin X+2-1 (since GIC adds 1)
149 */
150 perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
151 }
152
153 /*
154 * Setup the default performance counter timer interrupts
155 * for all VPEs
156 */
157 for (i = 0; i < numvpes; i++) {
158 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
159
160 /* Are Interrupts locally routable? */
161 GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
162 if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
163 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
164 GIC_MAP_TO_PIN_MSK | timer_intr);
165 if (cpu_has_veic) {
166 set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET,
167 gic_eic_irq_dispatch);
168 gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK;
169 }
170
171 if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
172 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
173 GIC_MAP_TO_PIN_MSK | perf_intr);
174 if (cpu_has_veic) {
175 set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch);
176 gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK;
177 }
178 }
179}
180
181unsigned int gic_compare_int(void)
182{
183 unsigned int pending;
184
185 GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending);
186 if (pending & GIC_VPE_PEND_CMP_MSK)
187 return 1;
188 else
189 return 0;
190}
191
192void gic_get_int_mask(unsigned long *dst, const unsigned long *src)
193{
194 unsigned int i;
195 unsigned long *pending, *intrmask, *pcpu_mask;
196 unsigned long *pending_abs, *intrmask_abs;
197
198 /* Get per-cpu bitmaps */
199 pending = pending_regs[smp_processor_id()].pending;
200 intrmask = intrmask_regs[smp_processor_id()].intrmask;
201 pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
202
203 pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
204 GIC_SH_PEND_31_0_OFS);
205 intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
206 GIC_SH_MASK_31_0_OFS);
207
208 for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) {
209 GICREAD(*pending_abs, pending[i]);
210 GICREAD(*intrmask_abs, intrmask[i]);
211 pending_abs++;
212 intrmask_abs++;
213 }
214
215 bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
216 bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
217 bitmap_and(dst, src, pending, GIC_NUM_INTRS);
218}
219
220unsigned int gic_get_int(void)
221{
222 DECLARE_BITMAP(interrupts, GIC_NUM_INTRS);
223
224 bitmap_fill(interrupts, GIC_NUM_INTRS);
225 gic_get_int_mask(interrupts, interrupts);
226
227 return find_first_bit(interrupts, GIC_NUM_INTRS);
228}
229
230static void gic_mask_irq(struct irq_data *d)
231{
232 GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
233}
234
235static void gic_unmask_irq(struct irq_data *d)
236{
237 GIC_SET_INTR_MASK(d->irq - gic_irq_base);
238}
239
240#ifdef CONFIG_SMP
241static DEFINE_SPINLOCK(gic_lock);
242
243static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
244 bool force)
245{
246 unsigned int irq = (d->irq - gic_irq_base);
247 cpumask_t tmp = CPU_MASK_NONE;
248 unsigned long flags;
249 int i;
250
251 cpumask_and(&tmp, cpumask, cpu_online_mask);
252 if (cpus_empty(tmp))
253 return -1;
254
255 /* Assumption : cpumask refers to a single CPU */
256 spin_lock_irqsave(&gic_lock, flags);
257
258 /* Re-route this IRQ */
259 GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
260
261 /* Update the pcpu_masks */
262 for (i = 0; i < NR_CPUS; i++)
263 clear_bit(irq, pcpu_masks[i].pcpu_mask);
264 set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
265
266 cpumask_copy(d->affinity, cpumask);
267 spin_unlock_irqrestore(&gic_lock, flags);
268
269 return IRQ_SET_MASK_OK_NOCOPY;
270}
271#endif
272
273static struct irq_chip gic_irq_controller = {
274 .name = "MIPS GIC",
275 .irq_ack = gic_irq_ack,
276 .irq_mask = gic_mask_irq,
277 .irq_mask_ack = gic_mask_irq,
278 .irq_unmask = gic_unmask_irq,
279 .irq_eoi = gic_finish_irq,
280#ifdef CONFIG_SMP
281 .irq_set_affinity = gic_set_affinity,
282#endif
283};
284
285static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
286 unsigned int pin, unsigned int polarity, unsigned int trigtype,
287 unsigned int flags)
288{
289 struct gic_shared_intr_map *map_ptr;
290
291 /* Setup Intr to Pin mapping */
292 if (pin & GIC_MAP_TO_NMI_MSK) {
293 int i;
294
295 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
296 /* FIXME: hack to route NMI to all cpu's */
297 for (i = 0; i < NR_CPUS; i += 32) {
298 GICWRITE(GIC_REG_ADDR(SHARED,
299 GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)),
300 0xffffffff);
301 }
302 } else {
303 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
304 GIC_MAP_TO_PIN_MSK | pin);
305 /* Setup Intr to CPU mapping */
306 GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
307 if (cpu_has_veic) {
308 set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET,
309 gic_eic_irq_dispatch);
310 map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET];
311 if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR)
312 BUG();
313 map_ptr->intr_list[map_ptr->num_shared_intr++] = intr;
314 }
315 }
316
317 /* Setup Intr Polarity */
318 GIC_SET_POLARITY(intr, polarity);
319
320 /* Setup Intr Trigger Type */
321 GIC_SET_TRIGGER(intr, trigtype);
322
323 /* Init Intr Masks */
324 GIC_CLR_INTR_MASK(intr);
325
326 /* Initialise per-cpu Interrupt software masks */
327 set_bit(intr, pcpu_masks[cpu].pcpu_mask);
328
329 if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0))
330 GIC_SET_INTR_MASK(intr);
331 if (trigtype == GIC_TRIG_EDGE)
332 gic_irq_flags[intr] |= GIC_TRIG_EDGE;
333}
334
335static void __init gic_basic_init(int numintrs, int numvpes,
336 struct gic_intr_map *intrmap, int mapsize)
337{
338 unsigned int i, cpu;
339 unsigned int pin_offset = 0;
340
341 board_bind_eic_interrupt = &gic_bind_eic_interrupt;
342
343 /* Setup defaults */
344 for (i = 0; i < numintrs; i++) {
345 GIC_SET_POLARITY(i, GIC_POL_POS);
346 GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
347 GIC_CLR_INTR_MASK(i);
348 if (i < GIC_NUM_INTRS) {
349 gic_irq_flags[i] = 0;
350 gic_shared_intr_map[i].num_shared_intr = 0;
351 gic_shared_intr_map[i].local_intr_mask = 0;
352 }
353 }
354
355 /*
356 * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract
357 * one because the GIC will add one (since 0=no intr).
358 */
359 if (cpu_has_veic)
360 pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
361
362 /* Setup specifics */
363 for (i = 0; i < mapsize; i++) {
364 cpu = intrmap[i].cpunum;
365 if (cpu == GIC_UNUSED)
366 continue;
367 gic_setup_intr(i,
368 intrmap[i].cpunum,
369 intrmap[i].pin + pin_offset,
370 intrmap[i].polarity,
371 intrmap[i].trigtype,
372 intrmap[i].flags);
373 }
374
375 vpe_local_setup(numvpes);
376}
377
378void __init gic_init(unsigned long gic_base_addr,
379 unsigned long gic_addrspace_size,
380 struct gic_intr_map *intr_map, unsigned int intr_map_size,
381 unsigned int irqbase)
382{
383 unsigned int gicconfig;
384 int numvpes, numintrs;
385
386 _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
387 gic_addrspace_size);
388 gic_irq_base = irqbase;
389
390 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
391 numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
392 GIC_SH_CONFIG_NUMINTRS_SHF;
393 numintrs = ((numintrs + 1) * 8);
394
395 numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
396 GIC_SH_CONFIG_NUMVPES_SHF;
397 numvpes = numvpes + 1;
398
399 gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
400
401 gic_platform_init(numintrs, &gic_irq_controller);
402}
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index e498f2b3646a..590c2c980fd3 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -36,6 +36,7 @@
36#include <asm/irq_cpu.h> 36#include <asm/irq_cpu.h>
37#include <asm/mipsregs.h> 37#include <asm/mipsregs.h>
38#include <asm/mipsmtregs.h> 38#include <asm/mipsmtregs.h>
39#include <asm/setup.h>
39 40
40static inline void unmask_mips_irq(struct irq_data *d) 41static inline void unmask_mips_irq(struct irq_data *d)
41{ 42{
@@ -94,28 +95,24 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
94 .irq_eoi = unmask_mips_irq, 95 .irq_eoi = unmask_mips_irq,
95}; 96};
96 97
97void __init mips_cpu_irq_init(void) 98asmlinkage void __weak plat_irq_dispatch(void)
98{ 99{
99 int irq_base = MIPS_CPU_IRQ_BASE; 100 unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM;
100 int i; 101 int irq;
101 102
102 /* Mask interrupts. */ 103 if (!pending) {
103 clear_c0_status(ST0_IM); 104 spurious_interrupt();
104 clear_c0_cause(CAUSEF_IP); 105 return;
105 106 }
106 /* Software interrupts are used for MT/CMT IPI */
107 for (i = irq_base; i < irq_base + 2; i++)
108 irq_set_chip_and_handler(i, cpu_has_mipsmt ?
109 &mips_mt_cpu_irq_controller :
110 &mips_cpu_irq_controller,
111 handle_percpu_irq);
112 107
113 for (i = irq_base + 2; i < irq_base + 8; i++) 108 pending >>= CAUSEB_IP;
114 irq_set_chip_and_handler(i, &mips_cpu_irq_controller, 109 while (pending) {
115 handle_percpu_irq); 110 irq = fls(pending) - 1;
111 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
112 pending &= ~BIT(irq);
113 }
116} 114}
117 115
118#ifdef CONFIG_IRQ_DOMAIN
119static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, 116static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
120 irq_hw_number_t hw) 117 irq_hw_number_t hw)
121{ 118{
@@ -128,6 +125,9 @@ static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
128 chip = &mips_cpu_irq_controller; 125 chip = &mips_cpu_irq_controller;
129 } 126 }
130 127
128 if (cpu_has_vint)
129 set_vi_handler(hw, plat_irq_dispatch);
130
131 irq_set_chip_and_handler(irq, chip, handle_percpu_irq); 131 irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
132 132
133 return 0; 133 return 0;
@@ -138,8 +138,7 @@ static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
138 .xlate = irq_domain_xlate_onecell, 138 .xlate = irq_domain_xlate_onecell,
139}; 139};
140 140
141int __init mips_cpu_intc_init(struct device_node *of_node, 141static void __init __mips_cpu_irq_init(struct device_node *of_node)
142 struct device_node *parent)
143{ 142{
144 struct irq_domain *domain; 143 struct irq_domain *domain;
145 144
@@ -151,7 +150,16 @@ int __init mips_cpu_intc_init(struct device_node *of_node,
151 &mips_cpu_intc_irq_domain_ops, NULL); 150 &mips_cpu_intc_irq_domain_ops, NULL);
152 if (!domain) 151 if (!domain)
153 panic("Failed to add irqdomain for MIPS CPU"); 152 panic("Failed to add irqdomain for MIPS CPU");
153}
154 154
155void __init mips_cpu_irq_init(void)
156{
157 __mips_cpu_irq_init(NULL);
158}
159
160int __init mips_cpu_irq_of_init(struct device_node *of_node,
161 struct device_node *parent)
162{
163 __mips_cpu_irq_init(of_node);
155 return 0; 164 return 0;
156} 165}
157#endif /* CONFIG_IRQ_DOMAIN */
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index f76f7a08412d..85bbe9b96759 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -16,7 +16,7 @@
16void __iomem *mips_cm_base; 16void __iomem *mips_cm_base;
17void __iomem *mips_cm_l2sync_base; 17void __iomem *mips_cm_l2sync_base;
18 18
19phys_t __mips_cm_phys_base(void) 19phys_addr_t __mips_cm_phys_base(void)
20{ 20{
21 u32 config3 = read_c0_config3(); 21 u32 config3 = read_c0_config3();
22 u32 cmgcr; 22 u32 cmgcr;
@@ -30,10 +30,10 @@ phys_t __mips_cm_phys_base(void)
30 return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); 30 return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32);
31} 31}
32 32
33phys_t mips_cm_phys_base(void) 33phys_addr_t mips_cm_phys_base(void)
34 __attribute__((weak, alias("__mips_cm_phys_base"))); 34 __attribute__((weak, alias("__mips_cm_phys_base")));
35 35
36phys_t __mips_cm_l2sync_phys_base(void) 36phys_addr_t __mips_cm_l2sync_phys_base(void)
37{ 37{
38 u32 base_reg; 38 u32 base_reg;
39 39
@@ -49,13 +49,13 @@ phys_t __mips_cm_l2sync_phys_base(void)
49 return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; 49 return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
50} 50}
51 51
52phys_t mips_cm_l2sync_phys_base(void) 52phys_addr_t mips_cm_l2sync_phys_base(void)
53 __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); 53 __attribute__((weak, alias("__mips_cm_l2sync_phys_base")));
54 54
55static void mips_cm_probe_l2sync(void) 55static void mips_cm_probe_l2sync(void)
56{ 56{
57 unsigned major_rev; 57 unsigned major_rev;
58 phys_t addr; 58 phys_addr_t addr;
59 59
60 /* L2-only sync was introduced with CM major revision 6 */ 60 /* L2-only sync was introduced with CM major revision 6 */
61 major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> 61 major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >>
@@ -78,7 +78,7 @@ static void mips_cm_probe_l2sync(void)
78 78
79int mips_cm_probe(void) 79int mips_cm_probe(void)
80{ 80{
81 phys_t addr; 81 phys_addr_t addr;
82 u32 base_reg; 82 u32 base_reg;
83 83
84 addr = mips_cm_phys_base(); 84 addr = mips_cm_phys_base();
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index ba473608a347..11964501c4b0 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -21,7 +21,7 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock);
21 21
22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); 22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
23 23
24phys_t __weak mips_cpc_phys_base(void) 24phys_addr_t __weak mips_cpc_phys_base(void)
25{ 25{
26 u32 cpc_base; 26 u32 cpc_base;
27 27
@@ -44,7 +44,7 @@ phys_t __weak mips_cpc_phys_base(void)
44 44
45int mips_cpc_probe(void) 45int mips_cpc_probe(void)
46{ 46{
47 phys_t addr; 47 phys_addr_t addr;
48 unsigned cpu; 48 unsigned cpu;
49 49
50 for_each_possible_cpu(cpu) 50 for_each_possible_cpu(cpu)
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 2607c3a4ff7e..17eaf0cf760c 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -24,9 +24,7 @@ extern long __strncpy_from_user_nocheck_asm(char *__to,
24 const char *__from, long __len); 24 const char *__from, long __len);
25extern long __strncpy_from_user_asm(char *__to, const char *__from, 25extern long __strncpy_from_user_asm(char *__to, const char *__from,
26 long __len); 26 long __len);
27extern long __strlen_kernel_nocheck_asm(const char *s);
28extern long __strlen_kernel_asm(const char *s); 27extern long __strlen_kernel_asm(const char *s);
29extern long __strlen_user_nocheck_asm(const char *s);
30extern long __strlen_user_asm(const char *s); 28extern long __strlen_user_asm(const char *s);
31extern long __strnlen_kernel_nocheck_asm(const char *s); 29extern long __strnlen_kernel_nocheck_asm(const char *s);
32extern long __strnlen_kernel_asm(const char *s); 30extern long __strnlen_kernel_asm(const char *s);
@@ -62,9 +60,7 @@ EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm);
62EXPORT_SYMBOL(__strncpy_from_kernel_asm); 60EXPORT_SYMBOL(__strncpy_from_kernel_asm);
63EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); 61EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm);
64EXPORT_SYMBOL(__strncpy_from_user_asm); 62EXPORT_SYMBOL(__strncpy_from_user_asm);
65EXPORT_SYMBOL(__strlen_kernel_nocheck_asm);
66EXPORT_SYMBOL(__strlen_kernel_asm); 63EXPORT_SYMBOL(__strlen_kernel_asm);
67EXPORT_SYMBOL(__strlen_user_nocheck_asm);
68EXPORT_SYMBOL(__strlen_user_asm); 64EXPORT_SYMBOL(__strlen_user_asm);
69EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); 65EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm);
70EXPORT_SYMBOL(__strnlen_kernel_asm); 66EXPORT_SYMBOL(__strnlen_kernel_asm);
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index a8f9cdc6f8b0..9466184d0039 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -561,8 +561,8 @@ static int mipspmu_get_irq(void)
561 IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, 561 IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD,
562 "mips_perf_pmu", NULL); 562 "mips_perf_pmu", NULL);
563 if (err) { 563 if (err) {
564 pr_warning("Unable to request IRQ%d for MIPS " 564 pr_warn("Unable to request IRQ%d for MIPS performance counters!\n",
565 "performance counters!\n", mipspmu.irq); 565 mipspmu.irq);
566 } 566 }
567 } else if (cp0_perfcount_irq < 0) { 567 } else if (cp0_perfcount_irq < 0) {
568 /* 568 /*
@@ -572,8 +572,7 @@ static int mipspmu_get_irq(void)
572 perf_irq = mipsxx_pmu_handle_shared_irq; 572 perf_irq = mipsxx_pmu_handle_shared_irq;
573 err = 0; 573 err = 0;
574 } else { 574 } else {
575 pr_warning("The platform hasn't properly defined its " 575 pr_warn("The platform hasn't properly defined its interrupt controller\n");
576 "interrupt controller.\n");
577 err = -ENOENT; 576 err = -ENOENT;
578 } 577 }
579 578
@@ -1614,22 +1613,13 @@ init_hw_perf_events(void)
1614 counters = counters_total_to_per_cpu(counters); 1613 counters = counters_total_to_per_cpu(counters);
1615#endif 1614#endif
1616 1615
1617#ifdef MSC01E_INT_BASE 1616 if (get_c0_perfcount_int)
1618 if (cpu_has_veic) { 1617 irq = get_c0_perfcount_int();
1619 /* 1618 else if ((cp0_perfcount_irq >= 0) &&
1620 * Using platform specific interrupt controller defines. 1619 (cp0_compare_irq != cp0_perfcount_irq))
1621 */ 1620 irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
1622 irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 1621 else
1623 } else { 1622 irq = -1;
1624#endif
1625 if ((cp0_perfcount_irq >= 0) &&
1626 (cp0_compare_irq != cp0_perfcount_irq))
1627 irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
1628 else
1629 irq = -1;
1630#ifdef MSC01E_INT_BASE
1631 }
1632#endif
1633 1623
1634 mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; 1624 mipspmu.map_raw_event = mipsxx_pmu_map_raw_event;
1635 1625
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 636b0745d7c7..eb76434828e8 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -42,6 +42,7 @@
42#include <asm/isadep.h> 42#include <asm/isadep.h>
43#include <asm/inst.h> 43#include <asm/inst.h>
44#include <asm/stacktrace.h> 44#include <asm/stacktrace.h>
45#include <asm/irq_regs.h>
45 46
46#ifdef CONFIG_HOTPLUG_CPU 47#ifdef CONFIG_HOTPLUG_CPU
47void arch_cpu_idle_dead(void) 48void arch_cpu_idle_dead(void)
@@ -187,21 +188,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
187 */ 188 */
188 if (mm_insn_16bit(ip->halfword[0])) { 189 if (mm_insn_16bit(ip->halfword[0])) {
189 mmi.word = (ip->halfword[0] << 16); 190 mmi.word = (ip->halfword[0] << 16);
190 return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && 191 return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
191 mmi.mm16_r5_format.rt == 31) || 192 mmi.mm16_r5_format.rt == 31) ||
192 (mmi.mm16_m_format.opcode == mm_pool16c_op && 193 (mmi.mm16_m_format.opcode == mm_pool16c_op &&
193 mmi.mm16_m_format.func == mm_swm16_op)); 194 mmi.mm16_m_format.func == mm_swm16_op);
194 } 195 }
195 else { 196 else {
196 mmi.halfword[0] = ip->halfword[1]; 197 mmi.halfword[0] = ip->halfword[1];
197 mmi.halfword[1] = ip->halfword[0]; 198 mmi.halfword[1] = ip->halfword[0];
198 return ((mmi.mm_m_format.opcode == mm_pool32b_op && 199 return (mmi.mm_m_format.opcode == mm_pool32b_op &&
199 mmi.mm_m_format.rd > 9 && 200 mmi.mm_m_format.rd > 9 &&
200 mmi.mm_m_format.base == 29 && 201 mmi.mm_m_format.base == 29 &&
201 mmi.mm_m_format.func == mm_swm32_func) || 202 mmi.mm_m_format.func == mm_swm32_func) ||
202 (mmi.i_format.opcode == mm_sw32_op && 203 (mmi.i_format.opcode == mm_sw32_op &&
203 mmi.i_format.rs == 29 && 204 mmi.i_format.rs == 29 &&
204 mmi.i_format.rt == 31)); 205 mmi.i_format.rt == 31);
205 } 206 }
206#else 207#else
207 /* sw / sd $ra, offset($sp) */ 208 /* sw / sd $ra, offset($sp) */
@@ -233,7 +234,7 @@ static inline int is_jump_ins(union mips_instruction *ip)
233 if (ip->r_format.opcode != mm_pool32a_op || 234 if (ip->r_format.opcode != mm_pool32a_op ||
234 ip->r_format.func != mm_pool32axf_op) 235 ip->r_format.func != mm_pool32axf_op)
235 return 0; 236 return 0;
236 return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); 237 return ((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op;
237#else 238#else
238 if (ip->j_format.opcode == j_op) 239 if (ip->j_format.opcode == j_op)
239 return 1; 240 return 1;
@@ -260,13 +261,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
260 union mips_instruction mmi; 261 union mips_instruction mmi;
261 262
262 mmi.word = (ip->halfword[0] << 16); 263 mmi.word = (ip->halfword[0] << 16);
263 return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && 264 return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
264 mmi.mm16_r3_format.simmediate && mm_addiusp_func) || 265 mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
265 (mmi.mm16_r5_format.opcode == mm_pool16d_op && 266 (mmi.mm16_r5_format.opcode == mm_pool16d_op &&
266 mmi.mm16_r5_format.rt == 29)); 267 mmi.mm16_r5_format.rt == 29);
267 } 268 }
268 return (ip->mm_i_format.opcode == mm_addiu32_op && 269 return ip->mm_i_format.opcode == mm_addiu32_op &&
269 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); 270 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
270#else 271#else
271 /* addiu/daddiu sp,sp,-imm */ 272 /* addiu/daddiu sp,sp,-imm */
272 if (ip->i_format.rs != 29 || ip->i_format.rt != 29) 273 if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
@@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp)
532 533
533 return sp & ALMASK; 534 return sp & ALMASK;
534} 535}
536
537static void arch_dump_stack(void *info)
538{
539 struct pt_regs *regs;
540
541 regs = get_irq_regs();
542
543 if (regs)
544 show_regs(regs);
545
546 dump_stack();
547}
548
549void arch_trigger_all_cpu_backtrace(bool include_self)
550{
551 smp_call_function(arch_dump_stack, NULL, 1);
552}
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 5d39bb85bf35..452d4350ce42 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -16,6 +16,7 @@
16#include <linux/debugfs.h> 16#include <linux/debugfs.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/of_fdt.h> 18#include <linux/of_fdt.h>
19#include <linux/of_platform.h>
19 20
20#include <asm/page.h> 21#include <asm/page.h>
21#include <asm/prom.h> 22#include <asm/prom.h>
@@ -54,4 +55,21 @@ void __init __dt_setup_arch(void *bph)
54 55
55 mips_set_machine_name(of_flat_dt_get_machine_name()); 56 mips_set_machine_name(of_flat_dt_get_machine_name());
56} 57}
58
59int __init __dt_register_buses(const char *bus0, const char *bus1)
60{
61 static struct of_device_id of_ids[3];
62
63 if (!of_have_populated_dt())
64 panic("device tree not present");
65
66 strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible));
67 strlcpy(of_ids[1].compatible, bus1, sizeof(of_ids[1].compatible));
68
69 if (of_platform_populate(NULL, of_ids, NULL, NULL))
70 panic("failed to populate DT");
71
72 return 0;
73}
74
57#endif 75#endif
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f3b635f86c39..058929041368 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -82,14 +82,14 @@ static struct resource data_resource = { .name = "Kernel data", };
82 82
83static void *detect_magic __initdata = detect_memory_region; 83static void *detect_magic __initdata = detect_memory_region;
84 84
85void __init add_memory_region(phys_t start, phys_t size, long type) 85void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
86{ 86{
87 int x = boot_mem_map.nr_map; 87 int x = boot_mem_map.nr_map;
88 int i; 88 int i;
89 89
90 /* Sanity check */ 90 /* Sanity check */
91 if (start + size < start) { 91 if (start + size < start) {
92 pr_warning("Trying to add an invalid memory region, skipped\n"); 92 pr_warn("Trying to add an invalid memory region, skipped\n");
93 return; 93 return;
94 } 94 }
95 95
@@ -127,10 +127,10 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
127 boot_mem_map.nr_map++; 127 boot_mem_map.nr_map++;
128} 128}
129 129
130void __init detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max) 130void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
131{ 131{
132 void *dm = &detect_magic; 132 void *dm = &detect_magic;
133 phys_t size; 133 phys_addr_t size;
134 134
135 for (size = sz_min; size < sz_max; size <<= 1) { 135 for (size = sz_min; size < sz_max; size <<= 1) {
136 if (!memcmp(dm, dm + size, sizeof(detect_magic))) 136 if (!memcmp(dm, dm + size, sizeof(detect_magic)))
@@ -493,7 +493,7 @@ static int usermem __initdata;
493 493
494static int __init early_parse_mem(char *p) 494static int __init early_parse_mem(char *p)
495{ 495{
496 phys_t start, size; 496 phys_addr_t start, size;
497 497
498 /* 498 /*
499 * If a user specifies memory size, we 499 * If a user specifies memory size, we
@@ -545,9 +545,9 @@ static int __init early_parse_elfcorehdr(char *p)
545early_param("elfcorehdr", early_parse_elfcorehdr); 545early_param("elfcorehdr", early_parse_elfcorehdr);
546#endif 546#endif
547 547
548static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) 548static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
549{ 549{
550 phys_t size; 550 phys_addr_t size;
551 int i; 551 int i;
552 552
553 size = end - mem; 553 size = end - mem;
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 16f1e4f2bf3c..545bf11bd2ed 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -530,7 +530,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
530 struct mips_abi *abi = current->thread.abi; 530 struct mips_abi *abi = current->thread.abi;
531#ifdef CONFIG_CPU_MICROMIPS 531#ifdef CONFIG_CPU_MICROMIPS
532 void *vdso; 532 void *vdso;
533 unsigned int tmp = (unsigned int)current->mm->context.vdso; 533 unsigned long tmp = (unsigned long)current->mm->context.vdso;
534 534
535 set_isa16_mode(tmp); 535 set_isa16_mode(tmp);
536 vdso = (void *)tmp; 536 vdso = (void *)tmp;
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 06bb5ed6d80a..b8bd9340c9c7 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -35,6 +35,7 @@
35#include <asm/bmips.h> 35#include <asm/bmips.h>
36#include <asm/traps.h> 36#include <asm/traps.h>
37#include <asm/barrier.h> 37#include <asm/barrier.h>
38#include <asm/cpu-features.h>
38 39
39static int __maybe_unused max_cpus = 1; 40static int __maybe_unused max_cpus = 1;
40 41
@@ -42,6 +43,12 @@ static int __maybe_unused max_cpus = 1;
42int bmips_smp_enabled = 1; 43int bmips_smp_enabled = 1;
43int bmips_cpu_offset; 44int bmips_cpu_offset;
44cpumask_t bmips_booted_mask; 45cpumask_t bmips_booted_mask;
46unsigned long bmips_tp1_irqs = IE_IRQ1;
47
48#define RESET_FROM_KSEG0 0x80080800
49#define RESET_FROM_KSEG1 0xa0080800
50
51static void bmips_set_reset_vec(int cpu, u32 val);
45 52
46#ifdef CONFIG_SMP 53#ifdef CONFIG_SMP
47 54
@@ -194,6 +201,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
194 pr_info("SMP: Booting CPU%d...\n", cpu); 201 pr_info("SMP: Booting CPU%d...\n", cpu);
195 202
196 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { 203 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
204 /* kseg1 might not exist if this CPU enabled XKS01 */
205 bmips_set_reset_vec(cpu, RESET_FROM_KSEG0);
206
197 switch (current_cpu_type()) { 207 switch (current_cpu_type()) {
198 case CPU_BMIPS4350: 208 case CPU_BMIPS4350:
199 case CPU_BMIPS4380: 209 case CPU_BMIPS4380:
@@ -203,8 +213,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
203 bmips5000_send_ipi_single(cpu, 0); 213 bmips5000_send_ipi_single(cpu, 0);
204 break; 214 break;
205 } 215 }
206 } 216 } else {
207 else { 217 bmips_set_reset_vec(cpu, RESET_FROM_KSEG1);
218
208 switch (current_cpu_type()) { 219 switch (current_cpu_type()) {
209 case CPU_BMIPS4350: 220 case CPU_BMIPS4350:
210 case CPU_BMIPS4380: 221 case CPU_BMIPS4380:
@@ -213,17 +224,7 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
213 set_c0_brcm_cmt_ctrl(0x01); 224 set_c0_brcm_cmt_ctrl(0x01);
214 break; 225 break;
215 case CPU_BMIPS5000: 226 case CPU_BMIPS5000:
216 if (cpu & 0x01) 227 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
217 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
218 else {
219 /*
220 * core N thread 0 was already booted; just
221 * pulse the NMI line
222 */
223 bmips_write_zscm_reg(0x210, 0xc0000000);
224 udelay(10);
225 bmips_write_zscm_reg(0x210, 0x00);
226 }
227 break; 228 break;
228 } 229 }
229 cpumask_set_cpu(cpu, &bmips_booted_mask); 230 cpumask_set_cpu(cpu, &bmips_booted_mask);
@@ -235,31 +236,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
235 */ 236 */
236static void bmips_init_secondary(void) 237static void bmips_init_secondary(void)
237{ 238{
238 /* move NMI vector to kseg0, in case XKS01 is enabled */
239
240 void __iomem *cbr;
241 unsigned long old_vec;
242 unsigned long relo_vector;
243 int boot_cpu;
244
245 switch (current_cpu_type()) { 239 switch (current_cpu_type()) {
246 case CPU_BMIPS4350: 240 case CPU_BMIPS4350:
247 case CPU_BMIPS4380: 241 case CPU_BMIPS4380:
248 cbr = BMIPS_GET_CBR();
249
250 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
251 relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
252 BMIPS_RELO_VECTOR_CONTROL_1;
253
254 old_vec = __raw_readl(cbr + relo_vector);
255 __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
256
257 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); 242 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
258 break; 243 break;
259 case CPU_BMIPS5000: 244 case CPU_BMIPS5000:
260 write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
261 (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
262
263 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); 245 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
264 break; 246 break;
265 } 247 }
@@ -276,7 +258,7 @@ static void bmips_smp_finish(void)
276 write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); 258 write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
277 259
278 irq_enable_hazard(); 260 irq_enable_hazard();
279 set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); 261 set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE);
280 irq_enable_hazard(); 262 irq_enable_hazard();
281} 263}
282 264
@@ -381,6 +363,7 @@ static int bmips_cpu_disable(void)
381 363
382 set_cpu_online(cpu, false); 364 set_cpu_online(cpu, false);
383 cpu_clear(cpu, cpu_callin_map); 365 cpu_clear(cpu, cpu_callin_map);
366 clear_c0_status(IE_IRQ5);
384 367
385 local_flush_tlb_all(); 368 local_flush_tlb_all();
386 local_flush_icache_range(0, ~0); 369 local_flush_icache_range(0, ~0);
@@ -405,7 +388,8 @@ void __ref play_dead(void)
405 * IRQ handlers; this clears ST0_IE and returns immediately. 388 * IRQ handlers; this clears ST0_IE and returns immediately.
406 */ 389 */
407 clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); 390 clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1);
408 change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, 391 change_c0_status(
392 IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV,
409 IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); 393 IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV);
410 irq_disable_hazard(); 394 irq_disable_hazard();
411 395
@@ -473,10 +457,61 @@ static inline void bmips_nmi_handler_setup(void)
473 &bmips_smp_int_vec_end); 457 &bmips_smp_int_vec_end);
474} 458}
475 459
460struct reset_vec_info {
461 int cpu;
462 u32 val;
463};
464
465static void bmips_set_reset_vec_remote(void *vinfo)
466{
467 struct reset_vec_info *info = vinfo;
468 int shift = info->cpu & 0x01 ? 16 : 0;
469 u32 mask = ~(0xffff << shift), val = info->val >> 16;
470
471 preempt_disable();
472 if (smp_processor_id() > 0) {
473 smp_call_function_single(0, &bmips_set_reset_vec_remote,
474 info, 1);
475 } else {
476 if (info->cpu & 0x02) {
477 /* BMIPS5200 "should" use mask/shift, but it's buggy */
478 bmips_write_zscm_reg(0xa0, (val << 16) | val);
479 bmips_read_zscm_reg(0xa0);
480 } else {
481 write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) |
482 (val << shift));
483 }
484 }
485 preempt_enable();
486}
487
488static void bmips_set_reset_vec(int cpu, u32 val)
489{
490 struct reset_vec_info info;
491
492 if (current_cpu_type() == CPU_BMIPS5000) {
493 /* this needs to run from CPU0 (which is always online) */
494 info.cpu = cpu;
495 info.val = val;
496 bmips_set_reset_vec_remote(&info);
497 } else {
498 void __iomem *cbr = BMIPS_GET_CBR();
499
500 if (cpu == 0)
501 __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
502 else {
503 if (current_cpu_type() != CPU_BMIPS4380)
504 return;
505 __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
506 }
507 }
508 __sync();
509 back_to_back_c0_hazard();
510}
511
476void bmips_ebase_setup(void) 512void bmips_ebase_setup(void)
477{ 513{
478 unsigned long new_ebase = ebase; 514 unsigned long new_ebase = ebase;
479 void __iomem __maybe_unused *cbr;
480 515
481 BUG_ON(ebase != CKSEG0); 516 BUG_ON(ebase != CKSEG0);
482 517
@@ -496,15 +531,14 @@ void bmips_ebase_setup(void)
496 &bmips_smp_int_vec, 0x80); 531 &bmips_smp_int_vec, 0x80);
497 __sync(); 532 __sync();
498 return; 533 return;
534 case CPU_BMIPS3300:
499 case CPU_BMIPS4380: 535 case CPU_BMIPS4380:
500 /* 536 /*
501 * 0x8000_0000: reset/NMI (initially in kseg1) 537 * 0x8000_0000: reset/NMI (initially in kseg1)
502 * 0x8000_0400: normal vectors 538 * 0x8000_0400: normal vectors
503 */ 539 */
504 new_ebase = 0x80000400; 540 new_ebase = 0x80000400;
505 cbr = BMIPS_GET_CBR(); 541 bmips_set_reset_vec(0, RESET_FROM_KSEG0);
506 __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
507 __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
508 break; 542 break;
509 case CPU_BMIPS5000: 543 case CPU_BMIPS5000:
510 /* 544 /*
@@ -512,10 +546,8 @@ void bmips_ebase_setup(void)
512 * 0x8000_1000: normal vectors 546 * 0x8000_1000: normal vectors
513 */ 547 */
514 new_ebase = 0x80001000; 548 new_ebase = 0x80001000;
515 write_c0_brcm_bootvec(0xa0088008); 549 bmips_set_reset_vec(0, RESET_FROM_KSEG0);
516 write_c0_ebase(new_ebase); 550 write_c0_ebase(new_ebase);
517 if (max_cpus > 2)
518 bmips_write_zscm_reg(0xa0, 0xa008a008);
519 break; 551 break;
520 default: 552 default:
521 return; 553 return;
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index fc8a51553426..1e0a93c5a3e7 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -24,6 +24,7 @@
24#include <linux/cpumask.h> 24#include <linux/cpumask.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/compiler.h> 26#include <linux/compiler.h>
27#include <linux/irqchip/mips-gic.h>
27 28
28#include <linux/atomic.h> 29#include <linux/atomic.h>
29#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
@@ -37,7 +38,6 @@
37#include <asm/mipsmtregs.h> 38#include <asm/mipsmtregs.h>
38#include <asm/mips_mt.h> 39#include <asm/mips_mt.h>
39#include <asm/amon.h> 40#include <asm/amon.h>
40#include <asm/gic.h>
41 41
42static void cmp_init_secondary(void) 42static void cmp_init_secondary(void)
43{ 43{
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index e6e16a1d4add..bed7590e475f 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -9,13 +9,13 @@
9 */ 9 */
10 10
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/irqchip/mips-gic.h>
12#include <linux/sched.h> 13#include <linux/sched.h>
13#include <linux/slab.h> 14#include <linux/slab.h>
14#include <linux/smp.h> 15#include <linux/smp.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#include <asm/bcache.h> 18#include <asm/bcache.h>
18#include <asm/gic.h>
19#include <asm/mips-cm.h> 19#include <asm/mips-cm.h>
20#include <asm/mips-cpc.h> 20#include <asm/mips-cpc.h>
21#include <asm/mips_mt.h> 21#include <asm/mips_mt.h>
@@ -273,8 +273,8 @@ static void cps_init_secondary(void)
273 if (cpu_has_mipsmt) 273 if (cpu_has_mipsmt)
274 dmt(); 274 dmt();
275 275
276 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | 276 change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 |
277 STATUSF_IP6 | STATUSF_IP7); 277 STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7);
278} 278}
279 279
280static void cps_smp_finish(void) 280static void cps_smp_finish(void)
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c
index 3b21a96d1ccb..5f0ab5bcd01e 100644
--- a/arch/mips/kernel/smp-gic.c
+++ b/arch/mips/kernel/smp-gic.c
@@ -12,9 +12,9 @@
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14 14
15#include <linux/irqchip/mips-gic.h>
15#include <linux/printk.h> 16#include <linux/printk.h>
16 17
17#include <asm/gic.h>
18#include <asm/mips-cpc.h> 18#include <asm/mips-cpc.h>
19#include <asm/smp-ops.h> 19#include <asm/smp-ops.h>
20 20
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 21f23add04f4..ad86951b73bd 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -21,6 +21,7 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/cpumask.h> 22#include <linux/cpumask.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/irqchip/mips-gic.h>
24#include <linux/compiler.h> 25#include <linux/compiler.h>
25#include <linux/smp.h> 26#include <linux/smp.h>
26 27
@@ -34,7 +35,6 @@
34#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
35#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
36#include <asm/mips_mt.h> 37#include <asm/mips_mt.h>
37#include <asm/gic.h>
38 38
39static void __init smvp_copy_vpe_config(void) 39static void __init smvp_copy_vpe_config(void)
40{ 40{
@@ -119,7 +119,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action)
119 unsigned long flags; 119 unsigned long flags;
120 int vpflags; 120 int vpflags;
121 121
122#ifdef CONFIG_IRQ_GIC 122#ifdef CONFIG_MIPS_GIC
123 if (gic_present) { 123 if (gic_present) {
124 gic_send_ipi_single(cpu, action); 124 gic_send_ipi_single(cpu, action);
125 return; 125 return;
@@ -158,7 +158,7 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
158 158
159static void vsmp_init_secondary(void) 159static void vsmp_init_secondary(void)
160{ 160{
161#ifdef CONFIG_IRQ_GIC 161#ifdef CONFIG_MIPS_GIC
162 /* This is Malta specific: IPI,performance and timer interrupts */ 162 /* This is Malta specific: IPI,performance and timer interrupts */
163 if (gic_present) 163 if (gic_present)
164 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | 164 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 4a4f9dda5658..604b558809c4 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -117,6 +117,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
117 "2: sc %[tmp], (%[addr]) \n" 117 "2: sc %[tmp], (%[addr]) \n"
118 " beqzl %[tmp], 1b \n" 118 " beqzl %[tmp], 1b \n"
119 "3: \n" 119 "3: \n"
120 " .insn \n"
120 " .section .fixup,\"ax\" \n" 121 " .section .fixup,\"ax\" \n"
121 "4: li %[err], %[efault] \n" 122 "4: li %[err], %[efault] \n"
122 " j 3b \n" 123 " j 3b \n"
@@ -142,6 +143,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
142 "2: sc %[tmp], (%[addr]) \n" 143 "2: sc %[tmp], (%[addr]) \n"
143 " bnez %[tmp], 4f \n" 144 " bnez %[tmp], 4f \n"
144 "3: \n" 145 "3: \n"
146 " .insn \n"
145 " .subsection 2 \n" 147 " .subsection 2 \n"
146 "4: b 1b \n" 148 "4: b 1b \n"
147 " .previous \n" 149 " .previous \n"
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 22b19c275044..ad3d2031c327 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -724,6 +724,50 @@ int process_fpemu_return(int sig, void __user *fault_addr)
724 } 724 }
725} 725}
726 726
727static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
728 unsigned long old_epc, unsigned long old_ra)
729{
730 union mips_instruction inst = { .word = opcode };
731 void __user *fault_addr = NULL;
732 int sig;
733
734 /* If it's obviously not an FP instruction, skip it */
735 switch (inst.i_format.opcode) {
736 case cop1_op:
737 case cop1x_op:
738 case lwc1_op:
739 case ldc1_op:
740 case swc1_op:
741 case sdc1_op:
742 break;
743
744 default:
745 return -1;
746 }
747
748 /*
749 * do_ri skipped over the instruction via compute_return_epc, undo
750 * that for the FPU emulator.
751 */
752 regs->cp0_epc = old_epc;
753 regs->regs[31] = old_ra;
754
755 /* Save the FP context to struct thread_struct */
756 lose_fpu(1);
757
758 /* Run the emulator */
759 sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
760 &fault_addr);
761
762 /* If something went wrong, signal */
763 process_fpemu_return(sig, fault_addr);
764
765 /* Restore the hardware register state */
766 own_fpu(1);
767
768 return 0;
769}
770
727/* 771/*
728 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX 772 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
729 */ 773 */
@@ -1016,6 +1060,9 @@ asmlinkage void do_ri(struct pt_regs *regs)
1016 1060
1017 if (status < 0) 1061 if (status < 0)
1018 status = simulate_sync(regs, opcode); 1062 status = simulate_sync(regs, opcode);
1063
1064 if (status < 0)
1065 status = simulate_fp(regs, opcode, old_epc, old31);
1019 } 1066 }
1020 1067
1021 if (status < 0) 1068 if (status < 0)
@@ -1380,12 +1427,19 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
1380 show_regs(regs); 1427 show_regs(regs);
1381 1428
1382 if (multi_match) { 1429 if (multi_match) {
1383 printk("Index : %0x\n", read_c0_index()); 1430 pr_err("Index : %0x\n", read_c0_index());
1384 printk("Pagemask: %0x\n", read_c0_pagemask()); 1431 pr_err("Pagemask: %0x\n", read_c0_pagemask());
1385 printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); 1432 pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi());
1386 printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); 1433 pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
1387 printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); 1434 pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
1388 printk("\n"); 1435 pr_err("Wired : %0x\n", read_c0_wired());
1436 pr_err("Pagegrain: %0x\n", read_c0_pagegrain());
1437 if (cpu_has_htw) {
1438 pr_err("PWField : %0*lx\n", field, read_c0_pwfield());
1439 pr_err("PWSize : %0*lx\n", field, read_c0_pwsize());
1440 pr_err("PWCtl : %0x\n", read_c0_pwctl());
1441 }
1442 pr_err("\n");
1389 dump_tlb_all(); 1443 dump_tlb_all();
1390 } 1444 }
1391 1445
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 0f1af58b036a..ed2a278722a9 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -16,9 +16,11 @@
16#include <linux/elf.h> 16#include <linux/elf.h>
17#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
18#include <linux/unistd.h> 18#include <linux/unistd.h>
19#include <linux/random.h>
19 20
20#include <asm/vdso.h> 21#include <asm/vdso.h>
21#include <asm/uasm.h> 22#include <asm/uasm.h>
23#include <asm/processor.h>
22 24
23/* 25/*
24 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... 26 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
@@ -67,7 +69,18 @@ subsys_initcall(init_vdso);
67 69
68static unsigned long vdso_addr(unsigned long start) 70static unsigned long vdso_addr(unsigned long start)
69{ 71{
70 return STACK_TOP; 72 unsigned long offset = 0UL;
73
74 if (current->flags & PF_RANDOMIZE) {
75 offset = get_random_int();
76 offset <<= PAGE_SHIFT;
77 if (TASK_IS_32BIT_ADDR)
78 offset &= 0xfffffful;
79 else
80 offset &= 0xffffffful;
81 }
82
83 return STACK_TOP + offset;
71} 84}
72 85
73int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) 86int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
index 468ffa043607..7edcd4946fc1 100644
--- a/arch/mips/lantiq/falcon/sysctrl.c
+++ b/arch/mips/lantiq/falcon/sysctrl.c
@@ -49,6 +49,7 @@
49 49
50/* Activation Status Register */ 50/* Activation Status Register */
51#define ACTS_ASC0_ACT 0x00001000 51#define ACTS_ASC0_ACT 0x00001000
52#define ACTS_SSC0 0x00002000
52#define ACTS_ASC1_ACT 0x00000800 53#define ACTS_ASC1_ACT 0x00000800
53#define ACTS_I2C_ACT 0x00004000 54#define ACTS_I2C_ACT 0x00004000
54#define ACTS_P0 0x00010000 55#define ACTS_P0 0x00010000
@@ -147,12 +148,11 @@ static void falcon_gpe_enable(void)
147 if (status & (1 << (GPPC_OFFSET + 1))) 148 if (status & (1 << (GPPC_OFFSET + 1)))
148 return; 149 return;
149 150
150 if (status_r32(STATUS_CONFIG) == 0) 151 freq = (status_r32(STATUS_CONFIG) &
152 GPEFREQ_MASK) >>
153 GPEFREQ_OFFSET;
154 if (freq == 0)
151 freq = 1; /* use 625MHz on unfused chip */ 155 freq = 1; /* use 625MHz on unfused chip */
152 else
153 freq = (status_r32(STATUS_CONFIG) &
154 GPEFREQ_MASK) >>
155 GPEFREQ_OFFSET;
156 156
157 /* apply new frequency */ 157 /* apply new frequency */
158 sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), 158 sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1),
@@ -260,5 +260,6 @@ void __init ltq_soc_init(void)
260 clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); 260 clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4);
261 clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); 261 clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT);
262 clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); 262 clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT);
263 clkdev_add_sys("1e100d00.spi", SYSCTL_SYS1, ACTS_SSC0);
263 clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); 264 clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
264} 265}
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 030568a70ac4..6ab10573490d 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -70,6 +70,7 @@ static struct resource ltq_eiu_irq[MAX_EIU];
70static void __iomem *ltq_icu_membase[MAX_IM]; 70static void __iomem *ltq_icu_membase[MAX_IM];
71static void __iomem *ltq_eiu_membase; 71static void __iomem *ltq_eiu_membase;
72static struct irq_domain *ltq_domain; 72static struct irq_domain *ltq_domain;
73static int ltq_perfcount_irq;
73 74
74int ltq_eiu_get_irq(int exin) 75int ltq_eiu_get_irq(int exin)
75{ 76{
@@ -378,30 +379,6 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
378 panic("Failed to remap icu memory"); 379 panic("Failed to remap icu memory");
379 } 380 }
380 381
381 /* the external interrupts are optional and xway only */
382 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
383 if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
384 /* find out how many external irq sources we have */
385 exin_avail = of_irq_count(eiu_node);
386
387 if (exin_avail > MAX_EIU)
388 exin_avail = MAX_EIU;
389
390 ret = of_irq_to_resource_table(eiu_node,
391 ltq_eiu_irq, exin_avail);
392 if (ret != exin_avail)
393 panic("failed to load external irq resources");
394
395 if (request_mem_region(res.start, resource_size(&res),
396 res.name) < 0)
397 pr_err("Failed to request eiu memory");
398
399 ltq_eiu_membase = ioremap_nocache(res.start,
400 resource_size(&res));
401 if (!ltq_eiu_membase)
402 panic("Failed to remap eiu memory");
403 }
404
405 /* turn off all irqs by default */ 382 /* turn off all irqs by default */
406 for (i = 0; i < MAX_IM; i++) { 383 for (i = 0; i < MAX_IM; i++) {
407 /* make sure all irqs are turned off by default */ 384 /* make sure all irqs are turned off by default */
@@ -449,7 +426,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
449#endif 426#endif
450 427
451 /* tell oprofile which irq to use */ 428 /* tell oprofile which irq to use */
452 cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); 429 ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);
453 430
454 /* 431 /*
455 * if the timer irq is not one of the mips irqs we need to 432 * if the timer irq is not one of the mips irqs we need to
@@ -458,9 +435,38 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
458 if (MIPS_CPU_TIMER_IRQ != 7) 435 if (MIPS_CPU_TIMER_IRQ != 7)
459 irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); 436 irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
460 437
438 /* the external interrupts are optional and xway only */
439 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
440 if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
441 /* find out how many external irq sources we have */
442 exin_avail = of_irq_count(eiu_node);
443
444 if (exin_avail > MAX_EIU)
445 exin_avail = MAX_EIU;
446
447 ret = of_irq_to_resource_table(eiu_node,
448 ltq_eiu_irq, exin_avail);
449 if (ret != exin_avail)
450 panic("failed to load external irq resources");
451
452 if (request_mem_region(res.start, resource_size(&res),
453 res.name) < 0)
454 pr_err("Failed to request eiu memory");
455
456 ltq_eiu_membase = ioremap_nocache(res.start,
457 resource_size(&res));
458 if (!ltq_eiu_membase)
459 panic("Failed to remap eiu memory");
460 }
461
461 return 0; 462 return 0;
462} 463}
463 464
465int get_c0_perfcount_int(void)
466{
467 return ltq_perfcount_irq;
468}
469
464unsigned int get_c0_compare_int(void) 470unsigned int get_c0_compare_int(void)
465{ 471{
466 return MIPS_CPU_TIMER_IRQ; 472 return MIPS_CPU_TIMER_IRQ;
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index 7447d322d14e..39ab3e786e59 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -36,6 +36,11 @@ const char *get_system_type(void)
36 return soc_info.sys_type; 36 return soc_info.sys_type;
37} 37}
38 38
39int ltq_soc_type(void)
40{
41 return soc_info.type;
42}
43
39void prom_free_prom_memory(void) 44void prom_free_prom_memory(void)
40{ 45{
41} 46}
@@ -72,6 +77,8 @@ void __init plat_mem_setup(void)
72 * parsed resulting in our memory appearing 77 * parsed resulting in our memory appearing
73 */ 78 */
74 __dt_setup_arch(__dtb_start); 79 __dt_setup_arch(__dtb_start);
80
81 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
75} 82}
76 83
77void __init device_tree_init(void) 84void __init device_tree_init(void)
@@ -97,16 +104,7 @@ void __init prom_init(void)
97 104
98int __init plat_of_setup(void) 105int __init plat_of_setup(void)
99{ 106{
100 static struct of_device_id of_ids[3]; 107 return __dt_register_buses(soc_info.compatible, "simple-bus");
101
102 if (!of_have_populated_dt())
103 panic("device tree not present");
104
105 strlcpy(of_ids[0].compatible, soc_info.compatible,
106 sizeof(of_ids[0].compatible));
107 strncpy(of_ids[1].compatible, "simple-bus",
108 sizeof(of_ids[1].compatible));
109 return of_platform_populate(NULL, of_ids, NULL, NULL);
110} 108}
111 109
112arch_initcall(plat_of_setup); 110arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 087497d97357..a2edc538f477 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,3 +1,5 @@
1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o 1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
2 2
3obj-y += vmmc.o
4
3obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o 5obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 1fa0f175357e..fe68f9ae47c1 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -14,6 +14,7 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/reset-controller.h>
17 18
18#include <asm/reboot.h> 19#include <asm/reboot.h>
19 20
@@ -113,10 +114,77 @@ void ltq_reset_once(unsigned int module, ulong u)
113 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); 114 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
114} 115}
115 116
117static int ltq_assert_device(struct reset_controller_dev *rcdev,
118 unsigned long id)
119{
120 u32 val;
121
122 if (id < 8)
123 return -1;
124
125 val = ltq_rcu_r32(RCU_RST_REQ);
126 val |= BIT(id);
127 ltq_rcu_w32(val, RCU_RST_REQ);
128
129 return 0;
130}
131
132static int ltq_deassert_device(struct reset_controller_dev *rcdev,
133 unsigned long id)
134{
135 u32 val;
136
137 if (id < 8)
138 return -1;
139
140 val = ltq_rcu_r32(RCU_RST_REQ);
141 val &= ~BIT(id);
142 ltq_rcu_w32(val, RCU_RST_REQ);
143
144 return 0;
145}
146
147static int ltq_reset_device(struct reset_controller_dev *rcdev,
148 unsigned long id)
149{
150 ltq_assert_device(rcdev, id);
151 return ltq_deassert_device(rcdev, id);
152}
153
154static struct reset_control_ops reset_ops = {
155 .reset = ltq_reset_device,
156 .assert = ltq_assert_device,
157 .deassert = ltq_deassert_device,
158};
159
160static struct reset_controller_dev reset_dev = {
161 .ops = &reset_ops,
162 .owner = THIS_MODULE,
163 .nr_resets = 32,
164 .of_reset_n_cells = 1,
165};
166
167void ltq_rst_init(void)
168{
169 reset_dev.of_node = of_find_compatible_node(NULL, NULL,
170 "lantiq,xway-reset");
171 if (!reset_dev.of_node)
172 pr_err("Failed to find reset controller node");
173 else
174 reset_controller_register(&reset_dev);
175}
176
116static void ltq_machine_restart(char *command) 177static void ltq_machine_restart(char *command)
117{ 178{
179 u32 val = ltq_rcu_r32(RCU_RST_REQ);
180
181 if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
182 val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200;
183
184 val |= RCU_RD_SRST;
185
118 local_irq_disable(); 186 local_irq_disable();
119 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); 187 ltq_rcu_w32(val, RCU_RST_REQ);
120 unreachable(); 188 unreachable();
121} 189}
122 190
diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c
new file mode 100644
index 000000000000..696cd57f6f13
--- /dev/null
+++ b/arch/mips/lantiq/xway/vmmc.c
@@ -0,0 +1,69 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/module.h>
10#include <linux/of_platform.h>
11#include <linux/of_gpio.h>
12#include <linux/dma-mapping.h>
13
14#include <lantiq_soc.h>
15
16static unsigned int *cp1_base;
17
18unsigned int *ltq_get_cp1_base(void)
19{
20 if (!cp1_base)
21 panic("no cp1 base was set\n");
22
23 return cp1_base;
24}
25EXPORT_SYMBOL(ltq_get_cp1_base);
26
27static int vmmc_probe(struct platform_device *pdev)
28{
29#define CP1_SIZE (1 << 20)
30 int gpio_count;
31 dma_addr_t dma;
32
33 cp1_base =
34 (void *) CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE,
35 &dma, GFP_ATOMIC));
36
37 gpio_count = of_gpio_count(pdev->dev.of_node);
38 while (gpio_count > 0) {
39 enum of_gpio_flags flags;
40 int gpio = of_get_gpio_flags(pdev->dev.of_node,
41 --gpio_count, &flags);
42 if (gpio_request(gpio, "vmmc-relay"))
43 continue;
44 dev_info(&pdev->dev, "requested GPIO %d\n", gpio);
45 gpio_direction_output(gpio,
46 (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1));
47 }
48
49 dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base);
50
51 return 0;
52}
53
54static const struct of_device_id vmmc_match[] = {
55 { .compatible = "lantiq,vmmc-xway" },
56 {},
57};
58MODULE_DEVICE_TABLE(of, vmmc_match);
59
60static struct platform_driver vmmc_driver = {
61 .probe = vmmc_probe,
62 .driver = {
63 .name = "lantiq,vmmc",
64 .owner = THIS_MODULE,
65 .of_match_table = vmmc_match,
66 },
67};
68
69module_platform_driver(vmmc_driver);
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c
index d4d9d31f152e..7c1e54c6a36c 100644
--- a/arch/mips/lantiq/xway/xrx200_phy_fw.c
+++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c
@@ -24,7 +24,28 @@ static dma_addr_t xway_gphy_load(struct platform_device *pdev)
24 void *fw_addr; 24 void *fw_addr;
25 size_t size; 25 size_t size;
26 26
27 if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { 27 if (of_get_property(pdev->dev.of_node, "firmware1", NULL) ||
28 of_get_property(pdev->dev.of_node, "firmware2", NULL)) {
29 switch (ltq_soc_type()) {
30 case SOC_TYPE_VR9:
31 if (of_property_read_string(pdev->dev.of_node,
32 "firmware1", &fw_name)) {
33 dev_err(&pdev->dev,
34 "failed to load firmware filename\n");
35 return 0;
36 }
37 break;
38 case SOC_TYPE_VR9_2:
39 if (of_property_read_string(pdev->dev.of_node,
40 "firmware2", &fw_name)) {
41 dev_err(&pdev->dev,
42 "failed to load firmware filename\n");
43 return 0;
44 }
45 break;
46 }
47 } else if (of_property_read_string(pdev->dev.of_node,
48 "firmware", &fw_name)) {
28 dev_err(&pdev->dev, "failed to load firmware filename\n"); 49 dev_err(&pdev->dev, "failed to load firmware filename\n");
29 return 0; 50 return 0;
30 } 51 }
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
index e3acb2dad33a..8e7e378ce51c 100644
--- a/arch/mips/lib/iomap.c
+++ b/arch/mips/lib/iomap.c
@@ -97,14 +97,14 @@ EXPORT_SYMBOL(iowrite32be);
97 97
98/* 98/*
99 * These are the "repeat MMIO read/write" functions. 99 * These are the "repeat MMIO read/write" functions.
100 * Note the "__raw" accesses, since we don't want to 100 * Note the "__mem" accesses, since we want to convert
101 * convert to CPU byte order. We write in "IO byte 101 * to CPU byte order if the host bus happens to not match the
102 * order" (we also don't have IO barriers). 102 * endianness of PCI/ISA (see mach-generic/mangle-port.h).
103 */ 103 */
104static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) 104static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
105{ 105{
106 while (--count >= 0) { 106 while (--count >= 0) {
107 u8 data = __raw_readb(addr); 107 u8 data = __mem_readb(addr);
108 *dst = data; 108 *dst = data;
109 dst++; 109 dst++;
110 } 110 }
@@ -113,7 +113,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
113static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) 113static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
114{ 114{
115 while (--count >= 0) { 115 while (--count >= 0) {
116 u16 data = __raw_readw(addr); 116 u16 data = __mem_readw(addr);
117 *dst = data; 117 *dst = data;
118 dst++; 118 dst++;
119 } 119 }
@@ -122,7 +122,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
122static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) 122static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
123{ 123{
124 while (--count >= 0) { 124 while (--count >= 0) {
125 u32 data = __raw_readl(addr); 125 u32 data = __mem_readl(addr);
126 *dst = data; 126 *dst = data;
127 dst++; 127 dst++;
128 } 128 }
@@ -131,7 +131,7 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
131static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) 131static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
132{ 132{
133 while (--count >= 0) { 133 while (--count >= 0) {
134 __raw_writeb(*src, addr); 134 __mem_writeb(*src, addr);
135 src++; 135 src++;
136 } 136 }
137} 137}
@@ -139,7 +139,7 @@ static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
139static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) 139static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
140{ 140{
141 while (--count >= 0) { 141 while (--count >= 0) {
142 __raw_writew(*src, addr); 142 __mem_writew(*src, addr);
143 src++; 143 src++;
144 } 144 }
145} 145}
@@ -147,7 +147,7 @@ static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
147static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) 147static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
148{ 148{
149 while (--count >= 0) { 149 while (--count >= 0) {
150 __raw_writel(*src, addr); 150 __mem_writel(*src, addr);
151 src++; 151 src++;
152 } 152 }
153} 153}
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 7b0e5462ca51..c8fe6b1968fb 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -114,8 +114,7 @@
114 R10KCBARRIER(0(ra)) 114 R10KCBARRIER(0(ra))
115#ifdef __MIPSEB__ 115#ifdef __MIPSEB__
116 EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ 116 EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
117#endif 117#else
118#ifdef __MIPSEL__
119 EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ 118 EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
120#endif 119#endif
121 PTR_SUBU a0, t0 /* long align ptr */ 120 PTR_SUBU a0, t0 /* long align ptr */
@@ -164,8 +163,7 @@
164 R10KCBARRIER(0(ra)) 163 R10KCBARRIER(0(ra))
165#ifdef __MIPSEB__ 164#ifdef __MIPSEB__
166 EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) 165 EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@)
167#endif 166#else
168#ifdef __MIPSEL__
169 EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) 167 EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@)
170#endif 168#endif
1711: jr ra 1691: jr ra
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c
index 57bcdaf1f1c8..be777d9a3f85 100644
--- a/arch/mips/lib/mips-atomic.c
+++ b/arch/mips/lib/mips-atomic.c
@@ -42,15 +42,11 @@ notrace void arch_local_irq_disable(void)
42 __asm__ __volatile__( 42 __asm__ __volatile__(
43 " .set push \n" 43 " .set push \n"
44 " .set noat \n" 44 " .set noat \n"
45#if defined(CONFIG_CPU_MIPSR2)
46 /* see irqflags.h for inline function */
47#else
48 " mfc0 $1,$12 \n" 45 " mfc0 $1,$12 \n"
49 " ori $1,0x1f \n" 46 " ori $1,0x1f \n"
50 " xori $1,0x1f \n" 47 " xori $1,0x1f \n"
51 " .set noreorder \n" 48 " .set noreorder \n"
52 " mtc0 $1,$12 \n" 49 " mtc0 $1,$12 \n"
53#endif
54 " " __stringify(__irq_disable_hazard) " \n" 50 " " __stringify(__irq_disable_hazard) " \n"
55 " .set pop \n" 51 " .set pop \n"
56 : /* no outputs */ 52 : /* no outputs */
@@ -72,15 +68,11 @@ notrace unsigned long arch_local_irq_save(void)
72 " .set push \n" 68 " .set push \n"
73 " .set reorder \n" 69 " .set reorder \n"
74 " .set noat \n" 70 " .set noat \n"
75#if defined(CONFIG_CPU_MIPSR2)
76 /* see irqflags.h for inline function */
77#else
78 " mfc0 %[flags], $12 \n" 71 " mfc0 %[flags], $12 \n"
79 " ori $1, %[flags], 0x1f \n" 72 " ori $1, %[flags], 0x1f \n"
80 " xori $1, 0x1f \n" 73 " xori $1, 0x1f \n"
81 " .set noreorder \n" 74 " .set noreorder \n"
82 " mtc0 $1, $12 \n" 75 " mtc0 $1, $12 \n"
83#endif
84 " " __stringify(__irq_disable_hazard) " \n" 76 " " __stringify(__irq_disable_hazard) " \n"
85 " .set pop \n" 77 " .set pop \n"
86 : [flags] "=r" (flags) 78 : [flags] "=r" (flags)
@@ -103,18 +95,12 @@ notrace void arch_local_irq_restore(unsigned long flags)
103 " .set push \n" 95 " .set push \n"
104 " .set noreorder \n" 96 " .set noreorder \n"
105 " .set noat \n" 97 " .set noat \n"
106#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
107 /* see irqflags.h for inline function */
108#elif defined(CONFIG_CPU_MIPSR2)
109 /* see irqflags.h for inline function */
110#else
111 " mfc0 $1, $12 \n" 98 " mfc0 $1, $12 \n"
112 " andi %[flags], 1 \n" 99 " andi %[flags], 1 \n"
113 " ori $1, 0x1f \n" 100 " ori $1, 0x1f \n"
114 " xori $1, 0x1f \n" 101 " xori $1, 0x1f \n"
115 " or %[flags], $1 \n" 102 " or %[flags], $1 \n"
116 " mtc0 %[flags], $12 \n" 103 " mtc0 %[flags], $12 \n"
117#endif
118 " " __stringify(__irq_disable_hazard) " \n" 104 " " __stringify(__irq_disable_hazard) " \n"
119 " .set pop \n" 105 " .set pop \n"
120 : [flags] "=r" (__tmp1) 106 : [flags] "=r" (__tmp1)
@@ -136,18 +122,12 @@ notrace void __arch_local_irq_restore(unsigned long flags)
136 " .set push \n" 122 " .set push \n"
137 " .set noreorder \n" 123 " .set noreorder \n"
138 " .set noat \n" 124 " .set noat \n"
139#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
140 /* see irqflags.h for inline function */
141#elif defined(CONFIG_CPU_MIPSR2)
142 /* see irqflags.h for inline function */
143#else
144 " mfc0 $1, $12 \n" 125 " mfc0 $1, $12 \n"
145 " andi %[flags], 1 \n" 126 " andi %[flags], 1 \n"
146 " ori $1, 0x1f \n" 127 " ori $1, 0x1f \n"
147 " xori $1, 0x1f \n" 128 " xori $1, 0x1f \n"
148 " or %[flags], $1 \n" 129 " or %[flags], $1 \n"
149 " mtc0 %[flags], $12 \n" 130 " mtc0 %[flags], $12 \n"
150#endif
151 " " __stringify(__irq_disable_hazard) " \n" 131 " " __stringify(__irq_disable_hazard) " \n"
152 " .set pop \n" 132 " .set pop \n"
153 : [flags] "=r" (__tmp1) 133 : [flags] "=r" (__tmp1)
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index 1ef365ab3cd3..975a13855116 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -9,6 +9,7 @@
9#include <linux/mm.h> 9#include <linux/mm.h>
10 10
11#include <asm/mipsregs.h> 11#include <asm/mipsregs.h>
12#include <asm/mmu_context.h>
12#include <asm/page.h> 13#include <asm/page.h>
13#include <asm/pgtable.h> 14#include <asm/pgtable.h>
14#include <asm/tlbdebug.h> 15#include <asm/tlbdebug.h>
@@ -21,7 +22,7 @@ static void dump_tlb(int first, int last)
21 unsigned int asid; 22 unsigned int asid;
22 unsigned long entryhi, entrylo0; 23 unsigned long entryhi, entrylo0;
23 24
24 asid = read_c0_entryhi() & 0xfc0; 25 asid = read_c0_entryhi() & ASID_MASK;
25 26
26 for (i = first; i <= last; i++) { 27 for (i = first; i <= last; i++) {
27 write_c0_index(i<<8); 28 write_c0_index(i<<8);
@@ -34,8 +35,8 @@ static void dump_tlb(int first, int last)
34 entrylo0 = read_c0_entrylo0(); 35 entrylo0 = read_c0_entrylo0();
35 36
36 /* Unused entries have a virtual address of KSEG0. */ 37 /* Unused entries have a virtual address of KSEG0. */
37 if ((entryhi & 0xfffff000) != 0x80000000 38 if ((entryhi & PAGE_MASK) != KSEG0
38 && (entryhi & 0xfc0) == asid) { 39 && (entryhi & ASID_MASK) == asid) {
39 /* 40 /*
40 * Only print entries in use 41 * Only print entries in use
41 */ 42 */
@@ -43,8 +44,8 @@ static void dump_tlb(int first, int last)
43 44
44 printk("va=%08lx asid=%08lx" 45 printk("va=%08lx asid=%08lx"
45 " [pa=%06lx n=%d d=%d v=%d g=%d]", 46 " [pa=%06lx n=%d d=%d v=%d g=%d]",
46 (entryhi & 0xfffff000), 47 entryhi & PAGE_MASK,
47 entryhi & 0xfc0, 48 entryhi & ASID_MASK,
48 entrylo0 & PAGE_MASK, 49 entrylo0 & PAGE_MASK,
49 (entrylo0 & (1 << 11)) ? 1 : 0, 50 (entrylo0 & (1 << 11)) ? 1 : 0,
50 (entrylo0 & (1 << 10)) ? 1 : 0, 51 (entrylo0 & (1 << 10)) ? 1 : 0,
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
index bef65c98df59..929bbacd697e 100644
--- a/arch/mips/lib/strlen_user.S
+++ b/arch/mips/lib/strlen_user.S
@@ -28,7 +28,6 @@ LEAF(__strlen_\func\()_asm)
28 and v0, a0 28 and v0, a0
29 bnez v0, .Lfault\@ 29 bnez v0, .Lfault\@
30 30
31FEXPORT(__strlen_\func\()_nocheck_asm)
32 move v0, a0 31 move v0, a0
33.ifeqs "\func", "kernel" 32.ifeqs "\func", "kernel"
341: EX(lbu, v1, (v0), .Lfault\@) 331: EX(lbu, v1, (v0), .Lfault\@)
@@ -48,9 +47,7 @@ FEXPORT(__strlen_\func\()_nocheck_asm)
48#ifndef CONFIG_EVA 47#ifndef CONFIG_EVA
49 /* Set aliases */ 48 /* Set aliases */
50 .global __strlen_user_asm 49 .global __strlen_user_asm
51 .global __strlen_user_nocheck_asm
52 .set __strlen_user_asm, __strlen_kernel_asm 50 .set __strlen_user_asm, __strlen_kernel_asm
53 .set __strlen_user_nocheck_asm, __strlen_kernel_nocheck_asm
54#endif 51#endif
55 52
56__BUILD_STRLEN_ASM kernel 53__BUILD_STRLEN_ASM kernel
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index 1b91fc6a921b..156de85b82cd 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -86,6 +86,7 @@ config LOONGSON_MACH3X
86 select LOONGSON_MC146818 86 select LOONGSON_MC146818
87 select ZONE_DMA32 87 select ZONE_DMA32
88 select LEFI_FIRMWARE_INTERFACE 88 select LEFI_FIRMWARE_INTERFACE
89 select PHYS48_TO_HT40
89 help 90 help
90 Generic Loongson 3 family machines utilize the 3A/3B revision 91 Generic Loongson 3 family machines utilize the 3A/3B revision
91 of Loongson processor and RS780/SBX00 chipset. 92 of Loongson processor and RS780/SBX00 chipset.
@@ -107,6 +108,18 @@ config CS5536_MFGPT
107 108
108 If unsure, say Yes. 109 If unsure, say Yes.
109 110
111config RS780_HPET
112 bool "RS780/SBX00 HPET Timer"
113 depends on LOONGSON_MACH3X
114 select MIPS_EXTERNAL_TIMER
115 help
116 This option enables the hpet timer of AMD RS780/SBX00.
117
118 If you want to enable the Loongson3 CPUFreq Driver, Please enable
119 this option at first, otherwise, You will get wrong system time.
120
121 If unsure, say Yes.
122
110config LOONGSON_SUSPEND 123config LOONGSON_SUSPEND
111 bool 124 bool
112 default y 125 default y
@@ -131,6 +144,10 @@ config SWIOTLB
131 select NEED_SG_DMA_LENGTH 144 select NEED_SG_DMA_LENGTH
132 select NEED_DMA_MAP_STATE 145 select NEED_DMA_MAP_STATE
133 146
147config PHYS48_TO_HT40
148 bool
149 default y if CPU_LOONGSON3
150
134config LOONGSON_MC146818 151config LOONGSON_MC146818
135 bool 152 bool
136 default n 153 default n
diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c
index 81bed9d18061..b739723205f8 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_pci.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/types.h> 23#include <linux/types.h>
24#include <cs5536/cs5536_pci.h>
24#include <cs5536/cs5536_vsm.h> 25#include <cs5536/cs5536_vsm.h>
25 26
26enum { 27enum {
@@ -35,21 +36,21 @@ enum {
35}; 36};
36 37
37static const cs5536_pci_vsm_write vsm_conf_write[] = { 38static const cs5536_pci_vsm_write vsm_conf_write[] = {
38 [CS5536_ISA_FUNC] pci_isa_write_reg, 39 [CS5536_ISA_FUNC] = pci_isa_write_reg,
39 [reserved_func] NULL, 40 [reserved_func] = NULL,
40 [CS5536_IDE_FUNC] pci_ide_write_reg, 41 [CS5536_IDE_FUNC] = pci_ide_write_reg,
41 [CS5536_ACC_FUNC] pci_acc_write_reg, 42 [CS5536_ACC_FUNC] = pci_acc_write_reg,
42 [CS5536_OHCI_FUNC] pci_ohci_write_reg, 43 [CS5536_OHCI_FUNC] = pci_ohci_write_reg,
43 [CS5536_EHCI_FUNC] pci_ehci_write_reg, 44 [CS5536_EHCI_FUNC] = pci_ehci_write_reg,
44}; 45};
45 46
46static const cs5536_pci_vsm_read vsm_conf_read[] = { 47static const cs5536_pci_vsm_read vsm_conf_read[] = {
47 [CS5536_ISA_FUNC] pci_isa_read_reg, 48 [CS5536_ISA_FUNC] = pci_isa_read_reg,
48 [reserved_func] NULL, 49 [reserved_func] = NULL,
49 [CS5536_IDE_FUNC] pci_ide_read_reg, 50 [CS5536_IDE_FUNC] = pci_ide_read_reg,
50 [CS5536_ACC_FUNC] pci_acc_read_reg, 51 [CS5536_ACC_FUNC] = pci_acc_read_reg,
51 [CS5536_OHCI_FUNC] pci_ohci_read_reg, 52 [CS5536_OHCI_FUNC] = pci_ohci_read_reg,
52 [CS5536_EHCI_FUNC] pci_ehci_read_reg, 53 [CS5536_EHCI_FUNC] = pci_ehci_read_reg,
53}; 54};
54 55
55/* 56/*
diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c
index c2be01f91575..2c6b989c1bc4 100644
--- a/arch/mips/loongson/common/dma-swiotlb.c
+++ b/arch/mips/loongson/common/dma-swiotlb.c
@@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask)
105 105
106dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 106dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
107{ 107{
108 long nid;
109#ifdef CONFIG_PHYS48_TO_HT40
110 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
111 * Loongson-3's 48bit address space and embed it into 40bit */
112 nid = (paddr >> 44) & 0x3;
113 paddr = ((nid << 44) ^ paddr) | (nid << 37);
114#endif
108 return paddr; 115 return paddr;
109} 116}
110 117
111phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) 118phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
112{ 119{
120 long nid;
121#ifdef CONFIG_PHYS48_TO_HT40
122 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
123 * Loongson-3's 48bit address space and embed it into 40bit */
124 nid = (daddr >> 37) & 0x3;
125 daddr = ((nid << 37) ^ daddr) | (nid << 44);
126#endif
113 return daddr; 127 return daddr;
114} 128}
115 129
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
index ced461b39069..6ca632e529dc 100644
--- a/arch/mips/loongson/common/early_printk.c
+++ b/arch/mips/loongson/common/early_printk.c
@@ -30,7 +30,7 @@ void prom_putchar(char c)
30 int timeout; 30 int timeout;
31 unsigned char *uart_base; 31 unsigned char *uart_base;
32 32
33 uart_base = (unsigned char *)_loongson_uart_base; 33 uart_base = (unsigned char *)_loongson_uart_base[0];
34 timeout = 1024; 34 timeout = 1024;
35 35
36 while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && 36 while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
index f15228550a22..045ea3d47c87 100644
--- a/arch/mips/loongson/common/env.c
+++ b/arch/mips/loongson/common/env.c
@@ -21,6 +21,7 @@
21#include <asm/bootinfo.h> 21#include <asm/bootinfo.h>
22#include <loongson.h> 22#include <loongson.h>
23#include <boot_param.h> 23#include <boot_param.h>
24#include <workarounds.h>
24 25
25u32 cpu_clock_freq; 26u32 cpu_clock_freq;
26EXPORT_SYMBOL(cpu_clock_freq); 27EXPORT_SYMBOL(cpu_clock_freq);
@@ -31,7 +32,6 @@ u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180};
31u64 loongson_freqctrl[MAX_PACKAGES]; 32u64 loongson_freqctrl[MAX_PACKAGES];
32 33
33unsigned long long smp_group[4]; 34unsigned long long smp_group[4];
34int cpuhotplug_workaround = 0;
35 35
36#define parse_even_earlier(res, option, p) \ 36#define parse_even_earlier(res, option, p) \
37do { \ 37do { \
@@ -67,6 +67,7 @@ void __init prom_init_env(void)
67#else 67#else
68 struct boot_params *boot_p; 68 struct boot_params *boot_p;
69 struct loongson_params *loongson_p; 69 struct loongson_params *loongson_p;
70 struct system_loongson *esys;
70 struct efi_cpuinfo_loongson *ecpu; 71 struct efi_cpuinfo_loongson *ecpu;
71 struct irq_source_routing_table *eirq_source; 72 struct irq_source_routing_table *eirq_source;
72 73
@@ -74,6 +75,8 @@ void __init prom_init_env(void)
74 boot_p = (struct boot_params *)fw_arg2; 75 boot_p = (struct boot_params *)fw_arg2;
75 loongson_p = &(boot_p->efi.smbios.lp); 76 loongson_p = &(boot_p->efi.smbios.lp);
76 77
78 esys = (struct system_loongson *)
79 ((u64)loongson_p + loongson_p->system_offset);
77 ecpu = (struct efi_cpuinfo_loongson *) 80 ecpu = (struct efi_cpuinfo_loongson *)
78 ((u64)loongson_p + loongson_p->cpu_offset); 81 ((u64)loongson_p + loongson_p->cpu_offset);
79 eirq_source = (struct irq_source_routing_table *) 82 eirq_source = (struct irq_source_routing_table *)
@@ -95,6 +98,7 @@ void __init prom_init_env(void)
95 loongson_chipcfg[2] = 0x900020001fe00180; 98 loongson_chipcfg[2] = 0x900020001fe00180;
96 loongson_chipcfg[3] = 0x900030001fe00180; 99 loongson_chipcfg[3] = 0x900030001fe00180;
97 loongson_sysconf.ht_control_base = 0x90000EFDFB000000; 100 loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
101 loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
98 } else if (ecpu->cputype == Loongson_3B) { 102 } else if (ecpu->cputype == Loongson_3B) {
99 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ 103 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */
100 loongson_sysconf.cores_per_package = 8; 104 loongson_sysconf.cores_per_package = 8;
@@ -111,7 +115,7 @@ void __init prom_init_env(void)
111 loongson_freqctrl[2] = 0x900040001fe001d0; 115 loongson_freqctrl[2] = 0x900040001fe001d0;
112 loongson_freqctrl[3] = 0x900060001fe001d0; 116 loongson_freqctrl[3] = 0x900060001fe001d0;
113 loongson_sysconf.ht_control_base = 0x90001EFDFB000000; 117 loongson_sysconf.ht_control_base = 0x90001EFDFB000000;
114 cpuhotplug_workaround = 1; 118 loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG;
115 } else { 119 } else {
116 loongson_sysconf.cores_per_node = 1; 120 loongson_sysconf.cores_per_node = 1;
117 loongson_sysconf.cores_per_package = 1; 121 loongson_sysconf.cores_per_package = 1;
@@ -119,6 +123,8 @@ void __init prom_init_env(void)
119 } 123 }
120 124
121 loongson_sysconf.nr_cpus = ecpu->nr_cpus; 125 loongson_sysconf.nr_cpus = ecpu->nr_cpus;
126 loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
127 loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
122 if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) 128 if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
123 loongson_sysconf.nr_cpus = NR_CPUS; 129 loongson_sysconf.nr_cpus = NR_CPUS;
124 loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + 130 loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
@@ -141,6 +147,24 @@ void __init prom_init_env(void)
141 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", 147 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n",
142 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, 148 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr,
143 loongson_sysconf.vgabios_addr); 149 loongson_sysconf.vgabios_addr);
150
151 memset(loongson_sysconf.ecname, 0, 32);
152 if (esys->has_ec)
153 memcpy(loongson_sysconf.ecname, esys->ec_name, 32);
154 loongson_sysconf.workarounds |= esys->workarounds;
155
156 loongson_sysconf.nr_uarts = esys->nr_uarts;
157 if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS)
158 loongson_sysconf.nr_uarts = 1;
159 memcpy(loongson_sysconf.uarts, esys->uarts,
160 sizeof(struct uart_device) * loongson_sysconf.nr_uarts);
161
162 loongson_sysconf.nr_sensors = esys->nr_sensors;
163 if (loongson_sysconf.nr_sensors > MAX_SENSORS)
164 loongson_sysconf.nr_sensors = 0;
165 if (loongson_sysconf.nr_sensors)
166 memcpy(loongson_sysconf.sensors, esys->sensors,
167 sizeof(struct sensor_device) * loongson_sysconf.nr_sensors);
144#endif 168#endif
145 if (cpu_clock_freq == 0) { 169 if (cpu_clock_freq == 0) {
146 processor_id = (&current_cpu_data)->processor_id; 170 processor_id = (&current_cpu_data)->processor_id;
diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c
index 21869908aaa4..29dbaa253061 100644
--- a/arch/mips/loongson/common/gpio.c
+++ b/arch/mips/loongson/common/gpio.c
@@ -37,7 +37,7 @@ int gpio_get_value(unsigned gpio)
37 val = LOONGSON_GPIODATA; 37 val = LOONGSON_GPIODATA;
38 spin_unlock(&gpio_lock); 38 spin_unlock(&gpio_lock);
39 39
40 return ((val & mask) != 0); 40 return (val & mask) != 0;
41} 41}
42EXPORT_SYMBOL(gpio_get_value); 42EXPORT_SYMBOL(gpio_get_value);
43 43
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c
index f6af3aba4c86..9b987fe98b5b 100644
--- a/arch/mips/loongson/common/init.c
+++ b/arch/mips/loongson/common/init.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/bootmem.h> 11#include <linux/bootmem.h>
12#include <asm/bootinfo.h>
12#include <asm/smp-ops.h> 13#include <asm/smp-ops.h>
13 14
14#include <loongson.h> 15#include <loongson.h>
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
index 1a4797984b8d..f2807bc662a3 100644
--- a/arch/mips/loongson/common/machtype.c
+++ b/arch/mips/loongson/common/machtype.c
@@ -19,19 +19,16 @@
19#define MACHTYPE_LEN 50 19#define MACHTYPE_LEN 50
20 20
21static const char *system_types[] = { 21static const char *system_types[] = {
22 [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", 22 [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine",
23 [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", 23 [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box",
24 [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", 24 [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box",
25 [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", 25 [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches",
26 [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", 26 [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches",
27 [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", 27 [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f",
28 [MACH_LEMOTE_NAS] "lemote-nas-2f", 28 [MACH_LEMOTE_NAS] = "lemote-nas-2f",
29 [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", 29 [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f",
30 [MACH_LEMOTE_A1004] "lemote-3a-notebook-a1004", 30 [MACH_LOONGSON_GENERIC] = "generic-loongson-machine",
31 [MACH_LEMOTE_A1101] "lemote-3a-itx-a1101", 31 [MACH_LOONGSON_END] = NULL,
32 [MACH_LEMOTE_A1201] "lemote-2gq-notebook-a1201",
33 [MACH_LEMOTE_A1205] "lemote-2gq-aio-a1205",
34 [MACH_LOONGSON_END] NULL,
35}; 32};
36 33
37const char *get_system_type(void) 34const char *get_system_type(void)
diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c
index a90d87c01555..b5709af09f7f 100644
--- a/arch/mips/loongson/common/rtc.c
+++ b/arch/mips/loongson/common/rtc.c
@@ -14,7 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/mc146818rtc.h> 15#include <linux/mc146818rtc.h>
16 16
17struct resource loongson_rtc_resources[] = { 17static struct resource loongson_rtc_resources[] = {
18 { 18 {
19 .start = RTC_PORT(0), 19 .start = RTC_PORT(0),
20 .end = RTC_PORT(1), 20 .end = RTC_PORT(1),
diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c
index bd2b7095b6dc..c23fa1373729 100644
--- a/arch/mips/loongson/common/serial.c
+++ b/arch/mips/loongson/common/serial.c
@@ -38,20 +38,17 @@
38 .regshift = 0, \ 38 .regshift = 0, \
39} 39}
40 40
41static struct plat_serial8250_port uart8250_data[][2] = { 41static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = {
42 [MACH_LOONGSON_UNKNOWN] {}, 42 [MACH_LOONGSON_UNKNOWN] = {},
43 [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, 43 [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} },
44 [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, 44 [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} },
45 [MACH_LEMOTE_ML2F7] {PORT_M(3, 3686400), {} }, 45 [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} },
46 [MACH_LEMOTE_YL2F89] {PORT_M(3, 3686400), {} }, 46 [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} },
47 [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, 47 [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} },
48 [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, 48 [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} },
49 [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, 49 [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} },
50 [MACH_LEMOTE_A1004] {PORT_M(2, 33177600), {} }, 50 [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} },
51 [MACH_LEMOTE_A1101] {PORT_M(2, 25000000), {} }, 51 [MACH_LOONGSON_END] = {},
52 [MACH_LEMOTE_A1201] {PORT_M(2, 25000000), {} },
53 [MACH_LEMOTE_A1205] {PORT_M(2, 25000000), {} },
54 [MACH_LOONGSON_END] {},
55}; 52};
56 53
57static struct platform_device uart8250_device = { 54static struct platform_device uart8250_device = {
@@ -61,17 +58,52 @@ static struct platform_device uart8250_device = {
61 58
62static int __init serial_init(void) 59static int __init serial_init(void)
63{ 60{
61 int i;
64 unsigned char iotype; 62 unsigned char iotype;
65 63
66 iotype = uart8250_data[mips_machtype][0].iotype; 64 iotype = uart8250_data[mips_machtype][0].iotype;
67 65
68 if (UPIO_MEM == iotype) 66 if (UPIO_MEM == iotype) {
67 uart8250_data[mips_machtype][0].mapbase =
68 loongson_uart_base[0];
69 uart8250_data[mips_machtype][0].membase = 69 uart8250_data[mips_machtype][0].membase =
70 (void __iomem *)_loongson_uart_base; 70 (void __iomem *)_loongson_uart_base[0];
71 }
71 else if (UPIO_PORT == iotype) 72 else if (UPIO_PORT == iotype)
72 uart8250_data[mips_machtype][0].iobase = 73 uart8250_data[mips_machtype][0].iobase =
73 loongson_uart_base - LOONGSON_PCIIO_BASE; 74 loongson_uart_base[0] - LOONGSON_PCIIO_BASE;
74 75
76 if (loongson_sysconf.uarts[0].uartclk)
77 uart8250_data[mips_machtype][0].uartclk =
78 loongson_sysconf.uarts[0].uartclk;
79
80 for (i = 1; i < loongson_sysconf.nr_uarts; i++) {
81 iotype = loongson_sysconf.uarts[i].iotype;
82 uart8250_data[mips_machtype][i].iotype = iotype;
83 loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base;
84
85 if (UPIO_MEM == iotype) {
86 uart8250_data[mips_machtype][i].irq =
87 MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset;
88 uart8250_data[mips_machtype][i].mapbase =
89 loongson_uart_base[i];
90 uart8250_data[mips_machtype][i].membase =
91 ioremap_nocache(loongson_uart_base[i], 8);
92 } else if (UPIO_PORT == iotype) {
93 uart8250_data[mips_machtype][i].irq =
94 loongson_sysconf.uarts[i].int_offset;
95 uart8250_data[mips_machtype][i].iobase =
96 loongson_uart_base[i] - LOONGSON_PCIIO_BASE;
97 }
98
99 uart8250_data[mips_machtype][i].uartclk =
100 loongson_sysconf.uarts[i].uartclk;
101 uart8250_data[mips_machtype][i].flags =
102 UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
103 }
104
105 memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts],
106 0, sizeof(struct plat_serial8250_port));
75 uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; 107 uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
76 108
77 return platform_device_register(&uart8250_device); 109 return platform_device_register(&uart8250_device);
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c
index bb4ac922e47a..d477dd6bb326 100644
--- a/arch/mips/loongson/common/setup.c
+++ b/arch/mips/loongson/common/setup.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11 11
12#include <asm/wbflush.h> 12#include <asm/wbflush.h>
13#include <asm/bootinfo.h>
13 14
14#include <loongson.h> 15#include <loongson.h>
15 16
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c
index 262a1f65b05e..e1a5382ad47e 100644
--- a/arch/mips/loongson/common/time.c
+++ b/arch/mips/loongson/common/time.c
@@ -12,6 +12,7 @@
12 */ 12 */
13#include <asm/mc146818-time.h> 13#include <asm/mc146818-time.h>
14#include <asm/time.h> 14#include <asm/time.h>
15#include <asm/hpet.h>
15 16
16#include <loongson.h> 17#include <loongson.h>
17#include <cs5536/cs5536_mfgpt.h> 18#include <cs5536/cs5536_mfgpt.h>
@@ -21,7 +22,11 @@ void __init plat_time_init(void)
21 /* setup mips r4k timer */ 22 /* setup mips r4k timer */
22 mips_hpt_frequency = cpu_clock_freq / 2; 23 mips_hpt_frequency = cpu_clock_freq / 2;
23 24
25#ifdef CONFIG_RS780_HPET
26 setup_hpet_timer();
27#else
24 setup_mfgpt0_timer(); 28 setup_mfgpt0_timer();
29#endif
25} 30}
26 31
27void read_persistent_clock(struct timespec *ts) 32void read_persistent_clock(struct timespec *ts)
diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c
index 1e1eeea73fde..9de559d58e1f 100644
--- a/arch/mips/loongson/common/uart_base.c
+++ b/arch/mips/loongson/common/uart_base.c
@@ -13,22 +13,27 @@
13 13
14#include <loongson.h> 14#include <loongson.h>
15 15
16/* ioremapped */
17unsigned long _loongson_uart_base;
18EXPORT_SYMBOL(_loongson_uart_base);
19/* raw */ 16/* raw */
20unsigned long loongson_uart_base; 17unsigned long loongson_uart_base[MAX_UARTS] = {};
18/* ioremapped */
19unsigned long _loongson_uart_base[MAX_UARTS] = {};
20
21EXPORT_SYMBOL(loongson_uart_base); 21EXPORT_SYMBOL(loongson_uart_base);
22EXPORT_SYMBOL(_loongson_uart_base);
22 23
23void prom_init_loongson_uart_base(void) 24void prom_init_loongson_uart_base(void)
24{ 25{
25 switch (mips_machtype) { 26 switch (mips_machtype) {
27 case MACH_LOONGSON_GENERIC:
28 /* The CPU provided serial port (CPU) */
29 loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0;
30 break;
26 case MACH_LEMOTE_FL2E: 31 case MACH_LEMOTE_FL2E:
27 loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; 32 loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8;
28 break; 33 break;
29 case MACH_LEMOTE_FL2F: 34 case MACH_LEMOTE_FL2F:
30 case MACH_LEMOTE_LL2F: 35 case MACH_LEMOTE_LL2F:
31 loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; 36 loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8;
32 break; 37 break;
33 case MACH_LEMOTE_ML2F7: 38 case MACH_LEMOTE_ML2F7:
34 case MACH_LEMOTE_YL2F89: 39 case MACH_LEMOTE_YL2F89:
@@ -36,17 +41,10 @@ void prom_init_loongson_uart_base(void)
36 case MACH_LEMOTE_NAS: 41 case MACH_LEMOTE_NAS:
37 default: 42 default:
38 /* The CPU provided serial port (LPC) */ 43 /* The CPU provided serial port (LPC) */
39 loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; 44 loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8;
40 break;
41 case MACH_LEMOTE_A1004:
42 case MACH_LEMOTE_A1101:
43 case MACH_LEMOTE_A1201:
44 case MACH_LEMOTE_A1205:
45 /* The CPU provided serial port (CPU) */
46 loongson_uart_base = LOONGSON_REG_BASE + 0x1e0;
47 break; 45 break;
48 } 46 }
49 47
50 _loongson_uart_base = 48 _loongson_uart_base[0] =
51 (unsigned long)ioremap_nocache(loongson_uart_base, 8); 49 (unsigned long)ioremap_nocache(loongson_uart_base[0], 8);
52} 50}
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
index 6f8682e44483..cab5f43e0e29 100644
--- a/arch/mips/loongson/lemote-2f/irq.c
+++ b/arch/mips/loongson/lemote-2f/irq.c
@@ -93,13 +93,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id)
93 return IRQ_HANDLED; 93 return IRQ_HANDLED;
94} 94}
95 95
96struct irqaction ip6_irqaction = { 96static struct irqaction ip6_irqaction = {
97 .handler = ip6_action, 97 .handler = ip6_action,
98 .name = "cascade", 98 .name = "cascade",
99 .flags = IRQF_SHARED | IRQF_NO_THREAD, 99 .flags = IRQF_SHARED | IRQF_NO_THREAD,
100}; 100};
101 101
102struct irqaction cascade_irqaction = { 102static struct irqaction cascade_irqaction = {
103 .handler = no_action, 103 .handler = no_action,
104 .name = "cascade", 104 .name = "cascade",
105 .flags = IRQF_NO_THREAD, 105 .flags = IRQF_NO_THREAD,
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c
index 79ac694fe744..a26ca7fcd7e0 100644
--- a/arch/mips/loongson/lemote-2f/reset.c
+++ b/arch/mips/loongson/lemote-2f/reset.c
@@ -76,7 +76,7 @@ static void fl2f_shutdown(void)
76 76
77/* reset support for yeeloong2f and mengloong2f notebook */ 77/* reset support for yeeloong2f and mengloong2f notebook */
78 78
79void ml2f_reboot(void) 79static void ml2f_reboot(void)
80{ 80{
81 reset_cpu(); 81 reset_cpu();
82 82
diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile
index b4df775b9f30..622fead5ebc9 100644
--- a/arch/mips/loongson/loongson-3/Makefile
+++ b/arch/mips/loongson/loongson-3/Makefile
@@ -1,8 +1,10 @@
1# 1#
2# Makefile for Loongson-3 family machines 2# Makefile for Loongson-3 family machines
3# 3#
4obj-y += irq.o cop2-ex.o 4obj-y += irq.o cop2-ex.o platform.o
5 5
6obj-$(CONFIG_SMP) += smp.o 6obj-$(CONFIG_SMP) += smp.o
7 7
8obj-$(CONFIG_NUMA) += numa.o 8obj-$(CONFIG_NUMA) += numa.o
9
10obj-$(CONFIG_RS780_HPET) += hpet.o
diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c
new file mode 100644
index 000000000000..e898d68668a9
--- /dev/null
+++ b/arch/mips/loongson/loongson-3/hpet.c
@@ -0,0 +1,257 @@
1#include <linux/init.h>
2#include <linux/pci.h>
3#include <linux/percpu.h>
4#include <linux/delay.h>
5#include <linux/spinlock.h>
6#include <linux/interrupt.h>
7
8#include <asm/hpet.h>
9#include <asm/time.h>
10
11#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000)
12#define SMBUS_PCI_REG40 0x40
13#define SMBUS_PCI_REG64 0x64
14#define SMBUS_PCI_REGB4 0xb4
15
16static DEFINE_SPINLOCK(hpet_lock);
17DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
18
19static unsigned int smbus_read(int offset)
20{
21 return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset);
22}
23
24static void smbus_write(int offset, int data)
25{
26 *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data;
27}
28
29static void smbus_enable(int offset, int bit)
30{
31 unsigned int cfg = smbus_read(offset);
32
33 cfg |= bit;
34 smbus_write(offset, cfg);
35}
36
37static int hpet_read(int offset)
38{
39 return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset);
40}
41
42static void hpet_write(int offset, int data)
43{
44 *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data;
45}
46
47static void hpet_start_counter(void)
48{
49 unsigned int cfg = hpet_read(HPET_CFG);
50
51 cfg |= HPET_CFG_ENABLE;
52 hpet_write(HPET_CFG, cfg);
53}
54
55static void hpet_stop_counter(void)
56{
57 unsigned int cfg = hpet_read(HPET_CFG);
58
59 cfg &= ~HPET_CFG_ENABLE;
60 hpet_write(HPET_CFG, cfg);
61}
62
63static void hpet_reset_counter(void)
64{
65 hpet_write(HPET_COUNTER, 0);
66 hpet_write(HPET_COUNTER + 4, 0);
67}
68
69static void hpet_restart_counter(void)
70{
71 hpet_stop_counter();
72 hpet_reset_counter();
73 hpet_start_counter();
74}
75
76static void hpet_enable_legacy_int(void)
77{
78 /* Do nothing on Loongson-3 */
79}
80
81static void hpet_set_mode(enum clock_event_mode mode,
82 struct clock_event_device *evt)
83{
84 int cfg = 0;
85
86 spin_lock(&hpet_lock);
87 switch (mode) {
88 case CLOCK_EVT_MODE_PERIODIC:
89 pr_info("set clock event to periodic mode!\n");
90 /* stop counter */
91 hpet_stop_counter();
92
93 /* enables the timer0 to generate a periodic interrupt */
94 cfg = hpet_read(HPET_T0_CFG);
95 cfg &= ~HPET_TN_LEVEL;
96 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
97 HPET_TN_SETVAL | HPET_TN_32BIT;
98 hpet_write(HPET_T0_CFG, cfg);
99
100 /* set the comparator */
101 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
102 udelay(1);
103 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
104
105 /* start counter */
106 hpet_start_counter();
107 break;
108 case CLOCK_EVT_MODE_SHUTDOWN:
109 case CLOCK_EVT_MODE_UNUSED:
110 cfg = hpet_read(HPET_T0_CFG);
111 cfg &= ~HPET_TN_ENABLE;
112 hpet_write(HPET_T0_CFG, cfg);
113 break;
114 case CLOCK_EVT_MODE_ONESHOT:
115 pr_info("set clock event to one shot mode!\n");
116 cfg = hpet_read(HPET_T0_CFG);
117 /* set timer0 type
118 * 1 : periodic interrupt
119 * 0 : non-periodic(oneshot) interrupt
120 */
121 cfg &= ~HPET_TN_PERIODIC;
122 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
123 hpet_write(HPET_T0_CFG, cfg);
124 break;
125 case CLOCK_EVT_MODE_RESUME:
126 hpet_enable_legacy_int();
127 break;
128 }
129 spin_unlock(&hpet_lock);
130}
131
132static int hpet_next_event(unsigned long delta,
133 struct clock_event_device *evt)
134{
135 unsigned int cnt;
136 int res;
137
138 cnt = hpet_read(HPET_COUNTER);
139 cnt += delta;
140 hpet_write(HPET_T0_CMP, cnt);
141
142 res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
143 return res;
144}
145
146static irqreturn_t hpet_irq_handler(int irq, void *data)
147{
148 int is_irq;
149 struct clock_event_device *cd;
150 unsigned int cpu = smp_processor_id();
151
152 is_irq = hpet_read(HPET_STATUS);
153 if (is_irq & HPET_T0_IRS) {
154 /* clear the TIMER0 irq status register */
155 hpet_write(HPET_STATUS, HPET_T0_IRS);
156 cd = &per_cpu(hpet_clockevent_device, cpu);
157 cd->event_handler(cd);
158 return IRQ_HANDLED;
159 }
160 return IRQ_NONE;
161}
162
163static struct irqaction hpet_irq = {
164 .handler = hpet_irq_handler,
165 .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
166 .name = "hpet",
167};
168
169/*
170 * hpet address assignation and irq setting should be done in bios.
171 * but pmon don't do this, we just setup here directly.
172 * The operation under is normal. unfortunately, hpet_setup process
173 * is before pci initialize.
174 *
175 * {
176 * struct pci_dev *pdev;
177 *
178 * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
179 * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR);
180 *
181 * ...
182 * }
183 */
184static void hpet_setup(void)
185{
186 /* set hpet base address */
187 smbus_write(SMBUS_PCI_REGB4, HPET_ADDR);
188
189 /* enable decodeing of access to HPET MMIO*/
190 smbus_enable(SMBUS_PCI_REG40, (1 << 28));
191
192 /* HPET irq enable */
193 smbus_enable(SMBUS_PCI_REG64, (1 << 10));
194
195 hpet_enable_legacy_int();
196}
197
198void __init setup_hpet_timer(void)
199{
200 unsigned int cpu = smp_processor_id();
201 struct clock_event_device *cd;
202
203 hpet_setup();
204
205 cd = &per_cpu(hpet_clockevent_device, cpu);
206 cd->name = "hpet";
207 cd->rating = 320;
208 cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
209 cd->set_mode = hpet_set_mode;
210 cd->set_next_event = hpet_next_event;
211 cd->irq = HPET_T0_IRQ;
212 cd->cpumask = cpumask_of(cpu);
213 clockevent_set_clock(cd, HPET_FREQ);
214 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
215 cd->min_delta_ns = 5000;
216
217 clockevents_register_device(cd);
218 setup_irq(HPET_T0_IRQ, &hpet_irq);
219 pr_info("hpet clock event device register\n");
220}
221
222static cycle_t hpet_read_counter(struct clocksource *cs)
223{
224 return (cycle_t)hpet_read(HPET_COUNTER);
225}
226
227static void hpet_suspend(struct clocksource *cs)
228{
229}
230
231static void hpet_resume(struct clocksource *cs)
232{
233 hpet_setup();
234 hpet_restart_counter();
235}
236
237static struct clocksource csrc_hpet = {
238 .name = "hpet",
239 /* mips clocksource rating is less than 300, so hpet is better. */
240 .rating = 300,
241 .read = hpet_read_counter,
242 .mask = CLOCKSOURCE_MASK(32),
243 /* oneshot mode work normal with this flag */
244 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
245 .suspend = hpet_suspend,
246 .resume = hpet_resume,
247 .mult = 0,
248 .shift = 10,
249};
250
251int __init init_hpet_clocksource(void)
252{
253 csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift);
254 return clocksource_register_hz(&csrc_hpet, HPET_FREQ);
255}
256
257arch_initcall(init_hpet_clocksource);
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c
index ca1c62af5188..21221edda7a9 100644
--- a/arch/mips/loongson/loongson-3/irq.c
+++ b/arch/mips/loongson/loongson-3/irq.c
@@ -9,7 +9,7 @@
9 9
10#include "smp.h" 10#include "smp.h"
11 11
12unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; 12unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15};
13 13
14static void ht_irqdispatch(void) 14static void ht_irqdispatch(void)
15{ 15{
@@ -55,8 +55,8 @@ static inline void mask_loongson_irq(struct irq_data *d)
55 /* Workaround: UART IRQ may deliver to any core */ 55 /* Workaround: UART IRQ may deliver to any core */
56 if (d->irq == LOONGSON_UART_IRQ) { 56 if (d->irq == LOONGSON_UART_IRQ) {
57 int cpu = smp_processor_id(); 57 int cpu = smp_processor_id();
58 int node_id = cpu / loongson_sysconf.cores_per_node; 58 int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
59 int core_id = cpu % loongson_sysconf.cores_per_node; 59 int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
60 u64 intenclr_addr = smp_group[node_id] | 60 u64 intenclr_addr = smp_group[node_id] |
61 (u64)(&LOONGSON_INT_ROUTER_INTENCLR); 61 (u64)(&LOONGSON_INT_ROUTER_INTENCLR);
62 u64 introuter_lpc_addr = smp_group[node_id] | 62 u64 introuter_lpc_addr = smp_group[node_id] |
@@ -72,8 +72,8 @@ static inline void unmask_loongson_irq(struct irq_data *d)
72 /* Workaround: UART IRQ may deliver to any core */ 72 /* Workaround: UART IRQ may deliver to any core */
73 if (d->irq == LOONGSON_UART_IRQ) { 73 if (d->irq == LOONGSON_UART_IRQ) {
74 int cpu = smp_processor_id(); 74 int cpu = smp_processor_id();
75 int node_id = cpu / loongson_sysconf.cores_per_node; 75 int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
76 int core_id = cpu % loongson_sysconf.cores_per_node; 76 int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
77 u64 intenset_addr = smp_group[node_id] | 77 u64 intenset_addr = smp_group[node_id] |
78 (u64)(&LOONGSON_INT_ROUTER_INTENSET); 78 (u64)(&LOONGSON_INT_ROUTER_INTENSET);
79 u64 introuter_lpc_addr = smp_group[node_id] | 79 u64 introuter_lpc_addr = smp_group[node_id] |
@@ -102,10 +102,12 @@ void irq_router_init(void)
102 int i; 102 int i;
103 103
104 /* route LPC int to cpu core0 int 0 */ 104 /* route LPC int to cpu core0 int 0 */
105 LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; 105 LOONGSON_INT_ROUTER_LPC =
106 LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0);
106 /* route HT1 int0 ~ int7 to cpu core0 INT1*/ 107 /* route HT1 int0 ~ int7 to cpu core0 INT1*/
107 for (i = 0; i < 8; i++) 108 for (i = 0; i < 8; i++)
108 LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; 109 LOONGSON_INT_ROUTER_HT1(i) =
110 LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1);
109 /* enable HT1 interrupt */ 111 /* enable HT1 interrupt */
110 LOONGSON_HT1_INTN_EN(0) = 0xffffffff; 112 LOONGSON_HT1_INTN_EN(0) = 0xffffffff;
111 /* enable router interrupt intenset */ 113 /* enable router interrupt intenset */
diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c
index 42323bcc5d28..6cae0e75de27 100644
--- a/arch/mips/loongson/loongson-3/numa.c
+++ b/arch/mips/loongson/loongson-3/numa.c
@@ -224,7 +224,7 @@ static void __init node_mem_init(unsigned int node)
224 224
225static __init void prom_meminit(void) 225static __init void prom_meminit(void)
226{ 226{
227 unsigned int node, cpu; 227 unsigned int node, cpu, active_cpu = 0;
228 228
229 cpu_node_probe(); 229 cpu_node_probe();
230 init_topology_matrix(); 230 init_topology_matrix();
@@ -240,8 +240,14 @@ static __init void prom_meminit(void)
240 node = cpu / loongson_sysconf.cores_per_node; 240 node = cpu / loongson_sysconf.cores_per_node;
241 if (node >= num_online_nodes()) 241 if (node >= num_online_nodes())
242 node = 0; 242 node = 0;
243 pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); 243
244 cpu_set(cpu, __node_data[(node)]->cpumask); 244 if (loongson_sysconf.reserved_cpus_mask & (1<<cpu))
245 continue;
246
247 cpu_set(active_cpu, __node_data[(node)]->cpumask);
248 pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node);
249
250 active_cpu++;
245 } 251 }
246} 252}
247 253
diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c
new file mode 100644
index 000000000000..25a97cc0ee33
--- /dev/null
+++ b/arch/mips/loongson/loongson-3/platform.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2009 Lemote Inc.
3 * Author: Wu Zhangjin, wuzhangjin@gmail.com
4 * Xiang Yu, xiangy@lemote.com
5 * Chen Huacai, chenhc@lemote.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/err.h>
14#include <linux/slab.h>
15#include <linux/platform_device.h>
16#include <asm/bootinfo.h>
17#include <boot_param.h>
18#include <loongson_hwmon.h>
19#include <workarounds.h>
20
21static int __init loongson3_platform_init(void)
22{
23 int i;
24 struct platform_device *pdev;
25
26 if (loongson_sysconf.ecname[0] != '\0')
27 platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0);
28
29 for (i = 0; i < loongson_sysconf.nr_sensors; i++) {
30 if (loongson_sysconf.sensors[i].type > SENSOR_FAN)
31 continue;
32
33 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
34 pdev->name = loongson_sysconf.sensors[i].name;
35 pdev->id = loongson_sysconf.sensors[i].id;
36 pdev->dev.platform_data = &loongson_sysconf.sensors[i];
37 platform_device_register(pdev);
38 }
39
40 return 0;
41}
42
43arch_initcall(loongson3_platform_init);
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c
index d8c63af6c7cc..e2eb688b5434 100644
--- a/arch/mips/loongson/loongson-3/smp.c
+++ b/arch/mips/loongson/loongson-3/smp.c
@@ -25,6 +25,7 @@
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <loongson.h> 27#include <loongson.h>
28#include <workarounds.h>
28 29
29#include "smp.h" 30#include "smp.h"
30 31
@@ -239,7 +240,7 @@ static void ipi_mailbox_buf_init(void)
239 */ 240 */
240static void loongson3_send_ipi_single(int cpu, unsigned int action) 241static void loongson3_send_ipi_single(int cpu, unsigned int action)
241{ 242{
242 loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]); 243 loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]);
243} 244}
244 245
245static void 246static void
@@ -248,7 +249,7 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
248 unsigned int i; 249 unsigned int i;
249 250
250 for_each_cpu(i, mask) 251 for_each_cpu(i, mask)
251 loongson3_ipi_write32((u32)action, ipi_set0_regs[i]); 252 loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]);
252} 253}
253 254
254void loongson3_ipi_interrupt(struct pt_regs *regs) 255void loongson3_ipi_interrupt(struct pt_regs *regs)
@@ -257,10 +258,10 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
257 unsigned int action, c0count; 258 unsigned int action, c0count;
258 259
259 /* Load the ipi register to figure out what we're supposed to do */ 260 /* Load the ipi register to figure out what we're supposed to do */
260 action = loongson3_ipi_read32(ipi_status0_regs[cpu]); 261 action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
261 262
262 /* Clear the ipi register to clear the interrupt */ 263 /* Clear the ipi register to clear the interrupt */
263 loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu]); 264 loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]);
264 265
265 if (action & SMP_RESCHEDULE_YOURSELF) 266 if (action & SMP_RESCHEDULE_YOURSELF)
266 scheduler_ipi(); 267 scheduler_ipi();
@@ -291,12 +292,14 @@ static void loongson3_init_secondary(void)
291 /* Set interrupt mask, but don't enable */ 292 /* Set interrupt mask, but don't enable */
292 change_c0_status(ST0_IM, imask); 293 change_c0_status(ST0_IM, imask);
293 294
294 for (i = 0; i < loongson_sysconf.nr_cpus; i++) 295 for (i = 0; i < num_possible_cpus(); i++)
295 loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); 296 loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]);
296 297
297 cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package;
298 cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package;
299 per_cpu(cpu_state, cpu) = CPU_ONLINE; 298 per_cpu(cpu_state, cpu) = CPU_ONLINE;
299 cpu_data[cpu].core =
300 cpu_logical_map(cpu) % loongson_sysconf.cores_per_package;
301 cpu_data[cpu].package =
302 cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
300 303
301 i = 0; 304 i = 0;
302 __this_cpu_write(core0_c0count, 0); 305 __this_cpu_write(core0_c0count, 0);
@@ -314,37 +317,50 @@ static void loongson3_init_secondary(void)
314 317
315static void loongson3_smp_finish(void) 318static void loongson3_smp_finish(void)
316{ 319{
320 int cpu = smp_processor_id();
321
317 write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); 322 write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
318 local_irq_enable(); 323 local_irq_enable();
319 loongson3_ipi_write64(0, 324 loongson3_ipi_write64(0,
320 (void *)(ipi_mailbox_buf[smp_processor_id()]+0x0)); 325 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
321 pr_info("CPU#%d finished, CP0_ST=%x\n", 326 pr_info("CPU#%d finished, CP0_ST=%x\n",
322 smp_processor_id(), read_c0_status()); 327 smp_processor_id(), read_c0_status());
323} 328}
324 329
325static void __init loongson3_smp_setup(void) 330static void __init loongson3_smp_setup(void)
326{ 331{
327 int i, num; 332 int i = 0, num = 0; /* i: physical id, num: logical id */
328 333
329 init_cpu_possible(cpu_none_mask); 334 init_cpu_possible(cpu_none_mask);
330 set_cpu_possible(0, true);
331
332 __cpu_number_map[0] = 0;
333 __cpu_logical_map[0] = 0;
334 335
335 /* For unified kernel, NR_CPUS is the maximum possible value, 336 /* For unified kernel, NR_CPUS is the maximum possible value,
336 * loongson_sysconf.nr_cpus is the really present value */ 337 * loongson_sysconf.nr_cpus is the really present value */
337 for (i = 1, num = 0; i < loongson_sysconf.nr_cpus; i++) { 338 while (i < loongson_sysconf.nr_cpus) {
338 set_cpu_possible(i, true); 339 if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
339 __cpu_number_map[i] = ++num; 340 /* Reserved physical CPU cores */
340 __cpu_logical_map[num] = i; 341 __cpu_number_map[i] = -1;
342 } else {
343 __cpu_number_map[i] = num;
344 __cpu_logical_map[num] = i;
345 set_cpu_possible(num, true);
346 num++;
347 }
348 i++;
341 } 349 }
350 pr_info("Detected %i available CPU(s)\n", num);
351
352 while (num < loongson_sysconf.nr_cpus) {
353 __cpu_logical_map[num] = -1;
354 num++;
355 }
356
342 ipi_set0_regs_init(); 357 ipi_set0_regs_init();
343 ipi_clear0_regs_init(); 358 ipi_clear0_regs_init();
344 ipi_status0_regs_init(); 359 ipi_status0_regs_init();
345 ipi_en0_regs_init(); 360 ipi_en0_regs_init();
346 ipi_mailbox_buf_init(); 361 ipi_mailbox_buf_init();
347 pr_info("Detected %i available secondary CPU(s)\n", num); 362 cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
363 cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
348} 364}
349 365
350static void __init loongson3_prepare_cpus(unsigned int max_cpus) 366static void __init loongson3_prepare_cpus(unsigned int max_cpus)
@@ -371,10 +387,14 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
371 pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", 387 pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
372 cpu, startargs[0], startargs[1], startargs[2]); 388 cpu, startargs[0], startargs[1], startargs[2]);
373 389
374 loongson3_ipi_write64(startargs[3], (void *)(ipi_mailbox_buf[cpu]+0x18)); 390 loongson3_ipi_write64(startargs[3],
375 loongson3_ipi_write64(startargs[2], (void *)(ipi_mailbox_buf[cpu]+0x10)); 391 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x18));
376 loongson3_ipi_write64(startargs[1], (void *)(ipi_mailbox_buf[cpu]+0x8)); 392 loongson3_ipi_write64(startargs[2],
377 loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu]+0x0)); 393 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x10));
394 loongson3_ipi_write64(startargs[1],
395 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
396 loongson3_ipi_write64(startargs[0],
397 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
378} 398}
379 399
380#ifdef CONFIG_HOTPLUG_CPU 400#ifdef CONFIG_HOTPLUG_CPU
@@ -568,7 +588,7 @@ void loongson3_disable_clock(int cpu)
568 if (loongson_sysconf.cputype == Loongson_3A) { 588 if (loongson_sysconf.cputype == Loongson_3A) {
569 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); 589 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
570 } else if (loongson_sysconf.cputype == Loongson_3B) { 590 } else if (loongson_sysconf.cputype == Loongson_3B) {
571 if (!cpuhotplug_workaround) 591 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
572 LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); 592 LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
573 } 593 }
574} 594}
@@ -581,7 +601,7 @@ void loongson3_enable_clock(int cpu)
581 if (loongson_sysconf.cputype == Loongson_3A) { 601 if (loongson_sysconf.cputype == Loongson_3A) {
582 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); 602 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
583 } else if (loongson_sysconf.cputype == Loongson_3B) { 603 } else if (loongson_sysconf.cputype == Loongson_3B) {
584 if (!cpuhotplug_workaround) 604 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
585 LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); 605 LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
586 } 606 }
587} 607}
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig
index e23c25d09963..a2b796eaf3c3 100644
--- a/arch/mips/loongson1/Kconfig
+++ b/arch/mips/loongson1/Kconfig
@@ -5,8 +5,8 @@ choice
5 5
6config LOONGSON1_LS1B 6config LOONGSON1_LS1B
7 bool "Loongson LS1B board" 7 bool "Loongson LS1B board"
8 select CEVT_R4K 8 select CEVT_R4K if !MIPS_EXTERNAL_TIMER
9 select CSRC_R4K 9 select CSRC_R4K if !MIPS_EXTERNAL_TIMER
10 select SYS_HAS_CPU_LOONGSON1B 10 select SYS_HAS_CPU_LOONGSON1B
11 select DMA_NONCOHERENT 11 select DMA_NONCOHERENT
12 select BOOT_ELF32 12 select BOOT_ELF32
@@ -16,8 +16,46 @@ config LOONGSON1_LS1B
16 select SYS_SUPPORTS_HIGHMEM 16 select SYS_SUPPORTS_HIGHMEM
17 select SYS_SUPPORTS_MIPS16 17 select SYS_SUPPORTS_MIPS16
18 select SYS_HAS_EARLY_PRINTK 18 select SYS_HAS_EARLY_PRINTK
19 select USE_GENERIC_EARLY_PRINTK_8250
19 select COMMON_CLK 20 select COMMON_CLK
20 21
21endchoice 22endchoice
22 23
24menuconfig CEVT_CSRC_LS1X
25 bool "Use PWM Timer for clockevent/clocksource"
26 select MIPS_EXTERNAL_TIMER
27 depends on CPU_LOONGSON1
28 help
29 This option changes the default clockevent/clocksource to PWM Timer,
30 and is required by Loongson1 CPUFreq support.
31
32 If unsure, say N.
33
34choice
35 prompt "Select clockevent/clocksource"
36 depends on CEVT_CSRC_LS1X
37 default TIMER_USE_PWM0
38
39config TIMER_USE_PWM0
40 bool "Use PWM Timer 0"
41 help
42 Use PWM Timer 0 as the default clockevent/clocksourcer.
43
44config TIMER_USE_PWM1
45 bool "Use PWM Timer 1"
46 help
47 Use PWM Timer 1 as the default clockevent/clocksourcer.
48
49config TIMER_USE_PWM2
50 bool "Use PWM Timer 2"
51 help
52 Use PWM Timer 2 as the default clockevent/clocksourcer.
53
54config TIMER_USE_PWM3
55 bool "Use PWM Timer 3"
56 help
57 Use PWM Timer 3 as the default clockevent/clocksourcer.
58
59endchoice
60
23endif # MACH_LOONGSON1 61endif # MACH_LOONGSON1
diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile
index b2797709ef5b..723b4ce3b8f0 100644
--- a/arch/mips/loongson1/common/Makefile
+++ b/arch/mips/loongson1/common/Makefile
@@ -2,4 +2,4 @@
2# Makefile for common code of loongson1 based machines. 2# Makefile for common code of loongson1 based machines.
3# 3#
4 4
5obj-y += clock.o irq.o platform.o prom.o reset.o setup.o 5obj-y += time.o irq.o platform.o prom.o reset.o setup.o
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c
deleted file mode 100644
index b4437f19c3d9..000000000000
--- a/arch/mips/loongson1/common/clock.c
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clk.h>
11#include <linux/err.h>
12#include <asm/time.h>
13#include <platform.h>
14
15void __init plat_time_init(void)
16{
17 struct clk *clk;
18
19 /* Initialize LS1X clocks */
20 ls1x_clk_init();
21
22 /* setup mips r4k timer */
23 clk = clk_get(NULL, "cpu");
24 if (IS_ERR(clk))
25 panic("unable to get cpu clock, err=%ld", PTR_ERR(clk));
26
27 mips_hpt_frequency = clk_get_rate(clk) / 2;
28}
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c
index fdf8cb5987a4..ddf1d4cbf31e 100644
--- a/arch/mips/loongson1/common/platform.c
+++ b/arch/mips/loongson1/common/platform.c
@@ -16,8 +16,10 @@
16#include <linux/usb/ehci_pdriver.h> 16#include <linux/usb/ehci_pdriver.h>
17#include <asm-generic/sizes.h> 17#include <asm-generic/sizes.h>
18 18
19#include <cpufreq.h>
19#include <loongson1.h> 20#include <loongson1.h>
20 21
22/* 8250/16550 compatible UART */
21#define LS1X_UART(_id) \ 23#define LS1X_UART(_id) \
22 { \ 24 { \
23 .mapbase = LS1X_UART ## _id ## _BASE, \ 25 .mapbase = LS1X_UART ## _id ## _BASE, \
@@ -27,7 +29,7 @@
27 .type = PORT_16550A, \ 29 .type = PORT_16550A, \
28 } 30 }
29 31
30static struct plat_serial8250_port ls1x_serial8250_port[] = { 32static struct plat_serial8250_port ls1x_serial8250_pdata[] = {
31 LS1X_UART(0), 33 LS1X_UART(0),
32 LS1X_UART(1), 34 LS1X_UART(1),
33 LS1X_UART(2), 35 LS1X_UART(2),
@@ -35,11 +37,11 @@ static struct plat_serial8250_port ls1x_serial8250_port[] = {
35 {}, 37 {},
36}; 38};
37 39
38struct platform_device ls1x_uart_device = { 40struct platform_device ls1x_uart_pdev = {
39 .name = "serial8250", 41 .name = "serial8250",
40 .id = PLAT8250_DEV_PLATFORM, 42 .id = PLAT8250_DEV_PLATFORM,
41 .dev = { 43 .dev = {
42 .platform_data = ls1x_serial8250_port, 44 .platform_data = ls1x_serial8250_pdata,
43 }, 45 },
44}; 46};
45 47
@@ -48,16 +50,97 @@ void __init ls1x_serial_setup(struct platform_device *pdev)
48 struct clk *clk; 50 struct clk *clk;
49 struct plat_serial8250_port *p; 51 struct plat_serial8250_port *p;
50 52
51 clk = clk_get(NULL, pdev->name); 53 clk = clk_get(&pdev->dev, pdev->name);
52 if (IS_ERR(clk)) 54 if (IS_ERR(clk)) {
53 panic("unable to get %s clock, err=%ld", 55 pr_err("unable to get %s clock, err=%ld",
54 pdev->name, PTR_ERR(clk)); 56 pdev->name, PTR_ERR(clk));
57 return;
58 }
59 clk_prepare_enable(clk);
55 60
56 for (p = pdev->dev.platform_data; p->flags != 0; ++p) 61 for (p = pdev->dev.platform_data; p->flags != 0; ++p)
57 p->uartclk = clk_get_rate(clk); 62 p->uartclk = clk_get_rate(clk);
58} 63}
59 64
65/* CPUFreq */
66static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = {
67 .clk_name = "cpu_clk",
68 .osc_clk_name = "osc_33m_clk",
69 .max_freq = 266 * 1000,
70 .min_freq = 33 * 1000,
71};
72
73struct platform_device ls1x_cpufreq_pdev = {
74 .name = "ls1x-cpufreq",
75 .dev = {
76 .platform_data = &ls1x_cpufreq_pdata,
77 },
78};
79
60/* Synopsys Ethernet GMAC */ 80/* Synopsys Ethernet GMAC */
81static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
82 .phy_mask = 0,
83};
84
85static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {
86 .pbl = 1,
87};
88
89int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
90{
91 struct plat_stmmacenet_data *plat_dat = NULL;
92 u32 val;
93
94 val = __raw_readl(LS1X_MUX_CTRL1);
95
96 plat_dat = dev_get_platdata(&pdev->dev);
97 if (plat_dat->bus_id) {
98 __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
99 GMAC1_USE_UART0, LS1X_MUX_CTRL0);
100 switch (plat_dat->interface) {
101 case PHY_INTERFACE_MODE_RGMII:
102 val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
103 break;
104 case PHY_INTERFACE_MODE_MII:
105 val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
106 break;
107 default:
108 pr_err("unsupported mii mode %d\n",
109 plat_dat->interface);
110 return -ENOTSUPP;
111 }
112 val &= ~GMAC1_SHUT;
113 } else {
114 switch (plat_dat->interface) {
115 case PHY_INTERFACE_MODE_RGMII:
116 val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
117 break;
118 case PHY_INTERFACE_MODE_MII:
119 val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
120 break;
121 default:
122 pr_err("unsupported mii mode %d\n",
123 plat_dat->interface);
124 return -ENOTSUPP;
125 }
126 val &= ~GMAC0_SHUT;
127 }
128 __raw_writel(val, LS1X_MUX_CTRL1);
129
130 return 0;
131}
132
133static struct plat_stmmacenet_data ls1x_eth0_pdata = {
134 .bus_id = 0,
135 .phy_addr = -1,
136 .interface = PHY_INTERFACE_MODE_MII,
137 .mdio_bus_data = &ls1x_mdio_bus_data,
138 .dma_cfg = &ls1x_eth_dma_cfg,
139 .has_gmac = 1,
140 .tx_coe = 1,
141 .init = ls1x_eth_mux_init,
142};
143
61static struct resource ls1x_eth0_resources[] = { 144static struct resource ls1x_eth0_resources[] = {
62 [0] = { 145 [0] = {
63 .start = LS1X_GMAC0_BASE, 146 .start = LS1X_GMAC0_BASE,
@@ -71,25 +154,47 @@ static struct resource ls1x_eth0_resources[] = {
71 }, 154 },
72}; 155};
73 156
74static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { 157struct platform_device ls1x_eth0_pdev = {
75 .phy_mask = 0, 158 .name = "stmmaceth",
159 .id = 0,
160 .num_resources = ARRAY_SIZE(ls1x_eth0_resources),
161 .resource = ls1x_eth0_resources,
162 .dev = {
163 .platform_data = &ls1x_eth0_pdata,
164 },
76}; 165};
77 166
78static struct plat_stmmacenet_data ls1x_eth_data = { 167static struct plat_stmmacenet_data ls1x_eth1_pdata = {
79 .bus_id = 0, 168 .bus_id = 1,
80 .phy_addr = -1, 169 .phy_addr = -1,
170 .interface = PHY_INTERFACE_MODE_MII,
81 .mdio_bus_data = &ls1x_mdio_bus_data, 171 .mdio_bus_data = &ls1x_mdio_bus_data,
172 .dma_cfg = &ls1x_eth_dma_cfg,
82 .has_gmac = 1, 173 .has_gmac = 1,
83 .tx_coe = 1, 174 .tx_coe = 1,
175 .init = ls1x_eth_mux_init,
84}; 176};
85 177
86struct platform_device ls1x_eth0_device = { 178static struct resource ls1x_eth1_resources[] = {
179 [0] = {
180 .start = LS1X_GMAC1_BASE,
181 .end = LS1X_GMAC1_BASE + SZ_64K - 1,
182 .flags = IORESOURCE_MEM,
183 },
184 [1] = {
185 .name = "macirq",
186 .start = LS1X_GMAC1_IRQ,
187 .flags = IORESOURCE_IRQ,
188 },
189};
190
191struct platform_device ls1x_eth1_pdev = {
87 .name = "stmmaceth", 192 .name = "stmmaceth",
88 .id = 0, 193 .id = 1,
89 .num_resources = ARRAY_SIZE(ls1x_eth0_resources), 194 .num_resources = ARRAY_SIZE(ls1x_eth1_resources),
90 .resource = ls1x_eth0_resources, 195 .resource = ls1x_eth1_resources,
91 .dev = { 196 .dev = {
92 .platform_data = &ls1x_eth_data, 197 .platform_data = &ls1x_eth1_pdata,
93 }, 198 },
94}; 199};
95 200
@@ -111,7 +216,7 @@ static struct resource ls1x_ehci_resources[] = {
111static struct usb_ehci_pdata ls1x_ehci_pdata = { 216static struct usb_ehci_pdata ls1x_ehci_pdata = {
112}; 217};
113 218
114struct platform_device ls1x_ehci_device = { 219struct platform_device ls1x_ehci_pdev = {
115 .name = "ehci-platform", 220 .name = "ehci-platform",
116 .id = -1, 221 .id = -1,
117 .num_resources = ARRAY_SIZE(ls1x_ehci_resources), 222 .num_resources = ARRAY_SIZE(ls1x_ehci_resources),
@@ -123,7 +228,7 @@ struct platform_device ls1x_ehci_device = {
123}; 228};
124 229
125/* Real Time Clock */ 230/* Real Time Clock */
126struct platform_device ls1x_rtc_device = { 231struct platform_device ls1x_rtc_pdev = {
127 .name = "ls1x-rtc", 232 .name = "ls1x-rtc",
128 .id = -1, 233 .id = -1,
129}; 234};
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c
index 2a47af5a55c3..68600980ea49 100644
--- a/arch/mips/loongson1/common/prom.c
+++ b/arch/mips/loongson1/common/prom.c
@@ -27,7 +27,7 @@ char *prom_getenv(char *envname)
27 i = strlen(envname); 27 i = strlen(envname);
28 28
29 while (*env) { 29 while (*env) {
30 if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') 30 if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=')
31 return *env + i + 1; 31 return *env + i + 1;
32 env++; 32 env++;
33 } 33 }
@@ -49,7 +49,7 @@ void __init prom_init_cmdline(void)
49 for (i = 1; i < prom_argc; i++) { 49 for (i = 1; i < prom_argc; i++) {
50 strcpy(c, prom_argv[i]); 50 strcpy(c, prom_argv[i]);
51 c += strlen(prom_argv[i]); 51 c += strlen(prom_argv[i]);
52 if (i < prom_argc-1) 52 if (i < prom_argc - 1)
53 *c++ = ' '; 53 *c++ = ' ';
54 } 54 }
55 *c = 0; 55 *c = 0;
@@ -57,6 +57,7 @@ void __init prom_init_cmdline(void)
57 57
58void __init prom_init(void) 58void __init prom_init(void)
59{ 59{
60 void __iomem *uart_base;
60 prom_argc = fw_arg0; 61 prom_argc = fw_arg0;
61 prom_argv = (char **)fw_arg1; 62 prom_argv = (char **)fw_arg1;
62 prom_envp = (char **)fw_arg2; 63 prom_envp = (char **)fw_arg2;
@@ -65,23 +66,18 @@ void __init prom_init(void)
65 66
66 memsize = env_or_default("memsize", DEFAULT_MEMSIZE); 67 memsize = env_or_default("memsize", DEFAULT_MEMSIZE);
67 highmemsize = env_or_default("highmemsize", 0x0); 68 highmemsize = env_or_default("highmemsize", 0x0);
68}
69 69
70void __init prom_free_prom_memory(void) 70 if (strstr(arcs_cmdline, "console=ttyS3"))
71{ 71 uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f);
72 else if (strstr(arcs_cmdline, "console=ttyS2"))
73 uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f);
74 else if (strstr(arcs_cmdline, "console=ttyS1"))
75 uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f);
76 else
77 uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f);
78 setup_8250_early_printk_port((unsigned long)uart_base, 0, 0);
72} 79}
73 80
74#define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) 81void __init prom_free_prom_memory(void)
75
76void prom_putchar(char c)
77{ 82{
78 int timeout;
79
80 timeout = 1024;
81
82 while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0)
83 && (timeout-- > 0))
84 ;
85
86 writeb(c, PORT(UART_TX));
87} 83}
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c
index 547f34b69e4c..c41e4ca56ab4 100644
--- a/arch/mips/loongson1/common/reset.c
+++ b/arch/mips/loongson1/common/reset.c
@@ -14,12 +14,7 @@
14 14
15#include <loongson1.h> 15#include <loongson1.h>
16 16
17static void ls1x_restart(char *command) 17static void __iomem *wdt_base;
18{
19 __raw_writel(0x1, LS1X_WDT_EN);
20 __raw_writel(0x5000000, LS1X_WDT_TIMER);
21 __raw_writel(0x1, LS1X_WDT_SET);
22}
23 18
24static void ls1x_halt(void) 19static void ls1x_halt(void)
25{ 20{
@@ -29,6 +24,15 @@ static void ls1x_halt(void)
29 } 24 }
30} 25}
31 26
27static void ls1x_restart(char *command)
28{
29 __raw_writel(0x1, wdt_base + WDT_EN);
30 __raw_writel(0x1, wdt_base + WDT_TIMER);
31 __raw_writel(0x1, wdt_base + WDT_SET);
32
33 ls1x_halt();
34}
35
32static void ls1x_power_off(void) 36static void ls1x_power_off(void)
33{ 37{
34 ls1x_halt(); 38 ls1x_halt();
@@ -36,6 +40,10 @@ static void ls1x_power_off(void)
36 40
37static int __init ls1x_reboot_setup(void) 41static int __init ls1x_reboot_setup(void)
38{ 42{
43 wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f);
44 if (!wdt_base)
45 panic("Failed to remap watchdog registers");
46
39 _machine_restart = ls1x_restart; 47 _machine_restart = ls1x_restart;
40 _machine_halt = ls1x_halt; 48 _machine_halt = ls1x_halt;
41 pm_power_off = ls1x_power_off; 49 pm_power_off = ls1x_power_off;
diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c
new file mode 100644
index 000000000000..df0f850d6a5f
--- /dev/null
+++ b/arch/mips/loongson1/common/time.c
@@ -0,0 +1,226 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clk.h>
11#include <linux/interrupt.h>
12#include <asm/time.h>
13
14#include <loongson1.h>
15#include <platform.h>
16
17#ifdef CONFIG_CEVT_CSRC_LS1X
18
19#if defined(CONFIG_TIMER_USE_PWM1)
20#define LS1X_TIMER_BASE LS1X_PWM1_BASE
21#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ
22
23#elif defined(CONFIG_TIMER_USE_PWM2)
24#define LS1X_TIMER_BASE LS1X_PWM2_BASE
25#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ
26
27#elif defined(CONFIG_TIMER_USE_PWM3)
28#define LS1X_TIMER_BASE LS1X_PWM3_BASE
29#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ
30
31#else
32#define LS1X_TIMER_BASE LS1X_PWM0_BASE
33#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ
34#endif
35
36DEFINE_RAW_SPINLOCK(ls1x_timer_lock);
37
38static void __iomem *timer_base;
39static uint32_t ls1x_jiffies_per_tick;
40
41static inline void ls1x_pwmtimer_set_period(uint32_t period)
42{
43 __raw_writel(period, timer_base + PWM_HRC);
44 __raw_writel(period, timer_base + PWM_LRC);
45}
46
47static inline void ls1x_pwmtimer_restart(void)
48{
49 __raw_writel(0x0, timer_base + PWM_CNT);
50 __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
51}
52
53void __init ls1x_pwmtimer_init(void)
54{
55 timer_base = ioremap(LS1X_TIMER_BASE, 0xf);
56 if (!timer_base)
57 panic("Failed to remap timer registers");
58
59 ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ);
60
61 ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
62 ls1x_pwmtimer_restart();
63}
64
65static cycle_t ls1x_clocksource_read(struct clocksource *cs)
66{
67 unsigned long flags;
68 int count;
69 u32 jifs;
70 static int old_count;
71 static u32 old_jifs;
72
73 raw_spin_lock_irqsave(&ls1x_timer_lock, flags);
74 /*
75 * Although our caller may have the read side of xtime_lock,
76 * this is now a seqlock, and we are cheating in this routine
77 * by having side effects on state that we cannot undo if
78 * there is a collision on the seqlock and our caller has to
79 * retry. (Namely, old_jifs and old_count.) So we must treat
80 * jiffies as volatile despite the lock. We read jiffies
81 * before latching the timer count to guarantee that although
82 * the jiffies value might be older than the count (that is,
83 * the counter may underflow between the last point where
84 * jiffies was incremented and the point where we latch the
85 * count), it cannot be newer.
86 */
87 jifs = jiffies;
88 /* read the count */
89 count = __raw_readl(timer_base + PWM_CNT);
90
91 /*
92 * It's possible for count to appear to go the wrong way for this
93 * reason:
94 *
95 * The timer counter underflows, but we haven't handled the resulting
96 * interrupt and incremented jiffies yet.
97 *
98 * Previous attempts to handle these cases intelligently were buggy, so
99 * we just do the simple thing now.
100 */
101 if (count < old_count && jifs == old_jifs)
102 count = old_count;
103
104 old_count = count;
105 old_jifs = jifs;
106
107 raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags);
108
109 return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count;
110}
111
112static struct clocksource ls1x_clocksource = {
113 .name = "ls1x-pwmtimer",
114 .read = ls1x_clocksource_read,
115 .mask = CLOCKSOURCE_MASK(24),
116 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
117};
118
119static irqreturn_t ls1x_clockevent_isr(int irq, void *devid)
120{
121 struct clock_event_device *cd = devid;
122
123 ls1x_pwmtimer_restart();
124 cd->event_handler(cd);
125
126 return IRQ_HANDLED;
127}
128
129static void ls1x_clockevent_set_mode(enum clock_event_mode mode,
130 struct clock_event_device *cd)
131{
132 raw_spin_lock(&ls1x_timer_lock);
133 switch (mode) {
134 case CLOCK_EVT_MODE_PERIODIC:
135 ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
136 ls1x_pwmtimer_restart();
137 case CLOCK_EVT_MODE_RESUME:
138 __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
139 break;
140 case CLOCK_EVT_MODE_ONESHOT:
141 case CLOCK_EVT_MODE_SHUTDOWN:
142 __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN,
143 timer_base + PWM_CTRL);
144 break;
145 default:
146 break;
147 }
148 raw_spin_unlock(&ls1x_timer_lock);
149}
150
151static int ls1x_clockevent_set_next(unsigned long evt,
152 struct clock_event_device *cd)
153{
154 raw_spin_lock(&ls1x_timer_lock);
155 ls1x_pwmtimer_set_period(evt);
156 ls1x_pwmtimer_restart();
157 raw_spin_unlock(&ls1x_timer_lock);
158
159 return 0;
160}
161
162static struct clock_event_device ls1x_clockevent = {
163 .name = "ls1x-pwmtimer",
164 .features = CLOCK_EVT_FEAT_PERIODIC,
165 .rating = 300,
166 .irq = LS1X_TIMER_IRQ,
167 .set_next_event = ls1x_clockevent_set_next,
168 .set_mode = ls1x_clockevent_set_mode,
169};
170
171static struct irqaction ls1x_pwmtimer_irqaction = {
172 .name = "ls1x-pwmtimer",
173 .handler = ls1x_clockevent_isr,
174 .dev_id = &ls1x_clockevent,
175 .flags = IRQF_PERCPU | IRQF_TIMER,
176};
177
178static void __init ls1x_time_init(void)
179{
180 struct clock_event_device *cd = &ls1x_clockevent;
181 int ret;
182
183 if (!mips_hpt_frequency)
184 panic("Invalid timer clock rate");
185
186 ls1x_pwmtimer_init();
187
188 clockevent_set_clock(cd, mips_hpt_frequency);
189 cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd);
190 cd->min_delta_ns = clockevent_delta2ns(0x000300, cd);
191 cd->cpumask = cpumask_of(smp_processor_id());
192 clockevents_register_device(cd);
193
194 ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000;
195 ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency);
196 if (ret)
197 panic(KERN_ERR "Failed to register clocksource: %d\n", ret);
198
199 setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction);
200}
201#endif /* CONFIG_CEVT_CSRC_LS1X */
202
203void __init plat_time_init(void)
204{
205 struct clk *clk = NULL;
206
207 /* initialize LS1X clocks */
208 ls1x_clk_init();
209
210#ifdef CONFIG_CEVT_CSRC_LS1X
211 /* setup LS1X PWM timer */
212 clk = clk_get(NULL, "ls1x_pwmtimer");
213 if (IS_ERR(clk))
214 panic("unable to get timer clock, err=%ld", PTR_ERR(clk));
215
216 mips_hpt_frequency = clk_get_rate(clk);
217 ls1x_time_init();
218#else
219 /* setup mips r4k timer */
220 clk = clk_get(NULL, "cpu_clk");
221 if (IS_ERR(clk))
222 panic("unable to get cpu clock, err=%ld", PTR_ERR(clk));
223
224 mips_hpt_frequency = clk_get_rate(clk) / 2;
225#endif /* CONFIG_CEVT_CSRC_LS1X */
226}
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c
index b26b10dac70a..58daeea25739 100644
--- a/arch/mips/loongson1/ls1b/board.c
+++ b/arch/mips/loongson1/ls1b/board.c
@@ -10,17 +10,19 @@
10#include <platform.h> 10#include <platform.h>
11 11
12static struct platform_device *ls1b_platform_devices[] __initdata = { 12static struct platform_device *ls1b_platform_devices[] __initdata = {
13 &ls1x_uart_device, 13 &ls1x_uart_pdev,
14 &ls1x_eth0_device, 14 &ls1x_cpufreq_pdev,
15 &ls1x_ehci_device, 15 &ls1x_eth0_pdev,
16 &ls1x_rtc_device, 16 &ls1x_eth1_pdev,
17 &ls1x_ehci_pdev,
18 &ls1x_rtc_pdev,
17}; 19};
18 20
19static int __init ls1b_platform_init(void) 21static int __init ls1b_platform_init(void)
20{ 22{
21 int err; 23 int err;
22 24
23 ls1x_serial_setup(&ls1x_uart_device); 25 ls1x_serial_setup(&ls1x_uart_pdev);
24 26
25 err = platform_add_devices(ls1b_platform_devices, 27 err = platform_add_devices(ls1b_platform_devices,
26 ARRAY_SIZE(ls1b_platform_devices)); 28 ARRAY_SIZE(ls1b_platform_devices));
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index cac529a405b8..9dfcd7fc1bc3 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -643,9 +643,14 @@ static inline int cop1_64bit(struct pt_regs *xcp)
643 return !test_thread_flag(TIF_32BIT_FPREGS); 643 return !test_thread_flag(TIF_32BIT_FPREGS);
644} 644}
645 645
646static inline bool hybrid_fprs(void)
647{
648 return test_thread_flag(TIF_HYBRID_FPREGS);
649}
650
646#define SIFROMREG(si, x) \ 651#define SIFROMREG(si, x) \
647do { \ 652do { \
648 if (cop1_64bit(xcp)) \ 653 if (cop1_64bit(xcp) && !hybrid_fprs()) \
649 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ 654 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \
650 else \ 655 else \
651 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ 656 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
@@ -653,7 +658,7 @@ do { \
653 658
654#define SITOREG(si, x) \ 659#define SITOREG(si, x) \
655do { \ 660do { \
656 if (cop1_64bit(xcp)) { \ 661 if (cop1_64bit(xcp) && !hybrid_fprs()) { \
657 unsigned i; \ 662 unsigned i; \
658 set_fpr32(&ctx->fpr[x], 0, si); \ 663 set_fpr32(&ctx->fpr[x], 0, si); \
659 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ 664 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
index fd134675fc2e..068f45a415fc 100644
--- a/arch/mips/math-emu/ieee754dp.c
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -38,7 +38,7 @@ int ieee754dp_isnan(union ieee754dp x)
38static inline int ieee754dp_issnan(union ieee754dp x) 38static inline int ieee754dp_issnan(union ieee754dp x)
39{ 39{
40 assert(ieee754dp_isnan(x)); 40 assert(ieee754dp_isnan(x));
41 return ((DPMANT(x) & DP_MBIT(DP_FBITS-1)) == DP_MBIT(DP_FBITS-1)); 41 return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
42} 42}
43 43
44 44
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
index d348efe91445..ba88301579c2 100644
--- a/arch/mips/math-emu/ieee754sp.c
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -38,7 +38,7 @@ int ieee754sp_isnan(union ieee754sp x)
38static inline int ieee754sp_issnan(union ieee754sp x) 38static inline int ieee754sp_issnan(union ieee754sp x)
39{ 39{
40 assert(ieee754sp_isnan(x)); 40 assert(ieee754sp_isnan(x));
41 return (SPMANT(x) & SP_MBIT(SP_FBITS-1)); 41 return SPMANT(x) & SP_MBIT(SP_FBITS - 1);
42} 42}
43 43
44 44
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 7f4f93ab22b7..67ede4ef9b8d 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -4,7 +4,13 @@
4 4
5obj-y += cache.o dma-default.o extable.o fault.o \ 5obj-y += cache.o dma-default.o extable.o fault.o \
6 gup.o init.o mmap.o page.o page-funcs.o \ 6 gup.o init.o mmap.o page.o page-funcs.o \
7 tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o 7 tlbex.o tlbex-fault.o tlb-funcs.o
8
9ifdef CONFIG_CPU_MICROMIPS
10obj-y += uasm-micromips.o
11else
12obj-y += uasm-mips.o
13endif
8 14
9obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o 15obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
10obj-$(CONFIG_64BIT) += pgtable-64.o 16obj-$(CONFIG_64BIT) += pgtable-64.o
@@ -22,5 +28,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
22obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o 28obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
23obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o 29obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
24obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o 30obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o
25
26obj-$(CONFIG_SYS_SUPPORTS_MICROMIPS) += uasm-micromips.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index fbcd8674ff1d..dd261df005c2 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -917,6 +917,18 @@ static inline void alias_74k_erratum(struct cpuinfo_mips *c)
917 } 917 }
918} 918}
919 919
920static void b5k_instruction_hazard(void)
921{
922 __sync();
923 __sync();
924 __asm__ __volatile__(
925 " nop; nop; nop; nop; nop; nop; nop; nop\n"
926 " nop; nop; nop; nop; nop; nop; nop; nop\n"
927 " nop; nop; nop; nop; nop; nop; nop; nop\n"
928 " nop; nop; nop; nop; nop; nop; nop; nop\n"
929 : : : "memory");
930}
931
920static char *way_string[] = { NULL, "direct mapped", "2-way", 932static char *way_string[] = { NULL, "direct mapped", "2-way",
921 "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" 933 "3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
922}; 934};
@@ -1683,6 +1695,37 @@ void r4k_cache_init(void)
1683 1695
1684 coherency_setup(); 1696 coherency_setup();
1685 board_cache_error_setup = r4k_cache_error_setup; 1697 board_cache_error_setup = r4k_cache_error_setup;
1698
1699 /*
1700 * Per-CPU overrides
1701 */
1702 switch (current_cpu_type()) {
1703 case CPU_BMIPS4350:
1704 case CPU_BMIPS4380:
1705 /* No IPI is needed because all CPUs share the same D$ */
1706 flush_data_cache_page = r4k_blast_dcache_page;
1707 break;
1708 case CPU_BMIPS5000:
1709 /* We lose our superpowers if L2 is disabled */
1710 if (c->scache.flags & MIPS_CACHE_NOT_PRESENT)
1711 break;
1712
1713 /* I$ fills from D$ just by emptying the write buffers */
1714 flush_cache_page = (void *)b5k_instruction_hazard;
1715 flush_cache_range = (void *)b5k_instruction_hazard;
1716 flush_cache_sigtramp = (void *)b5k_instruction_hazard;
1717 local_flush_data_cache_page = (void *)b5k_instruction_hazard;
1718 flush_data_cache_page = (void *)b5k_instruction_hazard;
1719 flush_icache_range = (void *)b5k_instruction_hazard;
1720 local_flush_icache_range = (void *)b5k_instruction_hazard;
1721
1722 /* Cache aliases are handled in hardware; allow HIGHMEM */
1723 current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES;
1724
1725 /* Optimization: an L2 flush implicitly flushes the L1 */
1726 current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES;
1727 break;
1728 }
1686} 1729}
1687 1730
1688static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, 1731static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd,
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 33ba3c558fe4..af5f046e627e 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -61,6 +61,11 @@ static inline struct page *dma_addr_to_page(struct device *dev,
61 * Warning on the terminology - Linux calls an uncached area coherent; 61 * Warning on the terminology - Linux calls an uncached area coherent;
62 * MIPS terminology calls memory areas with hardware maintained coherency 62 * MIPS terminology calls memory areas with hardware maintained coherency
63 * coherent. 63 * coherent.
64 *
65 * Note that the R14000 and R16000 should also be checked for in this
66 * condition. However this function is only called on non-I/O-coherent
67 * systems and only the R10000 and R12000 are used in such systems, the
68 * SGI IP28 Indigo² rsp. SGI IP32 aka O2.
64 */ 69 */
65static inline int cpu_needs_post_dma_flush(struct device *dev) 70static inline int cpu_needs_post_dma_flush(struct device *dev)
66{ 71{
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
index 06ce17c2a905..7cba480568c8 100644
--- a/arch/mips/mm/gup.c
+++ b/arch/mips/mm/gup.c
@@ -17,7 +17,7 @@
17 17
18static inline pte_t gup_get_pte(pte_t *ptep) 18static inline pte_t gup_get_pte(pte_t *ptep)
19{ 19{
20#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 20#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
21 pte_t pte; 21 pte_t pte;
22 22
23retry: 23retry:
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index f42e35e42790..448cde372af0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -95,7 +95,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
95 idx += in_interrupt() ? FIX_N_COLOURS : 0; 95 idx += in_interrupt() ? FIX_N_COLOURS : 0;
96 vaddr = __fix_to_virt(FIX_CMAP_END - idx); 96 vaddr = __fix_to_virt(FIX_CMAP_END - idx);
97 pte = mk_pte(page, prot); 97 pte = mk_pte(page, prot);
98#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 98#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
99 entrylo = pte.pte_high; 99 entrylo = pte.pte_high;
100#else 100#else
101 entrylo = pte_to_entrylo(pte_val(pte)); 101 entrylo = pte_to_entrylo(pte_val(pte));
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index 7f840bc08abf..8d5008cbdc0f 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -17,9 +17,9 @@
17#include <asm/tlbflush.h> 17#include <asm/tlbflush.h>
18 18
19static inline void remap_area_pte(pte_t * pte, unsigned long address, 19static inline void remap_area_pte(pte_t * pte, unsigned long address,
20 phys_t size, phys_t phys_addr, unsigned long flags) 20 phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
21{ 21{
22 phys_t end; 22 phys_addr_t end;
23 unsigned long pfn; 23 unsigned long pfn;
24 pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE 24 pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
25 | __WRITEABLE | flags); 25 | __WRITEABLE | flags);
@@ -43,9 +43,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address,
43} 43}
44 44
45static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, 45static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
46 phys_t size, phys_t phys_addr, unsigned long flags) 46 phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
47{ 47{
48 phys_t end; 48 phys_addr_t end;
49 49
50 address &= ~PGDIR_MASK; 50 address &= ~PGDIR_MASK;
51 end = address + size; 51 end = address + size;
@@ -64,8 +64,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
64 return 0; 64 return 0;
65} 65}
66 66
67static int remap_area_pages(unsigned long address, phys_t phys_addr, 67static int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
68 phys_t size, unsigned long flags) 68 phys_addr_t size, unsigned long flags)
69{ 69{
70 int error; 70 int error;
71 pgd_t * dir; 71 pgd_t * dir;
@@ -111,13 +111,13 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
111 * caller shouldn't need to know that small detail. 111 * caller shouldn't need to know that small detail.
112 */ 112 */
113 113
114#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) 114#define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
115 115
116void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) 116void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags)
117{ 117{
118 struct vm_struct * area; 118 struct vm_struct * area;
119 unsigned long offset; 119 unsigned long offset;
120 phys_t last_addr; 120 phys_addr_t last_addr;
121 void * addr; 121 void * addr;
122 122
123 phys_addr = fixup_bigphys_addr(phys_addr, size); 123 phys_addr = fixup_bigphys_addr(phys_addr, size);
diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c
index 0216ed6eaa2a..751b5cd18bf2 100644
--- a/arch/mips/mm/sc-r5k.c
+++ b/arch/mips/mm/sc-r5k.c
@@ -81,7 +81,7 @@ static inline int __init r5k_sc_probe(void)
81 unsigned long config = read_c0_config(); 81 unsigned long config = read_c0_config();
82 82
83 if (config & CONF_SC) 83 if (config & CONF_SC)
84 return(0); 84 return 0;
85 85
86 scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); 86 scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
87 87
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index c3917e251f59..e90b2e899291 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -332,7 +332,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
332 { 332 {
333 ptep = pte_offset_map(pmdp, address); 333 ptep = pte_offset_map(pmdp, address);
334 334
335#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 335#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
336 write_c0_entrylo0(ptep->pte_high); 336 write_c0_entrylo0(ptep->pte_high);
337 ptep++; 337 ptep++;
338 write_c0_entrylo1(ptep->pte_high); 338 write_c0_entrylo1(ptep->pte_high);
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index e3328a96e809..3978a3d81366 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -637,7 +637,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
637 if (cpu_has_rixi) { 637 if (cpu_has_rixi) {
638 UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); 638 UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
639 } else { 639 } else {
640#ifdef CONFIG_64BIT_PHYS_ADDR 640#ifdef CONFIG_PHYS_ADDR_T_64BIT
641 uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); 641 uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
642#else 642#else
643 UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); 643 UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
@@ -1009,7 +1009,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
1009 * 64bit address support (36bit on a 32bit CPU) in a 32bit 1009 * 64bit address support (36bit on a 32bit CPU) in a 32bit
1010 * Kernel is a special case. Only a few CPUs use it. 1010 * Kernel is a special case. Only a few CPUs use it.
1011 */ 1011 */
1012#ifdef CONFIG_64BIT_PHYS_ADDR 1012#ifdef CONFIG_PHYS_ADDR_T_64BIT
1013 if (cpu_has_64bits) { 1013 if (cpu_has_64bits) {
1014 uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ 1014 uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
1015 uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ 1015 uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
@@ -1510,14 +1510,14 @@ static void
1510iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) 1510iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
1511{ 1511{
1512#ifdef CONFIG_SMP 1512#ifdef CONFIG_SMP
1513# ifdef CONFIG_64BIT_PHYS_ADDR 1513# ifdef CONFIG_PHYS_ADDR_T_64BIT
1514 if (cpu_has_64bits) 1514 if (cpu_has_64bits)
1515 uasm_i_lld(p, pte, 0, ptr); 1515 uasm_i_lld(p, pte, 0, ptr);
1516 else 1516 else
1517# endif 1517# endif
1518 UASM_i_LL(p, pte, 0, ptr); 1518 UASM_i_LL(p, pte, 0, ptr);
1519#else 1519#else
1520# ifdef CONFIG_64BIT_PHYS_ADDR 1520# ifdef CONFIG_PHYS_ADDR_T_64BIT
1521 if (cpu_has_64bits) 1521 if (cpu_has_64bits)
1522 uasm_i_ld(p, pte, 0, ptr); 1522 uasm_i_ld(p, pte, 0, ptr);
1523 else 1523 else
@@ -1530,13 +1530,13 @@ static void
1530iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, 1530iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
1531 unsigned int mode) 1531 unsigned int mode)
1532{ 1532{
1533#ifdef CONFIG_64BIT_PHYS_ADDR 1533#ifdef CONFIG_PHYS_ADDR_T_64BIT
1534 unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); 1534 unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
1535#endif 1535#endif
1536 1536
1537 uasm_i_ori(p, pte, pte, mode); 1537 uasm_i_ori(p, pte, pte, mode);
1538#ifdef CONFIG_SMP 1538#ifdef CONFIG_SMP
1539# ifdef CONFIG_64BIT_PHYS_ADDR 1539# ifdef CONFIG_PHYS_ADDR_T_64BIT
1540 if (cpu_has_64bits) 1540 if (cpu_has_64bits)
1541 uasm_i_scd(p, pte, 0, ptr); 1541 uasm_i_scd(p, pte, 0, ptr);
1542 else 1542 else
@@ -1548,7 +1548,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
1548 else 1548 else
1549 uasm_il_beqz(p, r, pte, label_smp_pgtable_change); 1549 uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
1550 1550
1551# ifdef CONFIG_64BIT_PHYS_ADDR 1551# ifdef CONFIG_PHYS_ADDR_T_64BIT
1552 if (!cpu_has_64bits) { 1552 if (!cpu_has_64bits) {
1553 /* no uasm_i_nop needed */ 1553 /* no uasm_i_nop needed */
1554 uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); 1554 uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr);
@@ -1563,14 +1563,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
1563 uasm_i_nop(p); 1563 uasm_i_nop(p);
1564# endif 1564# endif
1565#else 1565#else
1566# ifdef CONFIG_64BIT_PHYS_ADDR 1566# ifdef CONFIG_PHYS_ADDR_T_64BIT
1567 if (cpu_has_64bits) 1567 if (cpu_has_64bits)
1568 uasm_i_sd(p, pte, 0, ptr); 1568 uasm_i_sd(p, pte, 0, ptr);
1569 else 1569 else
1570# endif 1570# endif
1571 UASM_i_SW(p, pte, 0, ptr); 1571 UASM_i_SW(p, pte, 0, ptr);
1572 1572
1573# ifdef CONFIG_64BIT_PHYS_ADDR 1573# ifdef CONFIG_PHYS_ADDR_T_64BIT
1574 if (!cpu_has_64bits) { 1574 if (!cpu_has_64bits) {
1575 uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); 1575 uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr);
1576 uasm_i_ori(p, pte, pte, hwmode); 1576 uasm_i_ori(p, pte, pte, hwmode);
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c
index 6708a2dbf934..8e02291cfc0c 100644
--- a/arch/mips/mm/uasm-mips.c
+++ b/arch/mips/mm/uasm-mips.c
@@ -96,9 +96,11 @@ static struct insn insn_table[] = {
96 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 96 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
97 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, 97 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
98 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, 98 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
99 { insn_mfhc0, M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET},
99 { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, 100 { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD },
100 { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, 101 { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD },
101 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, 102 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
103 { insn_mthc0, M(cop0_op, mthc0_op, 0, 0, 0, 0), RT | RD | SET},
102 { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, 104 { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD},
103 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, 105 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
104 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, 106 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index a01b0d6cedd2..4adf30284813 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -51,12 +51,12 @@ enum opcode {
51 insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, 51 insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret,
52 insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, 52 insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb,
53 insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, 53 insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw,
54 insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul, 54 insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi, insn_mflo, insn_mtc0,
55 insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, 55 insn_mthc0, insn_mul, insn_or, insn_ori, insn_pref, insn_rfe,
56 insn_sd, insn_sll, insn_sllv, insn_slt, insn_sltiu, insn_sltu, insn_sra, 56 insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll, insn_sllv, insn_slt,
57 insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, 57 insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu,
58 insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, 58 insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi,
59 insn_xor, insn_xori, insn_yield, 59 insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield,
60}; 60};
61 61
62struct insn { 62struct insn {
@@ -284,9 +284,11 @@ I_u2s3u1(_lld)
284I_u1s2(_lui) 284I_u1s2(_lui)
285I_u2s3u1(_lw) 285I_u2s3u1(_lw)
286I_u1u2u3(_mfc0) 286I_u1u2u3(_mfc0)
287I_u1u2u3(_mfhc0)
287I_u1(_mfhi) 288I_u1(_mfhi)
288I_u1(_mflo) 289I_u1(_mflo)
289I_u1u2u3(_mtc0) 290I_u1u2u3(_mtc0)
291I_u1u2u3(_mthc0)
290I_u3u1u2(_mul) 292I_u3u1u2(_mul)
291I_u2u1u3(_ori) 293I_u2u1u3(_ori)
292I_u3u1u2(_or) 294I_u3u1u2(_or)
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 0f60256d3784..6849f533154f 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -111,7 +111,7 @@ static void __init mips_ejtag_setup(void)
111 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); 111 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
112} 112}
113 113
114phys_t mips_cpc_default_phys_base(void) 114phys_addr_t mips_cpc_default_phys_base(void)
115{ 115{
116 return CPC_BASE_ADDR; 116 return CPC_BASE_ADDR;
117} 117}
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index e4f43baa8f67..d1392f8f5811 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -18,6 +18,7 @@
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/irqchip/mips-gic.h>
21#include <linux/kernel_stat.h> 22#include <linux/kernel_stat.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/random.h> 24#include <linux/random.h>
@@ -33,19 +34,13 @@
33#include <asm/mips-boards/generic.h> 34#include <asm/mips-boards/generic.h>
34#include <asm/mips-boards/msc01_pci.h> 35#include <asm/mips-boards/msc01_pci.h>
35#include <asm/msc01_ic.h> 36#include <asm/msc01_ic.h>
36#include <asm/gic.h>
37#include <asm/setup.h> 37#include <asm/setup.h>
38#include <asm/rtlx.h> 38#include <asm/rtlx.h>
39 39
40static unsigned long _msc01_biu_base; 40static void __iomem *_msc01_biu_base;
41static unsigned int ipi_map[NR_CPUS];
42 41
43static DEFINE_RAW_SPINLOCK(mips_irq_lock); 42static DEFINE_RAW_SPINLOCK(mips_irq_lock);
44 43
45#ifdef CONFIG_MIPS_GIC_IPI
46DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS);
47#endif
48
49static inline int mips_pcibios_iack(void) 44static inline int mips_pcibios_iack(void)
50{ 45{
51 int irq; 46 int irq;
@@ -127,24 +122,10 @@ static void malta_hw0_irqdispatch(void)
127#endif 122#endif
128} 123}
129 124
130static void malta_ipi_irqdispatch(void) 125static irqreturn_t i8259_handler(int irq, void *dev_id)
131{ 126{
132#ifdef CONFIG_MIPS_GIC_IPI 127 malta_hw0_irqdispatch();
133 unsigned long irq; 128 return IRQ_HANDLED;
134 DECLARE_BITMAP(pending, GIC_NUM_INTRS);
135
136 gic_get_int_mask(pending, ipi_ints);
137
138 irq = find_first_bit(pending, GIC_NUM_INTRS);
139
140 while (irq < GIC_NUM_INTRS) {
141 do_IRQ(MIPS_GIC_IRQ_BASE + irq);
142
143 irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1);
144 }
145#endif
146 if (gic_compare_int())
147 do_IRQ(MIPS_GIC_IRQ_BASE);
148} 129}
149 130
150static void corehi_irqdispatch(void) 131static void corehi_irqdispatch(void)
@@ -203,95 +184,10 @@ static void corehi_irqdispatch(void)
203 die("CoreHi interrupt", regs); 184 die("CoreHi interrupt", regs);
204} 185}
205 186
206static inline int clz(unsigned long x) 187static irqreturn_t corehi_handler(int irq, void *dev_id)
207{
208 __asm__(
209 " .set push \n"
210 " .set mips32 \n"
211 " clz %0, %1 \n"
212 " .set pop \n"
213 : "=r" (x)
214 : "r" (x));
215
216 return x;
217}
218
219/*
220 * Version of ffs that only looks at bits 12..15.
221 */
222static inline unsigned int irq_ffs(unsigned int pending)
223{
224#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
225 return -clz(pending) + 31 - CAUSEB_IP;
226#else
227 unsigned int a0 = 7;
228 unsigned int t0;
229
230 t0 = pending & 0xf000;
231 t0 = t0 < 1;
232 t0 = t0 << 2;
233 a0 = a0 - t0;
234 pending = pending << t0;
235
236 t0 = pending & 0xc000;
237 t0 = t0 < 1;
238 t0 = t0 << 1;
239 a0 = a0 - t0;
240 pending = pending << t0;
241
242 t0 = pending & 0x8000;
243 t0 = t0 < 1;
244 /* t0 = t0 << 2; */
245 a0 = a0 - t0;
246 /* pending = pending << t0; */
247
248 return a0;
249#endif
250}
251
252/*
253 * IRQs on the Malta board look basically (barring software IRQs which we
254 * don't use at all and all external interrupt sources are combined together
255 * on hardware interrupt 0 (MIPS IRQ 2)) like:
256 *
257 * MIPS IRQ Source
258 * -------- ------
259 * 0 Software (ignored)
260 * 1 Software (ignored)
261 * 2 Combined hardware interrupt (hw0)
262 * 3 Hardware (ignored)
263 * 4 Hardware (ignored)
264 * 5 Hardware (ignored)
265 * 6 Hardware (ignored)
266 * 7 R4k timer (what we use)
267 *
268 * We handle the IRQ according to _our_ priority which is:
269 *
270 * Highest ---- R4k Timer
271 * Lowest ---- Combined hardware interrupt
272 *
273 * then we just return, if multiple IRQs are pending then we will just take
274 * another exception, big deal.
275 */
276
277asmlinkage void plat_irq_dispatch(void)
278{ 188{
279 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 189 corehi_irqdispatch();
280 int irq; 190 return IRQ_HANDLED;
281
282 if (unlikely(!pending)) {
283 spurious_interrupt();
284 return;
285 }
286
287 irq = irq_ffs(pending);
288
289 if (irq == MIPSCPU_INT_I8259A)
290 malta_hw0_irqdispatch();
291 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
292 malta_ipi_irqdispatch();
293 else
294 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
295} 191}
296 192
297#ifdef CONFIG_MIPS_MT_SMP 193#ifdef CONFIG_MIPS_MT_SMP
@@ -312,13 +208,6 @@ static void ipi_call_dispatch(void)
312 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); 208 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
313} 209}
314 210
315#endif /* CONFIG_MIPS_MT_SMP */
316
317#ifdef CONFIG_MIPS_GIC_IPI
318
319#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3
320#define GIC_MIPS_CPU_IPI_CALL_IRQ 4
321
322static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) 211static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
323{ 212{
324#ifdef CONFIG_MIPS_VPE_APSP_API_CMP 213#ifdef CONFIG_MIPS_VPE_APSP_API_CMP
@@ -349,31 +238,16 @@ static struct irqaction irq_call = {
349 .flags = IRQF_PERCPU, 238 .flags = IRQF_PERCPU,
350 .name = "IPI_call" 239 .name = "IPI_call"
351}; 240};
352#endif /* CONFIG_MIPS_GIC_IPI */ 241#endif /* CONFIG_MIPS_MT_SMP */
353
354static int gic_resched_int_base;
355static int gic_call_int_base;
356#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu))
357#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu))
358
359unsigned int plat_ipi_call_int_xlate(unsigned int cpu)
360{
361 return GIC_CALL_INT(cpu);
362}
363
364unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
365{
366 return GIC_RESCHED_INT(cpu);
367}
368 242
369static struct irqaction i8259irq = { 243static struct irqaction i8259irq = {
370 .handler = no_action, 244 .handler = i8259_handler,
371 .name = "XT-PIC cascade", 245 .name = "XT-PIC cascade",
372 .flags = IRQF_NO_THREAD, 246 .flags = IRQF_NO_THREAD,
373}; 247};
374 248
375static struct irqaction corehi_irqaction = { 249static struct irqaction corehi_irqaction = {
376 .handler = no_action, 250 .handler = corehi_handler,
377 .name = "CoreHi", 251 .name = "CoreHi",
378 .flags = IRQF_NO_THREAD, 252 .flags = IRQF_NO_THREAD,
379}; 253};
@@ -399,60 +273,6 @@ static msc_irqmap_t msc_eicirqmap[] __initdata = {
399 273
400static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); 274static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap);
401 275
402/*
403 * This GIC specific tabular array defines the association between External
404 * Interrupts and CPUs/Core Interrupts. The nature of the External
405 * Interrupts is also defined here - polarity/trigger.
406 */
407
408#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
409#define X GIC_UNUSED
410
411static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
412 { X, X, X, X, 0 },
413 { X, X, X, X, 0 },
414 { X, X, X, X, 0 },
415 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
416 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
417 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
418 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
419 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
420 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
421 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
422 { X, X, X, X, 0 },
423 { X, X, X, X, 0 },
424 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
425 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
426 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
427 { X, X, X, X, 0 },
428 /* The remainder of this table is initialised by fill_ipi_map */
429};
430#undef X
431
432#ifdef CONFIG_MIPS_GIC_IPI
433static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
434{
435 int intr = baseintr + cpu;
436 gic_intr_map[intr].cpunum = cpu;
437 gic_intr_map[intr].pin = cpupin;
438 gic_intr_map[intr].polarity = GIC_POL_POS;
439 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
440 gic_intr_map[intr].flags = 0;
441 ipi_map[cpu] |= (1 << (cpupin + 2));
442 bitmap_set(ipi_ints, intr, 1);
443}
444
445static void __init fill_ipi_map(void)
446{
447 int cpu;
448
449 for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
450 fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1);
451 fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2);
452 }
453}
454#endif
455
456void __init arch_init_ipiirq(int irq, struct irqaction *action) 276void __init arch_init_ipiirq(int irq, struct irqaction *action)
457{ 277{
458 setup_irq(irq, action); 278 setup_irq(irq, action);
@@ -461,6 +281,8 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action)
461 281
462void __init arch_init_irq(void) 282void __init arch_init_irq(void)
463{ 283{
284 int corehi_irq, i8259_irq;
285
464 init_i8259_irqs(); 286 init_i8259_irqs();
465 287
466 if (!cpu_has_veic) 288 if (!cpu_has_veic)
@@ -471,12 +293,12 @@ void __init arch_init_irq(void)
471 gic_present = 1; 293 gic_present = 1;
472 } else { 294 } else {
473 if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { 295 if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) {
474 _msc01_biu_base = (unsigned long) 296 _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE,
475 ioremap_nocache(MSC01_BIU_REG_BASE,
476 MSC01_BIU_ADDRSPACE_SZ); 297 MSC01_BIU_ADDRSPACE_SZ);
477 gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & 298 gic_present =
478 MSC01_SC_CFG_GICPRES_MSK) >> 299 (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) &
479 MSC01_SC_CFG_GICPRES_SHF; 300 MSC01_SC_CFG_GICPRES_MSK) >>
301 MSC01_SC_CFG_GICPRES_SHF;
480 } 302 }
481 } 303 }
482 if (gic_present) 304 if (gic_present)
@@ -507,63 +329,20 @@ void __init arch_init_irq(void)
507 msc_nr_irqs); 329 msc_nr_irqs);
508 } 330 }
509 331
510 if (cpu_has_veic) {
511 set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch);
512 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
513 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
514 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
515 } else if (cpu_has_vint) {
516 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
517 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
518 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
519 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
520 &corehi_irqaction);
521 } else {
522 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
523 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
524 &corehi_irqaction);
525 }
526
527 if (gic_present) { 332 if (gic_present) {
528 /* FIXME */
529 int i; 333 int i;
530#if defined(CONFIG_MIPS_GIC_IPI) 334
531 gic_call_int_base = GIC_NUM_INTRS - 335 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC,
532 (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; 336 MIPS_GIC_IRQ_BASE);
533 gic_resched_int_base = gic_call_int_base - nr_cpu_ids;
534 fill_ipi_map();
535#endif
536 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
537 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
538 if (!mips_cm_present()) { 337 if (!mips_cm_present()) {
539 /* Enable the GIC */ 338 /* Enable the GIC */
540 i = REG(_msc01_biu_base, MSC01_SC_CFG); 339 i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS);
541 REG(_msc01_biu_base, MSC01_SC_CFG) = 340 __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF),
542 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); 341 _msc01_biu_base + MSC01_SC_CFG_OFS);
543 pr_debug("GIC Enabled\n"); 342 pr_debug("GIC Enabled\n");
544 } 343 }
545#if defined(CONFIG_MIPS_GIC_IPI) 344 i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A;
546 /* set up ipi interrupts */ 345 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
547 if (cpu_has_vint) {
548 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
549 set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch);
550 }
551 /* Argh.. this really needs sorting out.. */
552 pr_info("CPU%d: status register was %08x\n",
553 smp_processor_id(), read_c0_status());
554 write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4);
555 pr_info("CPU%d: status register now %08x\n",
556 smp_processor_id(), read_c0_status());
557 write_c0_status(0x1100dc00);
558 pr_info("CPU%d: status register frc %08x\n",
559 smp_processor_id(), read_c0_status());
560 for (i = 0; i < nr_cpu_ids; i++) {
561 arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
562 GIC_RESCHED_INT(i), &irq_resched);
563 arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
564 GIC_CALL_INT(i), &irq_call);
565 }
566#endif
567 } else { 346 } else {
568#if defined(CONFIG_MIPS_MT_SMP) 347#if defined(CONFIG_MIPS_MT_SMP)
569 /* set up ipi interrupts */ 348 /* set up ipi interrupts */
@@ -573,12 +352,6 @@ void __init arch_init_irq(void)
573 cpu_ipi_resched_irq = MSC01E_INT_SW0; 352 cpu_ipi_resched_irq = MSC01E_INT_SW0;
574 cpu_ipi_call_irq = MSC01E_INT_SW1; 353 cpu_ipi_call_irq = MSC01E_INT_SW1;
575 } else { 354 } else {
576 if (cpu_has_vint) {
577 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ,
578 ipi_resched_dispatch);
579 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ,
580 ipi_call_dispatch);
581 }
582 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + 355 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE +
583 MIPS_CPU_IPI_RESCHED_IRQ; 356 MIPS_CPU_IPI_RESCHED_IRQ;
584 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + 357 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE +
@@ -587,7 +360,21 @@ void __init arch_init_irq(void)
587 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); 360 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
588 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); 361 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
589#endif 362#endif
363 if (cpu_has_veic) {
364 set_vi_handler(MSC01E_INT_I8259A,
365 malta_hw0_irqdispatch);
366 set_vi_handler(MSC01E_INT_COREHI,
367 corehi_irqdispatch);
368 i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A;
369 corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI;
370 } else {
371 i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A;
372 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
373 }
590 } 374 }
375
376 setup_irq(i8259_irq, &i8259irq);
377 setup_irq(corehi_irq, &corehi_irqaction);
591} 378}
592 379
593void malta_be_init(void) 380void malta_be_init(void)
@@ -714,37 +501,3 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
714 501
715 return retval; 502 return retval;
716} 503}
717
718void gic_enable_interrupt(int irq_vec)
719{
720 GIC_SET_INTR_MASK(irq_vec);
721}
722
723void gic_disable_interrupt(int irq_vec)
724{
725 GIC_CLR_INTR_MASK(irq_vec);
726}
727
728void gic_irq_ack(struct irq_data *d)
729{
730 int irq = (d->irq - gic_irq_base);
731
732 GIC_CLR_INTR_MASK(irq);
733
734 if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
735 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
736}
737
738void gic_finish_irq(struct irq_data *d)
739{
740 /* Enable interrupts. */
741 GIC_SET_INTR_MASK(d->irq - gic_irq_base);
742}
743
744void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
745{
746 int i;
747
748 for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
749 irq_set_chip(i, irq_controller);
750}
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 3778a359f3ad..ce02dbdedc62 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -24,6 +24,7 @@
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/irqchip/mips-gic.h>
27#include <linux/timex.h> 28#include <linux/timex.h>
28#include <linux/mc146818rtc.h> 29#include <linux/mc146818rtc.h>
29 30
@@ -37,7 +38,6 @@
37#include <asm/time.h> 38#include <asm/time.h>
38#include <asm/mc146818-time.h> 39#include <asm/mc146818-time.h>
39#include <asm/msc01_ic.h> 40#include <asm/msc01_ic.h>
40#include <asm/gic.h>
41 41
42#include <asm/mips-boards/generic.h> 42#include <asm/mips-boards/generic.h>
43#include <asm/mips-boards/maltaint.h> 43#include <asm/mips-boards/maltaint.h>
@@ -46,6 +46,8 @@ static int mips_cpu_timer_irq;
46static int mips_cpu_perf_irq; 46static int mips_cpu_perf_irq;
47extern int cp0_perfcount_irq; 47extern int cp0_perfcount_irq;
48 48
49static unsigned int gic_frequency;
50
49static void mips_timer_dispatch(void) 51static void mips_timer_dispatch(void)
50{ 52{
51 do_IRQ(mips_cpu_timer_irq); 53 do_IRQ(mips_cpu_timer_irq);
@@ -70,9 +72,7 @@ static void __init estimate_frequencies(void)
70{ 72{
71 unsigned long flags; 73 unsigned long flags;
72 unsigned int count, start; 74 unsigned int count, start;
73#ifdef CONFIG_IRQ_GIC 75 cycle_t giccount = 0, gicstart = 0;
74 unsigned int giccount = 0, gicstart = 0;
75#endif
76 76
77#if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ 77#if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ
78 mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; 78 mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000;
@@ -87,32 +87,26 @@ static void __init estimate_frequencies(void)
87 87
88 /* Initialize counters. */ 88 /* Initialize counters. */
89 start = read_c0_count(); 89 start = read_c0_count();
90#ifdef CONFIG_IRQ_GIC
91 if (gic_present) 90 if (gic_present)
92 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); 91 gicstart = gic_read_count();
93#endif
94 92
95 /* Read counter exactly on falling edge of update flag. */ 93 /* Read counter exactly on falling edge of update flag. */
96 while (CMOS_READ(RTC_REG_A) & RTC_UIP); 94 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
97 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); 95 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
98 96
99 count = read_c0_count(); 97 count = read_c0_count();
100#ifdef CONFIG_IRQ_GIC
101 if (gic_present) 98 if (gic_present)
102 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); 99 giccount = gic_read_count();
103#endif
104 100
105 local_irq_restore(flags); 101 local_irq_restore(flags);
106 102
107 count -= start; 103 count -= start;
108 mips_hpt_frequency = count; 104 mips_hpt_frequency = count;
109 105
110#ifdef CONFIG_IRQ_GIC
111 if (gic_present) { 106 if (gic_present) {
112 giccount -= gicstart; 107 giccount -= gicstart;
113 gic_frequency = giccount; 108 gic_frequency = giccount;
114 } 109 }
115#endif
116} 110}
117 111
118void read_persistent_clock(struct timespec *ts) 112void read_persistent_clock(struct timespec *ts)
@@ -121,35 +115,30 @@ void read_persistent_clock(struct timespec *ts)
121 ts->tv_nsec = 0; 115 ts->tv_nsec = 0;
122} 116}
123 117
124static void __init plat_perf_setup(void) 118int get_c0_perfcount_int(void)
125{ 119{
126#ifdef MSC01E_INT_BASE
127 if (cpu_has_veic) { 120 if (cpu_has_veic) {
128 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); 121 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
129 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 122 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
130 } else 123 } else if (gic_present) {
131#endif 124 mips_cpu_perf_irq = gic_get_c0_perfcount_int();
132 if (cp0_perfcount_irq >= 0) { 125 } else if (cp0_perfcount_irq >= 0) {
133 if (cpu_has_vint)
134 set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
135 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 126 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
136#ifdef CONFIG_SMP 127 } else {
137 irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); 128 mips_cpu_perf_irq = -1;
138#endif
139 } 129 }
130
131 return mips_cpu_perf_irq;
140} 132}
141 133
142unsigned int get_c0_compare_int(void) 134unsigned int get_c0_compare_int(void)
143{ 135{
144#ifdef MSC01E_INT_BASE
145 if (cpu_has_veic) { 136 if (cpu_has_veic) {
146 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); 137 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
147 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; 138 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
148 } else 139 } else if (gic_present) {
149#endif 140 mips_cpu_timer_irq = gic_get_c0_compare_int();
150 { 141 } else {
151 if (cpu_has_vint)
152 set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
153 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 142 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
154 } 143 }
155 144
@@ -191,16 +180,14 @@ void __init plat_time_init(void)
191 setup_pit_timer(); 180 setup_pit_timer();
192#endif 181#endif
193 182
194#ifdef CONFIG_IRQ_GIC 183#ifdef CONFIG_MIPS_GIC
195 if (gic_present) { 184 if (gic_present) {
196 freq = freqround(gic_frequency, 5000); 185 freq = freqround(gic_frequency, 5000);
197 printk("GIC frequency %d.%02d MHz\n", freq/1000000, 186 printk("GIC frequency %d.%02d MHz\n", freq/1000000,
198 (freq%1000000)*100/1000000); 187 (freq%1000000)*100/1000000);
199#ifdef CONFIG_CSRC_GIC 188#ifdef CONFIG_CLKSRC_MIPS_GIC
200 gic_clocksource_init(gic_frequency); 189 gic_clocksource_init(gic_frequency);
201#endif 190#endif
202 } 191 }
203#endif 192#endif
204
205 plat_perf_setup();
206} 193}
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
index 772fc056a92d..014dd7ba4d68 100644
--- a/arch/mips/mti-sead3/sead3-ehci.c
+++ b/arch/mips/mti-sead3/sead3-ehci.c
@@ -9,6 +9,9 @@
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/dma-mapping.h> 10#include <linux/dma-mapping.h>
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/irqchip/mips-gic.h>
13
14#include <asm/mips-boards/sead3int.h>
12 15
13struct resource ehci_resources[] = { 16struct resource ehci_resources[] = {
14 { 17 {
@@ -17,7 +20,6 @@ struct resource ehci_resources[] = {
17 .flags = IORESOURCE_MEM 20 .flags = IORESOURCE_MEM
18 }, 21 },
19 { 22 {
20 .start = MIPS_CPU_IRQ_BASE + 2,
21 .flags = IORESOURCE_IRQ 23 .flags = IORESOURCE_IRQ
22 } 24 }
23}; 25};
@@ -37,6 +39,10 @@ static struct platform_device ehci_device = {
37 39
38static int __init ehci_init(void) 40static int __init ehci_init(void)
39{ 41{
42 if (gic_present)
43 ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI;
44 else
45 ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI;
40 return platform_device_register(&ehci_device); 46 return platform_device_register(&ehci_device);
41} 47}
42 48
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
index 6a560ac03def..e31e17f81eef 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -7,9 +7,9 @@
7 */ 7 */
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/irqchip/mips-gic.h>
10#include <linux/io.h> 11#include <linux/io.h>
11 12
12#include <asm/gic.h>
13#include <asm/irq_cpu.h> 13#include <asm/irq_cpu.h>
14#include <asm/setup.h> 14#include <asm/setup.h>
15 15
@@ -20,138 +20,23 @@
20#define SEAD_CONFIG_BASE 0x1b100110 20#define SEAD_CONFIG_BASE 0x1b100110
21#define SEAD_CONFIG_SIZE 4 21#define SEAD_CONFIG_SIZE 4
22 22
23static unsigned long sead3_config_reg; 23static void __iomem *sead3_config_reg;
24
25/*
26 * This table defines the setup for each external GIC interrupt. It is
27 * indexed by interrupt number.
28 */
29#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
30static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
31 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
32 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
33 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
34 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
35 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
36 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
37 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
38 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
39 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
40 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
41 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
42 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
43 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
44 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
45 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
46 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
47};
48
49asmlinkage void plat_irq_dispatch(void)
50{
51 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
52 int irq;
53
54 irq = (fls(pending) - CAUSEB_IP - 1);
55 if (irq >= 0)
56 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
57 else
58 spurious_interrupt();
59}
60 24
61void __init arch_init_irq(void) 25void __init arch_init_irq(void)
62{ 26{
63 int i; 27 if (!cpu_has_veic)
64
65 if (!cpu_has_veic) {
66 mips_cpu_irq_init(); 28 mips_cpu_irq_init();
67 29
68 if (cpu_has_vint) { 30 sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE);
69 /* install generic handler */ 31 gic_present = (__raw_readl(sead3_config_reg) &
70 for (i = 0; i < 8; i++) 32 SEAD_CONFIG_GIC_PRESENT_MSK) >>
71 set_vi_handler(i, plat_irq_dispatch);
72 }
73 }
74
75 sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE,
76 SEAD_CONFIG_SIZE);
77 gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
78 SEAD_CONFIG_GIC_PRESENT_SHF; 33 SEAD_CONFIG_GIC_PRESENT_SHF;
79 pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); 34 pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
80 pr_info("EIC: %s\n", 35 pr_info("EIC: %s\n",
81 (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); 36 (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off");
82 37
83 if (gic_present) 38 if (gic_present)
84 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, 39 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC,
85 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); 40 MIPS_GIC_IRQ_BASE);
86}
87
88void gic_enable_interrupt(int irq_vec)
89{
90 unsigned int i, irq_source;
91
92 /* enable all the interrupts associated with this vector */
93 for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
94 irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
95 GIC_SET_INTR_MASK(irq_source);
96 }
97 /* enable all local interrupts associated with this vector */
98 if (gic_shared_intr_map[irq_vec].local_intr_mask) {
99 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
100 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK),
101 gic_shared_intr_map[irq_vec].local_intr_mask);
102 }
103} 41}
104 42
105void gic_disable_interrupt(int irq_vec)
106{
107 unsigned int i, irq_source;
108
109 /* disable all the interrupts associated with this vector */
110 for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
111 irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
112 GIC_CLR_INTR_MASK(irq_source);
113 }
114 /* disable all local interrupts associated with this vector */
115 if (gic_shared_intr_map[irq_vec].local_intr_mask) {
116 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
117 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK),
118 gic_shared_intr_map[irq_vec].local_intr_mask);
119 }
120}
121
122void gic_irq_ack(struct irq_data *d)
123{
124 GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
125}
126
127void gic_finish_irq(struct irq_data *d)
128{
129 unsigned int irq = (d->irq - gic_irq_base);
130 unsigned int i, irq_source;
131
132 /* Clear edge detectors. */
133 for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) {
134 irq_source = gic_shared_intr_map[irq].intr_list[i];
135 if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE)
136 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source);
137 }
138
139 /* Enable interrupts. */
140 GIC_SET_INTR_MASK(irq);
141}
142
143void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
144{
145 int i;
146
147 /*
148 * For non-EIC mode, we want to setup the GIC in pass-through
149 * mode, as if the GIC didn't exist. Do not map any interrupts
150 * for an external interrupt controller.
151 */
152 if (!cpu_has_veic)
153 return;
154
155 for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
156 irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq);
157}
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
index dd11e7eb771c..46176b804576 100644
--- a/arch/mips/mti-sead3/sead3-net.c
+++ b/arch/mips/mti-sead3/sead3-net.c
@@ -7,9 +7,12 @@
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/irqchip/mips-gic.h>
10#include <linux/platform_device.h> 11#include <linux/platform_device.h>
11#include <linux/smsc911x.h> 12#include <linux/smsc911x.h>
12 13
14#include <asm/mips-boards/sead3int.h>
15
13static struct smsc911x_platform_config sead3_smsc911x_data = { 16static struct smsc911x_platform_config sead3_smsc911x_data = {
14 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 17 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
15 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, 18 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
@@ -17,14 +20,13 @@ static struct smsc911x_platform_config sead3_smsc911x_data = {
17 .phy_interface = PHY_INTERFACE_MODE_MII, 20 .phy_interface = PHY_INTERFACE_MODE_MII,
18}; 21};
19 22
20struct resource sead3_net_resourcess[] = { 23struct resource sead3_net_resources[] = {
21 { 24 {
22 .start = 0x1f010000, 25 .start = 0x1f010000,
23 .end = 0x1f01ffff, 26 .end = 0x1f01ffff,
24 .flags = IORESOURCE_MEM 27 .flags = IORESOURCE_MEM
25 }, 28 },
26 { 29 {
27 .start = MIPS_CPU_IRQ_BASE + 6,
28 .flags = IORESOURCE_IRQ 30 .flags = IORESOURCE_IRQ
29 } 31 }
30}; 32};
@@ -35,12 +37,16 @@ static struct platform_device sead3_net_device = {
35 .dev = { 37 .dev = {
36 .platform_data = &sead3_smsc911x_data, 38 .platform_data = &sead3_smsc911x_data,
37 }, 39 },
38 .num_resources = ARRAY_SIZE(sead3_net_resourcess), 40 .num_resources = ARRAY_SIZE(sead3_net_resources),
39 .resource = sead3_net_resourcess 41 .resource = sead3_net_resources
40}; 42};
41 43
42static int __init sead3_net_init(void) 44static int __init sead3_net_init(void)
43{ 45{
46 if (gic_present)
47 sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET;
48 else
49 sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET;
44 return platform_device_register(&sead3_net_device); 50 return platform_device_register(&sead3_net_device);
45} 51}
46 52
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c
index 6c3b33dbed18..53ee6f1f018d 100644
--- a/arch/mips/mti-sead3/sead3-platform.c
+++ b/arch/mips/mti-sead3/sead3-platform.c
@@ -7,12 +7,15 @@
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/irqchip/mips-gic.h>
10#include <linux/serial_8250.h> 11#include <linux/serial_8250.h>
11 12
12#define UART(base, int) \ 13#include <asm/mips-boards/sead3int.h>
14
15#define UART(base) \
13{ \ 16{ \
14 .mapbase = base, \ 17 .mapbase = base, \
15 .irq = int, \ 18 .irq = -1, \
16 .uartclk = 14745600, \ 19 .uartclk = 14745600, \
17 .iotype = UPIO_MEM32, \ 20 .iotype = UPIO_MEM32, \
18 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ 21 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
@@ -20,8 +23,8 @@
20} 23}
21 24
22static struct plat_serial8250_port uart8250_data[] = { 25static struct plat_serial8250_port uart8250_data[] = {
23 UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ 26 UART(0x1f000900), /* ttyS0 = USB */
24 UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ 27 UART(0x1f000800), /* ttyS1 = RS232 */
25 { }, 28 { },
26}; 29};
27 30
@@ -35,6 +38,13 @@ static struct platform_device uart8250_device = {
35 38
36static int __init uart8250_init(void) 39static int __init uart8250_init(void)
37{ 40{
41 if (gic_present) {
42 uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0;
43 uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1;
44 } else {
45 uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0;
46 uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1;
47 }
38 return platform_device_register(&uart8250_device); 48 return platform_device_register(&uart8250_device);
39} 49}
40 50
diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c
deleted file mode 100644
index bc52705bbee4..000000000000
--- a/arch/mips/mti-sead3/sead3-serial.c
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/serial_8250.h>
11
12#define UART(base, int) \
13{ \
14 .mapbase = base, \
15 .irq = int, \
16 .uartclk = 14745600, \
17 .iotype = UPIO_MEM32, \
18 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
19 .regshift = 2, \
20}
21
22static struct plat_serial8250_port uart8250_data[] = {
23 UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */
24 UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */
25 { },
26};
27
28static struct platform_device uart8250_device = {
29 .name = "serial8250",
30 .id = PLAT8250_DEV_PLATFORM,
31 .dev = {
32 .platform_data = uart8250_data,
33 },
34};
35
36static int __init uart8250_init(void)
37{
38 return platform_device_register(&uart8250_device);
39}
40
41module_init(uart8250_init);
42
43MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
44MODULE_LICENSE("GPL");
45MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform");
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c
index 678d03d53c60..ec1dd2491f96 100644
--- a/arch/mips/mti-sead3/sead3-time.c
+++ b/arch/mips/mti-sead3/sead3-time.c
@@ -6,6 +6,7 @@
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */ 7 */
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/irqchip/mips-gic.h>
9 10
10#include <asm/cpu.h> 11#include <asm/cpu.h>
11#include <asm/setup.h> 12#include <asm/setup.h>
@@ -13,19 +14,6 @@
13#include <asm/irq.h> 14#include <asm/irq.h>
14#include <asm/mips-boards/generic.h> 15#include <asm/mips-boards/generic.h>
15 16
16static int mips_cpu_timer_irq;
17static int mips_cpu_perf_irq;
18
19static void mips_timer_dispatch(void)
20{
21 do_IRQ(mips_cpu_timer_irq);
22}
23
24static void mips_perf_dispatch(void)
25{
26 do_IRQ(mips_cpu_perf_irq);
27}
28
29static void __iomem *status_reg = (void __iomem *)0xbf000410; 17static void __iomem *status_reg = (void __iomem *)0xbf000410;
30 18
31/* 19/*
@@ -81,21 +69,20 @@ void read_persistent_clock(struct timespec *ts)
81 ts->tv_nsec = 0; 69 ts->tv_nsec = 0;
82} 70}
83 71
84static void __init plat_perf_setup(void) 72int get_c0_perfcount_int(void)
85{ 73{
86 if (cp0_perfcount_irq >= 0) { 74 if (gic_present)
87 if (cpu_has_vint) 75 return gic_get_c0_compare_int();
88 set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); 76 if (cp0_perfcount_irq >= 0)
89 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 77 return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
90 } 78 return -1;
91} 79}
92 80
93unsigned int get_c0_compare_int(void) 81unsigned int get_c0_compare_int(void)
94{ 82{
95 if (cpu_has_vint) 83 if (gic_present)
96 set_vi_handler(cp0_compare_irq, mips_timer_dispatch); 84 return gic_get_c0_compare_int();
97 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 85 return MIPS_CPU_IRQ_BASE + cp0_compare_irq;
98 return mips_cpu_timer_irq;
99} 86}
100 87
101void __init plat_time_init(void) 88void __init plat_time_init(void)
@@ -108,6 +95,4 @@ void __init plat_time_init(void)
108 (est_freq % 1000000) * 100 / 1000000); 95 (est_freq % 1000000) * 100 / 1000000);
109 96
110 mips_scroll_message(); 97 mips_scroll_message();
111
112 plat_perf_setup();
113} 98}
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index 9c0a6782c091..070afdb297df 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -14,3 +14,4 @@ oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o
14oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o 14oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o
15oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o 15oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o
16oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o 16oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o
17oprofile-$(CONFIG_CPU_LOONGSON3) += op_model_loongson3.o
diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c
index 83a1dfd8f0e3..5e645c9a3162 100644
--- a/arch/mips/oprofile/backtrace.c
+++ b/arch/mips/oprofile/backtrace.c
@@ -65,7 +65,7 @@ static inline int is_end_of_function_marker(union mips_instruction *ip)
65 * - handle cases where the stack is adjusted inside a function 65 * - handle cases where the stack is adjusted inside a function
66 * (generally doesn't happen) 66 * (generally doesn't happen)
67 * - find optimal value for max_instr_check 67 * - find optimal value for max_instr_check
68 * - try to find a way to handle leaf functions 68 * - try to find a better way to handle leaf functions
69 */ 69 */
70 70
71static inline int unwind_user_frame(struct stackframe *old_frame, 71static inline int unwind_user_frame(struct stackframe *old_frame,
@@ -104,7 +104,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
104 } 104 }
105 105
106 if (!ra_offset || !stack_size) 106 if (!ra_offset || !stack_size)
107 return -1; 107 goto done;
108 108
109 if (ra_offset) { 109 if (ra_offset) {
110 new_frame.ra = old_frame->sp + ra_offset; 110 new_frame.ra = old_frame->sp + ra_offset;
@@ -121,6 +121,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
121 if (new_frame.sp > old_frame->sp) 121 if (new_frame.sp > old_frame->sp)
122 return -2; 122 return -2;
123 123
124done:
124 new_frame.pc = old_frame->ra; 125 new_frame.pc = old_frame->ra;
125 *old_frame = new_frame; 126 *old_frame = new_frame;
126 127
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index e74732449478..a26cbe372e06 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -18,6 +18,7 @@
18 18
19extern struct op_mips_model op_model_mipsxx_ops __weak; 19extern struct op_mips_model op_model_mipsxx_ops __weak;
20extern struct op_mips_model op_model_loongson2_ops __weak; 20extern struct op_mips_model op_model_loongson2_ops __weak;
21extern struct op_mips_model op_model_loongson3_ops __weak;
21 22
22static struct op_mips_model *model; 23static struct op_mips_model *model;
23 24
@@ -104,8 +105,17 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
104 case CPU_LOONGSON2: 105 case CPU_LOONGSON2:
105 lmodel = &op_model_loongson2_ops; 106 lmodel = &op_model_loongson2_ops;
106 break; 107 break;
108 case CPU_LOONGSON3:
109 lmodel = &op_model_loongson3_ops;
110 break;
107 }; 111 };
108 112
113 /*
114 * Always set the backtrace. This allows unsupported CPU types to still
115 * use timer-based oprofile.
116 */
117 ops->backtrace = op_mips_backtrace;
118
109 if (!lmodel) 119 if (!lmodel)
110 return -ENODEV; 120 return -ENODEV;
111 121
@@ -121,7 +131,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
121 ops->start = op_mips_start; 131 ops->start = op_mips_start;
122 ops->stop = op_mips_stop; 132 ops->stop = op_mips_stop;
123 ops->cpu_type = lmodel->cpu_type; 133 ops->cpu_type = lmodel->cpu_type;
124 ops->backtrace = op_mips_backtrace;
125 134
126 printk(KERN_INFO "oprofile: using %s performance monitoring.\n", 135 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
127 lmodel->cpu_type); 136 lmodel->cpu_type);
diff --git a/arch/mips/oprofile/op_model_loongson3.c b/arch/mips/oprofile/op_model_loongson3.c
new file mode 100644
index 000000000000..8bcf7fc40f0d
--- /dev/null
+++ b/arch/mips/oprofile/op_model_loongson3.c
@@ -0,0 +1,220 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 */
7#include <linux/init.h>
8#include <linux/cpu.h>
9#include <linux/smp.h>
10#include <linux/proc_fs.h>
11#include <linux/oprofile.h>
12#include <linux/spinlock.h>
13#include <linux/interrupt.h>
14#include <asm/uaccess.h>
15#include <irq.h>
16#include <loongson.h>
17#include "op_impl.h"
18
19#define LOONGSON3_PERFCNT_OVERFLOW (1ULL << 63)
20
21#define LOONGSON3_PERFCTRL_EXL (1UL << 0)
22#define LOONGSON3_PERFCTRL_KERNEL (1UL << 1)
23#define LOONGSON3_PERFCTRL_SUPERVISOR (1UL << 2)
24#define LOONGSON3_PERFCTRL_USER (1UL << 3)
25#define LOONGSON3_PERFCTRL_ENABLE (1UL << 4)
26#define LOONGSON3_PERFCTRL_W (1UL << 30)
27#define LOONGSON3_PERFCTRL_M (1UL << 31)
28#define LOONGSON3_PERFCTRL_EVENT(idx, event) \
29 (((event) & (idx ? 0x0f : 0x3f)) << 5)
30
31/* Loongson-3 PerfCount performance counter1 register */
32#define read_c0_perflo1() __read_64bit_c0_register($25, 0)
33#define write_c0_perflo1(val) __write_64bit_c0_register($25, 0, val)
34#define read_c0_perfhi1() __read_64bit_c0_register($25, 1)
35#define write_c0_perfhi1(val) __write_64bit_c0_register($25, 1, val)
36
37/* Loongson-3 PerfCount performance counter2 register */
38#define read_c0_perflo2() __read_64bit_c0_register($25, 2)
39#define write_c0_perflo2(val) __write_64bit_c0_register($25, 2, val)
40#define read_c0_perfhi2() __read_64bit_c0_register($25, 3)
41#define write_c0_perfhi2(val) __write_64bit_c0_register($25, 3, val)
42
43static int (*save_perf_irq)(void);
44
45static struct loongson3_register_config {
46 unsigned int control1;
47 unsigned int control2;
48 unsigned long long reset_counter1;
49 unsigned long long reset_counter2;
50 int ctr1_enable, ctr2_enable;
51} reg;
52
53static void reset_counters(void *arg)
54{
55 write_c0_perfhi1(0);
56 write_c0_perfhi2(0);
57 write_c0_perflo1(0xc0000000);
58 write_c0_perflo2(0x40000000);
59}
60
61/* Compute all of the registers in preparation for enabling profiling. */
62static void loongson3_reg_setup(struct op_counter_config *ctr)
63{
64 unsigned int control1 = 0;
65 unsigned int control2 = 0;
66
67 reg.reset_counter1 = 0;
68 reg.reset_counter2 = 0;
69 /* Compute the performance counter control word. */
70 /* For now count kernel and user mode */
71 if (ctr[0].enabled) {
72 control1 |= LOONGSON3_PERFCTRL_EVENT(0, ctr[0].event) |
73 LOONGSON3_PERFCTRL_ENABLE;
74 if (ctr[0].kernel)
75 control1 |= LOONGSON3_PERFCTRL_KERNEL;
76 if (ctr[0].user)
77 control1 |= LOONGSON3_PERFCTRL_USER;
78 reg.reset_counter1 = 0x8000000000000000ULL - ctr[0].count;
79 }
80
81 if (ctr[1].enabled) {
82 control2 |= LOONGSON3_PERFCTRL_EVENT(1, ctr[1].event) |
83 LOONGSON3_PERFCTRL_ENABLE;
84 if (ctr[1].kernel)
85 control2 |= LOONGSON3_PERFCTRL_KERNEL;
86 if (ctr[1].user)
87 control2 |= LOONGSON3_PERFCTRL_USER;
88 reg.reset_counter2 = 0x8000000000000000ULL - ctr[1].count;
89 }
90
91 if (ctr[0].enabled)
92 control1 |= LOONGSON3_PERFCTRL_EXL;
93 if (ctr[1].enabled)
94 control2 |= LOONGSON3_PERFCTRL_EXL;
95
96 reg.control1 = control1;
97 reg.control2 = control2;
98 reg.ctr1_enable = ctr[0].enabled;
99 reg.ctr2_enable = ctr[1].enabled;
100}
101
102/* Program all of the registers in preparation for enabling profiling. */
103static void loongson3_cpu_setup(void *args)
104{
105 uint64_t perfcount1, perfcount2;
106
107 perfcount1 = reg.reset_counter1;
108 perfcount2 = reg.reset_counter2;
109 write_c0_perfhi1(perfcount1);
110 write_c0_perfhi2(perfcount2);
111}
112
113static void loongson3_cpu_start(void *args)
114{
115 /* Start all counters on current CPU */
116 reg.control1 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M);
117 reg.control2 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M);
118
119 if (reg.ctr1_enable)
120 write_c0_perflo1(reg.control1);
121 if (reg.ctr2_enable)
122 write_c0_perflo2(reg.control2);
123}
124
125static void loongson3_cpu_stop(void *args)
126{
127 /* Stop all counters on current CPU */
128 write_c0_perflo1(0xc0000000);
129 write_c0_perflo2(0x40000000);
130 memset(&reg, 0, sizeof(reg));
131}
132
133static int loongson3_perfcount_handler(void)
134{
135 unsigned long flags;
136 uint64_t counter1, counter2;
137 uint32_t cause, handled = IRQ_NONE;
138 struct pt_regs *regs = get_irq_regs();
139
140 cause = read_c0_cause();
141 if (!(cause & CAUSEF_PCI))
142 return handled;
143
144 counter1 = read_c0_perfhi1();
145 counter2 = read_c0_perfhi2();
146
147 local_irq_save(flags);
148
149 if (counter1 & LOONGSON3_PERFCNT_OVERFLOW) {
150 if (reg.ctr1_enable)
151 oprofile_add_sample(regs, 0);
152 counter1 = reg.reset_counter1;
153 }
154 if (counter2 & LOONGSON3_PERFCNT_OVERFLOW) {
155 if (reg.ctr2_enable)
156 oprofile_add_sample(regs, 1);
157 counter2 = reg.reset_counter2;
158 }
159
160 local_irq_restore(flags);
161
162 write_c0_perfhi1(counter1);
163 write_c0_perfhi2(counter2);
164
165 if (!(cause & CAUSEF_TI))
166 handled = IRQ_HANDLED;
167
168 return handled;
169}
170
171static int loongson3_cpu_callback(struct notifier_block *nfb,
172 unsigned long action, void *hcpu)
173{
174 switch (action) {
175 case CPU_STARTING:
176 case CPU_STARTING_FROZEN:
177 write_c0_perflo1(reg.control1);
178 write_c0_perflo2(reg.control2);
179 break;
180 case CPU_DYING:
181 case CPU_DYING_FROZEN:
182 write_c0_perflo1(0xc0000000);
183 write_c0_perflo2(0x40000000);
184 break;
185 }
186
187 return NOTIFY_OK;
188}
189
190static struct notifier_block loongson3_notifier_block = {
191 .notifier_call = loongson3_cpu_callback
192};
193
194static int __init loongson3_init(void)
195{
196 on_each_cpu(reset_counters, NULL, 1);
197 register_hotcpu_notifier(&loongson3_notifier_block);
198 save_perf_irq = perf_irq;
199 perf_irq = loongson3_perfcount_handler;
200
201 return 0;
202}
203
204static void loongson3_exit(void)
205{
206 on_each_cpu(reset_counters, NULL, 1);
207 unregister_hotcpu_notifier(&loongson3_notifier_block);
208 perf_irq = save_perf_irq;
209}
210
211struct op_mips_model op_model_loongson3_ops = {
212 .reg_setup = loongson3_reg_setup,
213 .cpu_setup = loongson3_cpu_setup,
214 .init = loongson3_init,
215 .exit = loongson3_exit,
216 .cpu_start = loongson3_cpu_start,
217 .cpu_stop = loongson3_cpu_stop,
218 .cpu_type = "mips/loongson3",
219 .num_counters = 2
220};
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 42821ae2d77e..01f721a85c5b 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -11,6 +11,7 @@
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/smp.h> 12#include <linux/smp.h>
13#include <asm/irq_regs.h> 13#include <asm/irq_regs.h>
14#include <asm/time.h>
14 15
15#include "op_impl.h" 16#include "op_impl.h"
16 17
@@ -35,6 +36,7 @@
35#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) 36#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13)
36 37
37static int (*save_perf_irq)(void); 38static int (*save_perf_irq)(void);
39static int perfcount_irq;
38 40
39/* 41/*
40 * XLR has only one set of counters per core. Designate the 42 * XLR has only one set of counters per core. Designate the
@@ -431,8 +433,16 @@ static int __init mipsxx_init(void)
431 save_perf_irq = perf_irq; 433 save_perf_irq = perf_irq;
432 perf_irq = mipsxx_perfcount_handler; 434 perf_irq = mipsxx_perfcount_handler;
433 435
434 if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) 436 if (get_c0_perfcount_int)
435 return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, 437 perfcount_irq = get_c0_perfcount_int();
438 else if ((cp0_perfcount_irq >= 0) &&
439 (cp0_compare_irq != cp0_perfcount_irq))
440 perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
441 else
442 perfcount_irq = -1;
443
444 if (perfcount_irq >= 0)
445 return request_irq(perfcount_irq, mipsxx_perfcount_int,
436 0, "Perfcounter", save_perf_irq); 446 0, "Perfcounter", save_perf_irq);
437 447
438 return 0; 448 return 0;
@@ -442,8 +452,8 @@ static void mipsxx_exit(void)
442{ 452{
443 int counters = op_model_mipsxx_ops.num_counters; 453 int counters = op_model_mipsxx_ops.num_counters;
444 454
445 if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) 455 if (perfcount_irq >= 0)
446 free_irq(cp0_perfcount_irq, save_perf_irq); 456 free_irq(perfcount_irq, save_perf_irq);
447 457
448 counters = counters_per_cpu_to_total(counters); 458 counters = counters_per_cpu_to_total(counters);
449 on_each_cpu(reset_counters, (void *)(long)counters, 1); 459 on_each_cpu(reset_counters, (void *)(long)counters, 1);
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 6523d558ff5a..300591c6278d 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ 19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
20 ops-bcm63xx.o 20 ops-bcm63xx.o
21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o 21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
22obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
22obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o 23obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
23obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o 24obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
24obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o 25obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
42obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o 43obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
43obj-$(CONFIG_LANTIQ) += fixup-lantiq.o 44obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
44obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o 45obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
46obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o
45obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o 47obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
46obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o 48obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
47obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o 49obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
index 13eea696bbe7..d02eb9d16b55 100644
--- a/arch/mips/pci/ops-bcm63xx.c
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -469,7 +469,7 @@ static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
469{ 469{
470 switch (bus->number) { 470 switch (bus->number) {
471 case PCIE_BUS_BRIDGE: 471 case PCIE_BUS_BRIDGE:
472 return (PCI_SLOT(devfn) == 0); 472 return PCI_SLOT(devfn) == 0;
473 case PCIE_BUS_DEVICE: 473 case PCIE_BUS_DEVICE:
474 if (PCI_SLOT(devfn) == 0) 474 if (PCI_SLOT(devfn) == 0)
475 return bcm_pcie_readl(PCIE_DLSTATUS_REG) 475 return bcm_pcie_readl(PCIE_DLSTATUS_REG)
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
index a1a7c9f4096e..b9d1fd0ff7e2 100644
--- a/arch/mips/pci/ops-nile4.c
+++ b/arch/mips/pci/ops-nile4.c
@@ -13,8 +13,6 @@
13 13
14volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; 14volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
15 15
16static DEFINE_SPINLOCK(nile4_pci_lock);
17
18static int nile4_pcibios_config_access(unsigned char access_type, 16static int nile4_pcibios_config_access(unsigned char access_type,
19 struct pci_bus *bus, unsigned int devfn, int where, u32 *val) 17 struct pci_bus *bus, unsigned int devfn, int where, u32 *val)
20{ 18{
@@ -76,7 +74,6 @@ static int nile4_pcibios_config_access(unsigned char access_type,
76static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, 74static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
77 int where, int size, u32 *val) 75 int where, int size, u32 *val)
78{ 76{
79 unsigned long flags;
80 u32 data = 0; 77 u32 data = 0;
81 int err; 78 int err;
82 79
@@ -85,11 +82,8 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
85 else if ((size == 4) && (where & 3)) 82 else if ((size == 4) && (where & 3))
86 return PCIBIOS_BAD_REGISTER_NUMBER; 83 return PCIBIOS_BAD_REGISTER_NUMBER;
87 84
88 spin_lock_irqsave(&nile4_pci_lock, flags);
89 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 85 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
90 &data); 86 &data);
91 spin_unlock_irqrestore(&nile4_pci_lock, flags);
92
93 if (err) 87 if (err)
94 return err; 88 return err;
95 89
@@ -106,7 +100,6 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
106static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, 100static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
107 int where, int size, u32 val) 101 int where, int size, u32 val)
108{ 102{
109 unsigned long flags;
110 u32 data = 0; 103 u32 data = 0;
111 int err; 104 int err;
112 105
@@ -115,11 +108,8 @@ static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
115 else if ((size == 4) && (where & 3)) 108 else if ((size == 4) && (where & 3))
116 return PCIBIOS_BAD_REGISTER_NUMBER; 109 return PCIBIOS_BAD_REGISTER_NUMBER;
117 110
118 spin_lock_irqsave(&nile4_pci_lock, flags);
119 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 111 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
120 &data); 112 &data);
121 spin_unlock_irqrestore(&nile4_pci_lock, flags);
122
123 if (err) 113 if (err)
124 return err; 114 return err;
125 115
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 50034f985be1..dd2d9f7e9412 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -193,8 +193,6 @@ static void pci_proc_init(void)
193} 193}
194#endif /* CONFIG_PROC_FS && PCI_COUNTERS */ 194#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
195 195
196static DEFINE_SPINLOCK(bpci_lock);
197
198/***************************************************************************** 196/*****************************************************************************
199 * 197 *
200 * STRUCT: pci_io_resource 198 * STRUCT: pci_io_resource
@@ -368,7 +366,6 @@ int msp_pcibios_config_access(unsigned char access_type,
368 struct msp_pci_regs *preg = (void *)PCI_BASE_REG; 366 struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
369 unsigned char bus_num = bus->number; 367 unsigned char bus_num = bus->number;
370 unsigned char dev_fn = (unsigned char)devfn; 368 unsigned char dev_fn = (unsigned char)devfn;
371 unsigned long flags;
372 unsigned long intr; 369 unsigned long intr;
373 unsigned long value; 370 unsigned long value;
374 static char pciirqflag; 371 static char pciirqflag;
@@ -401,10 +398,7 @@ int msp_pcibios_config_access(unsigned char access_type,
401 } 398 }
402 399
403#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 400#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
404 local_irq_save(flags);
405 vpe_status = dvpe(); 401 vpe_status = dvpe();
406#else
407 spin_lock_irqsave(&bpci_lock, flags);
408#endif 402#endif
409 403
410 /* 404 /*
@@ -457,9 +451,6 @@ int msp_pcibios_config_access(unsigned char access_type,
457 451
458#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 452#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
459 evpe(vpe_status); 453 evpe(vpe_status);
460 local_irq_restore(flags);
461#else
462 spin_unlock_irqrestore(&bpci_lock, flags);
463#endif 454#endif
464 455
465 return -1; 456 return -1;
@@ -467,9 +458,6 @@ int msp_pcibios_config_access(unsigned char access_type,
467 458
468#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 459#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
469 evpe(vpe_status); 460 evpe(vpe_status);
470 local_irq_restore(flags);
471#else
472 spin_unlock_irqrestore(&bpci_lock, flags);
473#endif 461#endif
474 462
475 return PCIBIOS_SUCCESSFUL; 463 return PCIBIOS_SUCCESSFUL;
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
new file mode 100644
index 000000000000..bd2b3b60da83
--- /dev/null
+++ b/arch/mips/pci/pci-ar2315.c
@@ -0,0 +1,511 @@
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (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, see <http://www.gnu.org/licenses/>.
14 */
15
16/**
17 * Both AR2315 and AR2316 chips have PCI interface unit, which supports DMA
18 * and interrupt. PCI interface supports MMIO access method, but does not
19 * seem to support I/O ports.
20 *
21 * Read/write operation in the region 0x80000000-0xBFFFFFFF causes
22 * a memory read/write command on the PCI bus. 30 LSBs of address on
23 * the bus are taken from memory read/write request and 2 MSBs are
24 * determined by PCI unit configuration.
25 *
26 * To work with the configuration space instead of memory is necessary set
27 * the CFG_SEL bit in the PCI_MISC_CONFIG register.
28 *
29 * Devices on the bus can perform DMA requests via chip BAR1. PCI host
30 * controller BARs are programmend as if an external device is programmed.
31 * Which means that during configuration, IDSEL pin of the chip should be
32 * asserted.
33 *
34 * We know (and support) only one board that uses the PCI interface -
35 * Fonera 2.0g (FON2202). It has a USB EHCI controller connected to the
36 * AR2315 PCI bus. IDSEL pin of USB controller is connected to AD[13] line
37 * and IDSEL pin of AR2315 is connected to AD[16] line.
38 */
39
40#include <linux/types.h>
41#include <linux/pci.h>
42#include <linux/platform_device.h>
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/mm.h>
46#include <linux/delay.h>
47#include <linux/bitops.h>
48#include <linux/irq.h>
49#include <linux/irqdomain.h>
50#include <linux/io.h>
51#include <asm/paccess.h>
52
53/*
54 * PCI Bus Interface Registers
55 */
56#define AR2315_PCI_1MS_REG 0x0008
57
58#define AR2315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */
59
60#define AR2315_PCI_MISC_CONFIG 0x000c
61
62#define AR2315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */
63#define AR2315_PCIMISC_CFG_SEL 0x00000002 /* Mem or Config cycles */
64#define AR2315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */
65#define AR2315_PCIMISC_RST_MODE 0x00000030
66#define AR2315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */
67#define AR2315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */
68#define AR2315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */
69#define AR2315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */
70#define AR2315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */
71#define AR2315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */
72#define AR2315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */
73#define AR2315_PCICACHE_DIS 0x00001000 /* PCI external access cache
74 * disable */
75
76#define AR2315_PCI_OUT_TSTAMP 0x0010
77
78#define AR2315_PCI_UNCACHE_CFG 0x0014
79
80#define AR2315_PCI_IN_EN 0x0100
81
82#define AR2315_PCI_IN_EN0 0x01 /* Enable chain 0 */
83#define AR2315_PCI_IN_EN1 0x02 /* Enable chain 1 */
84#define AR2315_PCI_IN_EN2 0x04 /* Enable chain 2 */
85#define AR2315_PCI_IN_EN3 0x08 /* Enable chain 3 */
86
87#define AR2315_PCI_IN_DIS 0x0104
88
89#define AR2315_PCI_IN_DIS0 0x01 /* Disable chain 0 */
90#define AR2315_PCI_IN_DIS1 0x02 /* Disable chain 1 */
91#define AR2315_PCI_IN_DIS2 0x04 /* Disable chain 2 */
92#define AR2315_PCI_IN_DIS3 0x08 /* Disable chain 3 */
93
94#define AR2315_PCI_IN_PTR 0x0200
95
96#define AR2315_PCI_OUT_EN 0x0400
97
98#define AR2315_PCI_OUT_EN0 0x01 /* Enable chain 0 */
99
100#define AR2315_PCI_OUT_DIS 0x0404
101
102#define AR2315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */
103
104#define AR2315_PCI_OUT_PTR 0x0408
105
106/* PCI interrupt status (write one to clear) */
107#define AR2315_PCI_ISR 0x0500
108
109#define AR2315_PCI_INT_TX 0x00000001 /* Desc In Completed */
110#define AR2315_PCI_INT_TXOK 0x00000002 /* Desc In OK */
111#define AR2315_PCI_INT_TXERR 0x00000004 /* Desc In ERR */
112#define AR2315_PCI_INT_TXEOL 0x00000008 /* Desc In End-of-List */
113#define AR2315_PCI_INT_RX 0x00000010 /* Desc Out Completed */
114#define AR2315_PCI_INT_RXOK 0x00000020 /* Desc Out OK */
115#define AR2315_PCI_INT_RXERR 0x00000040 /* Desc Out ERR */
116#define AR2315_PCI_INT_RXEOL 0x00000080 /* Desc Out EOL */
117#define AR2315_PCI_INT_TXOOD 0x00000200 /* Desc In Out-of-Desc */
118#define AR2315_PCI_INT_DESCMASK 0x0000FFFF /* Desc Mask */
119#define AR2315_PCI_INT_EXT 0x02000000 /* Extern PCI INTA */
120#define AR2315_PCI_INT_ABORT 0x04000000 /* PCI bus abort event */
121
122/* PCI interrupt mask */
123#define AR2315_PCI_IMR 0x0504
124
125/* Global PCI interrupt enable */
126#define AR2315_PCI_IER 0x0508
127
128#define AR2315_PCI_IER_DISABLE 0x00 /* disable pci interrupts */
129#define AR2315_PCI_IER_ENABLE 0x01 /* enable pci interrupts */
130
131#define AR2315_PCI_HOST_IN_EN 0x0800
132#define AR2315_PCI_HOST_IN_DIS 0x0804
133#define AR2315_PCI_HOST_IN_PTR 0x0810
134#define AR2315_PCI_HOST_OUT_EN 0x0900
135#define AR2315_PCI_HOST_OUT_DIS 0x0904
136#define AR2315_PCI_HOST_OUT_PTR 0x0908
137
138/*
139 * PCI interrupts, which share IP5
140 * Keep ordered according to AR2315_PCI_INT_XXX bits
141 */
142#define AR2315_PCI_IRQ_EXT 25
143#define AR2315_PCI_IRQ_ABORT 26
144#define AR2315_PCI_IRQ_COUNT 27
145
146/* Arbitrary size of memory region to access the configuration space */
147#define AR2315_PCI_CFG_SIZE 0x00100000
148
149#define AR2315_PCI_HOST_SLOT 3
150#define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS)
151
152/* ??? access BAR */
153#define AR2315_PCI_HOST_MBAR0 0x10000000
154/* RAM access BAR */
155#define AR2315_PCI_HOST_MBAR1 AR2315_PCI_HOST_SDRAM_BASEADDR
156/* ??? access BAR */
157#define AR2315_PCI_HOST_MBAR2 0x30000000
158
159struct ar2315_pci_ctrl {
160 void __iomem *cfg_mem;
161 void __iomem *mmr_mem;
162 unsigned irq;
163 unsigned irq_ext;
164 struct irq_domain *domain;
165 struct pci_controller pci_ctrl;
166 struct resource mem_res;
167 struct resource io_res;
168};
169
170static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus)
171{
172 struct pci_controller *hose = bus->sysdata;
173
174 return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl);
175}
176
177static inline u32 ar2315_pci_reg_read(struct ar2315_pci_ctrl *apc, u32 reg)
178{
179 return __raw_readl(apc->mmr_mem + reg);
180}
181
182static inline void ar2315_pci_reg_write(struct ar2315_pci_ctrl *apc, u32 reg,
183 u32 val)
184{
185 __raw_writel(val, apc->mmr_mem + reg);
186}
187
188static inline void ar2315_pci_reg_mask(struct ar2315_pci_ctrl *apc, u32 reg,
189 u32 mask, u32 val)
190{
191 u32 ret = ar2315_pci_reg_read(apc, reg);
192
193 ret &= ~mask;
194 ret |= val;
195 ar2315_pci_reg_write(apc, reg, ret);
196}
197
198static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn,
199 int where, int size, u32 *ptr, bool write)
200{
201 int func = PCI_FUNC(devfn);
202 int dev = PCI_SLOT(devfn);
203 u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3);
204 u32 mask = 0xffffffff >> 8 * (4 - size);
205 u32 sh = (where & 3) * 8;
206 u32 value, isr;
207
208 /* Prevent access past the remapped area */
209 if (addr >= AR2315_PCI_CFG_SIZE || dev > 18)
210 return PCIBIOS_DEVICE_NOT_FOUND;
211
212 /* Clear pending errors */
213 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT);
214 /* Select Configuration access */
215 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, 0,
216 AR2315_PCIMISC_CFG_SEL);
217
218 mb(); /* PCI must see space change before we begin */
219
220 value = __raw_readl(apc->cfg_mem + addr);
221
222 isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR);
223
224 if (isr & AR2315_PCI_INT_ABORT)
225 goto exit_err;
226
227 if (write) {
228 value = (value & ~(mask << sh)) | *ptr << sh;
229 __raw_writel(value, apc->cfg_mem + addr);
230 isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR);
231 if (isr & AR2315_PCI_INT_ABORT)
232 goto exit_err;
233 } else {
234 *ptr = (value >> sh) & mask;
235 }
236
237 goto exit;
238
239exit_err:
240 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT);
241 if (!write)
242 *ptr = 0xffffffff;
243
244exit:
245 /* Select Memory access */
246 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL,
247 0);
248
249 return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND :
250 PCIBIOS_SUCCESSFUL;
251}
252
253static inline int ar2315_pci_local_cfg_rd(struct ar2315_pci_ctrl *apc,
254 unsigned devfn, int where, u32 *val)
255{
256 return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), val,
257 false);
258}
259
260static inline int ar2315_pci_local_cfg_wr(struct ar2315_pci_ctrl *apc,
261 unsigned devfn, int where, u32 val)
262{
263 return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), &val,
264 true);
265}
266
267static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where,
268 int size, u32 *value)
269{
270 struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus);
271
272 if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT)
273 return PCIBIOS_DEVICE_NOT_FOUND;
274
275 return ar2315_pci_cfg_access(apc, devfn, where, size, value, false);
276}
277
278static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where,
279 int size, u32 value)
280{
281 struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus);
282
283 if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT)
284 return PCIBIOS_DEVICE_NOT_FOUND;
285
286 return ar2315_pci_cfg_access(apc, devfn, where, size, &value, true);
287}
288
289static struct pci_ops ar2315_pci_ops = {
290 .read = ar2315_pci_cfg_read,
291 .write = ar2315_pci_cfg_write,
292};
293
294static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc)
295{
296 unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0);
297 int res;
298 u32 id;
299
300 res = ar2315_pci_local_cfg_rd(apc, devfn, PCI_VENDOR_ID, &id);
301 if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID)
302 return -ENODEV;
303
304 /* Program MBARs */
305 ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_0,
306 AR2315_PCI_HOST_MBAR0);
307 ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_1,
308 AR2315_PCI_HOST_MBAR1);
309 ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_2,
310 AR2315_PCI_HOST_MBAR2);
311
312 /* Run */
313 ar2315_pci_local_cfg_wr(apc, devfn, PCI_COMMAND, PCI_COMMAND_MEMORY |
314 PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL |
315 PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
316 PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
317
318 return 0;
319}
320
321static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc)
322{
323 struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq);
324 u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) &
325 ar2315_pci_reg_read(apc, AR2315_PCI_IMR);
326 unsigned pci_irq = 0;
327
328 if (pending)
329 pci_irq = irq_find_mapping(apc->domain, __ffs(pending));
330
331 if (pci_irq)
332 generic_handle_irq(pci_irq);
333 else
334 spurious_interrupt();
335}
336
337static void ar2315_pci_irq_mask(struct irq_data *d)
338{
339 struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d);
340
341 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, BIT(d->hwirq), 0);
342}
343
344static void ar2315_pci_irq_mask_ack(struct irq_data *d)
345{
346 struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d);
347 u32 m = BIT(d->hwirq);
348
349 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0);
350 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, m);
351}
352
353static void ar2315_pci_irq_unmask(struct irq_data *d)
354{
355 struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d);
356
357 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, 0, BIT(d->hwirq));
358}
359
360static struct irq_chip ar2315_pci_irq_chip = {
361 .name = "AR2315-PCI",
362 .irq_mask = ar2315_pci_irq_mask,
363 .irq_mask_ack = ar2315_pci_irq_mask_ack,
364 .irq_unmask = ar2315_pci_irq_unmask,
365};
366
367static int ar2315_pci_irq_map(struct irq_domain *d, unsigned irq,
368 irq_hw_number_t hw)
369{
370 irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip, handle_level_irq);
371 irq_set_chip_data(irq, d->host_data);
372 return 0;
373}
374
375static struct irq_domain_ops ar2315_pci_irq_domain_ops = {
376 .map = ar2315_pci_irq_map,
377};
378
379static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc)
380{
381 ar2315_pci_reg_mask(apc, AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0);
382 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT |
383 AR2315_PCI_INT_EXT), 0);
384
385 apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT);
386
387 irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler);
388 irq_set_handler_data(apc->irq, apc);
389
390 /* Clear any pending Abort or external Interrupts
391 * and enable interrupt processing */
392 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT |
393 AR2315_PCI_INT_EXT);
394 ar2315_pci_reg_mask(apc, AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE);
395}
396
397static int ar2315_pci_probe(struct platform_device *pdev)
398{
399 struct ar2315_pci_ctrl *apc;
400 struct device *dev = &pdev->dev;
401 struct resource *res;
402 int irq, err;
403
404 apc = devm_kzalloc(dev, sizeof(*apc), GFP_KERNEL);
405 if (!apc)
406 return -ENOMEM;
407
408 irq = platform_get_irq(pdev, 0);
409 if (irq < 0)
410 return -EINVAL;
411 apc->irq = irq;
412
413 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
414 "ar2315-pci-ctrl");
415 apc->mmr_mem = devm_ioremap_resource(dev, res);
416 if (IS_ERR(apc->mmr_mem))
417 return PTR_ERR(apc->mmr_mem);
418
419 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
420 "ar2315-pci-ext");
421 if (!res)
422 return -EINVAL;
423
424 apc->mem_res.name = "AR2315 PCI mem space";
425 apc->mem_res.parent = res;
426 apc->mem_res.start = res->start;
427 apc->mem_res.end = res->end;
428 apc->mem_res.flags = IORESOURCE_MEM;
429
430 /* Remap PCI config space */
431 apc->cfg_mem = devm_ioremap_nocache(dev, res->start,
432 AR2315_PCI_CFG_SIZE);
433 if (!apc->cfg_mem) {
434 dev_err(dev, "failed to remap PCI config space\n");
435 return -ENOMEM;
436 }
437
438 /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */
439 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG,
440 AR2315_PCIMISC_RST_MODE,
441 AR2315_PCIRST_LOW);
442 msleep(100);
443
444 /* Bring the PCI out of reset */
445 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG,
446 AR2315_PCIMISC_RST_MODE,
447 AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8);
448
449 ar2315_pci_reg_write(apc, AR2315_PCI_UNCACHE_CFG,
450 0x1E | /* 1GB uncached */
451 (1 << 5) | /* Enable uncached */
452 (0x2 << 30) /* Base: 0x80000000 */);
453 ar2315_pci_reg_read(apc, AR2315_PCI_UNCACHE_CFG);
454
455 msleep(500);
456
457 err = ar2315_pci_host_setup(apc);
458 if (err)
459 return err;
460
461 apc->domain = irq_domain_add_linear(NULL, AR2315_PCI_IRQ_COUNT,
462 &ar2315_pci_irq_domain_ops, apc);
463 if (!apc->domain) {
464 dev_err(dev, "failed to add IRQ domain\n");
465 return -ENOMEM;
466 }
467
468 ar2315_pci_irq_init(apc);
469
470 /* PCI controller does not support I/O ports */
471 apc->io_res.name = "AR2315 IO space";
472 apc->io_res.start = 0;
473 apc->io_res.end = 0;
474 apc->io_res.flags = IORESOURCE_IO,
475
476 apc->pci_ctrl.pci_ops = &ar2315_pci_ops;
477 apc->pci_ctrl.mem_resource = &apc->mem_res,
478 apc->pci_ctrl.io_resource = &apc->io_res,
479
480 register_pci_controller(&apc->pci_ctrl);
481
482 dev_info(dev, "register PCI controller\n");
483
484 return 0;
485}
486
487static struct platform_driver ar2315_pci_driver = {
488 .probe = ar2315_pci_probe,
489 .driver = {
490 .name = "ar2315-pci",
491 .owner = THIS_MODULE,
492 },
493};
494
495static int __init ar2315_pci_init(void)
496{
497 return platform_driver_register(&ar2315_pci_driver);
498}
499arch_initcall(ar2315_pci_init);
500
501int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
502{
503 struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(dev->bus);
504
505 return slot ? 0 : apc->irq_ext;
506}
507
508int pcibios_plat_dev_init(struct pci_dev *dev)
509{
510 return 0;
511}
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c
index d471a26dd5f8..2b534aea20e4 100644
--- a/arch/mips/pci/pci-ar71xx.c
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -50,7 +50,6 @@
50 50
51struct ar71xx_pci_controller { 51struct ar71xx_pci_controller {
52 void __iomem *cfg_base; 52 void __iomem *cfg_base;
53 spinlock_t lock;
54 int irq; 53 int irq;
55 int irq_base; 54 int irq_base;
56 struct pci_controller pci_ctrl; 55 struct pci_controller pci_ctrl;
@@ -182,7 +181,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
182{ 181{
183 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); 182 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
184 void __iomem *base = apc->cfg_base; 183 void __iomem *base = apc->cfg_base;
185 unsigned long flags;
186 u32 data; 184 u32 data;
187 int err; 185 int err;
188 int ret; 186 int ret;
@@ -190,8 +188,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
190 ret = PCIBIOS_SUCCESSFUL; 188 ret = PCIBIOS_SUCCESSFUL;
191 data = ~0; 189 data = ~0;
192 190
193 spin_lock_irqsave(&apc->lock, flags);
194
195 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, 191 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
196 AR71XX_PCI_CFG_CMD_READ); 192 AR71XX_PCI_CFG_CMD_READ);
197 if (err) 193 if (err)
@@ -199,8 +195,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
199 else 195 else
200 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); 196 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA);
201 197
202 spin_unlock_irqrestore(&apc->lock, flags);
203
204 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; 198 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7];
205 199
206 return ret; 200 return ret;
@@ -211,15 +205,12 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
211{ 205{
212 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); 206 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
213 void __iomem *base = apc->cfg_base; 207 void __iomem *base = apc->cfg_base;
214 unsigned long flags;
215 int err; 208 int err;
216 int ret; 209 int ret;
217 210
218 value = value << (8 * (where & 3)); 211 value = value << (8 * (where & 3));
219 ret = PCIBIOS_SUCCESSFUL; 212 ret = PCIBIOS_SUCCESSFUL;
220 213
221 spin_lock_irqsave(&apc->lock, flags);
222
223 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, 214 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
224 AR71XX_PCI_CFG_CMD_WRITE); 215 AR71XX_PCI_CFG_CMD_WRITE);
225 if (err) 216 if (err)
@@ -227,8 +218,6 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
227 else 218 else
228 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); 219 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA);
229 220
230 spin_unlock_irqrestore(&apc->lock, flags);
231
232 return ret; 221 return ret;
233} 222}
234 223
@@ -360,8 +349,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev)
360 if (!apc) 349 if (!apc)
361 return -ENOMEM; 350 return -ENOMEM;
362 351
363 spin_lock_init(&apc->lock);
364
365 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); 352 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
366 apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); 353 apc->cfg_base = devm_ioremap_resource(&pdev->dev, res);
367 if (IS_ERR(apc->cfg_base)) 354 if (IS_ERR(apc->cfg_base))
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
index 785b2659b519..b7a6fcbb8852 100644
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -9,7 +9,6 @@
9 * by the Free Software Foundation. 9 * by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/spinlock.h>
13#include <linux/irq.h> 12#include <linux/irq.h>
14#include <linux/pci.h> 13#include <linux/pci.h>
15#include <linux/module.h> 14#include <linux/module.h>
@@ -48,8 +47,6 @@ struct ar724x_pci_controller {
48 bool bar0_is_cached; 47 bool bar0_is_cached;
49 u32 bar0_value; 48 u32 bar0_value;
50 49
51 spinlock_t lock;
52
53 struct pci_controller pci_controller; 50 struct pci_controller pci_controller;
54 struct resource io_res; 51 struct resource io_res;
55 struct resource mem_res; 52 struct resource mem_res;
@@ -75,7 +72,6 @@ pci_bus_to_ar724x_controller(struct pci_bus *bus)
75static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, 72static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
76 int where, int size, u32 value) 73 int where, int size, u32 value)
77{ 74{
78 unsigned long flags;
79 void __iomem *base; 75 void __iomem *base;
80 u32 data; 76 u32 data;
81 int s; 77 int s;
@@ -86,8 +82,6 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
86 return PCIBIOS_DEVICE_NOT_FOUND; 82 return PCIBIOS_DEVICE_NOT_FOUND;
87 83
88 base = apc->crp_base; 84 base = apc->crp_base;
89
90 spin_lock_irqsave(&apc->lock, flags);
91 data = __raw_readl(base + (where & ~3)); 85 data = __raw_readl(base + (where & ~3));
92 86
93 switch (size) { 87 switch (size) {
@@ -105,14 +99,12 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
105 data = value; 99 data = value;
106 break; 100 break;
107 default: 101 default:
108 spin_unlock_irqrestore(&apc->lock, flags);
109 return PCIBIOS_BAD_REGISTER_NUMBER; 102 return PCIBIOS_BAD_REGISTER_NUMBER;
110 } 103 }
111 104
112 __raw_writel(data, base + (where & ~3)); 105 __raw_writel(data, base + (where & ~3));
113 /* flush write */ 106 /* flush write */
114 __raw_readl(base + (where & ~3)); 107 __raw_readl(base + (where & ~3));
115 spin_unlock_irqrestore(&apc->lock, flags);
116 108
117 return PCIBIOS_SUCCESSFUL; 109 return PCIBIOS_SUCCESSFUL;
118} 110}
@@ -121,7 +113,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
121 int size, uint32_t *value) 113 int size, uint32_t *value)
122{ 114{
123 struct ar724x_pci_controller *apc; 115 struct ar724x_pci_controller *apc;
124 unsigned long flags;
125 void __iomem *base; 116 void __iomem *base;
126 u32 data; 117 u32 data;
127 118
@@ -133,8 +124,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
133 return PCIBIOS_DEVICE_NOT_FOUND; 124 return PCIBIOS_DEVICE_NOT_FOUND;
134 125
135 base = apc->devcfg_base; 126 base = apc->devcfg_base;
136
137 spin_lock_irqsave(&apc->lock, flags);
138 data = __raw_readl(base + (where & ~3)); 127 data = __raw_readl(base + (where & ~3));
139 128
140 switch (size) { 129 switch (size) {
@@ -153,13 +142,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
153 case 4: 142 case 4:
154 break; 143 break;
155 default: 144 default:
156 spin_unlock_irqrestore(&apc->lock, flags);
157
158 return PCIBIOS_BAD_REGISTER_NUMBER; 145 return PCIBIOS_BAD_REGISTER_NUMBER;
159 } 146 }
160 147
161 spin_unlock_irqrestore(&apc->lock, flags);
162
163 if (where == PCI_BASE_ADDRESS_0 && size == 4 && 148 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
164 apc->bar0_is_cached) { 149 apc->bar0_is_cached) {
165 /* use the cached value */ 150 /* use the cached value */
@@ -175,7 +160,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
175 int size, uint32_t value) 160 int size, uint32_t value)
176{ 161{
177 struct ar724x_pci_controller *apc; 162 struct ar724x_pci_controller *apc;
178 unsigned long flags;
179 void __iomem *base; 163 void __iomem *base;
180 u32 data; 164 u32 data;
181 int s; 165 int s;
@@ -209,8 +193,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
209 } 193 }
210 194
211 base = apc->devcfg_base; 195 base = apc->devcfg_base;
212
213 spin_lock_irqsave(&apc->lock, flags);
214 data = __raw_readl(base + (where & ~3)); 196 data = __raw_readl(base + (where & ~3));
215 197
216 switch (size) { 198 switch (size) {
@@ -228,15 +210,12 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
228 data = value; 210 data = value;
229 break; 211 break;
230 default: 212 default:
231 spin_unlock_irqrestore(&apc->lock, flags);
232
233 return PCIBIOS_BAD_REGISTER_NUMBER; 213 return PCIBIOS_BAD_REGISTER_NUMBER;
234 } 214 }
235 215
236 __raw_writel(data, base + (where & ~3)); 216 __raw_writel(data, base + (where & ~3));
237 /* flush write */ 217 /* flush write */
238 __raw_readl(base + (where & ~3)); 218 __raw_readl(base + (where & ~3));
239 spin_unlock_irqrestore(&apc->lock, flags);
240 219
241 return PCIBIOS_SUCCESSFUL; 220 return PCIBIOS_SUCCESSFUL;
242} 221}
@@ -380,8 +359,6 @@ static int ar724x_pci_probe(struct platform_device *pdev)
380 if (apc->irq < 0) 359 if (apc->irq < 0)
381 return -EINVAL; 360 return -EINVAL;
382 361
383 spin_lock_init(&apc->lock);
384
385 res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); 362 res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
386 if (!res) 363 if (!res)
387 return -EINVAL; 364 return -EINVAL;
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index 59cccd95688b..d07e04121cc6 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -708,7 +708,7 @@ static int __init octeon_pci_setup(void)
708 708
709 if (IS_ERR(platform_device_register_simple("octeon_pci_edac", 709 if (IS_ERR(platform_device_register_simple("octeon_pci_edac",
710 -1, NULL, 0))) 710 -1, NULL, 0)))
711 pr_err("Registation of co_pci_edac failed!\n"); 711 pr_err("Registration of co_pci_edac failed!\n");
712 712
713 octeon_pci_dma_init(); 713 octeon_pci_dma_init();
714 714
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c
new file mode 100644
index 000000000000..a4574947e698
--- /dev/null
+++ b/arch/mips/pci/pci-rt2880.c
@@ -0,0 +1,285 @@
1/*
2 * Ralink RT288x SoC PCI register definitions
3 *
4 * Copyright (C) 2009 John Crispin <blogic@openwrt.org>
5 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * Parts of this file are based on Ralink's 2.6.21 BSP
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/types.h>
15#include <linux/pci.h>
16#include <linux/io.h>
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/of_platform.h>
20#include <linux/of_irq.h>
21#include <linux/of_pci.h>
22
23#include <asm/mach-ralink/rt288x.h>
24
25#define RT2880_PCI_BASE 0x00440000
26#define RT288X_CPU_IRQ_PCI 4
27
28#define RT2880_PCI_MEM_BASE 0x20000000
29#define RT2880_PCI_MEM_SIZE 0x10000000
30#define RT2880_PCI_IO_BASE 0x00460000
31#define RT2880_PCI_IO_SIZE 0x00010000
32
33#define RT2880_PCI_REG_PCICFG_ADDR 0x00
34#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c
35#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10
36#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18
37#define RT2880_PCI_REG_CONFIG_ADDR 0x20
38#define RT2880_PCI_REG_CONFIG_DATA 0x24
39#define RT2880_PCI_REG_MEMBASE 0x28
40#define RT2880_PCI_REG_IOBASE 0x2c
41#define RT2880_PCI_REG_ID 0x30
42#define RT2880_PCI_REG_CLASS 0x34
43#define RT2880_PCI_REG_SUBID 0x38
44#define RT2880_PCI_REG_ARBCTL 0x80
45
46static void __iomem *rt2880_pci_base;
47static DEFINE_SPINLOCK(rt2880_pci_lock);
48
49static u32 rt2880_pci_reg_read(u32 reg)
50{
51 return readl(rt2880_pci_base + reg);
52}
53
54static void rt2880_pci_reg_write(u32 val, u32 reg)
55{
56 writel(val, rt2880_pci_base + reg);
57}
58
59static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
60 unsigned int func, unsigned int where)
61{
62 return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
63 0x80000000);
64}
65
66static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn,
67 int where, int size, u32 *val)
68{
69 unsigned long flags;
70 u32 address;
71 u32 data;
72
73 address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
74 PCI_FUNC(devfn), where);
75
76 spin_lock_irqsave(&rt2880_pci_lock, flags);
77 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
78 data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
79 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
80
81 switch (size) {
82 case 1:
83 *val = (data >> ((where & 3) << 3)) & 0xff;
84 break;
85 case 2:
86 *val = (data >> ((where & 3) << 3)) & 0xffff;
87 break;
88 case 4:
89 *val = data;
90 break;
91 }
92
93 return PCIBIOS_SUCCESSFUL;
94}
95
96static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn,
97 int where, int size, u32 val)
98{
99 unsigned long flags;
100 u32 address;
101 u32 data;
102
103 address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
104 PCI_FUNC(devfn), where);
105
106 spin_lock_irqsave(&rt2880_pci_lock, flags);
107 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
108 data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
109
110 switch (size) {
111 case 1:
112 data = (data & ~(0xff << ((where & 3) << 3))) |
113 (val << ((where & 3) << 3));
114 break;
115 case 2:
116 data = (data & ~(0xffff << ((where & 3) << 3))) |
117 (val << ((where & 3) << 3));
118 break;
119 case 4:
120 data = val;
121 break;
122 }
123
124 rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA);
125 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
126
127 return PCIBIOS_SUCCESSFUL;
128}
129
130static struct pci_ops rt2880_pci_ops = {
131 .read = rt2880_pci_config_read,
132 .write = rt2880_pci_config_write,
133};
134
135static struct resource rt2880_pci_mem_resource = {
136 .name = "PCI MEM space",
137 .start = RT2880_PCI_MEM_BASE,
138 .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1,
139 .flags = IORESOURCE_MEM,
140};
141
142static struct resource rt2880_pci_io_resource = {
143 .name = "PCI IO space",
144 .start = RT2880_PCI_IO_BASE,
145 .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1,
146 .flags = IORESOURCE_IO,
147};
148
149static struct pci_controller rt2880_pci_controller = {
150 .pci_ops = &rt2880_pci_ops,
151 .mem_resource = &rt2880_pci_mem_resource,
152 .io_resource = &rt2880_pci_io_resource,
153};
154
155static inline u32 rt2880_pci_read_u32(unsigned long reg)
156{
157 unsigned long flags;
158 u32 address;
159 u32 ret;
160
161 address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
162
163 spin_lock_irqsave(&rt2880_pci_lock, flags);
164 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
165 ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
166 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
167
168 return ret;
169}
170
171static inline void rt2880_pci_write_u32(unsigned long reg, u32 val)
172{
173 unsigned long flags;
174 u32 address;
175
176 address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
177
178 spin_lock_irqsave(&rt2880_pci_lock, flags);
179 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
180 rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA);
181 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
182}
183
184int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
185{
186 u16 cmd;
187 int irq = -1;
188
189 if (dev->bus->number != 0)
190 return irq;
191
192 switch (PCI_SLOT(dev->devfn)) {
193 case 0x00:
194 rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
195 (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
196 break;
197 case 0x11:
198 irq = RT288X_CPU_IRQ_PCI;
199 break;
200 default:
201 pr_err("%s:%s[%d] trying to alloc unknown pci irq\n",
202 __FILE__, __func__, __LINE__);
203 BUG();
204 break;
205 }
206
207 pci_write_config_byte((struct pci_dev *) dev,
208 PCI_CACHE_LINE_SIZE, 0x14);
209 pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF);
210 pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd);
211 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
212 PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK |
213 PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY;
214 pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd);
215 pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE,
216 dev->irq);
217 return irq;
218}
219
220static int rt288x_pci_probe(struct platform_device *pdev)
221{
222 void __iomem *io_map_base;
223 int i;
224
225 rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
226
227 io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE);
228 rt2880_pci_controller.io_map_base = (unsigned long) io_map_base;
229 set_io_port_base((unsigned long) io_map_base);
230
231 ioport_resource.start = RT2880_PCI_IO_BASE;
232 ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
233
234 rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
235 for (i = 0; i < 0xfffff; i++)
236 ;
237
238 rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
239 rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
240 rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE);
241 rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE);
242 rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR);
243 rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID);
244 rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS);
245 rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID);
246 rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR);
247
248 rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
249 (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
250
251 register_pci_controller(&rt2880_pci_controller);
252 return 0;
253}
254
255int pcibios_plat_dev_init(struct pci_dev *dev)
256{
257 return 0;
258}
259
260static const struct of_device_id rt288x_pci_match[] = {
261 { .compatible = "ralink,rt288x-pci" },
262 {},
263};
264MODULE_DEVICE_TABLE(of, rt288x_pci_match);
265
266static struct platform_driver rt288x_pci_driver = {
267 .probe = rt288x_pci_probe,
268 .driver = {
269 .name = "rt288x-pci",
270 .owner = THIS_MODULE,
271 .of_match_table = rt288x_pci_match,
272 },
273};
274
275int __init pcibios_init(void)
276{
277 int ret = platform_driver_register(&rt288x_pci_driver);
278
279 if (ret)
280 pr_info("rt288x-pci: Error registering platform driver!");
281
282 return ret;
283}
284
285arch_initcall(pcibios_init);
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index 72919aeef42b..0bcc0b1cfddc 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -61,7 +61,6 @@
61 61
62struct rt3883_pci_controller { 62struct rt3883_pci_controller {
63 void __iomem *base; 63 void __iomem *base;
64 spinlock_t lock;
65 64
66 struct device_node *intc_of_node; 65 struct device_node *intc_of_node;
67 struct irq_domain *irq_domain; 66 struct irq_domain *irq_domain;
@@ -111,10 +110,8 @@ static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc,
111 110
112 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); 111 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
113 112
114 spin_lock_irqsave(&rpc->lock, flags);
115 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 113 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
116 ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 114 ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
117 spin_unlock_irqrestore(&rpc->lock, flags);
118 115
119 return ret; 116 return ret;
120} 117}
@@ -128,10 +125,8 @@ static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc,
128 125
129 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); 126 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
130 127
131 spin_lock_irqsave(&rpc->lock, flags);
132 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 128 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
133 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); 129 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);
134 spin_unlock_irqrestore(&rpc->lock, flags);
135} 130}
136 131
137static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 132static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
@@ -252,10 +247,8 @@ static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn,
252 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 247 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
253 PCI_FUNC(devfn), where); 248 PCI_FUNC(devfn), where);
254 249
255 spin_lock_irqsave(&rpc->lock, flags);
256 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 250 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
257 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 251 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
258 spin_unlock_irqrestore(&rpc->lock, flags);
259 252
260 switch (size) { 253 switch (size) {
261 case 1: 254 case 1:
@@ -288,7 +281,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
288 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 281 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
289 PCI_FUNC(devfn), where); 282 PCI_FUNC(devfn), where);
290 283
291 spin_lock_irqsave(&rpc->lock, flags);
292 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 284 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
293 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 285 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
294 286
@@ -307,7 +299,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
307 } 299 }
308 300
309 rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); 301 rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA);
310 spin_unlock_irqrestore(&rpc->lock, flags);
311 302
312 return PCIBIOS_SUCCESSFUL; 303 return PCIBIOS_SUCCESSFUL;
313} 304}
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c
index c10fbf2a19dc..cd8ed09c4f53 100644
--- a/arch/mips/pci/pci-tx4939.c
+++ b/arch/mips/pci/pci-tx4939.c
@@ -103,5 +103,5 @@ void __init tx4939_setup_pcierr_irq(void)
103 tx4927_pcierr_interrupt, 103 tx4927_pcierr_interrupt,
104 0, "PCI error", 104 0, "PCI error",
105 (void *)TX4939_PCIC_REG)) 105 (void *)TX4939_PCIC_REG))
106 pr_warning("Failed to request irq for PCIERR\n"); 106 pr_warn("Failed to request irq for PCIERR\n");
107} 107}
diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c
index 1c9897531660..ef620a4c82a5 100644
--- a/arch/mips/pmcs-msp71xx/msp_prom.c
+++ b/arch/mips/pmcs-msp71xx/msp_prom.c
@@ -295,7 +295,7 @@ char *prom_getenv(char *env_name)
295 295
296 while (*var) { 296 while (*var) {
297 if (strncmp(env_name, *var, i) == 0) { 297 if (strncmp(env_name, *var, i) == 0) {
298 return (*var + strlen(env_name) + 1); 298 return *var + strlen(env_name) + 1;
299 } 299 }
300 var++; 300 var++;
301 } 301 }
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 77e8a9620e18..b1c52ca580f9 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -16,6 +16,7 @@ choice
16 config SOC_RT288X 16 config SOC_RT288X
17 bool "RT288x" 17 bool "RT288x"
18 select MIPS_L1_CACHE_SHIFT_4 18 select MIPS_L1_CACHE_SHIFT_4
19 select HW_HAS_PCI
19 20
20 config SOC_RT305X 21 config SOC_RT305X
21 bool "RT305x" 22 bool "RT305x"
@@ -26,7 +27,7 @@ choice
26 select HW_HAS_PCI 27 select HW_HAS_PCI
27 28
28 config SOC_MT7620 29 config SOC_MT7620
29 bool "MT7620" 30 bool "MT7620/8"
30 31
31endchoice 32endchoice
32 33
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 2c09c8aa0ae2..a6c9d0061326 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -10,9 +10,13 @@ obj-y := prom.o of.o reset.o clk.o irq.o timer.o
10 10
11obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o 11obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
12 12
13obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
14
13obj-$(CONFIG_SOC_RT288X) += rt288x.o 15obj-$(CONFIG_SOC_RT288X) += rt288x.o
14obj-$(CONFIG_SOC_RT305X) += rt305x.o 16obj-$(CONFIG_SOC_RT305X) += rt305x.o
15obj-$(CONFIG_SOC_RT3883) += rt3883.o 17obj-$(CONFIG_SOC_RT3883) += rt3883.o
16obj-$(CONFIG_SOC_MT7620) += mt7620.o 18obj-$(CONFIG_SOC_MT7620) += mt7620.o
17 19
18obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 20obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
21
22obj-$(CONFIG_DEBUG_FS) += bootrom.o
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c
new file mode 100644
index 000000000000..5403468394fb
--- /dev/null
+++ b/arch/mips/ralink/bootrom.c
@@ -0,0 +1,48 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/debugfs.h>
10#include <linux/seq_file.h>
11
12#define BOOTROM_OFFSET 0x10118000
13#define BOOTROM_SIZE 0x8000
14
15static void __iomem *membase = (void __iomem *) KSEG1ADDR(BOOTROM_OFFSET);
16
17static int bootrom_show(struct seq_file *s, void *unused)
18{
19 seq_write(s, membase, BOOTROM_SIZE);
20
21 return 0;
22}
23
24static int bootrom_open(struct inode *inode, struct file *file)
25{
26 return single_open(file, bootrom_show, NULL);
27}
28
29static const struct file_operations bootrom_file_ops = {
30 .open = bootrom_open,
31 .read = seq_read,
32 .llseek = seq_lseek,
33 .release = single_release,
34};
35
36static int bootrom_setup(void)
37{
38 if (!debugfs_create_file("bootrom", 0444,
39 NULL, NULL, &bootrom_file_ops)) {
40 pr_err("Failed to create bootrom debugfs file\n");
41
42 return -EINVAL;
43 }
44
45 return 0;
46}
47
48postcore_initcall(bootrom_setup);
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
index 5d0983d47161..feb5a9bf98b4 100644
--- a/arch/mips/ralink/clk.c
+++ b/arch/mips/ralink/clk.c
@@ -56,6 +56,12 @@ unsigned long clk_get_rate(struct clk *clk)
56} 56}
57EXPORT_SYMBOL_GPL(clk_get_rate); 57EXPORT_SYMBOL_GPL(clk_get_rate);
58 58
59int clk_set_rate(struct clk *clk, unsigned long rate)
60{
61 return -1;
62}
63EXPORT_SYMBOL_GPL(clk_set_rate);
64
59void __init plat_time_init(void) 65void __init plat_time_init(void)
60{ 66{
61 struct clk *clk; 67 struct clk *clk;
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
index 42dfd6100a2d..8e7d8e618fb9 100644
--- a/arch/mips/ralink/common.h
+++ b/arch/mips/ralink/common.h
@@ -11,25 +11,6 @@
11 11
12#define RAMIPS_SYS_TYPE_LEN 32 12#define RAMIPS_SYS_TYPE_LEN 32
13 13
14struct ralink_pinmux_grp {
15 const char *name;
16 u32 mask;
17 int gpio_first;
18 int gpio_last;
19};
20
21struct ralink_pinmux {
22 struct ralink_pinmux_grp *mode;
23 struct ralink_pinmux_grp *uart;
24 int uart_shift;
25 u32 uart_mask;
26 void (*wdt_reset)(void);
27 struct ralink_pinmux_grp *pci;
28 int pci_shift;
29 u32 pci_mask;
30};
31extern struct ralink_pinmux rt_gpio_pinmux;
32
33struct ralink_soc_info { 14struct ralink_soc_info {
34 unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; 15 unsigned char sys_type[RAMIPS_SYS_TYPE_LEN];
35 unsigned char *compatible; 16 unsigned char *compatible;
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c
index b46d0419d09b..255d695ec8c6 100644
--- a/arch/mips/ralink/early_printk.c
+++ b/arch/mips/ralink/early_printk.c
@@ -12,21 +12,24 @@
12#include <asm/addrspace.h> 12#include <asm/addrspace.h>
13 13
14#ifdef CONFIG_SOC_RT288X 14#ifdef CONFIG_SOC_RT288X
15#define EARLY_UART_BASE 0x300c00 15#define EARLY_UART_BASE 0x300c00
16#define CHIPID_BASE 0x300004
17#elif defined(CONFIG_SOC_MT7621)
18#define EARLY_UART_BASE 0x1E000c00
19#define CHIPID_BASE 0x1E000004
16#else 20#else
17#define EARLY_UART_BASE 0x10000c00 21#define EARLY_UART_BASE 0x10000c00
22#define CHIPID_BASE 0x10000004
18#endif 23#endif
19 24
20#define UART_REG_RX 0x00 25#define MT7628_CHIP_NAME1 0x20203832
21#define UART_REG_TX 0x04 26
22#define UART_REG_IER 0x08 27#define UART_REG_TX 0x04
23#define UART_REG_IIR 0x0c 28#define UART_REG_LSR 0x14
24#define UART_REG_FCR 0x10 29#define UART_REG_LSR_RT2880 0x1c
25#define UART_REG_LCR 0x14
26#define UART_REG_MCR 0x18
27#define UART_REG_LSR 0x1c
28 30
29static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); 31static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
32static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE);
30 33
31static inline void uart_w32(u32 val, unsigned reg) 34static inline void uart_w32(u32 val, unsigned reg)
32{ 35{
@@ -38,11 +41,23 @@ static inline u32 uart_r32(unsigned reg)
38 return __raw_readl(uart_membase + reg); 41 return __raw_readl(uart_membase + reg);
39} 42}
40 43
44static inline int soc_is_mt7628(void)
45{
46 return IS_ENABLED(CONFIG_SOC_MT7620) &&
47 (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1);
48}
49
41void prom_putchar(unsigned char ch) 50void prom_putchar(unsigned char ch)
42{ 51{
43 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) 52 if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) {
44 ; 53 uart_w32(ch, UART_TX);
45 uart_w32(ch, UART_REG_TX); 54 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
46 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) 55 ;
47 ; 56 } else {
57 while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0)
58 ;
59 uart_w32(ch, UART_REG_TX);
60 while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0)
61 ;
62 }
48} 63}
diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c
new file mode 100644
index 000000000000..e20b02e3ae28
--- /dev/null
+++ b/arch/mips/ralink/ill_acc.c
@@ -0,0 +1,87 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/interrupt.h>
10#include <linux/of_platform.h>
11#include <linux/of_irq.h>
12
13#include <asm/mach-ralink/ralink_regs.h>
14
15#define REG_ILL_ACC_ADDR 0x10
16#define REG_ILL_ACC_TYPE 0x14
17
18#define ILL_INT_STATUS BIT(31)
19#define ILL_ACC_WRITE BIT(30)
20#define ILL_ACC_LEN_M 0xff
21#define ILL_ACC_OFF_M 0xf
22#define ILL_ACC_OFF_S 16
23#define ILL_ACC_ID_M 0x7
24#define ILL_ACC_ID_S 8
25
26#define DRV_NAME "ill_acc"
27
28static const char * const ill_acc_ids[] = {
29 "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb",
30};
31
32static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
33{
34 struct device *dev = (struct device *) _priv;
35 u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
36 u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
37
38 dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
39 (type & ILL_ACC_WRITE) ? ("write") : ("read"),
40 ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
41 addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
42 type & ILL_ACC_LEN_M);
43
44 rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE);
45
46 return IRQ_HANDLED;
47}
48
49static int __init ill_acc_of_setup(void)
50{
51 struct platform_device *pdev;
52 struct device_node *np;
53 int irq;
54
55 /* somehow this driver breaks on RT5350 */
56 if (of_machine_is_compatible("ralink,rt5350-soc"))
57 return -EINVAL;
58
59 np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
60 if (!np)
61 return -EINVAL;
62
63 pdev = of_find_device_by_node(np);
64 if (!pdev) {
65 pr_err("%s: failed to lookup pdev\n", np->name);
66 return -EINVAL;
67 }
68
69 irq = irq_of_parse_and_map(np, 0);
70 if (!irq) {
71 dev_err(&pdev->dev, "failed to get irq\n");
72 return -EINVAL;
73 }
74
75 if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
76 dev_err(&pdev->dev, "failed to request irq\n");
77 return -EINVAL;
78 }
79
80 rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
81
82 dev_info(&pdev->dev, "irq registered\n");
83
84 return 0;
85}
86
87arch_initcall(ill_acc_of_setup);
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
index 781b3d14a489..7cf91b92e9d1 100644
--- a/arch/mips/ralink/irq.c
+++ b/arch/mips/ralink/irq.c
@@ -20,14 +20,6 @@
20 20
21#include "common.h" 21#include "common.h"
22 22
23/* INTC register offsets */
24#define INTC_REG_STATUS0 0x00
25#define INTC_REG_STATUS1 0x04
26#define INTC_REG_TYPE 0x20
27#define INTC_REG_RAW_STATUS 0x30
28#define INTC_REG_ENABLE 0x34
29#define INTC_REG_DISABLE 0x38
30
31#define INTC_INT_GLOBAL BIT(31) 23#define INTC_INT_GLOBAL BIT(31)
32 24
33#define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) 25#define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2)
@@ -44,16 +36,36 @@
44 36
45#define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) 37#define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9)
46 38
39enum rt_intc_regs_enum {
40 INTC_REG_STATUS0 = 0,
41 INTC_REG_STATUS1,
42 INTC_REG_TYPE,
43 INTC_REG_RAW_STATUS,
44 INTC_REG_ENABLE,
45 INTC_REG_DISABLE,
46};
47
48static u32 rt_intc_regs[] = {
49 [INTC_REG_STATUS0] = 0x00,
50 [INTC_REG_STATUS1] = 0x04,
51 [INTC_REG_TYPE] = 0x20,
52 [INTC_REG_RAW_STATUS] = 0x30,
53 [INTC_REG_ENABLE] = 0x34,
54 [INTC_REG_DISABLE] = 0x38,
55};
56
47static void __iomem *rt_intc_membase; 57static void __iomem *rt_intc_membase;
48 58
59static int rt_perfcount_irq;
60
49static inline void rt_intc_w32(u32 val, unsigned reg) 61static inline void rt_intc_w32(u32 val, unsigned reg)
50{ 62{
51 __raw_writel(val, rt_intc_membase + reg); 63 __raw_writel(val, rt_intc_membase + rt_intc_regs[reg]);
52} 64}
53 65
54static inline u32 rt_intc_r32(unsigned reg) 66static inline u32 rt_intc_r32(unsigned reg)
55{ 67{
56 return __raw_readl(rt_intc_membase + reg); 68 return __raw_readl(rt_intc_membase + rt_intc_regs[reg]);
57} 69}
58 70
59static void ralink_intc_irq_unmask(struct irq_data *d) 71static void ralink_intc_irq_unmask(struct irq_data *d)
@@ -73,6 +85,11 @@ static struct irq_chip ralink_intc_irq_chip = {
73 .irq_mask_ack = ralink_intc_irq_mask, 85 .irq_mask_ack = ralink_intc_irq_mask,
74}; 86};
75 87
88int get_c0_perfcount_int(void)
89{
90 return rt_perfcount_irq;
91}
92
76unsigned int get_c0_compare_int(void) 93unsigned int get_c0_compare_int(void)
77{ 94{
78 return CP0_LEGACY_COMPARE_IRQ; 95 return CP0_LEGACY_COMPARE_IRQ;
@@ -134,6 +151,10 @@ static int __init intc_of_init(struct device_node *node,
134 struct irq_domain *domain; 151 struct irq_domain *domain;
135 int irq; 152 int irq;
136 153
154 if (!of_property_read_u32_array(node, "ralink,intc-registers",
155 rt_intc_regs, 6))
156 pr_info("intc: using register map from devicetree\n");
157
137 irq = irq_of_parse_and_map(node, 0); 158 irq = irq_of_parse_and_map(node, 0);
138 if (!irq) 159 if (!irq)
139 panic("Failed to get INTC IRQ"); 160 panic("Failed to get INTC IRQ");
@@ -167,13 +188,13 @@ static int __init intc_of_init(struct device_node *node,
167 irq_set_handler_data(irq, domain); 188 irq_set_handler_data(irq, domain);
168 189
169 /* tell the kernel which irq is used for performance monitoring */ 190 /* tell the kernel which irq is used for performance monitoring */
170 cp0_perfcount_irq = irq_create_mapping(domain, 9); 191 rt_perfcount_irq = irq_create_mapping(domain, 9);
171 192
172 return 0; 193 return 0;
173} 194}
174 195
175static struct of_device_id __initdata of_irq_ids[] = { 196static struct of_device_id __initdata of_irq_ids[] = {
176 { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, 197 { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
177 { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, 198 { .compatible = "ralink,rt2880-intc", .data = intc_of_init },
178 {}, 199 {},
179}; 200};
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
index a3ad56c2372d..2ea5ff6dc22e 100644
--- a/arch/mips/ralink/mt7620.c
+++ b/arch/mips/ralink/mt7620.c
@@ -17,124 +17,214 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/mt7620.h> 19#include <asm/mach-ralink/mt7620.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
24/* analog */
25#define PMU0_CFG 0x88
26#define PMU_SW_SET BIT(28)
27#define A_DCDC_EN BIT(24)
28#define A_SSC_PERI BIT(19)
29#define A_SSC_GEN BIT(18)
30#define A_SSC_M 0x3
31#define A_SSC_S 16
32#define A_DLY_M 0x7
33#define A_DLY_S 8
34#define A_VTUNE_M 0xff
35
36/* digital */
37#define PMU1_CFG 0x8C
38#define DIG_SW_SEL BIT(25)
39
40/* is this a MT7620 or a MT7628 */
41enum mt762x_soc_type mt762x_soc;
42
23/* does the board have sdram or ddram */ 43/* does the board have sdram or ddram */
24static int dram_type; 44static int dram_type;
25 45
26static struct ralink_pinmux_grp mode_mux[] = { 46static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) };
27 { 47static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
28 .name = "i2c", 48static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
29 .mask = MT7620_GPIO_MODE_I2C, 49static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 22, 2) };
30 .gpio_first = 1, 50static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
31 .gpio_last = 2, 51static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
32 }, { 52static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
33 .name = "spi", 53static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
34 .mask = MT7620_GPIO_MODE_SPI, 54static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
35 .gpio_first = 3, 55static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
36 .gpio_last = 6, 56static struct rt2880_pmx_func uartf_grp[] = {
37 }, { 57 FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8),
38 .name = "uartlite", 58 FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8),
39 .mask = MT7620_GPIO_MODE_UART1, 59 FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8),
40 .gpio_first = 15, 60 FUNC("i2s uartf", MT7620_GPIO_MODE_I2S_UARTF, 7, 8),
41 .gpio_last = 16, 61 FUNC("pcm gpio", MT7620_GPIO_MODE_PCM_GPIO, 11, 4),
42 }, { 62 FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4),
43 .name = "wdt", 63 FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4),
44 .mask = MT7620_GPIO_MODE_WDT, 64};
45 .gpio_first = 17, 65static struct rt2880_pmx_func wdt_grp[] = {
46 .gpio_last = 17, 66 FUNC("wdt rst", 0, 17, 1),
47 }, { 67 FUNC("wdt refclk", 0, 17, 1),
48 .name = "mdio", 68 };
49 .mask = MT7620_GPIO_MODE_MDIO, 69static struct rt2880_pmx_func pcie_rst_grp[] = {
50 .gpio_first = 22, 70 FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1),
51 .gpio_last = 23, 71 FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1)
52 }, { 72};
53 .name = "rgmii1", 73static struct rt2880_pmx_func nd_sd_grp[] = {
54 .mask = MT7620_GPIO_MODE_RGMII1, 74 FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15),
55 .gpio_first = 24, 75 FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15)
56 .gpio_last = 35, 76};
57 }, { 77
58 .name = "spi refclk", 78static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
59 .mask = MT7620_GPIO_MODE_SPI_REF_CLK, 79 GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C),
60 .gpio_first = 37, 80 GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK,
61 .gpio_last = 39, 81 MT7620_GPIO_MODE_UART0_SHIFT),
62 }, { 82 GRP("spi", spi_grp, 1, MT7620_GPIO_MODE_SPI),
63 .name = "jtag", 83 GRP("uartlite", uartlite_grp, 1, MT7620_GPIO_MODE_UART1),
64 .mask = MT7620_GPIO_MODE_JTAG, 84 GRP_G("wdt", wdt_grp, MT7620_GPIO_MODE_WDT_MASK,
65 .gpio_first = 40, 85 MT7620_GPIO_MODE_WDT_GPIO, MT7620_GPIO_MODE_WDT_SHIFT),
66 .gpio_last = 44, 86 GRP("mdio", mdio_grp, 1, MT7620_GPIO_MODE_MDIO),
67 }, { 87 GRP("rgmii1", rgmii1_grp, 1, MT7620_GPIO_MODE_RGMII1),
68 /* shared lines with jtag */ 88 GRP("spi refclk", refclk_grp, 1, MT7620_GPIO_MODE_SPI_REF_CLK),
69 .name = "ephy", 89 GRP_G("pcie", pcie_rst_grp, MT7620_GPIO_MODE_PCIE_MASK,
70 .mask = MT7620_GPIO_MODE_EPHY, 90 MT7620_GPIO_MODE_PCIE_GPIO, MT7620_GPIO_MODE_PCIE_SHIFT),
71 .gpio_first = 40, 91 GRP_G("nd_sd", nd_sd_grp, MT7620_GPIO_MODE_ND_SD_MASK,
72 .gpio_last = 44, 92 MT7620_GPIO_MODE_ND_SD_GPIO, MT7620_GPIO_MODE_ND_SD_SHIFT),
73 }, { 93 GRP("rgmii2", rgmii2_grp, 1, MT7620_GPIO_MODE_RGMII2),
74 .name = "nand", 94 GRP("wled", wled_grp, 1, MT7620_GPIO_MODE_WLED),
75 .mask = MT7620_GPIO_MODE_JTAG, 95 GRP("ephy", ephy_grp, 1, MT7620_GPIO_MODE_EPHY),
76 .gpio_first = 45, 96 GRP("pa", pa_grp, 1, MT7620_GPIO_MODE_PA),
77 .gpio_last = 59, 97 { 0 }
78 }, { 98};
79 .name = "rgmii2", 99
80 .mask = MT7620_GPIO_MODE_RGMII2, 100static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
81 .gpio_first = 60, 101 FUNC("sdcx", 3, 19, 1),
82 .gpio_last = 71, 102 FUNC("utif", 2, 19, 1),
83 }, { 103 FUNC("gpio", 1, 19, 1),
84 .name = "wled", 104 FUNC("pwm", 0, 19, 1),
85 .mask = MT7620_GPIO_MODE_WLED, 105};
86 .gpio_first = 72, 106
87 .gpio_last = 72, 107static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
88 }, {0} 108 FUNC("sdcx", 3, 18, 1),
109 FUNC("utif", 2, 18, 1),
110 FUNC("gpio", 1, 18, 1),
111 FUNC("pwm", 0, 18, 1),
112};
113
114static struct rt2880_pmx_func uart2_grp_mt7628[] = {
115 FUNC("sdcx", 3, 20, 2),
116 FUNC("pwm", 2, 20, 2),
117 FUNC("gpio", 1, 20, 2),
118 FUNC("uart", 0, 20, 2),
119};
120
121static struct rt2880_pmx_func uart1_grp_mt7628[] = {
122 FUNC("sdcx", 3, 45, 2),
123 FUNC("pwm", 2, 45, 2),
124 FUNC("gpio", 1, 45, 2),
125 FUNC("uart", 0, 45, 2),
126};
127
128static struct rt2880_pmx_func i2c_grp_mt7628[] = {
129 FUNC("-", 3, 4, 2),
130 FUNC("debug", 2, 4, 2),
131 FUNC("gpio", 1, 4, 2),
132 FUNC("i2c", 0, 4, 2),
133};
134
135static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
136static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
137static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) };
138static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
139
140static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
141 FUNC("jtag", 3, 22, 8),
142 FUNC("utif", 2, 22, 8),
143 FUNC("gpio", 1, 22, 8),
144 FUNC("sdcx", 0, 22, 8),
145};
146
147static struct rt2880_pmx_func uart0_grp_mt7628[] = {
148 FUNC("-", 3, 12, 2),
149 FUNC("-", 2, 12, 2),
150 FUNC("gpio", 1, 12, 2),
151 FUNC("uart", 0, 12, 2),
152};
153
154static struct rt2880_pmx_func i2s_grp_mt7628[] = {
155 FUNC("antenna", 3, 0, 4),
156 FUNC("pcm", 2, 0, 4),
157 FUNC("gpio", 1, 0, 4),
158 FUNC("i2s", 0, 0, 4),
159};
160
161static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
162 FUNC("-", 3, 6, 1),
163 FUNC("refclk", 2, 6, 1),
164 FUNC("gpio", 1, 6, 1),
165 FUNC("spi", 0, 6, 1),
166};
167
168static struct rt2880_pmx_func spis_grp_mt7628[] = {
169 FUNC("pwm", 3, 14, 4),
170 FUNC("util", 2, 14, 4),
171 FUNC("gpio", 1, 14, 4),
172 FUNC("spis", 0, 14, 4),
89}; 173};
90 174
91static struct ralink_pinmux_grp uart_mux[] = { 175static struct rt2880_pmx_func gpio_grp_mt7628[] = {
92 { 176 FUNC("pcie", 3, 11, 1),
93 .name = "uartf", 177 FUNC("refclk", 2, 11, 1),
94 .mask = MT7620_GPIO_MODE_UARTF, 178 FUNC("gpio", 1, 11, 1),
95 .gpio_first = 7, 179 FUNC("gpio", 0, 11, 1),
96 .gpio_last = 14,
97 }, {
98 .name = "pcm uartf",
99 .mask = MT7620_GPIO_MODE_PCM_UARTF,
100 .gpio_first = 7,
101 .gpio_last = 14,
102 }, {
103 .name = "pcm i2s",
104 .mask = MT7620_GPIO_MODE_PCM_I2S,
105 .gpio_first = 7,
106 .gpio_last = 14,
107 }, {
108 .name = "i2s uartf",
109 .mask = MT7620_GPIO_MODE_I2S_UARTF,
110 .gpio_first = 7,
111 .gpio_last = 14,
112 }, {
113 .name = "pcm gpio",
114 .mask = MT7620_GPIO_MODE_PCM_GPIO,
115 .gpio_first = 11,
116 .gpio_last = 14,
117 }, {
118 .name = "gpio uartf",
119 .mask = MT7620_GPIO_MODE_GPIO_UARTF,
120 .gpio_first = 7,
121 .gpio_last = 10,
122 }, {
123 .name = "gpio i2s",
124 .mask = MT7620_GPIO_MODE_GPIO_I2S,
125 .gpio_first = 7,
126 .gpio_last = 10,
127 }, {
128 .name = "gpio",
129 .mask = MT7620_GPIO_MODE_GPIO,
130 }, {0}
131}; 180};
132 181
133struct ralink_pinmux rt_gpio_pinmux = { 182#define MT7628_GPIO_MODE_MASK 0x3
134 .mode = mode_mux, 183
135 .uart = uart_mux, 184#define MT7628_GPIO_MODE_PWM1 30
136 .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, 185#define MT7628_GPIO_MODE_PWM0 28
137 .uart_mask = MT7620_GPIO_MODE_UART0_MASK, 186#define MT7628_GPIO_MODE_UART2 26
187#define MT7628_GPIO_MODE_UART1 24
188#define MT7628_GPIO_MODE_I2C 20
189#define MT7628_GPIO_MODE_REFCLK 18
190#define MT7628_GPIO_MODE_PERST 16
191#define MT7628_GPIO_MODE_WDT 14
192#define MT7628_GPIO_MODE_SPI 12
193#define MT7628_GPIO_MODE_SDMODE 10
194#define MT7628_GPIO_MODE_UART0 8
195#define MT7628_GPIO_MODE_I2S 6
196#define MT7628_GPIO_MODE_CS1 4
197#define MT7628_GPIO_MODE_SPIS 2
198#define MT7628_GPIO_MODE_GPIO 0
199
200static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
201 GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,
202 1, MT7628_GPIO_MODE_PWM1),
203 GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
204 1, MT7628_GPIO_MODE_PWM0),
205 GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,
206 1, MT7628_GPIO_MODE_UART2),
207 GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK,
208 1, MT7628_GPIO_MODE_UART1),
209 GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK,
210 1, MT7628_GPIO_MODE_I2C),
211 GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK),
212 GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST),
213 GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT),
214 GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI),
215 GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK,
216 1, MT7628_GPIO_MODE_SDMODE),
217 GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK,
218 1, MT7628_GPIO_MODE_UART0),
219 GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK,
220 1, MT7628_GPIO_MODE_I2S),
221 GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK,
222 1, MT7628_GPIO_MODE_CS1),
223 GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK,
224 1, MT7628_GPIO_MODE_SPIS),
225 GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,
226 1, MT7628_GPIO_MODE_GPIO),
227 { 0 }
138}; 228};
139 229
140static __init u32 230static __init u32
@@ -287,29 +377,42 @@ void __init ralink_clk_init(void)
287 377
288 xtal_rate = mt7620_get_xtal_rate(); 378 xtal_rate = mt7620_get_xtal_rate();
289 379
290 cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
291 pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
292
293 cpu_rate = mt7620_get_cpu_rate(pll_rate);
294 dram_rate = mt7620_get_dram_rate(pll_rate);
295 sys_rate = mt7620_get_sys_rate(cpu_rate);
296 periph_rate = mt7620_get_periph_rate(xtal_rate);
297
298#define RFMT(label) label ":%lu.%03luMHz " 380#define RFMT(label) label ":%lu.%03luMHz "
299#define RINT(x) ((x) / 1000000) 381#define RINT(x) ((x) / 1000000)
300#define RFRAC(x) (((x) / 1000) % 1000) 382#define RFRAC(x) (((x) / 1000) % 1000)
301 383
302 pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), 384 if (mt762x_soc == MT762X_SOC_MT7628AN) {
303 RINT(xtal_rate), RFRAC(xtal_rate), 385 if (xtal_rate == MHZ(40))
304 RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), 386 cpu_rate = MHZ(580);
305 RINT(pll_rate), RFRAC(pll_rate)); 387 else
388 cpu_rate = MHZ(575);
389 dram_rate = sys_rate = cpu_rate / 3;
390 periph_rate = MHZ(40);
391
392 ralink_clk_add("10000d00.uartlite", periph_rate);
393 ralink_clk_add("10000e00.uartlite", periph_rate);
394 } else {
395 cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
396 pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
397
398 cpu_rate = mt7620_get_cpu_rate(pll_rate);
399 dram_rate = mt7620_get_dram_rate(pll_rate);
400 sys_rate = mt7620_get_sys_rate(cpu_rate);
401 periph_rate = mt7620_get_periph_rate(xtal_rate);
402
403 pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
404 RINT(xtal_rate), RFRAC(xtal_rate),
405 RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
406 RINT(pll_rate), RFRAC(pll_rate));
407
408 ralink_clk_add("10000500.uart", periph_rate);
409 }
306 410
307 pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), 411 pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"),
308 RINT(cpu_rate), RFRAC(cpu_rate), 412 RINT(cpu_rate), RFRAC(cpu_rate),
309 RINT(dram_rate), RFRAC(dram_rate), 413 RINT(dram_rate), RFRAC(dram_rate),
310 RINT(sys_rate), RFRAC(sys_rate), 414 RINT(sys_rate), RFRAC(sys_rate),
311 RINT(periph_rate), RFRAC(periph_rate)); 415 RINT(periph_rate), RFRAC(periph_rate));
312
313#undef RFRAC 416#undef RFRAC
314#undef RINT 417#undef RINT
315#undef RFMT 418#undef RFMT
@@ -317,9 +420,9 @@ void __init ralink_clk_init(void)
317 ralink_clk_add("cpu", cpu_rate); 420 ralink_clk_add("cpu", cpu_rate);
318 ralink_clk_add("10000100.timer", periph_rate); 421 ralink_clk_add("10000100.timer", periph_rate);
319 ralink_clk_add("10000120.watchdog", periph_rate); 422 ralink_clk_add("10000120.watchdog", periph_rate);
320 ralink_clk_add("10000500.uart", periph_rate);
321 ralink_clk_add("10000b00.spi", sys_rate); 423 ralink_clk_add("10000b00.spi", sys_rate);
322 ralink_clk_add("10000c00.uartlite", periph_rate); 424 ralink_clk_add("10000c00.uartlite", periph_rate);
425 ralink_clk_add("10180000.wmac", xtal_rate);
323} 426}
324 427
325void __init ralink_of_remap(void) 428void __init ralink_of_remap(void)
@@ -331,6 +434,52 @@ void __init ralink_of_remap(void)
331 panic("Failed to remap core resources"); 434 panic("Failed to remap core resources");
332} 435}
333 436
437static __init void
438mt7620_dram_init(struct ralink_soc_info *soc_info)
439{
440 switch (dram_type) {
441 case SYSCFG0_DRAM_TYPE_SDRAM:
442 pr_info("Board has SDRAM\n");
443 soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
444 soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
445 break;
446
447 case SYSCFG0_DRAM_TYPE_DDR1:
448 pr_info("Board has DDR1\n");
449 soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
450 soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
451 break;
452
453 case SYSCFG0_DRAM_TYPE_DDR2:
454 pr_info("Board has DDR2\n");
455 soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
456 soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
457 break;
458 default:
459 BUG();
460 }
461}
462
463static __init void
464mt7628_dram_init(struct ralink_soc_info *soc_info)
465{
466 switch (dram_type) {
467 case SYSCFG0_DRAM_TYPE_DDR1_MT7628:
468 pr_info("Board has DDR1\n");
469 soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
470 soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
471 break;
472
473 case SYSCFG0_DRAM_TYPE_DDR2_MT7628:
474 pr_info("Board has DDR2\n");
475 soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
476 soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
477 break;
478 default:
479 BUG();
480 }
481}
482
334void prom_soc_init(struct ralink_soc_info *soc_info) 483void prom_soc_init(struct ralink_soc_info *soc_info)
335{ 484{
336 void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); 485 void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE);
@@ -339,22 +488,36 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
339 u32 n1; 488 u32 n1;
340 u32 rev; 489 u32 rev;
341 u32 cfg0; 490 u32 cfg0;
491 u32 pmu0;
492 u32 pmu1;
493 u32 bga;
342 494
343 n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); 495 n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
344 n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); 496 n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
345 497 rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
346 if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { 498 bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK;
347 name = "MT7620N"; 499
348 soc_info->compatible = "ralink,mt7620n-soc"; 500 if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) {
349 } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { 501 if (bga) {
350 name = "MT7620A"; 502 mt762x_soc = MT762X_SOC_MT7620A;
351 soc_info->compatible = "ralink,mt7620a-soc"; 503 name = "MT7620A";
504 soc_info->compatible = "ralink,mt7620a-soc";
505 } else {
506 mt762x_soc = MT762X_SOC_MT7620N;
507 name = "MT7620N";
508 soc_info->compatible = "ralink,mt7620n-soc";
509#ifdef CONFIG_PCI
510 panic("mt7620n is only supported for non pci kernels");
511#endif
512 }
513 } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) {
514 mt762x_soc = MT762X_SOC_MT7628AN;
515 name = "MT7628AN";
516 soc_info->compatible = "ralink,mt7628an-soc";
352 } else { 517 } else {
353 panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1); 518 panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
354 } 519 }
355 520
356 rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
357
358 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, 521 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
359 "Ralink %s ver:%u eco:%u", 522 "Ralink %s ver:%u eco:%u",
360 name, 523 name,
@@ -364,26 +527,22 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
364 cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); 527 cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0);
365 dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; 528 dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK;
366 529
367 switch (dram_type) {
368 case SYSCFG0_DRAM_TYPE_SDRAM:
369 pr_info("Board has SDRAM\n");
370 soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
371 soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
372 break;
373
374 case SYSCFG0_DRAM_TYPE_DDR1:
375 pr_info("Board has DDR1\n");
376 soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
377 soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
378 break;
379
380 case SYSCFG0_DRAM_TYPE_DDR2:
381 pr_info("Board has DDR2\n");
382 soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
383 soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
384 break;
385 default:
386 BUG();
387 }
388 soc_info->mem_base = MT7620_DRAM_BASE; 530 soc_info->mem_base = MT7620_DRAM_BASE;
531 if (mt762x_soc == MT762X_SOC_MT7628AN)
532 mt7628_dram_init(soc_info);
533 else
534 mt7620_dram_init(soc_info);
535
536 pmu0 = __raw_readl(sysc + PMU0_CFG);
537 pmu1 = __raw_readl(sysc + PMU1_CFG);
538
539 pr_info("Analog PMU set to %s control\n",
540 (pmu0 & PMU_SW_SET) ? ("sw") : ("hw"));
541 pr_info("Digital PMU set to %s control\n",
542 (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw"));
543
544 if (mt762x_soc == MT762X_SOC_MT7628AN)
545 rt2880_pinmux_data = mt7628an_pinmux_data;
546 else
547 rt2880_pinmux_data = mt7620a_pinmux_data;
389} 548}
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index 7c4598cb6de8..0d30dcd63246 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -53,6 +53,17 @@ void __init device_tree_init(void)
53 unflatten_and_copy_device_tree(); 53 unflatten_and_copy_device_tree();
54} 54}
55 55
56static int memory_dtb;
57
58static int __init early_init_dt_find_memory(unsigned long node,
59 const char *uname, int depth, void *data)
60{
61 if (depth == 1 && !strcmp(uname, "memory@0"))
62 memory_dtb = 1;
63
64 return 0;
65}
66
56void __init plat_mem_setup(void) 67void __init plat_mem_setup(void)
57{ 68{
58 set_io_port_base(KSEG1); 69 set_io_port_base(KSEG1);
@@ -63,7 +74,12 @@ void __init plat_mem_setup(void)
63 */ 74 */
64 __dt_setup_arch(__dtb_start); 75 __dt_setup_arch(__dtb_start);
65 76
66 if (soc_info.mem_size) 77 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
78
79 of_scan_flat_dt(early_init_dt_find_memory, NULL);
80 if (memory_dtb)
81 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
82 else if (soc_info.mem_size)
67 add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, 83 add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
68 BOOT_MEM_RAM); 84 BOOT_MEM_RAM);
69 else 85 else
@@ -74,19 +90,9 @@ void __init plat_mem_setup(void)
74 90
75static int __init plat_of_setup(void) 91static int __init plat_of_setup(void)
76{ 92{
77 static struct of_device_id of_ids[3]; 93 __dt_register_buses(soc_info.compatible, "palmbus");
78 int len = sizeof(of_ids[0].compatible);
79
80 if (!of_have_populated_dt())
81 panic("device tree not present");
82
83 strlcpy(of_ids[0].compatible, soc_info.compatible, len);
84 strlcpy(of_ids[1].compatible, "palmbus", len);
85
86 if (of_platform_populate(NULL, of_ids, NULL, NULL))
87 panic("failed to populate DT");
88 94
89 /* make sure ithat the reset controller is setup early */ 95 /* make sure that the reset controller is setup early */
90 ralink_rst_init(); 96 ralink_rst_init();
91 97
92 return 0; 98 return 0;
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c
index 9c64f029d047..09419f67da39 100644
--- a/arch/mips/ralink/prom.c
+++ b/arch/mips/ralink/prom.c
@@ -18,6 +18,7 @@
18#include "common.h" 18#include "common.h"
19 19
20struct ralink_soc_info soc_info; 20struct ralink_soc_info soc_info;
21struct rt2880_pmx_group *rt2880_pinmux_data = NULL;
21 22
22const char *get_system_type(void) 23const char *get_system_type(void)
23{ 24{
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c
index f87de1ab2198..738cec865f41 100644
--- a/arch/mips/ralink/rt288x.c
+++ b/arch/mips/ralink/rt288x.c
@@ -17,46 +17,27 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt288x.h> 19#include <asm/mach-ralink/rt288x.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
23static struct ralink_pinmux_grp mode_mux[] = { 24static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
24 { 25static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
25 .name = "i2c", 26static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
26 .mask = RT2880_GPIO_MODE_I2C, 27static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
27 .gpio_first = 1, 28static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
28 .gpio_last = 2, 29static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
29 }, { 30static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
30 .name = "spi", 31
31 .mask = RT2880_GPIO_MODE_SPI, 32static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
32 .gpio_first = 3, 33 GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C),
33 .gpio_last = 6, 34 GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI),
34 }, { 35 GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0),
35 .name = "uartlite", 36 GRP("jtag", jtag_func, 1, RT2880_GPIO_MODE_JTAG),
36 .mask = RT2880_GPIO_MODE_UART0, 37 GRP("mdio", mdio_func, 1, RT2880_GPIO_MODE_MDIO),
37 .gpio_first = 7, 38 GRP("sdram", sdram_func, 1, RT2880_GPIO_MODE_SDRAM),
38 .gpio_last = 14, 39 GRP("pci", pci_func, 1, RT2880_GPIO_MODE_PCI),
39 }, { 40 { 0 }
40 .name = "jtag",
41 .mask = RT2880_GPIO_MODE_JTAG,
42 .gpio_first = 17,
43 .gpio_last = 21,
44 }, {
45 .name = "mdio",
46 .mask = RT2880_GPIO_MODE_MDIO,
47 .gpio_first = 22,
48 .gpio_last = 23,
49 }, {
50 .name = "sdram",
51 .mask = RT2880_GPIO_MODE_SDRAM,
52 .gpio_first = 24,
53 .gpio_last = 39,
54 }, {
55 .name = "pci",
56 .mask = RT2880_GPIO_MODE_PCI,
57 .gpio_first = 40,
58 .gpio_last = 71,
59 }, {0}
60}; 41};
61 42
62static void rt288x_wdt_reset(void) 43static void rt288x_wdt_reset(void)
@@ -69,14 +50,9 @@ static void rt288x_wdt_reset(void)
69 rt_sysc_w32(t, SYSC_REG_CLKCFG); 50 rt_sysc_w32(t, SYSC_REG_CLKCFG);
70} 51}
71 52
72struct ralink_pinmux rt_gpio_pinmux = {
73 .mode = mode_mux,
74 .wdt_reset = rt288x_wdt_reset,
75};
76
77void __init ralink_clk_init(void) 53void __init ralink_clk_init(void)
78{ 54{
79 unsigned long cpu_rate; 55 unsigned long cpu_rate, wmac_rate = 40000000;
80 u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); 56 u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
81 t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); 57 t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
82 58
@@ -101,6 +77,7 @@ void __init ralink_clk_init(void)
101 ralink_clk_add("300500.uart", cpu_rate / 2); 77 ralink_clk_add("300500.uart", cpu_rate / 2);
102 ralink_clk_add("300c00.uartlite", cpu_rate / 2); 78 ralink_clk_add("300c00.uartlite", cpu_rate / 2);
103 ralink_clk_add("400000.ethernet", cpu_rate / 2); 79 ralink_clk_add("400000.ethernet", cpu_rate / 2);
80 ralink_clk_add("480000.wmac", wmac_rate);
104} 81}
105 82
106void __init ralink_of_remap(void) 83void __init ralink_of_remap(void)
@@ -140,4 +117,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
140 soc_info->mem_base = RT2880_SDRAM_BASE; 117 soc_info->mem_base = RT2880_SDRAM_BASE;
141 soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; 118 soc_info->mem_size_min = RT2880_MEM_SIZE_MIN;
142 soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; 119 soc_info->mem_size_max = RT2880_MEM_SIZE_MAX;
120
121 rt2880_pinmux_data = rt2880_pinmux_data_act;
143} 122}
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
index bb82a82da9e7..c40776ab67db 100644
--- a/arch/mips/ralink/rt305x.c
+++ b/arch/mips/ralink/rt305x.c
@@ -17,90 +17,78 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt305x.h> 19#include <asm/mach-ralink/rt305x.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
23enum rt305x_soc_type rt305x_soc; 24enum rt305x_soc_type rt305x_soc;
24 25
25static struct ralink_pinmux_grp mode_mux[] = { 26static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
26 { 27static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
27 .name = "i2c", 28static struct rt2880_pmx_func uartf_func[] = {
28 .mask = RT305X_GPIO_MODE_I2C, 29 FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8),
29 .gpio_first = RT305X_GPIO_I2C_SD, 30 FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8),
30 .gpio_last = RT305X_GPIO_I2C_SCLK, 31 FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8),
31 }, { 32 FUNC("i2s uartf", RT305X_GPIO_MODE_I2S_UARTF, 7, 8),
32 .name = "spi", 33 FUNC("pcm gpio", RT305X_GPIO_MODE_PCM_GPIO, 11, 4),
33 .mask = RT305X_GPIO_MODE_SPI, 34 FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4),
34 .gpio_first = RT305X_GPIO_SPI_EN, 35 FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4),
35 .gpio_last = RT305X_GPIO_SPI_CLK, 36};
36 }, { 37static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
37 .name = "uartlite", 38static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
38 .mask = RT305X_GPIO_MODE_UART1, 39static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
39 .gpio_first = RT305X_GPIO_UART1_TXD, 40static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
40 .gpio_last = RT305X_GPIO_UART1_RXD, 41static struct rt2880_pmx_func rt5350_cs1_func[] = {
41 }, { 42 FUNC("spi_cs1", 0, 27, 1),
42 .name = "jtag", 43 FUNC("wdg_cs1", 1, 27, 1),
43 .mask = RT305X_GPIO_MODE_JTAG, 44};
44 .gpio_first = RT305X_GPIO_JTAG_TDO, 45static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
45 .gpio_last = RT305X_GPIO_JTAG_TDI, 46static struct rt2880_pmx_func rt3352_rgmii_func[] = {
46 }, { 47 FUNC("rgmii", 0, 24, 12)
47 .name = "mdio", 48};
48 .mask = RT305X_GPIO_MODE_MDIO, 49static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
49 .gpio_first = RT305X_GPIO_MDIO_MDC, 50static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
50 .gpio_last = RT305X_GPIO_MDIO_MDIO, 51static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
51 }, { 52static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
52 .name = "sdram", 53
53 .mask = RT305X_GPIO_MODE_SDRAM, 54static struct rt2880_pmx_group rt3050_pinmux_data[] = {
54 .gpio_first = RT305X_GPIO_SDRAM_MD16, 55 GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
55 .gpio_last = RT305X_GPIO_SDRAM_MD31, 56 GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
56 }, { 57 GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
57 .name = "rgmii", 58 RT305X_GPIO_MODE_UART0_SHIFT),
58 .mask = RT305X_GPIO_MODE_RGMII, 59 GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
59 .gpio_first = RT305X_GPIO_GE0_TXD0, 60 GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
60 .gpio_last = RT305X_GPIO_GE0_RXCLK, 61 GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO),
61 }, {0} 62 GRP("rgmii", rgmii_func, 1, RT305X_GPIO_MODE_RGMII),
63 GRP("sdram", sdram_func, 1, RT305X_GPIO_MODE_SDRAM),
64 { 0 }
62}; 65};
63 66
64static struct ralink_pinmux_grp uart_mux[] = { 67static struct rt2880_pmx_group rt3352_pinmux_data[] = {
65 { 68 GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
66 .name = "uartf", 69 GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
67 .mask = RT305X_GPIO_MODE_UARTF, 70 GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
68 .gpio_first = RT305X_GPIO_7, 71 RT305X_GPIO_MODE_UART0_SHIFT),
69 .gpio_last = RT305X_GPIO_14, 72 GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
70 }, { 73 GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
71 .name = "pcm uartf", 74 GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO),
72 .mask = RT305X_GPIO_MODE_PCM_UARTF, 75 GRP("rgmii", rt3352_rgmii_func, 1, RT305X_GPIO_MODE_RGMII),
73 .gpio_first = RT305X_GPIO_7, 76 GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA),
74 .gpio_last = RT305X_GPIO_14, 77 GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA),
75 }, { 78 GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
76 .name = "pcm i2s", 79 { 0 }
77 .mask = RT305X_GPIO_MODE_PCM_I2S, 80};
78 .gpio_first = RT305X_GPIO_7, 81
79 .gpio_last = RT305X_GPIO_14, 82static struct rt2880_pmx_group rt5350_pinmux_data[] = {
80 }, { 83 GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
81 .name = "i2s uartf", 84 GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
82 .mask = RT305X_GPIO_MODE_I2S_UARTF, 85 GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
83 .gpio_first = RT305X_GPIO_7, 86 RT305X_GPIO_MODE_UART0_SHIFT),
84 .gpio_last = RT305X_GPIO_14, 87 GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
85 }, { 88 GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
86 .name = "pcm gpio", 89 GRP("led", rt5350_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
87 .mask = RT305X_GPIO_MODE_PCM_GPIO, 90 GRP("spi_cs1", rt5350_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1),
88 .gpio_first = RT305X_GPIO_10, 91 { 0 }
89 .gpio_last = RT305X_GPIO_14,
90 }, {
91 .name = "gpio uartf",
92 .mask = RT305X_GPIO_MODE_GPIO_UARTF,
93 .gpio_first = RT305X_GPIO_7,
94 .gpio_last = RT305X_GPIO_10,
95 }, {
96 .name = "gpio i2s",
97 .mask = RT305X_GPIO_MODE_GPIO_I2S,
98 .gpio_first = RT305X_GPIO_7,
99 .gpio_last = RT305X_GPIO_10,
100 }, {
101 .name = "gpio",
102 .mask = RT305X_GPIO_MODE_GPIO,
103 }, {0}
104}; 92};
105 93
106static void rt305x_wdt_reset(void) 94static void rt305x_wdt_reset(void)
@@ -114,14 +102,6 @@ static void rt305x_wdt_reset(void)
114 rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); 102 rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
115} 103}
116 104
117struct ralink_pinmux rt_gpio_pinmux = {
118 .mode = mode_mux,
119 .uart = uart_mux,
120 .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT,
121 .uart_mask = RT305X_GPIO_MODE_UART0_MASK,
122 .wdt_reset = rt305x_wdt_reset,
123};
124
125static unsigned long rt5350_get_mem_size(void) 105static unsigned long rt5350_get_mem_size(void)
126{ 106{
127 void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); 107 void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
@@ -290,11 +270,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
290 soc_info->mem_base = RT305X_SDRAM_BASE; 270 soc_info->mem_base = RT305X_SDRAM_BASE;
291 if (soc_is_rt5350()) { 271 if (soc_is_rt5350()) {
292 soc_info->mem_size = rt5350_get_mem_size(); 272 soc_info->mem_size = rt5350_get_mem_size();
273 rt2880_pinmux_data = rt5350_pinmux_data;
293 } else if (soc_is_rt305x() || soc_is_rt3350()) { 274 } else if (soc_is_rt305x() || soc_is_rt3350()) {
294 soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; 275 soc_info->mem_size_min = RT305X_MEM_SIZE_MIN;
295 soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; 276 soc_info->mem_size_max = RT305X_MEM_SIZE_MAX;
277 rt2880_pinmux_data = rt3050_pinmux_data;
296 } else if (soc_is_rt3352()) { 278 } else if (soc_is_rt3352()) {
297 soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; 279 soc_info->mem_size_min = RT3352_MEM_SIZE_MIN;
298 soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; 280 soc_info->mem_size_max = RT3352_MEM_SIZE_MAX;
281 rt2880_pinmux_data = rt3352_pinmux_data;
299 } 282 }
300} 283}
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
index b474ac284b83..86a535c770d8 100644
--- a/arch/mips/ralink/rt3883.c
+++ b/arch/mips/ralink/rt3883.c
@@ -17,132 +17,50 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt3883.h> 19#include <asm/mach-ralink/rt3883.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
23static struct ralink_pinmux_grp mode_mux[] = { 24static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
24 { 25static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
25 .name = "i2c", 26static struct rt2880_pmx_func uartf_func[] = {
26 .mask = RT3883_GPIO_MODE_I2C, 27 FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8),
27 .gpio_first = RT3883_GPIO_I2C_SD, 28 FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8),
28 .gpio_last = RT3883_GPIO_I2C_SCLK, 29 FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8),
29 }, { 30 FUNC("i2s uartf", RT3883_GPIO_MODE_I2S_UARTF, 7, 8),
30 .name = "spi", 31 FUNC("pcm gpio", RT3883_GPIO_MODE_PCM_GPIO, 11, 4),
31 .mask = RT3883_GPIO_MODE_SPI, 32 FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4),
32 .gpio_first = RT3883_GPIO_SPI_CS0, 33 FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4),
33 .gpio_last = RT3883_GPIO_SPI_MISO,
34 }, {
35 .name = "uartlite",
36 .mask = RT3883_GPIO_MODE_UART1,
37 .gpio_first = RT3883_GPIO_UART1_TXD,
38 .gpio_last = RT3883_GPIO_UART1_RXD,
39 }, {
40 .name = "jtag",
41 .mask = RT3883_GPIO_MODE_JTAG,
42 .gpio_first = RT3883_GPIO_JTAG_TDO,
43 .gpio_last = RT3883_GPIO_JTAG_TCLK,
44 }, {
45 .name = "mdio",
46 .mask = RT3883_GPIO_MODE_MDIO,
47 .gpio_first = RT3883_GPIO_MDIO_MDC,
48 .gpio_last = RT3883_GPIO_MDIO_MDIO,
49 }, {
50 .name = "ge1",
51 .mask = RT3883_GPIO_MODE_GE1,
52 .gpio_first = RT3883_GPIO_GE1_TXD0,
53 .gpio_last = RT3883_GPIO_GE1_RXCLK,
54 }, {
55 .name = "ge2",
56 .mask = RT3883_GPIO_MODE_GE2,
57 .gpio_first = RT3883_GPIO_GE2_TXD0,
58 .gpio_last = RT3883_GPIO_GE2_RXCLK,
59 }, {
60 .name = "pci",
61 .mask = RT3883_GPIO_MODE_PCI,
62 .gpio_first = RT3883_GPIO_PCI_AD0,
63 .gpio_last = RT3883_GPIO_PCI_AD31,
64 }, {
65 .name = "lna a",
66 .mask = RT3883_GPIO_MODE_LNA_A,
67 .gpio_first = RT3883_GPIO_LNA_PE_A0,
68 .gpio_last = RT3883_GPIO_LNA_PE_A2,
69 }, {
70 .name = "lna g",
71 .mask = RT3883_GPIO_MODE_LNA_G,
72 .gpio_first = RT3883_GPIO_LNA_PE_G0,
73 .gpio_last = RT3883_GPIO_LNA_PE_G2,
74 }, {0}
75}; 34};
76 35static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
77static struct ralink_pinmux_grp uart_mux[] = { 36static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
78 { 37static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
79 .name = "uartf", 38static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
80 .mask = RT3883_GPIO_MODE_UARTF, 39static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) };
81 .gpio_first = RT3883_GPIO_7, 40static struct rt2880_pmx_func pci_func[] = {
82 .gpio_last = RT3883_GPIO_14, 41 FUNC("pci-dev", 0, 40, 32),
83 }, { 42 FUNC("pci-host2", 1, 40, 32),
84 .name = "pcm uartf", 43 FUNC("pci-host1", 2, 40, 32),
85 .mask = RT3883_GPIO_MODE_PCM_UARTF, 44 FUNC("pci-fnc", 3, 40, 32)
86 .gpio_first = RT3883_GPIO_7,
87 .gpio_last = RT3883_GPIO_14,
88 }, {
89 .name = "pcm i2s",
90 .mask = RT3883_GPIO_MODE_PCM_I2S,
91 .gpio_first = RT3883_GPIO_7,
92 .gpio_last = RT3883_GPIO_14,
93 }, {
94 .name = "i2s uartf",
95 .mask = RT3883_GPIO_MODE_I2S_UARTF,
96 .gpio_first = RT3883_GPIO_7,
97 .gpio_last = RT3883_GPIO_14,
98 }, {
99 .name = "pcm gpio",
100 .mask = RT3883_GPIO_MODE_PCM_GPIO,
101 .gpio_first = RT3883_GPIO_11,
102 .gpio_last = RT3883_GPIO_14,
103 }, {
104 .name = "gpio uartf",
105 .mask = RT3883_GPIO_MODE_GPIO_UARTF,
106 .gpio_first = RT3883_GPIO_7,
107 .gpio_last = RT3883_GPIO_10,
108 }, {
109 .name = "gpio i2s",
110 .mask = RT3883_GPIO_MODE_GPIO_I2S,
111 .gpio_first = RT3883_GPIO_7,
112 .gpio_last = RT3883_GPIO_10,
113 }, {
114 .name = "gpio",
115 .mask = RT3883_GPIO_MODE_GPIO,
116 }, {0}
117}; 45};
118 46static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
119static struct ralink_pinmux_grp pci_mux[] = { 47static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) };
120 { 48
121 .name = "pci-dev", 49static struct rt2880_pmx_group rt3883_pinmux_data[] = {
122 .mask = 0, 50 GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C),
123 .gpio_first = RT3883_GPIO_PCI_AD0, 51 GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI),
124 .gpio_last = RT3883_GPIO_PCI_AD31, 52 GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK,
125 }, { 53 RT3883_GPIO_MODE_UART0_SHIFT),
126 .name = "pci-host2", 54 GRP("uartlite", uartlite_func, 1, RT3883_GPIO_MODE_UART1),
127 .mask = 1, 55 GRP("jtag", jtag_func, 1, RT3883_GPIO_MODE_JTAG),
128 .gpio_first = RT3883_GPIO_PCI_AD0, 56 GRP("mdio", mdio_func, 1, RT3883_GPIO_MODE_MDIO),
129 .gpio_last = RT3883_GPIO_PCI_AD31, 57 GRP("lna a", lna_a_func, 1, RT3883_GPIO_MODE_LNA_A),
130 }, { 58 GRP("lna g", lna_g_func, 1, RT3883_GPIO_MODE_LNA_G),
131 .name = "pci-host1", 59 GRP("pci", pci_func, RT3883_GPIO_MODE_PCI_MASK,
132 .mask = 2, 60 RT3883_GPIO_MODE_PCI_SHIFT),
133 .gpio_first = RT3883_GPIO_PCI_AD0, 61 GRP("ge1", ge1_func, 1, RT3883_GPIO_MODE_GE1),
134 .gpio_last = RT3883_GPIO_PCI_AD31, 62 GRP("ge2", ge2_func, 1, RT3883_GPIO_MODE_GE2),
135 }, { 63 { 0 }
136 .name = "pci-fnc",
137 .mask = 3,
138 .gpio_first = RT3883_GPIO_PCI_AD0,
139 .gpio_last = RT3883_GPIO_PCI_AD31,
140 }, {
141 .name = "pci-gpio",
142 .mask = 7,
143 .gpio_first = RT3883_GPIO_PCI_AD0,
144 .gpio_last = RT3883_GPIO_PCI_AD31,
145 }, {0}
146}; 64};
147 65
148static void rt3883_wdt_reset(void) 66static void rt3883_wdt_reset(void)
@@ -155,17 +73,6 @@ static void rt3883_wdt_reset(void)
155 rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); 73 rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
156} 74}
157 75
158struct ralink_pinmux rt_gpio_pinmux = {
159 .mode = mode_mux,
160 .uart = uart_mux,
161 .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT,
162 .uart_mask = RT3883_GPIO_MODE_UART0_MASK,
163 .wdt_reset = rt3883_wdt_reset,
164 .pci = pci_mux,
165 .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT,
166 .pci_mask = RT3883_GPIO_MODE_PCI_MASK,
167};
168
169void __init ralink_clk_init(void) 76void __init ralink_clk_init(void)
170{ 77{
171 unsigned long cpu_rate, sys_rate; 78 unsigned long cpu_rate, sys_rate;
@@ -204,6 +111,7 @@ void __init ralink_clk_init(void)
204 ralink_clk_add("10000b00.spi", sys_rate); 111 ralink_clk_add("10000b00.spi", sys_rate);
205 ralink_clk_add("10000c00.uartlite", 40000000); 112 ralink_clk_add("10000c00.uartlite", 40000000);
206 ralink_clk_add("10100000.ethernet", sys_rate); 113 ralink_clk_add("10100000.ethernet", sys_rate);
114 ralink_clk_add("10180000.wmac", 40000000);
207} 115}
208 116
209void __init ralink_of_remap(void) 117void __init ralink_of_remap(void)
@@ -243,4 +151,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
243 soc_info->mem_base = RT3883_SDRAM_BASE; 151 soc_info->mem_base = RT3883_SDRAM_BASE;
244 soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; 152 soc_info->mem_size_min = RT3883_MEM_SIZE_MIN;
245 soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; 153 soc_info->mem_size_max = RT3883_MEM_SIZE_MAX;
154
155 rt2880_pinmux_data = rt3883_pinmux_data;
246} 156}
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index a18007613c30..5aa3df853082 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -79,7 +79,7 @@ static inline void rb532_set_bit(unsigned bitval,
79 */ 79 */
80static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) 80static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr)
81{ 81{
82 return (readl(ioaddr) & (1 << offset)); 82 return readl(ioaddr) & (1 << offset);
83} 83}
84 84
85/* 85/*
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
index a757ded437cd..657210e767c2 100644
--- a/arch/mips/rb532/prom.c
+++ b/arch/mips/rb532/prom.c
@@ -122,8 +122,8 @@ void __init prom_setup_cmdline(void)
122void __init prom_init(void) 122void __init prom_init(void)
123{ 123{
124 struct ddr_ram __iomem *ddr; 124 struct ddr_ram __iomem *ddr;
125 phys_t memsize; 125 phys_addr_t memsize;
126 phys_t ddrbase; 126 phys_addr_t ddrbase;
127 127
128 ddr = ioremap_nocache(ddr_reg[0].start, 128 ddr = ioremap_nocache(ddr_reg[0].start,
129 ddr_reg[0].end - ddr_reg[0].start); 129 ddr_reg[0].end - ddr_reg[0].start);
@@ -133,8 +133,8 @@ void __init prom_init(void)
133 return; 133 return;
134 } 134 }
135 135
136 ddrbase = (phys_t)&ddr->ddrbase; 136 ddrbase = (phys_addr_t)&ddr->ddrbase;
137 memsize = (phys_t)&ddr->ddrmask; 137 memsize = (phys_addr_t)&ddr->ddrmask;
138 memsize = 0 - memsize; 138 memsize = 0 - memsize;
139 139
140 prom_setup_cmdline(); 140 prom_setup_cmdline();
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index 7cec0a4e527d..6b009c45abed 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -24,14 +24,12 @@ EXPORT_SYMBOL(sgimc);
24 24
25static inline unsigned long get_bank_addr(unsigned int memconfig) 25static inline unsigned long get_bank_addr(unsigned int memconfig)
26{ 26{
27 return ((memconfig & SGIMC_MCONFIG_BASEADDR) << 27 return (memconfig & SGIMC_MCONFIG_BASEADDR) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22);
28 ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22));
29} 28}
30 29
31static inline unsigned long get_bank_size(unsigned int memconfig) 30static inline unsigned long get_bank_size(unsigned int memconfig)
32{ 31{
33 return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << 32 return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
34 ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
35} 33}
36 34
37static inline unsigned int get_bank_config(int bank) 35static inline unsigned int get_bank_config(int bank)
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
index 3f47346608d7..712cc0f6a58d 100644
--- a/arch/mips/sgi-ip22/ip28-berr.c
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -338,7 +338,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
338 PHYS_TO_XKSEG_UNCACHED(pte); 338 PHYS_TO_XKSEG_UNCACHED(pte);
339 a = (a & 0x3f) << 6; /* PFN */ 339 a = (a & 0x3f) << 6; /* PFN */
340 a += vaddr & ((1 << pgsz) - 1); 340 a += vaddr & ((1 << pgsz) - 1);
341 return (cpu_err_addr == a); 341 return cpu_err_addr == a;
342 } 342 }
343 } 343 }
344 } 344 }
@@ -351,7 +351,7 @@ static int check_vdma_memaddr(void)
351 u32 a = sgimc->maddronly; 351 u32 a = sgimc->maddronly;
352 352
353 if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ 353 if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
354 return (cpu_err_addr == a); 354 return cpu_err_addr == a;
355 355
356 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || 356 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
357 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || 357 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
@@ -367,7 +367,7 @@ static int check_vdma_gioaddr(void)
367 if (gio_err_stat & GIO_ERRMASK) { 367 if (gio_err_stat & GIO_ERRMASK) {
368 u32 a = sgimc->gio_dma_trans; 368 u32 a = sgimc->gio_dma_trans;
369 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); 369 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
370 return (gio_err_addr == a); 370 return gio_err_addr == a;
371 } 371 }
372 return 0; 372 return 0;
373} 373}
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
index 7a53b1e28a93..ecbb62f339c5 100644
--- a/arch/mips/sgi-ip27/ip27-klnuma.c
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c
@@ -125,8 +125,7 @@ unsigned long node_getfirstfree(cnodeid_t cnode)
125#endif 125#endif
126 offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; 126 offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
127 if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) 127 if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
128 return (TO_NODE(nasid, offset) >> PAGE_SHIFT); 128 return TO_NODE(nasid, offset) >> PAGE_SHIFT;
129 else 129 else
130 return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> 130 return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT;
131 PAGE_SHIFT);
132} 131}
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index a304bcc37e4f..0b68469e063f 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -42,8 +42,7 @@ static int fine_mode;
42 42
43static int is_fine_dirmode(void) 43static int is_fine_dirmode(void)
44{ 44{
45 return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) 45 return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
46 >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
47} 46}
48 47
49static hubreg_t get_region(cnodeid_t cnode) 48static hubreg_t get_region(cnodeid_t cnode)
@@ -288,7 +287,7 @@ static unsigned long __init slot_psize_compute(cnodeid_t node, int slot)
288 if (size <= 128) { 287 if (size <= 128) {
289 if (slot % 4 == 0) { 288 if (slot % 4 == 0) {
290 size <<= 20; /* size in bytes */ 289 size <<= 20; /* size in bytes */
291 return(size >> PAGE_SHIFT); 290 return size >> PAGE_SHIFT;
292 } else 291 } else
293 return 0; 292 return 0;
294 } else { 293 } else {
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c
index 588e1806a1a3..c1a11a11db7f 100644
--- a/arch/mips/sibyte/common/cfe.c
+++ b/arch/mips/sibyte/common/cfe.c
@@ -38,7 +38,7 @@
38#define MAX_RAM_SIZE (~0ULL) 38#define MAX_RAM_SIZE (~0ULL)
39#else 39#else
40#ifdef CONFIG_HIGHMEM 40#ifdef CONFIG_HIGHMEM
41#ifdef CONFIG_64BIT_PHYS_ADDR 41#ifdef CONFIG_PHYS_ADDR_T_64BIT
42#define MAX_RAM_SIZE (~0ULL) 42#define MAX_RAM_SIZE (~0ULL)
43#else 43#else
44#define MAX_RAM_SIZE (0xffffffffULL) 44#define MAX_RAM_SIZE (0xffffffffULL)
@@ -49,8 +49,8 @@
49#endif 49#endif
50 50
51#define SIBYTE_MAX_MEM_REGIONS 8 51#define SIBYTE_MAX_MEM_REGIONS 8
52phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; 52phys_addr_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS];
53phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; 53phys_addr_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS];
54unsigned int board_mem_region_count; 54unsigned int board_mem_region_count;
55 55
56int cfe_cons_handle; 56int cfe_cons_handle;
@@ -96,7 +96,7 @@ static void __noreturn cfe_linux_halt(void)
96 96
97static __init void prom_meminit(void) 97static __init void prom_meminit(void)
98{ 98{
99 u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ 99 u64 addr, size, type; /* regardless of PHYS_ADDR_T_64BIT */
100 int mem_flags = 0; 100 int mem_flags = 0;
101 unsigned int idx; 101 unsigned int idx;
102 int rd_flag; 102 int rd_flag;
diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c
index 9480c14ec66a..1cecdcf85cf1 100644
--- a/arch/mips/sibyte/swarm/platform.c
+++ b/arch/mips/sibyte/swarm/platform.c
@@ -50,7 +50,7 @@ static struct platform_device swarm_pata_device = {
50static int __init swarm_pata_init(void) 50static int __init swarm_pata_init(void)
51{ 51{
52 u8 __iomem *base; 52 u8 __iomem *base;
53 phys_t offset, size; 53 phys_addr_t offset, size;
54 struct resource *r; 54 struct resource *r;
55 55
56 if (!SIBYTE_HAVE_IDE) 56 if (!SIBYTE_HAVE_IDE)
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index b732600b47f5..e62466445f08 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -109,7 +109,7 @@ static int m41t81_read(uint8_t addr)
109 return -1; 109 return -1;
110 } 110 }
111 111
112 return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); 112 return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff;
113} 113}
114 114
115static int m41t81_write(uint8_t addr, int b) 115static int m41t81_write(uint8_t addr, int b)
@@ -229,5 +229,5 @@ int m41t81_probe(void)
229 tmp = m41t81_read(M41T81REG_SC); 229 tmp = m41t81_read(M41T81REG_SC);
230 m41t81_write(M41T81REG_SC, tmp & 0x7f); 230 m41t81_write(M41T81REG_SC, tmp & 0x7f);
231 231
232 return (m41t81_read(M41T81REG_SC) != -1); 232 return m41t81_read(M41T81REG_SC) != -1;
233} 233}
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index 178a824b28d4..50a82c495427 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -84,7 +84,7 @@ static int xicor_read(uint8_t addr)
84 return -1; 84 return -1;
85 } 85 }
86 86
87 return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); 87 return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff;
88} 88}
89 89
90static int xicor_write(uint8_t addr, int b) 90static int xicor_write(uint8_t addr, int b)
@@ -206,5 +206,5 @@ unsigned long xicor_get_time(void)
206 206
207int xicor_probe(void) 207int xicor_probe(void)
208{ 208{
209 return (xicor_read(X1241REG_SC) != -1); 209 return xicor_read(X1241REG_SC) != -1;
210} 210}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 3462c831d0ea..494fb0a475ac 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -76,7 +76,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
76 printk("DBE physical address: %010Lx\n", 76 printk("DBE physical address: %010Lx\n",
77 __read_64bit_c0_register($26, 1)); 77 __read_64bit_c0_register($26, 1));
78 } 78 }
79 return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); 79 return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
80} 80}
81 81
82enum swarm_rtc_type { 82enum swarm_rtc_type {
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
index e714d6ce9a82..a4664cb6c1e1 100644
--- a/arch/mips/txx9/generic/setup_tx4927.c
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -29,8 +29,8 @@ static void __init tx4927_wdr_init(void)
29{ 29{
30 /* report watchdog reset status */ 30 /* report watchdog reset status */
31 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) 31 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)
32 pr_warning("Watchdog reset detected at 0x%lx\n", 32 pr_warn("Watchdog reset detected at 0x%lx\n",
33 read_c0_errorepc()); 33 read_c0_errorepc());
34 /* clear WatchDogReset (W1C) */ 34 /* clear WatchDogReset (W1C) */
35 tx4927_ccfg_set(TX4927_CCFG_WDRST); 35 tx4927_ccfg_set(TX4927_CCFG_WDRST);
36 /* do reset on watchdog */ 36 /* do reset on watchdog */
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index 0a3bf2dfaba1..58cdb2aba5e1 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -31,8 +31,8 @@ static void __init tx4938_wdr_init(void)
31{ 31{
32 /* report watchdog reset status */ 32 /* report watchdog reset status */
33 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) 33 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)
34 pr_warning("Watchdog reset detected at 0x%lx\n", 34 pr_warn("Watchdog reset detected at 0x%lx\n",
35 read_c0_errorepc()); 35 read_c0_errorepc());
36 /* clear WatchDogReset (W1C) */ 36 /* clear WatchDogReset (W1C) */
37 tx4938_ccfg_set(TX4938_CCFG_WDRST); 37 tx4938_ccfg_set(TX4938_CCFG_WDRST);
38 /* do reset on watchdog */ 38 /* do reset on watchdog */
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index b7eccbd17bf7..e3733cde50d6 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -35,8 +35,8 @@ static void __init tx4939_wdr_init(void)
35{ 35{
36 /* report watchdog reset status */ 36 /* report watchdog reset status */
37 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) 37 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)
38 pr_warning("Watchdog reset detected at 0x%lx\n", 38 pr_warn("Watchdog reset detected at 0x%lx\n",
39 read_c0_errorepc()); 39 read_c0_errorepc());
40 /* clear WatchDogReset (W1C) */ 40 /* clear WatchDogReset (W1C) */
41 tx4939_ccfg_set(TX4939_CCFG_WDRST); 41 tx4939_ccfg_set(TX4939_CCFG_WDRST);
42 /* do reset on watchdog */ 42 /* do reset on watchdog */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 88eace4e28c3..af696874248b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -88,6 +88,7 @@ config PPC
88 select ARCH_MIGHT_HAVE_PC_PARPORT 88 select ARCH_MIGHT_HAVE_PC_PARPORT
89 select ARCH_MIGHT_HAVE_PC_SERIO 89 select ARCH_MIGHT_HAVE_PC_SERIO
90 select BINFMT_ELF 90 select BINFMT_ELF
91 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
91 select OF 92 select OF
92 select OF_EARLY_FLATTREE 93 select OF_EARLY_FLATTREE
93 select OF_RESERVED_MEM 94 select OF_RESERVED_MEM
@@ -148,6 +149,8 @@ config PPC
148 select HAVE_ARCH_AUDITSYSCALL 149 select HAVE_ARCH_AUDITSYSCALL
149 select ARCH_SUPPORTS_ATOMIC_RMW 150 select ARCH_SUPPORTS_ATOMIC_RMW
150 select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN 151 select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN
152 select NO_BOOTMEM
153 select HAVE_GENERIC_RCU_GUP
151 154
152config GENERIC_CSUM 155config GENERIC_CSUM
153 def_bool CPU_LITTLE_ENDIAN 156 def_bool CPU_LITTLE_ENDIAN
@@ -549,7 +552,7 @@ config PPC_4K_PAGES
549 bool "4k page size" 552 bool "4k page size"
550 553
551config PPC_16K_PAGES 554config PPC_16K_PAGES
552 bool "16k page size" if 44x 555 bool "16k page size" if 44x || PPC_8xx
553 556
554config PPC_64K_PAGES 557config PPC_64K_PAGES
555 bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64 558 bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64
diff --git a/arch/powerpc/boot/dts/b4860emu.dts b/arch/powerpc/boot/dts/b4860emu.dts
index 85646b4f96e1..2aa5cd318ce8 100644
--- a/arch/powerpc/boot/dts/b4860emu.dts
+++ b/arch/powerpc/boot/dts/b4860emu.dts
@@ -193,9 +193,9 @@
193 fsl,liodn-bits = <12>; 193 fsl,liodn-bits = <12>;
194 }; 194 };
195 195
196 clockgen: global-utilities@e1000 { 196/include/ "fsl/qoriq-clockgen2.dtsi"
197 global-utilities@e1000 {
197 compatible = "fsl,b4-clockgen", "fsl,qoriq-clockgen-2.0"; 198 compatible = "fsl,b4-clockgen", "fsl,qoriq-clockgen-2.0";
198 reg = <0xe1000 0x1000>;
199 }; 199 };
200 200
201/include/ "fsl/qoriq-dma-0.dtsi" 201/include/ "fsl/qoriq-dma-0.dtsi"
diff --git a/arch/powerpc/boot/dts/b4qds.dtsi b/arch/powerpc/boot/dts/b4qds.dtsi
index 8b47edcfabf0..e5bde0b85135 100644
--- a/arch/powerpc/boot/dts/b4qds.dtsi
+++ b/arch/powerpc/boot/dts/b4qds.dtsi
@@ -152,6 +152,29 @@
152 reg = <0x68>; 152 reg = <0x68>;
153 }; 153 };
154 }; 154 };
155
156 i2c@2 {
157 #address-cells = <1>;
158 #size-cells = <0>;
159 reg = <0x2>;
160
161 ina220@40 {
162 compatible = "ti,ina220";
163 reg = <0x40>;
164 shunt-resistor = <1000>;
165 };
166 };
167
168 i2c@3 {
169 #address-cells = <1>;
170 #size-cells = <0>;
171 reg = <0x3>;
172
173 adt7461@4c {
174 compatible = "adi,adt7461";
175 reg = <0x4c>;
176 };
177 };
155 }; 178 };
156 }; 179 };
157 180
diff --git a/arch/powerpc/boot/dts/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/bsc9131rdb.dtsi
index 9e6c01339ccc..45efcbadb23c 100644
--- a/arch/powerpc/boot/dts/bsc9131rdb.dtsi
+++ b/arch/powerpc/boot/dts/bsc9131rdb.dtsi
@@ -40,31 +40,6 @@
40 compatible = "fsl,ifc-nand"; 40 compatible = "fsl,ifc-nand";
41 reg = <0x0 0x0 0x4000>; 41 reg = <0x0 0x0 0x4000>;
42 42
43 partition@0 {
44 /* This location must not be altered */
45 /* 3MB for u-boot Bootloader Image */
46 reg = <0x0 0x00300000>;
47 label = "NAND U-Boot Image";
48 read-only;
49 };
50
51 partition@300000 {
52 /* 1MB for DTB Image */
53 reg = <0x00300000 0x00100000>;
54 label = "NAND DTB Image";
55 };
56
57 partition@400000 {
58 /* 8MB for Linux Kernel Image */
59 reg = <0x00400000 0x00800000>;
60 label = "NAND Linux Kernel Image";
61 };
62
63 partition@c00000 {
64 /* Rest space for Root file System Image */
65 reg = <0x00c00000 0x07400000>;
66 label = "NAND RFS Image";
67 };
68 }; 43 };
69}; 44};
70 45
@@ -82,31 +57,6 @@
82 reg = <0>; 57 reg = <0>;
83 spi-max-frequency = <50000000>; 58 spi-max-frequency = <50000000>;
84 59
85 /* 512KB for u-boot Bootloader Image */
86 partition@0 {
87 reg = <0x0 0x00080000>;
88 label = "SPI Flash U-Boot Image";
89 read-only;
90 };
91
92 /* 512KB for DTB Image */
93 partition@80000 {
94 reg = <0x00080000 0x00080000>;
95 label = "SPI Flash DTB Image";
96 };
97
98 /* 4MB for Linux Kernel Image */
99 partition@100000 {
100 reg = <0x00100000 0x00400000>;
101 label = "SPI Flash Kernel Image";
102 };
103
104 /*11MB for RFS Image */
105 partition@500000 {
106 reg = <0x00500000 0x00B00000>;
107 label = "SPI Flash RFS Image";
108 };
109
110 }; 60 };
111 }; 61 };
112 62
diff --git a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
index d67894459ac8..86161ae6c966 100644
--- a/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
@@ -80,33 +80,9 @@
80 compatible = "fsl,b4420-device-config", "fsl,qoriq-device-config-2.0"; 80 compatible = "fsl,b4420-device-config", "fsl,qoriq-device-config-2.0";
81 }; 81 };
82 82
83 clockgen: global-utilities@e1000 { 83/include/ "qoriq-clockgen2.dtsi"
84 global-utilities@e1000 {
84 compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0"; 85 compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0";
85 ranges = <0x0 0xe1000 0x1000>;
86 #address-cells = <1>;
87 #size-cells = <1>;
88
89 sysclk: sysclk {
90 #clock-cells = <0>;
91 compatible = "fsl,qoriq-sysclk-2.0";
92 clock-output-names = "sysclk";
93 };
94
95 pll0: pll0@800 {
96 #clock-cells = <1>;
97 reg = <0x800 0x4>;
98 compatible = "fsl,qoriq-core-pll-2.0";
99 clocks = <&sysclk>;
100 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
101 };
102
103 pll1: pll1@820 {
104 #clock-cells = <1>;
105 reg = <0x820 0x4>;
106 compatible = "fsl,qoriq-core-pll-2.0";
107 clocks = <&sysclk>;
108 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
109 };
110 86
111 mux0: mux0@0 { 87 mux0: mux0@0 {
112 #clock-cells = <0>; 88 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
index 582381dba1d7..65100b9636b7 100644
--- a/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
@@ -124,33 +124,9 @@
124 compatible = "fsl,b4860-device-config", "fsl,qoriq-device-config-2.0"; 124 compatible = "fsl,b4860-device-config", "fsl,qoriq-device-config-2.0";
125 }; 125 };
126 126
127 clockgen: global-utilities@e1000 { 127/include/ "qoriq-clockgen2.dtsi"
128 global-utilities@e1000 {
128 compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0"; 129 compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0";
129 ranges = <0x0 0xe1000 0x1000>;
130 #address-cells = <1>;
131 #size-cells = <1>;
132
133 sysclk: sysclk {
134 #clock-cells = <0>;
135 compatible = "fsl,qoriq-sysclk-2.0";
136 clock-output-names = "sysclk";
137 };
138
139 pll0: pll0@800 {
140 #clock-cells = <1>;
141 reg = <0x800 0x4>;
142 compatible = "fsl,qoriq-core-pll-2.0";
143 clocks = <&sysclk>;
144 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
145 };
146
147 pll1: pll1@820 {
148 #clock-cells = <1>;
149 reg = <0x820 0x4>;
150 compatible = "fsl,qoriq-core-pll-2.0";
151 clocks = <&sysclk>;
152 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
153 };
154 130
155 mux0: mux0@0 { 131 mux0: mux0@0 {
156 #clock-cells = <0>; 132 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
index 69ce1026c948..efd74db4f9b0 100644
--- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
@@ -305,53 +305,9 @@
305 #sleep-cells = <2>; 305 #sleep-cells = <2>;
306 }; 306 };
307 307
308 clockgen: global-utilities@e1000 { 308/include/ "qoriq-clockgen1.dtsi"
309 global-utilities@e1000 {
309 compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0"; 310 compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
310 ranges = <0x0 0xe1000 0x1000>;
311 reg = <0xe1000 0x1000>;
312 clock-frequency = <0>;
313 #address-cells = <1>;
314 #size-cells = <1>;
315
316 sysclk: sysclk {
317 #clock-cells = <0>;
318 compatible = "fsl,qoriq-sysclk-1.0";
319 clock-output-names = "sysclk";
320 };
321
322 pll0: pll0@800 {
323 #clock-cells = <1>;
324 reg = <0x800 0x4>;
325 compatible = "fsl,qoriq-core-pll-1.0";
326 clocks = <&sysclk>;
327 clock-output-names = "pll0", "pll0-div2";
328 };
329
330 pll1: pll1@820 {
331 #clock-cells = <1>;
332 reg = <0x820 0x4>;
333 compatible = "fsl,qoriq-core-pll-1.0";
334 clocks = <&sysclk>;
335 clock-output-names = "pll1", "pll1-div2";
336 };
337
338 mux0: mux0@0 {
339 #clock-cells = <0>;
340 reg = <0x0 0x4>;
341 compatible = "fsl,qoriq-core-mux-1.0";
342 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
343 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
344 clock-output-names = "cmux0";
345 };
346
347 mux1: mux1@20 {
348 #clock-cells = <0>;
349 reg = <0x20 0x4>;
350 compatible = "fsl,qoriq-core-mux-1.0";
351 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
352 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
353 clock-output-names = "cmux1";
354 };
355 311
356 mux2: mux2@40 { 312 mux2: mux2@40 {
357 #clock-cells = <0>; 313 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
index cd63cb1b1042..d7425ef1ae41 100644
--- a/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
@@ -332,53 +332,9 @@
332 #sleep-cells = <2>; 332 #sleep-cells = <2>;
333 }; 333 };
334 334
335 clockgen: global-utilities@e1000 { 335/include/ "qoriq-clockgen1.dtsi"
336 global-utilities@e1000 {
336 compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0"; 337 compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0";
337 ranges = <0x0 0xe1000 0x1000>;
338 reg = <0xe1000 0x1000>;
339 clock-frequency = <0>;
340 #address-cells = <1>;
341 #size-cells = <1>;
342
343 sysclk: sysclk {
344 #clock-cells = <0>;
345 compatible = "fsl,qoriq-sysclk-1.0";
346 clock-output-names = "sysclk";
347 };
348
349 pll0: pll0@800 {
350 #clock-cells = <1>;
351 reg = <0x800 0x4>;
352 compatible = "fsl,qoriq-core-pll-1.0";
353 clocks = <&sysclk>;
354 clock-output-names = "pll0", "pll0-div2";
355 };
356
357 pll1: pll1@820 {
358 #clock-cells = <1>;
359 reg = <0x820 0x4>;
360 compatible = "fsl,qoriq-core-pll-1.0";
361 clocks = <&sysclk>;
362 clock-output-names = "pll1", "pll1-div2";
363 };
364
365 mux0: mux0@0 {
366 #clock-cells = <0>;
367 reg = <0x0 0x4>;
368 compatible = "fsl,qoriq-core-mux-1.0";
369 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
370 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
371 clock-output-names = "cmux0";
372 };
373
374 mux1: mux1@20 {
375 #clock-cells = <0>;
376 reg = <0x20 0x4>;
377 compatible = "fsl,qoriq-core-mux-1.0";
378 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
379 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
380 clock-output-names = "cmux1";
381 };
382 338
383 mux2: mux2@40 { 339 mux2: mux2@40 {
384 #clock-cells = <0>; 340 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
index 12947ccddf25..7005a4a4cef0 100644
--- a/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
@@ -352,35 +352,9 @@
352 #sleep-cells = <2>; 352 #sleep-cells = <2>;
353 }; 353 };
354 354
355 clockgen: global-utilities@e1000 { 355/include/ "qoriq-clockgen1.dtsi"
356 global-utilities@e1000 {
356 compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0"; 357 compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0";
357 ranges = <0x0 0xe1000 0x1000>;
358 reg = <0xe1000 0x1000>;
359 clock-frequency = <0>;
360 #address-cells = <1>;
361 #size-cells = <1>;
362
363 sysclk: sysclk {
364 #clock-cells = <0>;
365 compatible = "fsl,qoriq-sysclk-1.0";
366 clock-output-names = "sysclk";
367 };
368
369 pll0: pll0@800 {
370 #clock-cells = <1>;
371 reg = <0x800 0x4>;
372 compatible = "fsl,qoriq-core-pll-1.0";
373 clocks = <&sysclk>;
374 clock-output-names = "pll0", "pll0-div2";
375 };
376
377 pll1: pll1@820 {
378 #clock-cells = <1>;
379 reg = <0x820 0x4>;
380 compatible = "fsl,qoriq-core-pll-1.0";
381 clocks = <&sysclk>;
382 clock-output-names = "pll1", "pll1-div2";
383 };
384 358
385 pll2: pll2@840 { 359 pll2: pll2@840 {
386 #clock-cells = <1>; 360 #clock-cells = <1>;
@@ -398,24 +372,6 @@
398 clock-output-names = "pll3", "pll3-div2"; 372 clock-output-names = "pll3", "pll3-div2";
399 }; 373 };
400 374
401 mux0: mux0@0 {
402 #clock-cells = <0>;
403 reg = <0x0 0x4>;
404 compatible = "fsl,qoriq-core-mux-1.0";
405 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
406 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
407 clock-output-names = "cmux0";
408 };
409
410 mux1: mux1@20 {
411 #clock-cells = <0>;
412 reg = <0x20 0x4>;
413 compatible = "fsl,qoriq-core-mux-1.0";
414 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
415 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
416 clock-output-names = "cmux1";
417 };
418
419 mux2: mux2@40 { 375 mux2: mux2@40 {
420 #clock-cells = <0>; 376 #clock-cells = <0>;
421 reg = <0x40 0x4>; 377 reg = <0x40 0x4>;
diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
index 4c4a2b0436b2..55834211bd28 100644
--- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
@@ -337,53 +337,9 @@
337 #sleep-cells = <2>; 337 #sleep-cells = <2>;
338 }; 338 };
339 339
340 clockgen: global-utilities@e1000 { 340/include/ "qoriq-clockgen1.dtsi"
341 global-utilities@e1000 {
341 compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0"; 342 compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
342 ranges = <0x0 0xe1000 0x1000>;
343 reg = <0xe1000 0x1000>;
344 clock-frequency = <0>;
345 #address-cells = <1>;
346 #size-cells = <1>;
347
348 sysclk: sysclk {
349 #clock-cells = <0>;
350 compatible = "fsl,qoriq-sysclk-1.0";
351 clock-output-names = "sysclk";
352 };
353
354 pll0: pll0@800 {
355 #clock-cells = <1>;
356 reg = <0x800 0x4>;
357 compatible = "fsl,qoriq-core-pll-1.0";
358 clocks = <&sysclk>;
359 clock-output-names = "pll0", "pll0-div2";
360 };
361
362 pll1: pll1@820 {
363 #clock-cells = <1>;
364 reg = <0x820 0x4>;
365 compatible = "fsl,qoriq-core-pll-1.0";
366 clocks = <&sysclk>;
367 clock-output-names = "pll1", "pll1-div2";
368 };
369
370 mux0: mux0@0 {
371 #clock-cells = <0>;
372 reg = <0x0 0x4>;
373 compatible = "fsl,qoriq-core-mux-1.0";
374 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
375 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
376 clock-output-names = "cmux0";
377 };
378
379 mux1: mux1@20 {
380 #clock-cells = <0>;
381 reg = <0x20 0x4>;
382 compatible = "fsl,qoriq-core-mux-1.0";
383 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
384 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
385 clock-output-names = "cmux1";
386 };
387 }; 343 };
388 344
389 rcpm: global-utilities@e2000 { 345 rcpm: global-utilities@e2000 {
diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
index 67296fdd9698..6e4cd6ce363c 100644
--- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
@@ -297,53 +297,9 @@
297 #sleep-cells = <2>; 297 #sleep-cells = <2>;
298 }; 298 };
299 299
300 clockgen: global-utilities@e1000 { 300/include/ "qoriq-clockgen1.dtsi"
301 global-utilities@e1000 {
301 compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0"; 302 compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0";
302 ranges = <0x0 0xe1000 0x1000>;
303 reg = <0xe1000 0x1000>;
304 clock-frequency = <0>;
305 #address-cells = <1>;
306 #size-cells = <1>;
307
308 sysclk: sysclk {
309 #clock-cells = <0>;
310 compatible = "fsl,qoriq-sysclk-1.0";
311 clock-output-names = "sysclk";
312 };
313
314 pll0: pll0@800 {
315 #clock-cells = <1>;
316 reg = <0x800 0x4>;
317 compatible = "fsl,qoriq-core-pll-1.0";
318 clocks = <&sysclk>;
319 clock-output-names = "pll0", "pll0-div2";
320 };
321
322 pll1: pll1@820 {
323 #clock-cells = <1>;
324 reg = <0x820 0x4>;
325 compatible = "fsl,qoriq-core-pll-1.0";
326 clocks = <&sysclk>;
327 clock-output-names = "pll1", "pll1-div2";
328 };
329
330 mux0: mux0@0 {
331 #clock-cells = <0>;
332 reg = <0x0 0x4>;
333 compatible = "fsl,qoriq-core-mux-1.0";
334 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
335 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
336 clock-output-names = "cmux0";
337 };
338
339 mux1: mux1@20 {
340 #clock-cells = <0>;
341 reg = <0x20 0x4>;
342 compatible = "fsl,qoriq-core-mux-1.0";
343 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
344 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
345 clock-output-names = "cmux1";
346 };
347 303
348 mux2: mux2@40 { 304 mux2: mux2@40 {
349 #clock-cells = <0>; 305 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
new file mode 100644
index 000000000000..4ece1edbff63
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi
@@ -0,0 +1,85 @@
1/*
2 * QorIQ clock control device tree stub [ controller @ offset 0xe1000 ]
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35global-utilities@e1000 {
36 compatible = "fsl,qoriq-clockgen-1.0";
37 ranges = <0x0 0xe1000 0x1000>;
38 reg = <0xe1000 0x1000>;
39 clock-frequency = <0>;
40 #address-cells = <1>;
41 #size-cells = <1>;
42
43 sysclk: sysclk {
44 #clock-cells = <0>;
45 compatible = "fsl,qoriq-sysclk-1.0", "fixed-clock";
46 clock-output-names = "sysclk";
47 };
48 pll0: pll0@800 {
49 #clock-cells = <1>;
50 reg = <0x800 0x4>;
51 compatible = "fsl,qoriq-core-pll-1.0";
52 clocks = <&sysclk>;
53 clock-output-names = "pll0", "pll0-div2";
54 };
55 pll1: pll1@820 {
56 #clock-cells = <1>;
57 reg = <0x820 0x4>;
58 compatible = "fsl,qoriq-core-pll-1.0";
59 clocks = <&sysclk>;
60 clock-output-names = "pll1", "pll1-div2";
61 };
62 mux0: mux0@0 {
63 #clock-cells = <0>;
64 reg = <0x0 0x4>;
65 compatible = "fsl,qoriq-core-mux-1.0";
66 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
67 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
68 clock-output-names = "cmux0";
69 };
70 mux1: mux1@20 {
71 #clock-cells = <0>;
72 reg = <0x20 0x4>;
73 compatible = "fsl,qoriq-core-mux-1.0";
74 clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
75 clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
76 clock-output-names = "cmux1";
77 };
78 platform_pll: platform-pll@c00 {
79 #clock-cells = <1>;
80 reg = <0xc00 0x4>;
81 compatible = "fsl,qoriq-platform-pll-1.0";
82 clocks = <&sysclk>;
83 clock-output-names = "platform-pll", "platform-pll-div2";
84 };
85};
diff --git a/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi
new file mode 100644
index 000000000000..48e0b6e4ce33
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi
@@ -0,0 +1,68 @@
1/*
2 * QorIQ clock control device tree stub [ controller @ offset 0xe1000 ]
3 *
4 * Copyright 2014 Freescale Semiconductor Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Freescale Semiconductor nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35global-utilities@e1000 {
36 compatible = "fsl,qoriq-clockgen-2.0";
37 ranges = <0x0 0xe1000 0x1000>;
38 reg = <0xe1000 0x1000>;
39 #address-cells = <1>;
40 #size-cells = <1>;
41
42 sysclk: sysclk {
43 #clock-cells = <0>;
44 compatible = "fsl,qoriq-sysclk-2.0", "fixed-clock";
45 clock-output-names = "sysclk";
46 };
47 pll0: pll0@800 {
48 #clock-cells = <1>;
49 reg = <0x800 0x4>;
50 compatible = "fsl,qoriq-core-pll-2.0";
51 clocks = <&sysclk>;
52 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
53 };
54 pll1: pll1@820 {
55 #clock-cells = <1>;
56 reg = <0x820 0x4>;
57 compatible = "fsl,qoriq-core-pll-2.0";
58 clocks = <&sysclk>;
59 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
60 };
61 platform_pll: platform-pll@c00 {
62 #clock-cells = <1>;
63 reg = <0xc00 0x4>;
64 compatible = "fsl,qoriq-platform-pll-2.0";
65 clocks = <&sysclk>;
66 clock-output-names = "platform-pll", "platform-pll-div2";
67 };
68};
diff --git a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
index 12e597eea3c8..15ae462e758f 100644
--- a/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t1040si-post.dtsi
@@ -281,35 +281,9 @@
281 fsl,liodn-bits = <12>; 281 fsl,liodn-bits = <12>;
282 }; 282 };
283 283
284 clockgen: global-utilities@e1000 { 284/include/ "qoriq-clockgen2.dtsi"
285 global-utilities@e1000 {
285 compatible = "fsl,t1040-clockgen", "fsl,qoriq-clockgen-2.0"; 286 compatible = "fsl,t1040-clockgen", "fsl,qoriq-clockgen-2.0";
286 ranges = <0x0 0xe1000 0x1000>;
287 reg = <0xe1000 0x1000>;
288 #address-cells = <1>;
289 #size-cells = <1>;
290
291 sysclk: sysclk {
292 #clock-cells = <0>;
293 compatible = "fsl,qoriq-sysclk-2.0";
294 clock-output-names = "sysclk", "fixed-clock";
295 };
296
297
298 pll0: pll0@800 {
299 #clock-cells = <1>;
300 reg = <0x800 4>;
301 compatible = "fsl,qoriq-core-pll-2.0";
302 clocks = <&sysclk>;
303 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
304 };
305
306 pll1: pll1@820 {
307 #clock-cells = <1>;
308 reg = <0x820 4>;
309 compatible = "fsl,qoriq-core-pll-2.0";
310 clocks = <&sysclk>;
311 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
312 };
313 287
314 mux0: mux0@0 { 288 mux0: mux0@0 {
315 #clock-cells = <0>; 289 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
index aecee9690a88..1ce91e3485a9 100644
--- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -305,34 +305,9 @@
305 fsl,liodn-bits = <12>; 305 fsl,liodn-bits = <12>;
306 }; 306 };
307 307
308 clockgen: global-utilities@e1000 { 308/include/ "qoriq-clockgen2.dtsi"
309 global-utilities@e1000 {
309 compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0"; 310 compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0";
310 ranges = <0x0 0xe1000 0x1000>;
311 reg = <0xe1000 0x1000>;
312 #address-cells = <1>;
313 #size-cells = <1>;
314
315 sysclk: sysclk {
316 #clock-cells = <0>;
317 compatible = "fsl,qoriq-sysclk-2.0";
318 clock-output-names = "sysclk", "fixed-clock";
319 };
320
321 pll0: pll0@800 {
322 #clock-cells = <1>;
323 reg = <0x800 4>;
324 compatible = "fsl,qoriq-core-pll-2.0";
325 clocks = <&sysclk>;
326 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
327 };
328
329 pll1: pll1@820 {
330 #clock-cells = <1>;
331 reg = <0x820 4>;
332 compatible = "fsl,qoriq-core-pll-2.0";
333 clocks = <&sysclk>;
334 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
335 };
336 311
337 mux0: mux0@0 { 312 mux0: mux0@0 {
338 #clock-cells = <0>; 313 #clock-cells = <0>;
diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
index 7e2fc7cdce48..0e96fcabe812 100644
--- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
@@ -368,34 +368,9 @@
368 fsl,liodn-bits = <12>; 368 fsl,liodn-bits = <12>;
369 }; 369 };
370 370
371 clockgen: global-utilities@e1000 { 371/include/ "qoriq-clockgen2.dtsi"
372 global-utilities@e1000 {
372 compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; 373 compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0";
373 ranges = <0x0 0xe1000 0x1000>;
374 reg = <0xe1000 0x1000>;
375 #address-cells = <1>;
376 #size-cells = <1>;
377
378 sysclk: sysclk {
379 #clock-cells = <0>;
380 compatible = "fsl,qoriq-sysclk-2.0";
381 clock-output-names = "sysclk";
382 };
383
384 pll0: pll0@800 {
385 #clock-cells = <1>;
386 reg = <0x800 0x4>;
387 compatible = "fsl,qoriq-core-pll-2.0";
388 clocks = <&sysclk>;
389 clock-output-names = "pll0", "pll0-div2", "pll0-div4";
390 };
391
392 pll1: pll1@820 {
393 #clock-cells = <1>;
394 reg = <0x820 0x4>;
395 compatible = "fsl,qoriq-core-pll-2.0";
396 clocks = <&sysclk>;
397 clock-output-names = "pll1", "pll1-div2", "pll1-div4";
398 };
399 374
400 pll2: pll2@840 { 375 pll2: pll2@840 {
401 #clock-cells = <1>; 376 #clock-cells = <1>;
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts
index 2fed3bc0b990..394ea9c943c9 100644
--- a/arch/powerpc/boot/dts/p3041ds.dts
+++ b/arch/powerpc/boot/dts/p3041ds.dts
@@ -98,6 +98,26 @@
98 reg = <0x68>; 98 reg = <0x68>;
99 interrupts = <0x1 0x1 0 0>; 99 interrupts = <0x1 0x1 0 0>;
100 }; 100 };
101 ina220@40 {
102 compatible = "ti,ina220";
103 reg = <0x40>;
104 shunt-resistor = <1000>;
105 };
106 ina220@41 {
107 compatible = "ti,ina220";
108 reg = <0x41>;
109 shunt-resistor = <1000>;
110 };
111 ina220@44 {
112 compatible = "ti,ina220";
113 reg = <0x44>;
114 shunt-resistor = <1000>;
115 };
116 ina220@45 {
117 compatible = "ti,ina220";
118 reg = <0x45>;
119 shunt-resistor = <1000>;
120 };
101 adt7461@4c { 121 adt7461@4c {
102 compatible = "adi,adt7461"; 122 compatible = "adi,adt7461";
103 reg = <0x4c>; 123 reg = <0x4c>;
diff --git a/arch/powerpc/boot/dts/p5020ds.dts b/arch/powerpc/boot/dts/p5020ds.dts
index 2869fea717dd..b7f3057cd894 100644
--- a/arch/powerpc/boot/dts/p5020ds.dts
+++ b/arch/powerpc/boot/dts/p5020ds.dts
@@ -98,6 +98,26 @@
98 reg = <0x68>; 98 reg = <0x68>;
99 interrupts = <0x1 0x1 0 0>; 99 interrupts = <0x1 0x1 0 0>;
100 }; 100 };
101 ina220@40 {
102 compatible = "ti,ina220";
103 reg = <0x40>;
104 shunt-resistor = <1000>;
105 };
106 ina220@41 {
107 compatible = "ti,ina220";
108 reg = <0x41>;
109 shunt-resistor = <1000>;
110 };
111 ina220@44 {
112 compatible = "ti,ina220";
113 reg = <0x44>;
114 shunt-resistor = <1000>;
115 };
116 ina220@45 {
117 compatible = "ti,ina220";
118 reg = <0x45>;
119 shunt-resistor = <1000>;
120 };
101 adt7461@4c { 121 adt7461@4c {
102 compatible = "adi,adt7461"; 122 compatible = "adi,adt7461";
103 reg = <0x4c>; 123 reg = <0x4c>;
diff --git a/arch/powerpc/boot/dts/p5040ds.dts b/arch/powerpc/boot/dts/p5040ds.dts
index 860b5ccf76c0..7e04bf487c04 100644
--- a/arch/powerpc/boot/dts/p5040ds.dts
+++ b/arch/powerpc/boot/dts/p5040ds.dts
@@ -95,6 +95,26 @@
95 reg = <0x68>; 95 reg = <0x68>;
96 interrupts = <0x1 0x1 0 0>; 96 interrupts = <0x1 0x1 0 0>;
97 }; 97 };
98 ina220@40 {
99 compatible = "ti,ina220";
100 reg = <0x40>;
101 shunt-resistor = <1000>;
102 };
103 ina220@41 {
104 compatible = "ti,ina220";
105 reg = <0x41>;
106 shunt-resistor = <1000>;
107 };
108 ina220@44 {
109 compatible = "ti,ina220";
110 reg = <0x44>;
111 shunt-resistor = <1000>;
112 };
113 ina220@45 {
114 compatible = "ti,ina220";
115 reg = <0x45>;
116 shunt-resistor = <1000>;
117 };
98 adt7461@4c { 118 adt7461@4c {
99 compatible = "adi,adt7461"; 119 compatible = "adi,adt7461";
100 reg = <0x4c>; 120 reg = <0x4c>;
diff --git a/arch/powerpc/boot/dts/t104xrdb.dtsi b/arch/powerpc/boot/dts/t104xrdb.dtsi
index 1cf0f3c5f7e5..187add885cae 100644
--- a/arch/powerpc/boot/dts/t104xrdb.dtsi
+++ b/arch/powerpc/boot/dts/t104xrdb.dtsi
@@ -83,6 +83,13 @@
83 }; 83 };
84 }; 84 };
85 85
86 i2c@118000 {
87 adt7461@4c {
88 compatible = "adi,adt7461";
89 reg = <0x4c>;
90 };
91 };
92
86 i2c@118100 { 93 i2c@118100 {
87 pca9546@77 { 94 pca9546@77 {
88 compatible = "nxp,pca9546"; 95 compatible = "nxp,pca9546";
diff --git a/arch/powerpc/boot/dts/t208xqds.dtsi b/arch/powerpc/boot/dts/t208xqds.dtsi
index 555dc6e03d89..59061834d54e 100644
--- a/arch/powerpc/boot/dts/t208xqds.dtsi
+++ b/arch/powerpc/boot/dts/t208xqds.dtsi
@@ -169,6 +169,17 @@
169 shunt-resistor = <1000>; 169 shunt-resistor = <1000>;
170 }; 170 };
171 }; 171 };
172
173 i2c@3 {
174 #address-cells = <1>;
175 #size-cells = <0>;
176 reg = <0x3>;
177
178 adt7461@4c {
179 compatible = "adi,adt7461";
180 reg = <0x4c>;
181 };
182 };
172 }; 183 };
173 }; 184 };
174 185
diff --git a/arch/powerpc/boot/dts/t4240emu.dts b/arch/powerpc/boot/dts/t4240emu.dts
index bc12127a03fb..decaf357db9c 100644
--- a/arch/powerpc/boot/dts/t4240emu.dts
+++ b/arch/powerpc/boot/dts/t4240emu.dts
@@ -250,9 +250,9 @@
250 fsl,liodn-bits = <12>; 250 fsl,liodn-bits = <12>;
251 }; 251 };
252 252
253 clockgen: global-utilities@e1000 { 253/include/ "fsl/qoriq-clockgen2.dtsi"
254 global-utilities@e1000 {
254 compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0"; 255 compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0";
255 reg = <0xe1000 0x1000>;
256 }; 256 };
257 257
258/include/ "fsl/qoriq-dma-0.dtsi" 258/include/ "fsl/qoriq-dma-0.dtsi"
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index d367a0aece2a..d80161b633f4 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -144,13 +144,24 @@ static char cmdline[BOOT_COMMAND_LINE_SIZE]
144 144
145static void prep_cmdline(void *chosen) 145static void prep_cmdline(void *chosen)
146{ 146{
147 unsigned int getline_timeout = 5000;
148 int v;
149 int n;
150
151 /* Wait-for-input time */
152 n = getprop(chosen, "linux,cmdline-timeout", &v, sizeof(v));
153 if (n == sizeof(v))
154 getline_timeout = v;
155
147 if (cmdline[0] == '\0') 156 if (cmdline[0] == '\0')
148 getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); 157 getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1);
149 158
150 printf("\n\rLinux/PowerPC load: %s", cmdline); 159 printf("\n\rLinux/PowerPC load: %s", cmdline);
160
151 /* If possible, edit the command line */ 161 /* If possible, edit the command line */
152 if (console_ops.edit_cmdline) 162 if (console_ops.edit_cmdline && getline_timeout)
153 console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); 163 console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE, getline_timeout);
164
154 printf("\n\r"); 165 printf("\n\r");
155 166
156 /* Put the command line back into the devtree for the kernel */ 167 /* Put the command line back into the devtree for the kernel */
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 8aad3c55aeda..5e75e1c5518e 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -58,7 +58,7 @@ extern struct dt_ops dt_ops;
58struct console_ops { 58struct console_ops {
59 int (*open)(void); 59 int (*open)(void);
60 void (*write)(const char *buf, int len); 60 void (*write)(const char *buf, int len);
61 void (*edit_cmdline)(char *buf, int len); 61 void (*edit_cmdline)(char *buf, int len, unsigned int getline_timeout);
62 void (*close)(void); 62 void (*close)(void);
63 void *data; 63 void *data;
64}; 64};
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index f2156f07571f..167ee9433de6 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -33,7 +33,7 @@ static void serial_write(const char *buf, int len)
33 scdp->putc(*buf++); 33 scdp->putc(*buf++);
34} 34}
35 35
36static void serial_edit_cmdline(char *buf, int len) 36static void serial_edit_cmdline(char *buf, int len, unsigned int timeout)
37{ 37{
38 int timer = 0, count; 38 int timer = 0, count;
39 char ch, *cp; 39 char ch, *cp;
@@ -44,7 +44,7 @@ static void serial_edit_cmdline(char *buf, int len)
44 cp = &buf[count]; 44 cp = &buf[count];
45 count++; 45 count++;
46 46
47 while (timer++ < 5*1000) { 47 do {
48 if (scdp->tstc()) { 48 if (scdp->tstc()) {
49 while (((ch = scdp->getc()) != '\n') && (ch != '\r')) { 49 while (((ch = scdp->getc()) != '\n') && (ch != '\r')) {
50 /* Test for backspace/delete */ 50 /* Test for backspace/delete */
@@ -70,7 +70,7 @@ static void serial_edit_cmdline(char *buf, int len)
70 break; /* Exit 'timer' loop */ 70 break; /* Exit 'timer' loop */
71 } 71 }
72 udelay(1000); /* 1 msec */ 72 udelay(1000); /* 1 msec */
73 } 73 } while (timer++ < timeout);
74 *cp = 0; 74 *cp = 0;
75} 75}
76 76
diff --git a/arch/powerpc/configs/corenet32_smp_defconfig b/arch/powerpc/configs/corenet32_smp_defconfig
index 688e9e4d29a1..611efe99faeb 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -144,6 +144,7 @@ CONFIG_RTC_DRV_DS1374=y
144CONFIG_RTC_DRV_DS3232=y 144CONFIG_RTC_DRV_DS3232=y
145CONFIG_UIO=y 145CONFIG_UIO=y
146CONFIG_STAGING=y 146CONFIG_STAGING=y
147CONFIG_MEMORY=y
147CONFIG_VIRT_DRIVERS=y 148CONFIG_VIRT_DRIVERS=y
148CONFIG_FSL_HV_MANAGER=y 149CONFIG_FSL_HV_MANAGER=y
149CONFIG_EXT2_FS=y 150CONFIG_EXT2_FS=y
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig
index 6db97e4414b2..be24a18c0d96 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -118,6 +118,7 @@ CONFIG_FSL_DMA=y
118CONFIG_VIRT_DRIVERS=y 118CONFIG_VIRT_DRIVERS=y
119CONFIG_FSL_HV_MANAGER=y 119CONFIG_FSL_HV_MANAGER=y
120CONFIG_FSL_CORENET_CF=y 120CONFIG_FSL_CORENET_CF=y
121CONFIG_MEMORY=y
121CONFIG_EXT2_FS=y 122CONFIG_EXT2_FS=y
122CONFIG_EXT3_FS=y 123CONFIG_EXT3_FS=y
123CONFIG_ISO9660_FS=m 124CONFIG_ISO9660_FS=m
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index d2c415489f72..02395fab19bd 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -215,6 +215,7 @@ CONFIG_RTC_DRV_DS3232=y
215CONFIG_RTC_DRV_CMOS=y 215CONFIG_RTC_DRV_CMOS=y
216CONFIG_DMADEVICES=y 216CONFIG_DMADEVICES=y
217CONFIG_FSL_DMA=y 217CONFIG_FSL_DMA=y
218CONFIG_MEMORY=y
218# CONFIG_NET_DMA is not set 219# CONFIG_NET_DMA is not set
219CONFIG_EXT2_FS=y 220CONFIG_EXT2_FS=y
220CONFIG_EXT3_FS=y 221CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 87460083dbc7..b5d1b82a1b43 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -216,6 +216,7 @@ CONFIG_RTC_DRV_DS3232=y
216CONFIG_RTC_DRV_CMOS=y 216CONFIG_RTC_DRV_CMOS=y
217CONFIG_DMADEVICES=y 217CONFIG_DMADEVICES=y
218CONFIG_FSL_DMA=y 218CONFIG_FSL_DMA=y
219CONFIG_MEMORY=y
219# CONFIG_NET_DMA is not set 220# CONFIG_NET_DMA is not set
220CONFIG_EXT2_FS=y 221CONFIG_EXT2_FS=y
221CONFIG_EXT3_FS=y 222CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index bd3bd573d0ae..59abc620f8e8 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -14,9 +14,9 @@
14 * 14 *
15 * The bitop functions are defined to work on unsigned longs, so for a 15 * The bitop functions are defined to work on unsigned longs, so for a
16 * ppc64 system the bits end up numbered: 16 * ppc64 system the bits end up numbered:
17 * |63..............0|127............64|191...........128|255...........196| 17 * |63..............0|127............64|191...........128|255...........192|
18 * and on ppc32: 18 * and on ppc32:
19 * |31.....0|63....31|95....64|127...96|159..128|191..160|223..192|255..224| 19 * |31.....0|63....32|95....64|127...96|159..128|191..160|223..192|255..224|
20 * 20 *
21 * There are a few little-endian macros used mostly for filesystem 21 * There are a few little-endian macros used mostly for filesystem
22 * bitmaps, these work on similar bit arrays layouts, but 22 * bitmaps, these work on similar bit arrays layouts, but
@@ -213,7 +213,7 @@ static __inline__ unsigned long ffz(unsigned long x)
213 return __ilog2(x & -x); 213 return __ilog2(x & -x);
214} 214}
215 215
216static __inline__ int __ffs(unsigned long x) 216static __inline__ unsigned long __ffs(unsigned long x)
217{ 217{
218 return __ilog2(x & -x); 218 return __ilog2(x & -x);
219} 219}
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index daa5af91163c..22d5a7da9e68 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -448,13 +448,9 @@ extern const char *powerpc_base_platform;
448 CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX) 448 CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX)
449#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2) 449#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
450 450
451#define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \
452 CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \
453 CPU_FTR_ICSWX | CPU_FTR_DABRX )
454
455#ifdef __powerpc64__ 451#ifdef __powerpc64__
456#ifdef CONFIG_PPC_BOOK3E 452#ifdef CONFIG_PPC_BOOK3E
457#define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500 | CPU_FTRS_A2) 453#define CPU_FTRS_POSSIBLE (CPU_FTRS_E6500 | CPU_FTRS_E5500)
458#else 454#else
459#define CPU_FTRS_POSSIBLE \ 455#define CPU_FTRS_POSSIBLE \
460 (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ 456 (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
@@ -505,13 +501,13 @@ enum {
505 501
506#ifdef __powerpc64__ 502#ifdef __powerpc64__
507#ifdef CONFIG_PPC_BOOK3E 503#ifdef CONFIG_PPC_BOOK3E
508#define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500 & CPU_FTRS_A2) 504#define CPU_FTRS_ALWAYS (CPU_FTRS_E6500 & CPU_FTRS_E5500)
509#else 505#else
510#define CPU_FTRS_ALWAYS \ 506#define CPU_FTRS_ALWAYS \
511 (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ 507 (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \
512 CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ 508 CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \
513 CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ 509 CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \
514 CPU_FTRS_POWER8_DD1 & CPU_FTRS_POSSIBLE) 510 CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE)
515#endif 511#endif
516#else 512#else
517enum { 513enum {
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index ca07f9c27335..0652ebe117af 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -39,6 +39,7 @@ struct device_node;
39#define EEH_PROBE_MODE_DEV 0x04 /* From PCI device */ 39#define EEH_PROBE_MODE_DEV 0x04 /* From PCI device */
40#define EEH_PROBE_MODE_DEVTREE 0x08 /* From device tree */ 40#define EEH_PROBE_MODE_DEVTREE 0x08 /* From device tree */
41#define EEH_ENABLE_IO_FOR_LOG 0x10 /* Enable IO for log */ 41#define EEH_ENABLE_IO_FOR_LOG 0x10 /* Enable IO for log */
42#define EEH_EARLY_DUMP_LOG 0x20 /* Dump log immediately */
42 43
43/* 44/*
44 * Delay for PE reset, all in ms 45 * Delay for PE reset, all in ms
@@ -72,6 +73,7 @@ struct device_node;
72#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ 73#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */
73#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ 74#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */
74#define EEH_PE_CFG_BLOCKED (1 << 2) /* Block config access */ 75#define EEH_PE_CFG_BLOCKED (1 << 2) /* Block config access */
76#define EEH_PE_RESET (1 << 3) /* PE reset in progress */
75 77
76#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */ 78#define EEH_PE_KEEP (1 << 8) /* Keep PE on hotplug */
77#define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */ 79#define EEH_PE_CFG_RESTRICTED (1 << 9) /* Block config on error */
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 888d8f3f2524..57d289acb803 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -28,8 +28,7 @@
28 the loader. We need to make sure that it is out of the way of the program 28 the loader. We need to make sure that it is out of the way of the program
29 that it will "exec", and that there is sufficient room for the brk. */ 29 that it will "exec", and that there is sufficient room for the brk. */
30 30
31extern unsigned long randomize_et_dyn(unsigned long base); 31#define ELF_ET_DYN_BASE 0x20000000
32#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
33 32
34#define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0) 33#define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
35 34
diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h
index 77ced0b3d81d..43b6bb1a4a9c 100644
--- a/arch/powerpc/include/asm/fsl_guts.h
+++ b/arch/powerpc/include/asm/fsl_guts.h
@@ -68,7 +68,10 @@ struct ccsr_guts {
68 u8 res0b4[0xc0 - 0xb4]; 68 u8 res0b4[0xc0 - 0xb4];
69 __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register 69 __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register
70 Called 'elbcvselcr' on 86xx SOCs */ 70 Called 'elbcvselcr' on 86xx SOCs */
71 u8 res0c4[0x224 - 0xc4]; 71 u8 res0c4[0x100 - 0xc4];
72 __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
73 There are 16 registers */
74 u8 res140[0x224 - 0x140];
72 __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */ 75 __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
73 __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */ 76 __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
74 u8 res22c[0x604 - 0x22c]; 77 u8 res22c[0x604 - 0x22c];
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 1bbb3013d6aa..8add8b861e8d 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -21,7 +21,12 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
21 21
22#define __ARCH_IRQ_STAT 22#define __ARCH_IRQ_STAT
23 23
24#define local_softirq_pending() __get_cpu_var(irq_stat).__softirq_pending 24#define local_softirq_pending() __this_cpu_read(irq_stat.__softirq_pending)
25
26#define __ARCH_SET_SOFTIRQ_PENDING
27
28#define set_softirq_pending(x) __this_cpu_write(irq_stat.__softirq_pending, (x))
29#define or_softirq_pending(x) __this_cpu_or(irq_stat.__softirq_pending, (x))
25 30
26static inline void ack_bad_irq(unsigned int irq) 31static inline void ack_bad_irq(unsigned int irq)
27{ 32{
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 766b77d527ac..1d53a65b4ec1 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -48,7 +48,7 @@ static inline unsigned int hugepd_shift(hugepd_t hpd)
48#endif /* CONFIG_PPC_BOOK3S_64 */ 48#endif /* CONFIG_PPC_BOOK3S_64 */
49 49
50 50
51static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, 51static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
52 unsigned pdshift) 52 unsigned pdshift)
53{ 53{
54 /* 54 /*
@@ -58,9 +58,9 @@ static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr,
58 */ 58 */
59 unsigned long idx = 0; 59 unsigned long idx = 0;
60 60
61 pte_t *dir = hugepd_page(*hpdp); 61 pte_t *dir = hugepd_page(hpd);
62#ifndef CONFIG_PPC_FSL_BOOK3E 62#ifndef CONFIG_PPC_FSL_BOOK3E
63 idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(*hpdp); 63 idx = (addr & ((1UL << pdshift) - 1)) >> hugepd_shift(hpd);
64#endif 64#endif
65 65
66 return dir + idx; 66 return dir + idx;
@@ -193,7 +193,7 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma,
193} 193}
194 194
195#define hugepd_shift(x) 0 195#define hugepd_shift(x) 0
196static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr, 196static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr,
197 unsigned pdshift) 197 unsigned pdshift)
198{ 198{
199 return 0; 199 return 0;
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 9eaf301ac952..a8d2ef30d473 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -855,9 +855,6 @@ static inline void * bus_to_virt(unsigned long address)
855 855
856#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) 856#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
857 857
858void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
859 size_t size, unsigned long flags);
860
861#endif /* __KERNEL__ */ 858#endif /* __KERNEL__ */
862 859
863#endif /* _ASM_POWERPC_IO_H */ 860#endif /* _ASM_POWERPC_IO_H */
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 307347f8ddbd..c8175a3fe560 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -42,7 +42,7 @@ struct machdep_calls {
42 unsigned long newpp, 42 unsigned long newpp,
43 unsigned long vpn, 43 unsigned long vpn,
44 int bpsize, int apsize, 44 int bpsize, int apsize,
45 int ssize, int local); 45 int ssize, unsigned long flags);
46 void (*hpte_updateboltedpp)(unsigned long newpp, 46 void (*hpte_updateboltedpp)(unsigned long newpp,
47 unsigned long ea, 47 unsigned long ea,
48 int psize, int ssize); 48 int psize, int ssize);
@@ -60,7 +60,7 @@ struct machdep_calls {
60 void (*hugepage_invalidate)(unsigned long vsid, 60 void (*hugepage_invalidate)(unsigned long vsid,
61 unsigned long addr, 61 unsigned long addr,
62 unsigned char *hpte_slot_array, 62 unsigned char *hpte_slot_array,
63 int psize, int ssize); 63 int psize, int ssize, int local);
64 /* special for kexec, to be called in real mode, linear mapping is 64 /* special for kexec, to be called in real mode, linear mapping is
65 * destroyed as well */ 65 * destroyed as well */
66 void (*hpte_clear_all)(void); 66 void (*hpte_clear_all)(void);
@@ -142,7 +142,6 @@ struct machdep_calls {
142#endif 142#endif
143 143
144 void (*restart)(char *cmd); 144 void (*restart)(char *cmd);
145 void (*power_off)(void);
146 void (*halt)(void); 145 void (*halt)(void);
147 void (*panic)(char *str); 146 void (*panic)(char *str);
148 void (*cpu_die)(void); 147 void (*cpu_die)(void);
@@ -292,10 +291,6 @@ struct machdep_calls {
292#ifdef CONFIG_ARCH_RANDOM 291#ifdef CONFIG_ARCH_RANDOM
293 int (*get_random_long)(unsigned long *v); 292 int (*get_random_long)(unsigned long *v);
294#endif 293#endif
295
296#ifdef CONFIG_MEMORY_HOTREMOVE
297 int (*remove_memory)(u64, u64);
298#endif
299}; 294};
300 295
301extern void e500_idle(void); 296extern void e500_idle(void);
@@ -343,16 +338,6 @@ extern sys_ctrler_t sys_ctrler;
343 338
344#endif /* CONFIG_PPC_PMAC */ 339#endif /* CONFIG_PPC_PMAC */
345 340
346
347/* Functions to produce codes on the leds.
348 * The SRC code should be unique for the message category and should
349 * be limited to the lower 24 bits (the upper 8 are set by these funcs),
350 * and (for boot & dump) should be sorted numerically in the order
351 * the events occur.
352 */
353/* Print a boot progress message. */
354void ppc64_boot_msg(unsigned int src, const char *msg);
355
356static inline void log_error(char *buf, unsigned int err_type, int fatal) 341static inline void log_error(char *buf, unsigned int err_type, int fatal)
357{ 342{
358 if (ppc_md.log_error) 343 if (ppc_md.log_error)
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
index 3d11d3ce79ec..986b9e1e1044 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -56,6 +56,7 @@
56 * additional information from the MI_EPN, and MI_TWC registers. 56 * additional information from the MI_EPN, and MI_TWC registers.
57 */ 57 */
58#define SPRN_MI_RPN 790 58#define SPRN_MI_RPN 790
59#define MI_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */
59 60
60/* Define an RPN value for mapping kernel memory to large virtual 61/* Define an RPN value for mapping kernel memory to large virtual
61 * pages for boot initialization. This has real page number of 0, 62 * pages for boot initialization. This has real page number of 0,
@@ -129,6 +130,7 @@
129 * additional information from the MD_EPN, and MD_TWC registers. 130 * additional information from the MD_EPN, and MD_TWC registers.
130 */ 131 */
131#define SPRN_MD_RPN 798 132#define SPRN_MD_RPN 798
133#define MD_SPS16K 0x00000008 /* Small page size (0 = 4k, 1 = 16k) */
132 134
133/* This is a temporary storage register that could be used to save 135/* This is a temporary storage register that could be used to save
134 * a processor working register during a tablewalk. 136 * a processor working register during a tablewalk.
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index aeebc94b2bce..4f13c3ed7acf 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -316,27 +316,33 @@ static inline unsigned long hpt_hash(unsigned long vpn,
316 return hash & 0x7fffffffffUL; 316 return hash & 0x7fffffffffUL;
317} 317}
318 318
319#define HPTE_LOCAL_UPDATE 0x1
320#define HPTE_NOHPTE_UPDATE 0x2
321
319extern int __hash_page_4K(unsigned long ea, unsigned long access, 322extern int __hash_page_4K(unsigned long ea, unsigned long access,
320 unsigned long vsid, pte_t *ptep, unsigned long trap, 323 unsigned long vsid, pte_t *ptep, unsigned long trap,
321 unsigned int local, int ssize, int subpage_prot); 324 unsigned long flags, int ssize, int subpage_prot);
322extern int __hash_page_64K(unsigned long ea, unsigned long access, 325extern int __hash_page_64K(unsigned long ea, unsigned long access,
323 unsigned long vsid, pte_t *ptep, unsigned long trap, 326 unsigned long vsid, pte_t *ptep, unsigned long trap,
324 unsigned int local, int ssize); 327 unsigned long flags, int ssize);
325struct mm_struct; 328struct mm_struct;
326unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap); 329unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap);
327extern int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap); 330extern int hash_page_mm(struct mm_struct *mm, unsigned long ea,
328extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); 331 unsigned long access, unsigned long trap,
332 unsigned long flags);
333extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
334 unsigned long dsisr);
329int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, 335int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
330 pte_t *ptep, unsigned long trap, int local, int ssize, 336 pte_t *ptep, unsigned long trap, unsigned long flags,
331 unsigned int shift, unsigned int mmu_psize); 337 int ssize, unsigned int shift, unsigned int mmu_psize);
332#ifdef CONFIG_TRANSPARENT_HUGEPAGE 338#ifdef CONFIG_TRANSPARENT_HUGEPAGE
333extern int __hash_page_thp(unsigned long ea, unsigned long access, 339extern int __hash_page_thp(unsigned long ea, unsigned long access,
334 unsigned long vsid, pmd_t *pmdp, unsigned long trap, 340 unsigned long vsid, pmd_t *pmdp, unsigned long trap,
335 int local, int ssize, unsigned int psize); 341 unsigned long flags, int ssize, unsigned int psize);
336#else 342#else
337static inline int __hash_page_thp(unsigned long ea, unsigned long access, 343static inline int __hash_page_thp(unsigned long ea, unsigned long access,
338 unsigned long vsid, pmd_t *pmdp, 344 unsigned long vsid, pmd_t *pmdp,
339 unsigned long trap, int local, 345 unsigned long trap, unsigned long flags,
340 int ssize, unsigned int psize) 346 int ssize, unsigned int psize)
341{ 347{
342 BUG(); 348 BUG();
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9124b0ede1fc..5cd8d2fddba9 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -154,6 +154,10 @@ struct opal_sg_list {
154#define OPAL_HANDLE_HMI 98 154#define OPAL_HANDLE_HMI 98
155#define OPAL_REGISTER_DUMP_REGION 101 155#define OPAL_REGISTER_DUMP_REGION 101
156#define OPAL_UNREGISTER_DUMP_REGION 102 156#define OPAL_UNREGISTER_DUMP_REGION 102
157#define OPAL_WRITE_TPO 103
158#define OPAL_READ_TPO 104
159#define OPAL_IPMI_SEND 107
160#define OPAL_IPMI_RECV 108
157 161
158#ifndef __ASSEMBLY__ 162#ifndef __ASSEMBLY__
159 163
@@ -284,62 +288,6 @@ enum OpalMessageType {
284 OPAL_MSG_TYPE_MAX, 288 OPAL_MSG_TYPE_MAX,
285}; 289};
286 290
287/* Machine check related definitions */
288enum OpalMCE_Version {
289 OpalMCE_V1 = 1,
290};
291
292enum OpalMCE_Severity {
293 OpalMCE_SEV_NO_ERROR = 0,
294 OpalMCE_SEV_WARNING = 1,
295 OpalMCE_SEV_ERROR_SYNC = 2,
296 OpalMCE_SEV_FATAL = 3,
297};
298
299enum OpalMCE_Disposition {
300 OpalMCE_DISPOSITION_RECOVERED = 0,
301 OpalMCE_DISPOSITION_NOT_RECOVERED = 1,
302};
303
304enum OpalMCE_Initiator {
305 OpalMCE_INITIATOR_UNKNOWN = 0,
306 OpalMCE_INITIATOR_CPU = 1,
307};
308
309enum OpalMCE_ErrorType {
310 OpalMCE_ERROR_TYPE_UNKNOWN = 0,
311 OpalMCE_ERROR_TYPE_UE = 1,
312 OpalMCE_ERROR_TYPE_SLB = 2,
313 OpalMCE_ERROR_TYPE_ERAT = 3,
314 OpalMCE_ERROR_TYPE_TLB = 4,
315};
316
317enum OpalMCE_UeErrorType {
318 OpalMCE_UE_ERROR_INDETERMINATE = 0,
319 OpalMCE_UE_ERROR_IFETCH = 1,
320 OpalMCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2,
321 OpalMCE_UE_ERROR_LOAD_STORE = 3,
322 OpalMCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4,
323};
324
325enum OpalMCE_SlbErrorType {
326 OpalMCE_SLB_ERROR_INDETERMINATE = 0,
327 OpalMCE_SLB_ERROR_PARITY = 1,
328 OpalMCE_SLB_ERROR_MULTIHIT = 2,
329};
330
331enum OpalMCE_EratErrorType {
332 OpalMCE_ERAT_ERROR_INDETERMINATE = 0,
333 OpalMCE_ERAT_ERROR_PARITY = 1,
334 OpalMCE_ERAT_ERROR_MULTIHIT = 2,
335};
336
337enum OpalMCE_TlbErrorType {
338 OpalMCE_TLB_ERROR_INDETERMINATE = 0,
339 OpalMCE_TLB_ERROR_PARITY = 1,
340 OpalMCE_TLB_ERROR_MULTIHIT = 2,
341};
342
343enum OpalThreadStatus { 291enum OpalThreadStatus {
344 OPAL_THREAD_INACTIVE = 0x0, 292 OPAL_THREAD_INACTIVE = 0x0,
345 OPAL_THREAD_STARTED = 0x1, 293 OPAL_THREAD_STARTED = 0x1,
@@ -452,52 +400,15 @@ struct opal_msg {
452 __be64 params[8]; 400 __be64 params[8];
453}; 401};
454 402
455struct opal_machine_check_event { 403enum {
456 enum OpalMCE_Version version:8; /* 0x00 */ 404 OPAL_IPMI_MSG_FORMAT_VERSION_1 = 1,
457 uint8_t in_use; /* 0x01 */ 405};
458 enum OpalMCE_Severity severity:8; /* 0x02 */
459 enum OpalMCE_Initiator initiator:8; /* 0x03 */
460 enum OpalMCE_ErrorType error_type:8; /* 0x04 */
461 enum OpalMCE_Disposition disposition:8; /* 0x05 */
462 uint8_t reserved_1[2]; /* 0x06 */
463 uint64_t gpr3; /* 0x08 */
464 uint64_t srr0; /* 0x10 */
465 uint64_t srr1; /* 0x18 */
466 union { /* 0x20 */
467 struct {
468 enum OpalMCE_UeErrorType ue_error_type:8;
469 uint8_t effective_address_provided;
470 uint8_t physical_address_provided;
471 uint8_t reserved_1[5];
472 uint64_t effective_address;
473 uint64_t physical_address;
474 uint8_t reserved_2[8];
475 } ue_error;
476
477 struct {
478 enum OpalMCE_SlbErrorType slb_error_type:8;
479 uint8_t effective_address_provided;
480 uint8_t reserved_1[6];
481 uint64_t effective_address;
482 uint8_t reserved_2[16];
483 } slb_error;
484
485 struct {
486 enum OpalMCE_EratErrorType erat_error_type:8;
487 uint8_t effective_address_provided;
488 uint8_t reserved_1[6];
489 uint64_t effective_address;
490 uint8_t reserved_2[16];
491 } erat_error;
492 406
493 struct { 407struct opal_ipmi_msg {
494 enum OpalMCE_TlbErrorType tlb_error_type:8; 408 uint8_t version;
495 uint8_t effective_address_provided; 409 uint8_t netfn;
496 uint8_t reserved_1[6]; 410 uint8_t cmd;
497 uint64_t effective_address; 411 uint8_t data[];
498 uint8_t reserved_2[16];
499 } tlb_error;
500 } u;
501}; 412};
502 413
503/* FSP memory errors handling */ 414/* FSP memory errors handling */
@@ -819,6 +730,9 @@ int64_t opal_rtc_read(__be32 *year_month_day,
819 __be64 *hour_minute_second_millisecond); 730 __be64 *hour_minute_second_millisecond);
820int64_t opal_rtc_write(uint32_t year_month_day, 731int64_t opal_rtc_write(uint32_t year_month_day,
821 uint64_t hour_minute_second_millisecond); 732 uint64_t hour_minute_second_millisecond);
733int64_t opal_tpo_read(uint64_t token, __be32 *year_mon_day, __be32 *hour_min);
734int64_t opal_tpo_write(uint64_t token, uint32_t year_mon_day,
735 uint32_t hour_min);
822int64_t opal_cec_power_down(uint64_t request); 736int64_t opal_cec_power_down(uint64_t request);
823int64_t opal_cec_reboot(void); 737int64_t opal_cec_reboot(void);
824int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset); 738int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
@@ -963,6 +877,10 @@ int64_t opal_handle_hmi(void);
963int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end); 877int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
964int64_t opal_unregister_dump_region(uint32_t id); 878int64_t opal_unregister_dump_region(uint32_t id);
965int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t pe_number); 879int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t pe_number);
880int64_t opal_ipmi_send(uint64_t interface, struct opal_ipmi_msg *msg,
881 uint64_t msg_len);
882int64_t opal_ipmi_recv(uint64_t interface, struct opal_ipmi_msg *msg,
883 uint64_t *msg_len);
966 884
967/* Internal functions */ 885/* Internal functions */
968extern int early_init_dt_scan_opal(unsigned long node, const char *uname, 886extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
@@ -992,8 +910,6 @@ extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg);
992extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); 910extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
993 911
994struct rtc_time; 912struct rtc_time;
995extern int opal_set_rtc_time(struct rtc_time *tm);
996extern void opal_get_rtc_time(struct rtc_time *tm);
997extern unsigned long opal_get_boot_time(void); 913extern unsigned long opal_get_boot_time(void);
998extern void opal_nvram_init(void); 914extern void opal_nvram_init(void);
999extern void opal_flash_init(void); 915extern void opal_flash_init(void);
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index a5139ea6910b..24a386cbb928 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -42,7 +42,6 @@ extern unsigned int debug_smp_processor_id(void); /* from linux/smp.h */
42#define get_slb_shadow() (get_paca()->slb_shadow_ptr) 42#define get_slb_shadow() (get_paca()->slb_shadow_ptr)
43 43
44struct task_struct; 44struct task_struct;
45struct opal_machine_check_event;
46 45
47/* 46/*
48 * Defines the layout of the paca. 47 * Defines the layout of the paca.
@@ -153,12 +152,6 @@ struct paca_struct {
153 u64 tm_scratch; /* TM scratch area for reclaim */ 152 u64 tm_scratch; /* TM scratch area for reclaim */
154#endif 153#endif
155 154
156#ifdef CONFIG_PPC_POWERNV
157 /* Pointer to OPAL machine check event structure set by the
158 * early exception handler for use by high level C handler
159 */
160 struct opal_machine_check_event *opal_mc_evt;
161#endif
162#ifdef CONFIG_PPC_BOOK3S_64 155#ifdef CONFIG_PPC_BOOK3S_64
163 /* Exclusive emergency stack pointer for machine check exception. */ 156 /* Exclusive emergency stack pointer for machine check exception. */
164 void *mc_emergency_sp; 157 void *mc_emergency_sp;
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 26fe1ae15212..69c059887a2c 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -379,12 +379,14 @@ static inline int hugepd_ok(hugepd_t hpd)
379} 379}
380#endif 380#endif
381 381
382#define is_hugepd(pdep) (hugepd_ok(*((hugepd_t *)(pdep)))) 382#define is_hugepd(hpd) (hugepd_ok(hpd))
383#define pgd_huge pgd_huge
383int pgd_huge(pgd_t pgd); 384int pgd_huge(pgd_t pgd);
384#else /* CONFIG_HUGETLB_PAGE */ 385#else /* CONFIG_HUGETLB_PAGE */
385#define is_hugepd(pdep) 0 386#define is_hugepd(pdep) 0
386#define pgd_huge(pgd) 0 387#define pgd_huge(pgd) 0
387#endif /* CONFIG_HUGETLB_PAGE */ 388#endif /* CONFIG_HUGETLB_PAGE */
389#define __hugepd(x) ((hugepd_t) { (x) })
388 390
389struct page; 391struct page;
390extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); 392extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index 945e47adf7db..234e07c47803 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -170,6 +170,25 @@ static inline unsigned long pte_update(pte_t *p,
170#ifdef PTE_ATOMIC_UPDATES 170#ifdef PTE_ATOMIC_UPDATES
171 unsigned long old, tmp; 171 unsigned long old, tmp;
172 172
173#ifdef CONFIG_PPC_8xx
174 unsigned long tmp2;
175
176 __asm__ __volatile__("\
1771: lwarx %0,0,%4\n\
178 andc %1,%0,%5\n\
179 or %1,%1,%6\n\
180 /* 0x200 == Extended encoding, bit 22 */ \
181 /* Bit 22 has to be 1 if neither _PAGE_USER nor _PAGE_RW are set */ \
182 rlwimi %1,%1,32-2,0x200\n /* get _PAGE_USER */ \
183 rlwinm %3,%1,32-1,0x200\n /* get _PAGE_RW */ \
184 or %1,%3,%1\n\
185 xori %1,%1,0x200\n"
186" stwcx. %1,0,%4\n\
187 bne- 1b"
188 : "=&r" (old), "=&r" (tmp), "=m" (*p), "=&r" (tmp2)
189 : "r" (p), "r" (clr), "r" (set), "m" (*p)
190 : "cc" );
191#else /* CONFIG_PPC_8xx */
173 __asm__ __volatile__("\ 192 __asm__ __volatile__("\
1741: lwarx %0,0,%3\n\ 1931: lwarx %0,0,%3\n\
175 andc %1,%0,%4\n\ 194 andc %1,%0,%4\n\
@@ -180,6 +199,7 @@ static inline unsigned long pte_update(pte_t *p,
180 : "=&r" (old), "=&r" (tmp), "=m" (*p) 199 : "=&r" (old), "=&r" (tmp), "=m" (*p)
181 : "r" (p), "r" (clr), "r" (set), "m" (*p) 200 : "r" (p), "r" (clr), "r" (set), "m" (*p)
182 : "cc" ); 201 : "cc" );
202#endif /* CONFIG_PPC_8xx */
183#else /* PTE_ATOMIC_UPDATES */ 203#else /* PTE_ATOMIC_UPDATES */
184 unsigned long old = pte_val(*p); 204 unsigned long old = pte_val(*p);
185 *p = __pte((old & ~clr) | set); 205 *p = __pte((old & ~clr) | set);
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
index 7b935683f268..132ee1d482c2 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
@@ -57,7 +57,21 @@
57#define pgd_present(pgd) (pgd_val(pgd) != 0) 57#define pgd_present(pgd) (pgd_val(pgd) != 0)
58#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0) 58#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0)
59#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) 59#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS)
60#define pgd_page(pgd) virt_to_page(pgd_page_vaddr(pgd)) 60
61#ifndef __ASSEMBLY__
62
63static inline pte_t pgd_pte(pgd_t pgd)
64{
65 return __pte(pgd_val(pgd));
66}
67
68static inline pgd_t pte_pgd(pte_t pte)
69{
70 return __pgd(pte_val(pte));
71}
72extern struct page *pgd_page(pgd_t pgd);
73
74#endif /* !__ASSEMBLY__ */
61 75
62#define pud_offset(pgdp, addr) \ 76#define pud_offset(pgdp, addr) \
63 (((pud_t *) pgd_page_vaddr(*(pgdp))) + \ 77 (((pud_t *) pgd_page_vaddr(*(pgdp))) + \
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
index a56b82fb0609..1de35bbd02a6 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
@@ -38,4 +38,7 @@
38/* Bits to mask out from a PGD/PUD to get to the PMD page */ 38/* Bits to mask out from a PGD/PUD to get to the PMD page */
39#define PUD_MASKED_BITS 0x1ff 39#define PUD_MASKED_BITS 0x1ff
40 40
41#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd })))
42#define pte_pgd(pte) ((pgd_t)pte_pud(pte))
43
41#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */ 44#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 9b4b1904efae..b9dcc936e2d1 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -152,7 +152,7 @@
152#define pmd_none(pmd) (!pmd_val(pmd)) 152#define pmd_none(pmd) (!pmd_val(pmd))
153#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ 153#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
154 || (pmd_val(pmd) & PMD_BAD_BITS)) 154 || (pmd_val(pmd) & PMD_BAD_BITS))
155#define pmd_present(pmd) (pmd_val(pmd) != 0) 155#define pmd_present(pmd) (!pmd_none(pmd))
156#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) 156#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
157#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) 157#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
158extern struct page *pmd_page(pmd_t pmd); 158extern struct page *pmd_page(pmd_t pmd);
@@ -164,9 +164,21 @@ extern struct page *pmd_page(pmd_t pmd);
164#define pud_present(pud) (pud_val(pud) != 0) 164#define pud_present(pud) (pud_val(pud) != 0)
165#define pud_clear(pudp) (pud_val(*(pudp)) = 0) 165#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
166#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) 166#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
167#define pud_page(pud) virt_to_page(pud_page_vaddr(pud))
168 167
168extern struct page *pud_page(pud_t pud);
169
170static inline pte_t pud_pte(pud_t pud)
171{
172 return __pte(pud_val(pud));
173}
174
175static inline pud_t pte_pud(pte_t pte)
176{
177 return __pud(pte_val(pte));
178}
179#define pud_write(pud) pte_write(pud_pte(pud))
169#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) 180#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);})
181#define pgd_write(pgd) pte_write(pgd_pte(pgd))
170 182
171/* 183/*
172 * Find an entry in a page-table-directory. We combine the address region 184 * Find an entry in a page-table-directory. We combine the address region
@@ -422,7 +434,22 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
422 pmd_t *pmdp, pmd_t pmd); 434 pmd_t *pmdp, pmd_t pmd);
423extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, 435extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
424 pmd_t *pmd); 436 pmd_t *pmd);
425 437/*
438 *
439 * For core kernel code by design pmd_trans_huge is never run on any hugetlbfs
440 * page. The hugetlbfs page table walking and mangling paths are totally
441 * separated form the core VM paths and they're differentiated by
442 * VM_HUGETLB being set on vm_flags well before any pmd_trans_huge could run.
443 *
444 * pmd_trans_huge() is defined as false at build time if
445 * CONFIG_TRANSPARENT_HUGEPAGE=n to optimize away code blocks at build
446 * time in such case.
447 *
448 * For ppc64 we need to differntiate from explicit hugepages from THP, because
449 * for THP we also track the subpage details at the pmd level. We don't do
450 * that for explicit huge pages.
451 *
452 */
426static inline int pmd_trans_huge(pmd_t pmd) 453static inline int pmd_trans_huge(pmd_t pmd)
427{ 454{
428 /* 455 /*
@@ -431,16 +458,6 @@ static inline int pmd_trans_huge(pmd_t pmd)
431 return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE); 458 return (pmd_val(pmd) & 0x3) && (pmd_val(pmd) & _PAGE_THP_HUGE);
432} 459}
433 460
434static inline int pmd_large(pmd_t pmd)
435{
436 /*
437 * leaf pte for huge page, bottom two bits != 00
438 */
439 if (pmd_trans_huge(pmd))
440 return pmd_val(pmd) & _PAGE_PRESENT;
441 return 0;
442}
443
444static inline int pmd_trans_splitting(pmd_t pmd) 461static inline int pmd_trans_splitting(pmd_t pmd)
445{ 462{
446 if (pmd_trans_huge(pmd)) 463 if (pmd_trans_huge(pmd))
@@ -451,6 +468,14 @@ static inline int pmd_trans_splitting(pmd_t pmd)
451extern int has_transparent_hugepage(void); 468extern int has_transparent_hugepage(void);
452#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ 469#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
453 470
471static inline int pmd_large(pmd_t pmd)
472{
473 /*
474 * leaf pte for huge page, bottom two bits != 00
475 */
476 return ((pmd_val(pmd) & 0x3) != 0x0);
477}
478
454static inline pte_t pmd_pte(pmd_t pmd) 479static inline pte_t pmd_pte(pmd_t pmd)
455{ 480{
456 return __pte(pmd_val(pmd)); 481 return __pte(pmd_val(pmd));
@@ -576,6 +601,5 @@ static inline int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl,
576 */ 601 */
577 return true; 602 return true;
578} 603}
579
580#endif /* __ASSEMBLY__ */ 604#endif /* __ASSEMBLY__ */
581#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */ 605#endif /* _ASM_POWERPC_PGTABLE_PPC64_H_ */
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 316f9a5da173..a8805fee0df9 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -274,11 +274,9 @@ extern void paging_init(void);
274 */ 274 */
275extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); 275extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
276 276
277extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr,
278 unsigned long end, int write, struct page **pages, int *nr);
279
280extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, 277extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
281 unsigned long end, int write, struct page **pages, int *nr); 278 unsigned long end, int write,
279 struct page **pages, int *nr);
282#ifndef CONFIG_TRANSPARENT_HUGEPAGE 280#ifndef CONFIG_TRANSPARENT_HUGEPAGE
283#define pmd_large(pmd) 0 281#define pmd_large(pmd) 0
284#define has_transparent_hugepage() 0 282#define has_transparent_hugepage() 0
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index dda7ac4c80bd..29c3798cf800 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -451,7 +451,7 @@ extern unsigned long cpuidle_disable;
451enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; 451enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
452 452
453extern int powersave_nap; /* set if nap mode can be used in idle loop */ 453extern int powersave_nap; /* set if nap mode can be used in idle loop */
454extern void power7_nap(int check_irq); 454extern unsigned long power7_nap(int check_irq);
455extern void power7_sleep(void); 455extern void power7_sleep(void);
456extern void flush_instruction_cache(void); 456extern void flush_instruction_cache(void);
457extern void hard_reset_now(void); 457extern void hard_reset_now(void);
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
index d44826e4ff97..daa4616e61c4 100644
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -48,19 +48,22 @@
48 */ 48 */
49#define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */ 49#define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */
50#define _PAGE_USER 0x0800 /* msb PP bits */ 50#define _PAGE_USER 0x0800 /* msb PP bits */
51/* set when neither _PAGE_USER nor _PAGE_RW are set */
52#define _PAGE_KNLRO 0x0200
51 53
52#define _PMD_PRESENT 0x0001 54#define _PMD_PRESENT 0x0001
53#define _PMD_BAD 0x0ff0 55#define _PMD_BAD 0x0ff0
54#define _PMD_PAGE_MASK 0x000c 56#define _PMD_PAGE_MASK 0x000c
55#define _PMD_PAGE_8M 0x000c 57#define _PMD_PAGE_8M 0x000c
56 58
57#define _PTE_NONE_MASK _PAGE_ACCESSED 59#define _PTE_NONE_MASK _PAGE_KNLRO
58 60
59/* Until my rework is finished, 8xx still needs atomic PTE updates */ 61/* Until my rework is finished, 8xx still needs atomic PTE updates */
60#define PTE_ATOMIC_UPDATES 1 62#define PTE_ATOMIC_UPDATES 1
61 63
62/* We need to add _PAGE_SHARED to kernel pages */ 64/* We need to add _PAGE_SHARED to kernel pages */
63#define _PAGE_KERNEL_RO (_PAGE_SHARED) 65#define _PAGE_KERNEL_RO (_PAGE_SHARED | _PAGE_KNLRO)
66#define _PAGE_KERNEL_ROX (_PAGE_EXEC | _PAGE_KNLRO)
64#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) 67#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
65 68
66#endif /* __KERNEL__ */ 69#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 11ba86e17631..fbdf18cf954c 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -8,7 +8,6 @@ extern void ppc_printk_progress(char *s, unsigned short hex);
8 8
9extern unsigned int rtas_data; 9extern unsigned int rtas_data;
10extern int mem_init_done; /* set on boot once kmalloc can be called */ 10extern int mem_init_done; /* set on boot once kmalloc can be called */
11extern int init_bootmem_done; /* set once bootmem is available */
12extern unsigned long long memory_limit; 11extern unsigned long long memory_limit;
13extern unsigned long klimit; 12extern unsigned long klimit;
14extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); 13extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
@@ -24,7 +23,7 @@ extern void reloc_got2(unsigned long);
24#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x))) 23#define PTRRELOC(x) ((typeof(x)) add_reloc_offset((unsigned long)(x)))
25 24
26void check_for_initrd(void); 25void check_for_initrd(void);
27void do_init_bootmem(void); 26void initmem_init(void);
28void setup_panic(void); 27void setup_panic(void);
29#define ARCH_PANIC_TIMEOUT 180 28#define ARCH_PANIC_TIMEOUT 180
30 29
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index b034ecdb7c74..ebc4f165690a 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -71,13 +71,12 @@ struct thread_info {
71#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) 71#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
72 72
73/* how to get the thread information struct from C */ 73/* how to get the thread information struct from C */
74register unsigned long __current_r1 asm("r1");
74static inline struct thread_info *current_thread_info(void) 75static inline struct thread_info *current_thread_info(void)
75{ 76{
76 register unsigned long sp asm("r1");
77
78 /* gcc4, at least, is smart enough to turn this into a single 77 /* gcc4, at least, is smart enough to turn this into a single
79 * rlwinm for ppc32 and clrrdi for ppc64 */ 78 * rlwinm for ppc32 and clrrdi for ppc64 */
80 return (struct thread_info *)(sp & ~(THREAD_SIZE-1)); 79 return (struct thread_info *)(__current_r1 & ~(THREAD_SIZE-1));
81} 80}
82 81
83#endif /* __ASSEMBLY__ */ 82#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index 2def01ed0cb2..23d351ca0303 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -107,14 +107,14 @@ extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch);
107 107
108static inline void arch_enter_lazy_mmu_mode(void) 108static inline void arch_enter_lazy_mmu_mode(void)
109{ 109{
110 struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); 110 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
111 111
112 batch->active = 1; 112 batch->active = 1;
113} 113}
114 114
115static inline void arch_leave_lazy_mmu_mode(void) 115static inline void arch_leave_lazy_mmu_mode(void)
116{ 116{
117 struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); 117 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
118 118
119 if (batch->index) 119 if (batch->index)
120 __flush_tlb_pending(batch); 120 __flush_tlb_pending(batch);
@@ -125,9 +125,11 @@ static inline void arch_leave_lazy_mmu_mode(void)
125 125
126 126
127extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, 127extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize,
128 int ssize, int local); 128 int ssize, unsigned long flags);
129extern void flush_hash_range(unsigned long number, int local); 129extern void flush_hash_range(unsigned long number, int local);
130 130extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
131 pmd_t *pmdp, unsigned int psize, int ssize,
132 unsigned long flags);
131 133
132static inline void local_flush_tlb_mm(struct mm_struct *mm) 134static inline void local_flush_tlb_mm(struct mm_struct *mm)
133{ 135{
diff --git a/arch/powerpc/include/asm/vga.h b/arch/powerpc/include/asm/vga.h
index a2eac409c1ec..e5f8dd366212 100644
--- a/arch/powerpc/include/asm/vga.h
+++ b/arch/powerpc/include/asm/vga.h
@@ -38,12 +38,10 @@ static inline u16 scr_readw(volatile const u16 *addr)
38 38
39#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */ 39#endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
40 40
41extern unsigned long vgacon_remap_base;
42
43#ifdef __powerpc64__ 41#ifdef __powerpc64__
44#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap((x), s)) 42#define VGA_MAP_MEM(x,s) ((unsigned long) ioremap((x), s))
45#else 43#else
46#define VGA_MAP_MEM(x,s) (x + vgacon_remap_base) 44#define VGA_MAP_MEM(x,s) (x)
47#endif 45#endif
48 46
49#define vga_readb(x) (*(x)) 47#define vga_readb(x) (*(x))
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index 0d050ea37a04..6997f4a271df 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -98,7 +98,7 @@ DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
98 98
99static inline void xics_push_cppr(unsigned int vec) 99static inline void xics_push_cppr(unsigned int vec)
100{ 100{
101 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); 101 struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
102 102
103 if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1)) 103 if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
104 return; 104 return;
@@ -111,7 +111,7 @@ static inline void xics_push_cppr(unsigned int vec)
111 111
112static inline unsigned char xics_pop_cppr(void) 112static inline unsigned char xics_pop_cppr(void)
113{ 113{
114 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); 114 struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
115 115
116 if (WARN_ON(os_cppr->index < 1)) 116 if (WARN_ON(os_cppr->index < 1))
117 return LOWEST_PRIORITY; 117 return LOWEST_PRIORITY;
@@ -121,7 +121,7 @@ static inline unsigned char xics_pop_cppr(void)
121 121
122static inline void xics_set_base_cppr(unsigned char cppr) 122static inline void xics_set_base_cppr(unsigned char cppr)
123{ 123{
124 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); 124 struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
125 125
126 /* we only really want to set the priority when there's 126 /* we only really want to set the priority when there's
127 * just one cppr value on the stack 127 * just one cppr value on the stack
@@ -133,7 +133,7 @@ static inline void xics_set_base_cppr(unsigned char cppr)
133 133
134static inline unsigned char xics_cppr_top(void) 134static inline unsigned char xics_cppr_top(void)
135{ 135{
136 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); 136 struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
137 137
138 return os_cppr->stack[os_cppr->index]; 138 return os_cppr->stack[os_cppr->index];
139} 139}
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 34f55524d456..86150fbb42c3 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -908,7 +908,7 @@ int fix_alignment(struct pt_regs *regs)
908 flush_fp_to_thread(current); 908 flush_fp_to_thread(current);
909 } 909 }
910 910
911 if ((nb == 16)) { 911 if (nb == 16) {
912 if (flags & F) { 912 if (flags & F) {
913 /* Special case for 16-byte FP loads and stores */ 913 /* Special case for 16-byte FP loads and stores */
914 PPC_WARN_ALIGNMENT(fp_pair, regs); 914 PPC_WARN_ALIGNMENT(fp_pair, regs);
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 9d7dede2847c..c161ef3f28a1 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -726,12 +726,5 @@ int main(void)
726 arch.timing_last_enter.tv32.tbl)); 726 arch.timing_last_enter.tv32.tbl));
727#endif 727#endif
728 728
729#ifdef CONFIG_PPC_POWERNV
730 DEFINE(OPAL_MC_GPR3, offsetof(struct opal_machine_check_event, gpr3));
731 DEFINE(OPAL_MC_SRR0, offsetof(struct opal_machine_check_event, srr0));
732 DEFINE(OPAL_MC_SRR1, offsetof(struct opal_machine_check_event, srr1));
733 DEFINE(PACA_OPAL_MC_EVT, offsetof(struct paca_struct, opal_mc_evt));
734#endif
735
736 return 0; 729 return 0;
737} 730}
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index c78e6dac4d7d..cfa0f81a5bb0 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -12,7 +12,6 @@
12#undef DEBUG 12#undef DEBUG
13 13
14#include <linux/crash_dump.h> 14#include <linux/crash_dump.h>
15#include <linux/bootmem.h>
16#include <linux/io.h> 15#include <linux/io.h>
17#include <linux/memblock.h> 16#include <linux/memblock.h>
18#include <asm/code-patching.h> 17#include <asm/code-patching.h>
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index d55c76c571f3..f4217819cc31 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -41,7 +41,7 @@ void doorbell_exception(struct pt_regs *regs)
41 41
42 may_hard_irq_enable(); 42 may_hard_irq_enable();
43 43
44 __get_cpu_var(irq_stat).doorbell_irqs++; 44 __this_cpu_inc(irq_stat.doorbell_irqs);
45 45
46 smp_ipi_demux(); 46 smp_ipi_demux();
47 47
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 2248a1999c64..e1b6d8e17289 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -143,6 +143,8 @@ static int __init eeh_setup(char *str)
143{ 143{
144 if (!strcmp(str, "off")) 144 if (!strcmp(str, "off"))
145 eeh_add_flag(EEH_FORCE_DISABLED); 145 eeh_add_flag(EEH_FORCE_DISABLED);
146 else if (!strcmp(str, "early_log"))
147 eeh_add_flag(EEH_EARLY_DUMP_LOG);
146 148
147 return 1; 149 return 1;
148} 150}
@@ -758,30 +760,41 @@ static void eeh_reset_pe_once(struct eeh_pe *pe)
758int eeh_reset_pe(struct eeh_pe *pe) 760int eeh_reset_pe(struct eeh_pe *pe)
759{ 761{
760 int flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); 762 int flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE);
761 int i, rc; 763 int i, state, ret;
764
765 /* Mark as reset and block config space */
766 eeh_pe_state_mark(pe, EEH_PE_RESET | EEH_PE_CFG_BLOCKED);
762 767
763 /* Take three shots at resetting the bus */ 768 /* Take three shots at resetting the bus */
764 for (i=0; i<3; i++) { 769 for (i = 0; i < 3; i++) {
765 eeh_reset_pe_once(pe); 770 eeh_reset_pe_once(pe);
766 771
767 /* 772 /*
768 * EEH_PE_ISOLATED is expected to be removed after 773 * EEH_PE_ISOLATED is expected to be removed after
769 * BAR restore. 774 * BAR restore.
770 */ 775 */
771 rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); 776 state = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC);
772 if ((rc & flags) == flags) 777 if ((state & flags) == flags) {
773 return 0; 778 ret = 0;
779 goto out;
780 }
774 781
775 if (rc < 0) { 782 if (state < 0) {
776 pr_err("%s: Unrecoverable slot failure on PHB#%d-PE#%x", 783 pr_warn("%s: Unrecoverable slot failure on PHB#%d-PE#%x",
777 __func__, pe->phb->global_number, pe->addr); 784 __func__, pe->phb->global_number, pe->addr);
778 return -1; 785 ret = -ENOTRECOVERABLE;
786 goto out;
779 } 787 }
780 pr_err("EEH: bus reset %d failed on PHB#%d-PE#%x, rc=%d\n", 788
781 i+1, pe->phb->global_number, pe->addr, rc); 789 /* We might run out of credits */
790 ret = -EIO;
791 pr_warn("%s: Failure %d resetting PHB#%x-PE#%x\n (%d)\n",
792 __func__, state, pe->phb->global_number, pe->addr, (i + 1));
782 } 793 }
783 794
784 return -1; 795out:
796 eeh_pe_state_clear(pe, EEH_PE_RESET | EEH_PE_CFG_BLOCKED);
797 return ret;
785} 798}
786 799
787/** 800/**
@@ -920,11 +933,8 @@ int eeh_init(void)
920 pr_warn("%s: Platform EEH operation not found\n", 933 pr_warn("%s: Platform EEH operation not found\n",
921 __func__); 934 __func__);
922 return -EEXIST; 935 return -EEXIST;
923 } else if ((ret = eeh_ops->init())) { 936 } else if ((ret = eeh_ops->init()))
924 pr_warn("%s: Failed to call platform init function (%d)\n",
925 __func__, ret);
926 return ret; 937 return ret;
927 }
928 938
929 /* Initialize EEH event */ 939 /* Initialize EEH event */
930 ret = eeh_event_init(); 940 ret = eeh_event_init();
@@ -1209,6 +1219,7 @@ int eeh_unfreeze_pe(struct eeh_pe *pe, bool sw_state)
1209static struct pci_device_id eeh_reset_ids[] = { 1219static struct pci_device_id eeh_reset_ids[] = {
1210 { PCI_DEVICE(0x19a2, 0x0710) }, /* Emulex, BE */ 1220 { PCI_DEVICE(0x19a2, 0x0710) }, /* Emulex, BE */
1211 { PCI_DEVICE(0x10df, 0xe220) }, /* Emulex, Lancer */ 1221 { PCI_DEVICE(0x10df, 0xe220) }, /* Emulex, Lancer */
1222 { PCI_DEVICE(0x14e4, 0x1657) }, /* Broadcom BCM5719 */
1212 { 0 } 1223 { 0 }
1213}; 1224};
1214 1225
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 6535936bdf27..b17e793ba67e 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -528,13 +528,11 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe)
528 eeh_pe_dev_traverse(pe, eeh_report_error, &result); 528 eeh_pe_dev_traverse(pe, eeh_report_error, &result);
529 529
530 /* Issue reset */ 530 /* Issue reset */
531 eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
532 ret = eeh_reset_pe(pe); 531 ret = eeh_reset_pe(pe);
533 if (ret) { 532 if (ret) {
534 eeh_pe_state_clear(pe, EEH_PE_RECOVERING | EEH_PE_CFG_BLOCKED); 533 eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
535 return ret; 534 return ret;
536 } 535 }
537 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
538 536
539 /* Unfreeze the PE */ 537 /* Unfreeze the PE */
540 ret = eeh_clear_pe_frozen_state(pe, true); 538 ret = eeh_clear_pe_frozen_state(pe, true);
@@ -601,19 +599,15 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
601 * config accesses. So we prefer to block them. However, controlled 599 * config accesses. So we prefer to block them. However, controlled
602 * PCI config accesses initiated from EEH itself are allowed. 600 * PCI config accesses initiated from EEH itself are allowed.
603 */ 601 */
604 eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED);
605 rc = eeh_reset_pe(pe); 602 rc = eeh_reset_pe(pe);
606 if (rc) { 603 if (rc)
607 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
608 return rc; 604 return rc;
609 }
610 605
611 pci_lock_rescan_remove(); 606 pci_lock_rescan_remove();
612 607
613 /* Restore PE */ 608 /* Restore PE */
614 eeh_ops->configure_bridge(pe); 609 eeh_ops->configure_bridge(pe);
615 eeh_pe_restore_bars(pe); 610 eeh_pe_restore_bars(pe);
616 eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED);
617 611
618 /* Clear frozen state */ 612 /* Clear frozen state */
619 rc = eeh_clear_pe_frozen_state(pe, false); 613 rc = eeh_clear_pe_frozen_state(pe, false);
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 22b45a4955cd..10a093579191 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -1424,12 +1424,18 @@ _GLOBAL(ftrace_graph_caller)
1424 lwz r4, 44(r1) 1424 lwz r4, 44(r1)
1425 subi r4, r4, MCOUNT_INSN_SIZE 1425 subi r4, r4, MCOUNT_INSN_SIZE
1426 1426
1427 /* get the parent address */ 1427 /* Grab the LR out of the caller stack frame */
1428 addi r3, r1, 52 1428 lwz r3,52(r1)
1429 1429
1430 bl prepare_ftrace_return 1430 bl prepare_ftrace_return
1431 nop 1431 nop
1432 1432
1433 /*
1434 * prepare_ftrace_return gives us the address we divert to.
1435 * Change the LR in the callers stack frame to this.
1436 */
1437 stw r3,52(r1)
1438
1433 MCOUNT_RESTORE_FRAME 1439 MCOUNT_RESTORE_FRAME
1434 /* old link register ends up in ctr reg */ 1440 /* old link register ends up in ctr reg */
1435 bctr 1441 bctr
@@ -1457,4 +1463,4 @@ _GLOBAL(return_to_handler)
1457 blr 1463 blr
1458#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 1464#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
1459 1465
1460#endif /* CONFIG_MCOUNT */ 1466#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 0905c8da90f1..194e46dcf08d 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1227,13 +1227,20 @@ _GLOBAL(ftrace_graph_caller)
1227 ld r4, 128(r1) 1227 ld r4, 128(r1)
1228 subi r4, r4, MCOUNT_INSN_SIZE 1228 subi r4, r4, MCOUNT_INSN_SIZE
1229 1229
1230 /* get the parent address */ 1230 /* Grab the LR out of the caller stack frame */
1231 ld r11, 112(r1) 1231 ld r11, 112(r1)
1232 addi r3, r11, 16 1232 ld r3, 16(r11)
1233 1233
1234 bl prepare_ftrace_return 1234 bl prepare_ftrace_return
1235 nop 1235 nop
1236 1236
1237 /*
1238 * prepare_ftrace_return gives us the address we divert to.
1239 * Change the LR in the callers stack frame to this.
1240 */
1241 ld r11, 112(r1)
1242 std r3, 16(r11)
1243
1237 ld r0, 128(r1) 1244 ld r0, 128(r1)
1238 mtlr r0 1245 mtlr r0
1239 addi r1, r1, 112 1246 addi r1, r1, 112
@@ -1241,28 +1248,6 @@ _GLOBAL(ftrace_graph_caller)
1241 1248
1242_GLOBAL(return_to_handler) 1249_GLOBAL(return_to_handler)
1243 /* need to save return values */ 1250 /* need to save return values */
1244 std r4, -24(r1)
1245 std r3, -16(r1)
1246 std r31, -8(r1)
1247 mr r31, r1
1248 stdu r1, -112(r1)
1249
1250 bl ftrace_return_to_handler
1251 nop
1252
1253 /* return value has real return address */
1254 mtlr r3
1255
1256 ld r1, 0(r1)
1257 ld r4, -24(r1)
1258 ld r3, -16(r1)
1259 ld r31, -8(r1)
1260
1261 /* Jump back to real return address */
1262 blr
1263
1264_GLOBAL(mod_return_to_handler)
1265 /* need to save return values */
1266 std r4, -32(r1) 1251 std r4, -32(r1)
1267 std r3, -24(r1) 1252 std r3, -24(r1)
1268 /* save TOC */ 1253 /* save TOC */
@@ -1272,7 +1257,7 @@ _GLOBAL(mod_return_to_handler)
1272 stdu r1, -112(r1) 1257 stdu r1, -112(r1)
1273 1258
1274 /* 1259 /*
1275 * We are in a module using the module's TOC. 1260 * We might be called from a module.
1276 * Switch to our TOC to run inside the core kernel. 1261 * Switch to our TOC to run inside the core kernel.
1277 */ 1262 */
1278 ld r2, PACATOC(r13) 1263 ld r2, PACATOC(r13)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 72e783ea0681..db08382e19f1 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -131,6 +131,8 @@ BEGIN_FTR_SECTION
1311: 1311:
132#endif 132#endif
133 133
134 /* Return SRR1 from power7_nap() */
135 mfspr r3,SPRN_SRR1
134 beq cr1,2f 136 beq cr1,2f
135 b power7_wakeup_noloss 137 b power7_wakeup_noloss
1362: b power7_wakeup_loss 1382: b power7_wakeup_loss
@@ -292,15 +294,26 @@ decrementer_pSeries:
292 . = 0xc00 294 . = 0xc00
293 .globl system_call_pSeries 295 .globl system_call_pSeries
294system_call_pSeries: 296system_call_pSeries:
295 HMT_MEDIUM 297 /*
298 * If CONFIG_KVM_BOOK3S_64_HANDLER is set, save the PPR (on systems
299 * that support it) before changing to HMT_MEDIUM. That allows the KVM
300 * code to save that value into the guest state (it is the guest's PPR
301 * value). Otherwise just change to HMT_MEDIUM as userspace has
302 * already saved the PPR.
303 */
296#ifdef CONFIG_KVM_BOOK3S_64_HANDLER 304#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
297 SET_SCRATCH0(r13) 305 SET_SCRATCH0(r13)
298 GET_PACA(r13) 306 GET_PACA(r13)
299 std r9,PACA_EXGEN+EX_R9(r13) 307 std r9,PACA_EXGEN+EX_R9(r13)
308 OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR);
309 HMT_MEDIUM;
300 std r10,PACA_EXGEN+EX_R10(r13) 310 std r10,PACA_EXGEN+EX_R10(r13)
311 OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r9, CPU_FTR_HAS_PPR);
301 mfcr r9 312 mfcr r9
302 KVMTEST(0xc00) 313 KVMTEST(0xc00)
303 GET_SCRATCH0(r13) 314 GET_SCRATCH0(r13)
315#else
316 HMT_MEDIUM;
304#endif 317#endif
305 SYSCALL_PSERIES_1 318 SYSCALL_PSERIES_1
306 SYSCALL_PSERIES_2_RFID 319 SYSCALL_PSERIES_2_RFID
@@ -1301,23 +1314,6 @@ hmi_exception_after_realmode:
1301 EXCEPTION_PROLOG_0(PACA_EXGEN) 1314 EXCEPTION_PROLOG_0(PACA_EXGEN)
1302 b hmi_exception_hv 1315 b hmi_exception_hv
1303 1316
1304#ifdef CONFIG_PPC_POWERNV
1305_GLOBAL(opal_mc_secondary_handler)
1306 HMT_MEDIUM_PPR_DISCARD
1307 SET_SCRATCH0(r13)
1308 GET_PACA(r13)
1309 clrldi r3,r3,2
1310 tovirt(r3,r3)
1311 std r3,PACA_OPAL_MC_EVT(r13)
1312 ld r13,OPAL_MC_SRR0(r3)
1313 mtspr SPRN_SRR0,r13
1314 ld r13,OPAL_MC_SRR1(r3)
1315 mtspr SPRN_SRR1,r13
1316 ld r3,OPAL_MC_GPR3(r3)
1317 GET_SCRATCH0(r13)
1318 b machine_check_pSeries
1319#endif /* CONFIG_PPC_POWERNV */
1320
1321 1317
1322#define MACHINE_CHECK_HANDLER_WINDUP \ 1318#define MACHINE_CHECK_HANDLER_WINDUP \
1323 /* Clear MSR_RI before setting SRR0 and SRR1. */\ 1319 /* Clear MSR_RI before setting SRR0 and SRR1. */\
@@ -1571,9 +1567,11 @@ do_hash_page:
1571 * r3 contains the faulting address 1567 * r3 contains the faulting address
1572 * r4 contains the required access permissions 1568 * r4 contains the required access permissions
1573 * r5 contains the trap number 1569 * r5 contains the trap number
1570 * r6 contains dsisr
1574 * 1571 *
1575 * at return r3 = 0 for success, 1 for page fault, negative for error 1572 * at return r3 = 0 for success, 1 for page fault, negative for error
1576 */ 1573 */
1574 ld r6,_DSISR(r1)
1577 bl hash_page /* build HPTE if possible */ 1575 bl hash_page /* build HPTE if possible */
1578 cmpdi r3,0 /* see if hash_page succeeded */ 1576 cmpdi r3,0 /* see if hash_page succeeded */
1579 1577
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index e66af6d265e8..44d4d8eb3c85 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -510,79 +510,36 @@ int ftrace_disable_ftrace_graph_caller(void)
510} 510}
511#endif /* CONFIG_DYNAMIC_FTRACE */ 511#endif /* CONFIG_DYNAMIC_FTRACE */
512 512
513#ifdef CONFIG_PPC64
514extern void mod_return_to_handler(void);
515#endif
516
517/* 513/*
518 * Hook the return address and push it in the stack of return addrs 514 * Hook the return address and push it in the stack of return addrs
519 * in current thread info. 515 * in current thread info. Return the address we want to divert to.
520 */ 516 */
521void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) 517unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
522{ 518{
523 unsigned long old;
524 int faulted;
525 struct ftrace_graph_ent trace; 519 struct ftrace_graph_ent trace;
526 unsigned long return_hooker = (unsigned long)&return_to_handler; 520 unsigned long return_hooker;
527 521
528 if (unlikely(ftrace_graph_is_dead())) 522 if (unlikely(ftrace_graph_is_dead()))
529 return; 523 goto out;
530 524
531 if (unlikely(atomic_read(&current->tracing_graph_pause))) 525 if (unlikely(atomic_read(&current->tracing_graph_pause)))
532 return; 526 goto out;
533
534#ifdef CONFIG_PPC64
535 /* non core kernel code needs to save and restore the TOC */
536 if (REGION_ID(self_addr) != KERNEL_REGION_ID)
537 return_hooker = (unsigned long)&mod_return_to_handler;
538#endif
539
540 return_hooker = ppc_function_entry((void *)return_hooker);
541 527
542 /* 528 return_hooker = ppc_function_entry(return_to_handler);
543 * Protect against fault, even if it shouldn't
544 * happen. This tool is too much intrusive to
545 * ignore such a protection.
546 */
547 asm volatile(
548 "1: " PPC_LL "%[old], 0(%[parent])\n"
549 "2: " PPC_STL "%[return_hooker], 0(%[parent])\n"
550 " li %[faulted], 0\n"
551 "3:\n"
552
553 ".section .fixup, \"ax\"\n"
554 "4: li %[faulted], 1\n"
555 " b 3b\n"
556 ".previous\n"
557
558 ".section __ex_table,\"a\"\n"
559 PPC_LONG_ALIGN "\n"
560 PPC_LONG "1b,4b\n"
561 PPC_LONG "2b,4b\n"
562 ".previous"
563
564 : [old] "=&r" (old), [faulted] "=r" (faulted)
565 : [parent] "r" (parent), [return_hooker] "r" (return_hooker)
566 : "memory"
567 );
568
569 if (unlikely(faulted)) {
570 ftrace_graph_stop();
571 WARN_ON(1);
572 return;
573 }
574 529
575 trace.func = self_addr; 530 trace.func = ip;
576 trace.depth = current->curr_ret_stack + 1; 531 trace.depth = current->curr_ret_stack + 1;
577 532
578 /* Only trace if the calling function expects to */ 533 /* Only trace if the calling function expects to */
579 if (!ftrace_graph_entry(&trace)) { 534 if (!ftrace_graph_entry(&trace))
580 *parent = old; 535 goto out;
581 return; 536
582 } 537 if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
538 goto out;
583 539
584 if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) 540 parent = return_hooker;
585 *parent = old; 541out:
542 return parent;
586} 543}
587#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 544#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
588 545
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index fafff8dbd5d9..d99aac0d69f1 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -33,13 +33,31 @@
33 33
34/* Macro to make the code more readable. */ 34/* Macro to make the code more readable. */
35#ifdef CONFIG_8xx_CPU6 35#ifdef CONFIG_8xx_CPU6
36#define DO_8xx_CPU6(val, reg) \ 36#define SPRN_MI_TWC_ADDR 0x2b80
37 li reg, val; \ 37#define SPRN_MI_RPN_ADDR 0x2d80
38 stw reg, 12(r0); \ 38#define SPRN_MD_TWC_ADDR 0x3b80
39 lwz reg, 12(r0); 39#define SPRN_MD_RPN_ADDR 0x3d80
40
41#define MTSPR_CPU6(spr, reg, treg) \
42 li treg, spr##_ADDR; \
43 stw treg, 12(r0); \
44 lwz treg, 12(r0); \
45 mtspr spr, reg
40#else 46#else
41#define DO_8xx_CPU6(val, reg) 47#define MTSPR_CPU6(spr, reg, treg) \
48 mtspr spr, reg
42#endif 49#endif
50
51/*
52 * Value for the bits that have fixed value in RPN entries.
53 * Also used for tagging DAR for DTLBerror.
54 */
55#ifdef CONFIG_PPC_16K_PAGES
56#define RPN_PATTERN (0x00f0 | MD_SPS16K)
57#else
58#define RPN_PATTERN 0x00f0
59#endif
60
43 __HEAD 61 __HEAD
44_ENTRY(_stext); 62_ENTRY(_stext);
45_ENTRY(_start); 63_ENTRY(_start);
@@ -65,13 +83,6 @@ _ENTRY(_start);
65 * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to 83 * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to
66 * the "internal" processor registers before MMU_init is called. 84 * the "internal" processor registers before MMU_init is called.
67 * 85 *
68 * The TLB code currently contains a major hack. Since I use the condition
69 * code register, I have to save and restore it. I am out of registers, so
70 * I just store it in memory location 0 (the TLB handlers are not reentrant).
71 * To avoid making any decisions, I need to use the "segment" valid bit
72 * in the first level table, but that would require many changes to the
73 * Linux page directory/table functions that I don't want to do right now.
74 *
75 * -- Dan 86 * -- Dan
76 */ 87 */
77 .globl __start 88 .globl __start
@@ -211,7 +222,7 @@ MachineCheck:
211 EXCEPTION_PROLOG 222 EXCEPTION_PROLOG
212 mfspr r4,SPRN_DAR 223 mfspr r4,SPRN_DAR
213 stw r4,_DAR(r11) 224 stw r4,_DAR(r11)
214 li r5,0x00f0 225 li r5,RPN_PATTERN
215 mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */ 226 mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
216 mfspr r5,SPRN_DSISR 227 mfspr r5,SPRN_DSISR
217 stw r5,_DSISR(r11) 228 stw r5,_DSISR(r11)
@@ -219,30 +230,16 @@ MachineCheck:
219 EXC_XFER_STD(0x200, machine_check_exception) 230 EXC_XFER_STD(0x200, machine_check_exception)
220 231
221/* Data access exception. 232/* Data access exception.
222 * This is "never generated" by the MPC8xx. We jump to it for other 233 * This is "never generated" by the MPC8xx.
223 * translation errors.
224 */ 234 */
225 . = 0x300 235 . = 0x300
226DataAccess: 236DataAccess:
227 EXCEPTION_PROLOG
228 mfspr r10,SPRN_DSISR
229 stw r10,_DSISR(r11)
230 mr r5,r10
231 mfspr r4,SPRN_DAR
232 li r10,0x00f0
233 mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */
234 EXC_XFER_LITE(0x300, handle_page_fault)
235 237
236/* Instruction access exception. 238/* Instruction access exception.
237 * This is "never generated" by the MPC8xx. We jump to it for other 239 * This is "never generated" by the MPC8xx.
238 * translation errors.
239 */ 240 */
240 . = 0x400 241 . = 0x400
241InstructionAccess: 242InstructionAccess:
242 EXCEPTION_PROLOG
243 mr r4,r12
244 mr r5,r9
245 EXC_XFER_LITE(0x400, handle_page_fault)
246 243
247/* External interrupt */ 244/* External interrupt */
248 EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) 245 EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
@@ -253,7 +250,7 @@ Alignment:
253 EXCEPTION_PROLOG 250 EXCEPTION_PROLOG
254 mfspr r4,SPRN_DAR 251 mfspr r4,SPRN_DAR
255 stw r4,_DAR(r11) 252 stw r4,_DAR(r11)
256 li r5,0x00f0 253 li r5,RPN_PATTERN
257 mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */ 254 mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
258 mfspr r5,SPRN_DSISR 255 mfspr r5,SPRN_DSISR
259 stw r5,_DSISR(r11) 256 stw r5,_DSISR(r11)
@@ -292,8 +289,8 @@ SystemCall:
292 . = 0x1100 289 . = 0x1100
293/* 290/*
294 * For the MPC8xx, this is a software tablewalk to load the instruction 291 * For the MPC8xx, this is a software tablewalk to load the instruction
295 * TLB. It is modelled after the example in the Motorola manual. The task 292 * TLB. The task switch loads the M_TW register with the pointer to the first
296 * switch loads the M_TWB register with the pointer to the first level table. 293 * level table.
297 * If we discover there is no second level table (value is zero) or if there 294 * If we discover there is no second level table (value is zero) or if there
298 * is an invalid pte, we load that into the TLB, which causes another fault 295 * is an invalid pte, we load that into the TLB, which causes another fault
299 * into the TLB Error interrupt where we can handle such problems. 296 * into the TLB Error interrupt where we can handle such problems.
@@ -302,20 +299,17 @@ SystemCall:
302 */ 299 */
303InstructionTLBMiss: 300InstructionTLBMiss:
304#ifdef CONFIG_8xx_CPU6 301#ifdef CONFIG_8xx_CPU6
305 stw r3, 8(r0) 302 mtspr SPRN_DAR, r3
306#endif 303#endif
307 EXCEPTION_PROLOG_0 304 EXCEPTION_PROLOG_0
308 mtspr SPRN_SPRG_SCRATCH2, r10 305 mtspr SPRN_SPRG_SCRATCH2, r10
309 mfspr r10, SPRN_SRR0 /* Get effective address of fault */ 306 mfspr r10, SPRN_SRR0 /* Get effective address of fault */
310#ifdef CONFIG_8xx_CPU15 307#ifdef CONFIG_8xx_CPU15
311 addi r11, r10, 0x1000 308 addi r11, r10, PAGE_SIZE
312 tlbie r11 309 tlbie r11
313 addi r11, r10, -0x1000 310 addi r11, r10, -PAGE_SIZE
314 tlbie r11 311 tlbie r11
315#endif 312#endif
316 DO_8xx_CPU6(0x3780, r3)
317 mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */
318 mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
319 313
320 /* If we are faulting a kernel address, we have to use the 314 /* If we are faulting a kernel address, we have to use the
321 * kernel page tables. 315 * kernel page tables.
@@ -323,32 +317,37 @@ InstructionTLBMiss:
323#ifdef CONFIG_MODULES 317#ifdef CONFIG_MODULES
324 /* Only modules will cause ITLB Misses as we always 318 /* Only modules will cause ITLB Misses as we always
325 * pin the first 8MB of kernel memory */ 319 * pin the first 8MB of kernel memory */
326 andi. r11, r10, 0x0800 /* Address >= 0x80000000 */ 320 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */
321#endif
322 mfspr r11, SPRN_M_TW /* Get level 1 table base address */
323#ifdef CONFIG_MODULES
327 beq 3f 324 beq 3f
328 lis r11, swapper_pg_dir@h 325 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
329 ori r11, r11, swapper_pg_dir@l 326 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
330 rlwimi r10, r11, 0, 2, 19
3313: 3273:
332#endif 328#endif
333 lwz r11, 0(r10) /* Get the level 1 entry */ 329 /* Extract level 1 index */
330 rlwinm r10, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
331 lwzx r11, r10, r11 /* Get the level 1 entry */
334 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ 332 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
335 beq 2f /* If zero, don't try to find a pte */ 333 beq 2f /* If zero, don't try to find a pte */
336 334
337 /* We have a pte table, so load the MI_TWC with the attributes 335 /* We have a pte table, so load the MI_TWC with the attributes
338 * for this "segment." 336 * for this "segment."
339 */ 337 */
340 ori r11,r11,1 /* Set valid bit */ 338 MTSPR_CPU6(SPRN_MI_TWC, r11, r3) /* Set segment attributes */
341 DO_8xx_CPU6(0x2b80, r3) 339 mfspr r11, SPRN_SRR0 /* Get effective address of fault */
342 mtspr SPRN_MI_TWC, r11 /* Set segment attributes */ 340 /* Extract level 2 index */
343 DO_8xx_CPU6(0x3b80, r3) 341 rlwinm r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
344 mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ 342 lwzx r10, r10, r11 /* Get the pte */
345 mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
346 lwz r10, 0(r11) /* Get the pte */
347 343
348#ifdef CONFIG_SWAP 344#ifdef CONFIG_SWAP
349 andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT 345 andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
350 cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT 346 cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT
347 li r11, RPN_PATTERN
351 bne- cr0, 2f 348 bne- cr0, 2f
349#else
350 li r11, RPN_PATTERN
352#endif 351#endif
353 /* The Linux PTE won't go exactly into the MMU TLB. 352 /* The Linux PTE won't go exactly into the MMU TLB.
354 * Software indicator bits 21 and 28 must be clear. 353 * Software indicator bits 21 and 28 must be clear.
@@ -356,62 +355,63 @@ InstructionTLBMiss:
356 * set. All other Linux PTE bits control the behavior 355 * set. All other Linux PTE bits control the behavior
357 * of the MMU. 356 * of the MMU.
358 */ 357 */
359 li r11, 0x00f0
360 rlwimi r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */ 358 rlwimi r10, r11, 0, 0x07f8 /* Set 24-27, clear 21-23,28 */
361 DO_8xx_CPU6(0x2d80, r3) 359 MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */
362 mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
363 360
364 /* Restore registers */ 361 /* Restore registers */
365#ifdef CONFIG_8xx_CPU6 362#ifdef CONFIG_8xx_CPU6
366 lwz r3, 8(r0) 363 mfspr r3, SPRN_DAR
364 mtspr SPRN_DAR, r11 /* Tag DAR */
367#endif 365#endif
368 mfspr r10, SPRN_SPRG_SCRATCH2 366 mfspr r10, SPRN_SPRG_SCRATCH2
369 EXCEPTION_EPILOG_0 367 EXCEPTION_EPILOG_0
370 rfi 368 rfi
3712: 3692:
372 mfspr r11, SPRN_SRR1 370 mfspr r10, SPRN_SRR1
373 /* clear all error bits as TLB Miss 371 /* clear all error bits as TLB Miss
374 * sets a few unconditionally 372 * sets a few unconditionally
375 */ 373 */
376 rlwinm r11, r11, 0, 0xffff 374 rlwinm r10, r10, 0, 0xffff
377 mtspr SPRN_SRR1, r11 375 mtspr SPRN_SRR1, r10
378 376
379 /* Restore registers */ 377 /* Restore registers */
380#ifdef CONFIG_8xx_CPU6 378#ifdef CONFIG_8xx_CPU6
381 lwz r3, 8(r0) 379 mfspr r3, SPRN_DAR
380 mtspr SPRN_DAR, r11 /* Tag DAR */
382#endif 381#endif
383 mfspr r10, SPRN_SPRG_SCRATCH2 382 mfspr r10, SPRN_SPRG_SCRATCH2
384 EXCEPTION_EPILOG_0 383 b InstructionTLBError1
385 b InstructionAccess
386 384
387 . = 0x1200 385 . = 0x1200
388DataStoreTLBMiss: 386DataStoreTLBMiss:
389#ifdef CONFIG_8xx_CPU6 387#ifdef CONFIG_8xx_CPU6
390 stw r3, 8(r0) 388 mtspr SPRN_DAR, r3
391#endif 389#endif
392 EXCEPTION_PROLOG_0 390 EXCEPTION_PROLOG_0
393 mtspr SPRN_SPRG_SCRATCH2, r10 391 mtspr SPRN_SPRG_SCRATCH2, r10
394 mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ 392 mfspr r10, SPRN_MD_EPN
395 393
396 /* If we are faulting a kernel address, we have to use the 394 /* If we are faulting a kernel address, we have to use the
397 * kernel page tables. 395 * kernel page tables.
398 */ 396 */
399 andi. r11, r10, 0x0800 397 andis. r11, r10, 0x8000
398 mfspr r11, SPRN_M_TW /* Get level 1 table base address */
400 beq 3f 399 beq 3f
401 lis r11, swapper_pg_dir@h 400 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
402 ori r11, r11, swapper_pg_dir@l 401 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
403 rlwimi r10, r11, 0, 2, 19
4043: 4023:
405 lwz r11, 0(r10) /* Get the level 1 entry */ 403 /* Extract level 1 index */
404 rlwinm r10, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
405 lwzx r11, r10, r11 /* Get the level 1 entry */
406 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ 406 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
407 beq 2f /* If zero, don't try to find a pte */ 407 beq 2f /* If zero, don't try to find a pte */
408 408
409 /* We have a pte table, so load fetch the pte from the table. 409 /* We have a pte table, so load fetch the pte from the table.
410 */ 410 */
411 ori r11, r11, 1 /* Set valid bit in physical L2 page */ 411 mfspr r10, SPRN_MD_EPN /* Get address of fault */
412 DO_8xx_CPU6(0x3b80, r3) 412 /* Extract level 2 index */
413 mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ 413 rlwinm r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
414 mfspr r10, SPRN_MD_TWC /* ....and get the pte address */ 414 rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
415 lwz r10, 0(r10) /* Get the pte */ 415 lwz r10, 0(r10) /* Get the pte */
416 416
417 /* Insert the Guarded flag into the TWC from the Linux PTE. 417 /* Insert the Guarded flag into the TWC from the Linux PTE.
@@ -425,8 +425,7 @@ DataStoreTLBMiss:
425 * It is bit 25 in the Linux PTE and bit 30 in the TWC 425 * It is bit 25 in the Linux PTE and bit 30 in the TWC
426 */ 426 */
427 rlwimi r11, r10, 32-5, 30, 30 427 rlwimi r11, r10, 32-5, 30, 30
428 DO_8xx_CPU6(0x3b80, r3) 428 MTSPR_CPU6(SPRN_MD_TWC, r11, r3)
429 mtspr SPRN_MD_TWC, r11
430 429
431 /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set. 430 /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
432 * We also need to know if the insn is a load/store, so: 431 * We also need to know if the insn is a load/store, so:
@@ -442,14 +441,8 @@ DataStoreTLBMiss:
442 and r11, r11, r10 441 and r11, r11, r10
443 rlwimi r10, r11, 0, _PAGE_PRESENT 442 rlwimi r10, r11, 0, _PAGE_PRESENT
444#endif 443#endif
445 /* Honour kernel RO, User NA */ 444 /* invert RW */
446 /* 0x200 == Extended encoding, bit 22 */ 445 xori r10, r10, _PAGE_RW
447 rlwimi r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */
448 /* r11 = (r10 & _PAGE_RW) >> 1 */
449 rlwinm r11, r10, 32-1, 0x200
450 or r10, r11, r10
451 /* invert RW and 0x200 bits */
452 xori r10, r10, _PAGE_RW | 0x200
453 446
454 /* The Linux PTE won't go exactly into the MMU TLB. 447 /* The Linux PTE won't go exactly into the MMU TLB.
455 * Software indicator bits 22 and 28 must be clear. 448 * Software indicator bits 22 and 28 must be clear.
@@ -457,14 +450,13 @@ DataStoreTLBMiss:
457 * set. All other Linux PTE bits control the behavior 450 * set. All other Linux PTE bits control the behavior
458 * of the MMU. 451 * of the MMU.
459 */ 452 */
4602: li r11, 0x00f0 4532: li r11, RPN_PATTERN
461 rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ 454 rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
462 DO_8xx_CPU6(0x3d80, r3) 455 MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */
463 mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
464 456
465 /* Restore registers */ 457 /* Restore registers */
466#ifdef CONFIG_8xx_CPU6 458#ifdef CONFIG_8xx_CPU6
467 lwz r3, 8(r0) 459 mfspr r3, SPRN_DAR
468#endif 460#endif
469 mtspr SPRN_DAR, r11 /* Tag DAR */ 461 mtspr SPRN_DAR, r11 /* Tag DAR */
470 mfspr r10, SPRN_SPRG_SCRATCH2 462 mfspr r10, SPRN_SPRG_SCRATCH2
@@ -477,7 +469,17 @@ DataStoreTLBMiss:
477 */ 469 */
478 . = 0x1300 470 . = 0x1300
479InstructionTLBError: 471InstructionTLBError:
480 b InstructionAccess 472 EXCEPTION_PROLOG_0
473InstructionTLBError1:
474 EXCEPTION_PROLOG_1
475 EXCEPTION_PROLOG_2
476 mr r4,r12
477 mr r5,r9
478 andis. r10,r5,0x4000
479 beq+ 1f
480 tlbie r4
481 /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */
4821: EXC_XFER_LITE(0x400, handle_page_fault)
481 483
482/* This is the data TLB error on the MPC8xx. This could be due to 484/* This is the data TLB error on the MPC8xx. This could be due to
483 * many reasons, including a dirty update to a pte. We bail out to 485 * many reasons, including a dirty update to a pte. We bail out to
@@ -488,11 +490,21 @@ DataTLBError:
488 EXCEPTION_PROLOG_0 490 EXCEPTION_PROLOG_0
489 491
490 mfspr r11, SPRN_DAR 492 mfspr r11, SPRN_DAR
491 cmpwi cr0, r11, 0x00f0 493 cmpwi cr0, r11, RPN_PATTERN
492 beq- FixupDAR /* must be a buggy dcbX, icbi insn. */ 494 beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
493DARFixed:/* Return from dcbx instruction bug workaround */ 495DARFixed:/* Return from dcbx instruction bug workaround */
494 EXCEPTION_EPILOG_0 496 EXCEPTION_PROLOG_1
495 b DataAccess 497 EXCEPTION_PROLOG_2
498 mfspr r5,SPRN_DSISR
499 stw r5,_DSISR(r11)
500 mfspr r4,SPRN_DAR
501 andis. r10,r5,0x4000
502 beq+ 1f
503 tlbie r4
5041: li r10,RPN_PATTERN
505 mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */
506 /* 0x300 is DataAccess exception, needed by bad_page_fault() */
507 EXC_XFER_LITE(0x300, handle_page_fault)
496 508
497 EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) 509 EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
498 EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) 510 EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
@@ -521,29 +533,30 @@ DARFixed:/* Return from dcbx instruction bug workaround */
521#define NO_SELF_MODIFYING_CODE 533#define NO_SELF_MODIFYING_CODE
522FixupDAR:/* Entry point for dcbx workaround. */ 534FixupDAR:/* Entry point for dcbx workaround. */
523#ifdef CONFIG_8xx_CPU6 535#ifdef CONFIG_8xx_CPU6
524 stw r3, 8(r0) 536 mtspr SPRN_DAR, r3
525#endif 537#endif
526 mtspr SPRN_SPRG_SCRATCH2, r10 538 mtspr SPRN_SPRG_SCRATCH2, r10
527 /* fetch instruction from memory. */ 539 /* fetch instruction from memory. */
528 mfspr r10, SPRN_SRR0 540 mfspr r10, SPRN_SRR0
529 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ 541 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */
530 DO_8xx_CPU6(0x3780, r3) 542 mfspr r11, SPRN_M_TW /* Get level 1 table base address */
531 mtspr SPRN_MD_EPN, r10
532 mfspr r11, SPRN_M_TWB /* Get level 1 table entry address */
533 beq- 3f /* Branch if user space */ 543 beq- 3f /* Branch if user space */
534 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h 544 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
535 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 545 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
536 rlwimi r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */ 546 /* Extract level 1 index */
5373: lwz r11, 0(r11) /* Get the level 1 entry */ 5473: rlwinm r10, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
538 DO_8xx_CPU6(0x3b80, r3) 548 lwzx r11, r10, r11 /* Get the level 1 entry */
539 mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ 549 rlwinm r10, r11,0,0,19 /* Extract page descriptor page address */
540 mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ 550 mfspr r11, SPRN_SRR0 /* Get effective address of fault */
541 lwz r11, 0(r11) /* Get the pte */ 551 /* Extract level 2 index */
552 rlwinm r11, r11, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
553 lwzx r11, r10, r11 /* Get the pte */
542#ifdef CONFIG_8xx_CPU6 554#ifdef CONFIG_8xx_CPU6
543 lwz r3, 8(r0) /* restore r3 from memory */ 555 mfspr r3, SPRN_DAR
544#endif 556#endif
545 /* concat physical page address(r11) and page offset(r10) */ 557 /* concat physical page address(r11) and page offset(r10) */
546 rlwimi r11, r10, 0, 20, 31 558 mfspr r10, SPRN_SRR0
559 rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31
547 lwz r11,0(r11) 560 lwz r11,0(r11)
548/* Check if it really is a dcbx instruction. */ 561/* Check if it really is a dcbx instruction. */
549/* dcbt and dcbtst does not generate DTLB Misses/Errors, 562/* dcbt and dcbtst does not generate DTLB Misses/Errors,
@@ -698,11 +711,11 @@ start_here:
698#ifdef CONFIG_8xx_CPU6 711#ifdef CONFIG_8xx_CPU6
699 lis r4, cpu6_errata_word@h 712 lis r4, cpu6_errata_word@h
700 ori r4, r4, cpu6_errata_word@l 713 ori r4, r4, cpu6_errata_word@l
701 li r3, 0x3980 714 li r3, 0x3f80
702 stw r3, 12(r4) 715 stw r3, 12(r4)
703 lwz r3, 12(r4) 716 lwz r3, 12(r4)
704#endif 717#endif
705 mtspr SPRN_M_TWB, r6 718 mtspr SPRN_M_TW, r6
706 lis r4,2f@h 719 lis r4,2f@h
707 ori r4,r4,2f@l 720 ori r4,r4,2f@l
708 tophys(r4,r4) 721 tophys(r4,r4)
@@ -876,10 +889,10 @@ _GLOBAL(set_context)
876 lis r6, cpu6_errata_word@h 889 lis r6, cpu6_errata_word@h
877 ori r6, r6, cpu6_errata_word@l 890 ori r6, r6, cpu6_errata_word@l
878 tophys (r4, r4) 891 tophys (r4, r4)
879 li r7, 0x3980 892 li r7, 0x3f80
880 stw r7, 12(r6) 893 stw r7, 12(r6)
881 lwz r7, 12(r6) 894 lwz r7, 12(r6)
882 mtspr SPRN_M_TWB, r4 /* Update MMU base address */ 895 mtspr SPRN_M_TW, r4 /* Update MMU base address */
883 li r7, 0x3380 896 li r7, 0x3380
884 stw r7, 12(r6) 897 stw r7, 12(r6)
885 lwz r7, 12(r6) 898 lwz r7, 12(r6)
@@ -887,7 +900,7 @@ _GLOBAL(set_context)
887#else 900#else
888 mtspr SPRN_M_CASID,r3 /* Update context */ 901 mtspr SPRN_M_CASID,r3 /* Update context */
889 tophys (r4, r4) 902 tophys (r4, r4)
890 mtspr SPRN_M_TWB, r4 /* and pgd */ 903 mtspr SPRN_M_TW, r4 /* and pgd */
891#endif 904#endif
892 SYNC 905 SYNC
893 blr 906 blr
@@ -919,12 +932,13 @@ set_dec_cpu6:
919 .globl sdata 932 .globl sdata
920sdata: 933sdata:
921 .globl empty_zero_page 934 .globl empty_zero_page
935 .align PAGE_SHIFT
922empty_zero_page: 936empty_zero_page:
923 .space 4096 937 .space PAGE_SIZE
924 938
925 .globl swapper_pg_dir 939 .globl swapper_pg_dir
926swapper_pg_dir: 940swapper_pg_dir:
927 .space 4096 941 .space PGD_TABLE_SIZE
928 942
929/* Room for two PTE table poiners, usually the kernel and current user 943/* Room for two PTE table poiners, usually the kernel and current user
930 * pointer to their respective root page table (pgdir). 944 * pointer to their respective root page table (pgdir).
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 1f7d84e2e8b2..05e804cdecaa 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -63,7 +63,7 @@ int hw_breakpoint_slots(int type)
63int arch_install_hw_breakpoint(struct perf_event *bp) 63int arch_install_hw_breakpoint(struct perf_event *bp)
64{ 64{
65 struct arch_hw_breakpoint *info = counter_arch_bp(bp); 65 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
66 struct perf_event **slot = &__get_cpu_var(bp_per_reg); 66 struct perf_event **slot = this_cpu_ptr(&bp_per_reg);
67 67
68 *slot = bp; 68 *slot = bp;
69 69
@@ -88,7 +88,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
88 */ 88 */
89void arch_uninstall_hw_breakpoint(struct perf_event *bp) 89void arch_uninstall_hw_breakpoint(struct perf_event *bp)
90{ 90{
91 struct perf_event **slot = &__get_cpu_var(bp_per_reg); 91 struct perf_event **slot = this_cpu_ptr(&bp_per_reg);
92 92
93 if (*slot != bp) { 93 if (*slot != bp) {
94 WARN_ONCE(1, "Can't find the breakpoint"); 94 WARN_ONCE(1, "Can't find the breakpoint");
@@ -226,7 +226,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
226 */ 226 */
227 rcu_read_lock(); 227 rcu_read_lock();
228 228
229 bp = __get_cpu_var(bp_per_reg); 229 bp = __this_cpu_read(bp_per_reg);
230 if (!bp) 230 if (!bp)
231 goto out; 231 goto out;
232 info = counter_arch_bp(bp); 232 info = counter_arch_bp(bp);
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index c0754bbf8118..18c0687e5ab3 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -212,6 +212,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
212 mtspr SPRN_SRR0,r5 212 mtspr SPRN_SRR0,r5
213 rfid 213 rfid
214 214
215/*
216 * R3 here contains the value that will be returned to the caller
217 * of power7_nap.
218 */
215_GLOBAL(power7_wakeup_loss) 219_GLOBAL(power7_wakeup_loss)
216 ld r1,PACAR1(r13) 220 ld r1,PACAR1(r13)
217BEGIN_FTR_SECTION 221BEGIN_FTR_SECTION
@@ -219,15 +223,19 @@ BEGIN_FTR_SECTION
219END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) 223END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
220 REST_NVGPRS(r1) 224 REST_NVGPRS(r1)
221 REST_GPR(2, r1) 225 REST_GPR(2, r1)
222 ld r3,_CCR(r1) 226 ld r6,_CCR(r1)
223 ld r4,_MSR(r1) 227 ld r4,_MSR(r1)
224 ld r5,_NIP(r1) 228 ld r5,_NIP(r1)
225 addi r1,r1,INT_FRAME_SIZE 229 addi r1,r1,INT_FRAME_SIZE
226 mtcr r3 230 mtcr r6
227 mtspr SPRN_SRR1,r4 231 mtspr SPRN_SRR1,r4
228 mtspr SPRN_SRR0,r5 232 mtspr SPRN_SRR0,r5
229 rfid 233 rfid
230 234
235/*
236 * R3 here contains the value that will be returned to the caller
237 * of power7_nap.
238 */
231_GLOBAL(power7_wakeup_noloss) 239_GLOBAL(power7_wakeup_noloss)
232 lbz r0,PACA_NAPSTATELOST(r13) 240 lbz r0,PACA_NAPSTATELOST(r13)
233 cmpwi r0,0 241 cmpwi r0,0
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index a83cf5ef6488..5d3968c4d799 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -208,7 +208,7 @@ static unsigned long iommu_range_alloc(struct device *dev,
208 * We don't need to disable preemption here because any CPU can 208 * We don't need to disable preemption here because any CPU can
209 * safely use any IOMMU pool. 209 * safely use any IOMMU pool.
210 */ 210 */
211 pool_nr = __raw_get_cpu_var(iommu_pool_hash) & (tbl->nr_pools - 1); 211 pool_nr = __this_cpu_read(iommu_pool_hash) & (tbl->nr_pools - 1);
212 212
213 if (largealloc) 213 if (largealloc)
214 pool = &(tbl->large_pool); 214 pool = &(tbl->large_pool);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index c14383575fe8..45096033d37b 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -50,7 +50,6 @@
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/radix-tree.h> 51#include <linux/radix-tree.h>
52#include <linux/mutex.h> 52#include <linux/mutex.h>
53#include <linux/bootmem.h>
54#include <linux/pci.h> 53#include <linux/pci.h>
55#include <linux/debugfs.h> 54#include <linux/debugfs.h>
56#include <linux/of.h> 55#include <linux/of.h>
@@ -114,7 +113,7 @@ static inline notrace void set_soft_enabled(unsigned long enable)
114static inline notrace int decrementer_check_overflow(void) 113static inline notrace int decrementer_check_overflow(void)
115{ 114{
116 u64 now = get_tb_or_rtc(); 115 u64 now = get_tb_or_rtc();
117 u64 *next_tb = &__get_cpu_var(decrementers_next_tb); 116 u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
118 117
119 return now >= *next_tb; 118 return now >= *next_tb;
120} 119}
@@ -499,7 +498,7 @@ void __do_irq(struct pt_regs *regs)
499 498
500 /* And finally process it */ 499 /* And finally process it */
501 if (unlikely(irq == NO_IRQ)) 500 if (unlikely(irq == NO_IRQ))
502 __get_cpu_var(irq_stat).spurious_irqs++; 501 __this_cpu_inc(irq_stat.spurious_irqs);
503 else 502 else
504 generic_handle_irq(irq); 503 generic_handle_irq(irq);
505 504
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 8504657379f1..e77c3ccf8dcf 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -155,7 +155,7 @@ static int kgdb_singlestep(struct pt_regs *regs)
155{ 155{
156 struct thread_info *thread_info, *exception_thread_info; 156 struct thread_info *thread_info, *exception_thread_info;
157 struct thread_info *backup_current_thread_info = 157 struct thread_info *backup_current_thread_info =
158 &__get_cpu_var(kgdb_thread_info); 158 this_cpu_ptr(&kgdb_thread_info);
159 159
160 if (user_mode(regs)) 160 if (user_mode(regs))
161 return 0; 161 return 0;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 2f72af82513c..7c053f281406 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -119,7 +119,7 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
119 119
120static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) 120static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
121{ 121{
122 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 122 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
123 kcb->kprobe_status = kcb->prev_kprobe.status; 123 kcb->kprobe_status = kcb->prev_kprobe.status;
124 kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; 124 kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
125} 125}
@@ -127,7 +127,7 @@ static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
127static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, 127static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
128 struct kprobe_ctlblk *kcb) 128 struct kprobe_ctlblk *kcb)
129{ 129{
130 __get_cpu_var(current_kprobe) = p; 130 __this_cpu_write(current_kprobe, p);
131 kcb->kprobe_saved_msr = regs->msr; 131 kcb->kprobe_saved_msr = regs->msr;
132} 132}
133 133
@@ -192,7 +192,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
192 ret = 1; 192 ret = 1;
193 goto no_kprobe; 193 goto no_kprobe;
194 } 194 }
195 p = __get_cpu_var(current_kprobe); 195 p = __this_cpu_read(current_kprobe);
196 if (p->break_handler && p->break_handler(p, regs)) { 196 if (p->break_handler && p->break_handler(p, regs)) {
197 goto ss_probe; 197 goto ss_probe;
198 } 198 }
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index a7fd4cb78b78..15c99b649b04 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -73,8 +73,8 @@ void save_mce_event(struct pt_regs *regs, long handled,
73 uint64_t nip, uint64_t addr) 73 uint64_t nip, uint64_t addr)
74{ 74{
75 uint64_t srr1; 75 uint64_t srr1;
76 int index = __get_cpu_var(mce_nest_count)++; 76 int index = __this_cpu_inc_return(mce_nest_count);
77 struct machine_check_event *mce = &__get_cpu_var(mce_event[index]); 77 struct machine_check_event *mce = this_cpu_ptr(&mce_event[index]);
78 78
79 /* 79 /*
80 * Return if we don't have enough space to log mce event. 80 * Return if we don't have enough space to log mce event.
@@ -143,7 +143,7 @@ void save_mce_event(struct pt_regs *regs, long handled,
143 */ 143 */
144int get_mce_event(struct machine_check_event *mce, bool release) 144int get_mce_event(struct machine_check_event *mce, bool release)
145{ 145{
146 int index = __get_cpu_var(mce_nest_count) - 1; 146 int index = __this_cpu_read(mce_nest_count) - 1;
147 struct machine_check_event *mc_evt; 147 struct machine_check_event *mc_evt;
148 int ret = 0; 148 int ret = 0;
149 149
@@ -153,7 +153,7 @@ int get_mce_event(struct machine_check_event *mce, bool release)
153 153
154 /* Check if we have MCE info to process. */ 154 /* Check if we have MCE info to process. */
155 if (index < MAX_MC_EVT) { 155 if (index < MAX_MC_EVT) {
156 mc_evt = &__get_cpu_var(mce_event[index]); 156 mc_evt = this_cpu_ptr(&mce_event[index]);
157 /* Copy the event structure and release the original */ 157 /* Copy the event structure and release the original */
158 if (mce) 158 if (mce)
159 *mce = *mc_evt; 159 *mce = *mc_evt;
@@ -163,7 +163,7 @@ int get_mce_event(struct machine_check_event *mce, bool release)
163 } 163 }
164 /* Decrement the count to free the slot. */ 164 /* Decrement the count to free the slot. */
165 if (release) 165 if (release)
166 __get_cpu_var(mce_nest_count)--; 166 __this_cpu_dec(mce_nest_count);
167 167
168 return ret; 168 return ret;
169} 169}
@@ -184,13 +184,13 @@ void machine_check_queue_event(void)
184 if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) 184 if (!get_mce_event(&evt, MCE_EVENT_RELEASE))
185 return; 185 return;
186 186
187 index = __get_cpu_var(mce_queue_count)++; 187 index = __this_cpu_inc_return(mce_queue_count);
188 /* If queue is full, just return for now. */ 188 /* If queue is full, just return for now. */
189 if (index >= MAX_MC_EVT) { 189 if (index >= MAX_MC_EVT) {
190 __get_cpu_var(mce_queue_count)--; 190 __this_cpu_dec(mce_queue_count);
191 return; 191 return;
192 } 192 }
193 __get_cpu_var(mce_event_queue[index]) = evt; 193 memcpy(this_cpu_ptr(&mce_event_queue[index]), &evt, sizeof(evt));
194 194
195 /* Queue irq work to process this event later. */ 195 /* Queue irq work to process this event later. */
196 irq_work_queue(&mce_event_process_work); 196 irq_work_queue(&mce_event_process_work);
@@ -208,11 +208,11 @@ static void machine_check_process_queued_event(struct irq_work *work)
208 * For now just print it to console. 208 * For now just print it to console.
209 * TODO: log this error event to FSP or nvram. 209 * TODO: log this error event to FSP or nvram.
210 */ 210 */
211 while (__get_cpu_var(mce_queue_count) > 0) { 211 while (__this_cpu_read(mce_queue_count) > 0) {
212 index = __get_cpu_var(mce_queue_count) - 1; 212 index = __this_cpu_read(mce_queue_count) - 1;
213 machine_check_print_event_info( 213 machine_check_print_event_info(
214 &__get_cpu_var(mce_event_queue[index])); 214 this_cpu_ptr(&mce_event_queue[index]));
215 __get_cpu_var(mce_queue_count)--; 215 __this_cpu_dec(mce_queue_count);
216 } 216 }
217} 217}
218 218
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index aa9aff3d6ad3..b6f123ab90ed 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -79,7 +79,7 @@ static long mce_handle_derror(uint64_t dsisr, uint64_t slb_error_bits)
79 } 79 }
80 if (dsisr & P7_DSISR_MC_TLB_MULTIHIT_MFTLB) { 80 if (dsisr & P7_DSISR_MC_TLB_MULTIHIT_MFTLB) {
81 if (cur_cpu_spec && cur_cpu_spec->flush_tlb) 81 if (cur_cpu_spec && cur_cpu_spec->flush_tlb)
82 cur_cpu_spec->flush_tlb(TLBIEL_INVAL_PAGE); 82 cur_cpu_spec->flush_tlb(TLBIEL_INVAL_SET);
83 /* reset error bits */ 83 /* reset error bits */
84 dsisr &= ~P7_DSISR_MC_TLB_MULTIHIT_MFTLB; 84 dsisr &= ~P7_DSISR_MC_TLB_MULTIHIT_MFTLB;
85 } 85 }
@@ -110,7 +110,7 @@ static long mce_handle_common_ierror(uint64_t srr1)
110 break; 110 break;
111 case P7_SRR1_MC_IFETCH_TLB_MULTIHIT: 111 case P7_SRR1_MC_IFETCH_TLB_MULTIHIT:
112 if (cur_cpu_spec && cur_cpu_spec->flush_tlb) { 112 if (cur_cpu_spec && cur_cpu_spec->flush_tlb) {
113 cur_cpu_spec->flush_tlb(TLBIEL_INVAL_PAGE); 113 cur_cpu_spec->flush_tlb(TLBIEL_INVAL_SET);
114 handled = 1; 114 handled = 1;
115 } 115 }
116 break; 116 break;
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index e5dad9a9edc0..37d512d35943 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -20,7 +20,6 @@
20#include <linux/pci.h> 20#include <linux/pci.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/bootmem.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/export.h> 24#include <linux/export.h>
26#include <linux/of_address.h> 25#include <linux/of_address.h>
@@ -1464,7 +1463,7 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose,
1464 res = &hose->io_resource; 1463 res = &hose->io_resource;
1465 1464
1466 if (!res->flags) { 1465 if (!res->flags) {
1467 printk(KERN_WARNING "PCI: I/O resource not set for host" 1466 pr_info("PCI: I/O resource not set for host"
1468 " bridge %s (domain %d)\n", 1467 " bridge %s (domain %d)\n",
1469 hose->dn->full_name, hose->global_number); 1468 hose->dn->full_name, hose->global_number);
1470 } else { 1469 } else {
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 432459c817fa..1f7930037cb7 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -199,9 +199,7 @@ pci_create_OF_bus_map(void)
199 struct property* of_prop; 199 struct property* of_prop;
200 struct device_node *dn; 200 struct device_node *dn;
201 201
202 of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); 202 of_prop = memblock_virt_alloc(sizeof(struct property) + 256, 0);
203 if (!of_prop)
204 return;
205 dn = of_find_node_by_path("/"); 203 dn = of_find_node_by_path("/");
206 if (dn) { 204 if (dn) {
207 memset(of_prop, -1, sizeof(struct property) + 256); 205 memset(of_prop, -1, sizeof(struct property) + 256);
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index b15194e2c5fc..60bb187cb46a 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -17,7 +17,6 @@
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/bootmem.h>
21#include <linux/export.h> 20#include <linux/export.h>
22#include <linux/mm.h> 21#include <linux/mm.h>
23#include <linux/list.h> 22#include <linux/list.h>
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 923cd2daba89..b4cc7bef6b16 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -37,9 +37,9 @@
37#include <linux/personality.h> 37#include <linux/personality.h>
38#include <linux/random.h> 38#include <linux/random.h>
39#include <linux/hw_breakpoint.h> 39#include <linux/hw_breakpoint.h>
40#include <linux/uaccess.h>
40 41
41#include <asm/pgtable.h> 42#include <asm/pgtable.h>
42#include <asm/uaccess.h>
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/processor.h> 44#include <asm/processor.h>
45#include <asm/mmu.h> 45#include <asm/mmu.h>
@@ -499,7 +499,7 @@ static inline int set_dawr(struct arch_hw_breakpoint *brk)
499 499
500void __set_breakpoint(struct arch_hw_breakpoint *brk) 500void __set_breakpoint(struct arch_hw_breakpoint *brk)
501{ 501{
502 __get_cpu_var(current_brk) = *brk; 502 memcpy(this_cpu_ptr(&current_brk), brk, sizeof(*brk));
503 503
504 if (cpu_has_feature(CPU_FTR_DAWR)) 504 if (cpu_has_feature(CPU_FTR_DAWR))
505 set_dawr(brk); 505 set_dawr(brk);
@@ -842,7 +842,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
842 * schedule DABR 842 * schedule DABR
843 */ 843 */
844#ifndef CONFIG_HAVE_HW_BREAKPOINT 844#ifndef CONFIG_HAVE_HW_BREAKPOINT
845 if (unlikely(!hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk))) 845 if (unlikely(!hw_brk_match(this_cpu_ptr(&current_brk), &new->thread.hw_brk)))
846 __set_breakpoint(&new->thread.hw_brk); 846 __set_breakpoint(&new->thread.hw_brk);
847#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 847#endif /* CONFIG_HAVE_HW_BREAKPOINT */
848#endif 848#endif
@@ -856,7 +856,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
856 * Collect processor utilization data per process 856 * Collect processor utilization data per process
857 */ 857 */
858 if (firmware_has_feature(FW_FEATURE_SPLPAR)) { 858 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
859 struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); 859 struct cpu_usage *cu = this_cpu_ptr(&cpu_usage_array);
860 long unsigned start_tb, current_tb; 860 long unsigned start_tb, current_tb;
861 start_tb = old_thread->start_tb; 861 start_tb = old_thread->start_tb;
862 cu->current_tb = current_tb = mfspr(SPRN_PURR); 862 cu->current_tb = current_tb = mfspr(SPRN_PURR);
@@ -866,7 +866,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
866#endif /* CONFIG_PPC64 */ 866#endif /* CONFIG_PPC64 */
867 867
868#ifdef CONFIG_PPC_BOOK3S_64 868#ifdef CONFIG_PPC_BOOK3S_64
869 batch = &__get_cpu_var(ppc64_tlb_batch); 869 batch = this_cpu_ptr(&ppc64_tlb_batch);
870 if (batch->active) { 870 if (batch->active) {
871 current_thread_info()->local_flags |= _TLF_LAZY_MMU; 871 current_thread_info()->local_flags |= _TLF_LAZY_MMU;
872 if (batch->index) 872 if (batch->index)
@@ -889,7 +889,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
889#ifdef CONFIG_PPC_BOOK3S_64 889#ifdef CONFIG_PPC_BOOK3S_64
890 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { 890 if (current_thread_info()->local_flags & _TLF_LAZY_MMU) {
891 current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; 891 current_thread_info()->local_flags &= ~_TLF_LAZY_MMU;
892 batch = &__get_cpu_var(ppc64_tlb_batch); 892 batch = this_cpu_ptr(&ppc64_tlb_batch);
893 batch->active = 1; 893 batch->active = 1;
894 } 894 }
895#endif /* CONFIG_PPC_BOOK3S_64 */ 895#endif /* CONFIG_PPC_BOOK3S_64 */
@@ -921,12 +921,8 @@ static void show_instructions(struct pt_regs *regs)
921 pc = (unsigned long)phys_to_virt(pc); 921 pc = (unsigned long)phys_to_virt(pc);
922#endif 922#endif
923 923
924 /* We use __get_user here *only* to avoid an OOPS on a
925 * bad address because the pc *should* only be a
926 * kernel address.
927 */
928 if (!__kernel_text_address(pc) || 924 if (!__kernel_text_address(pc) ||
929 __get_user(instr, (unsigned int __user *)pc)) { 925 probe_kernel_address((unsigned int __user *)pc, instr)) {
930 printk(KERN_CONT "XXXXXXXX "); 926 printk(KERN_CONT "XXXXXXXX ");
931 } else { 927 } else {
932 if (regs->nip == pc) 928 if (regs->nip == pc)
@@ -1531,13 +1527,6 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1531 int curr_frame = current->curr_ret_stack; 1527 int curr_frame = current->curr_ret_stack;
1532 extern void return_to_handler(void); 1528 extern void return_to_handler(void);
1533 unsigned long rth = (unsigned long)return_to_handler; 1529 unsigned long rth = (unsigned long)return_to_handler;
1534 unsigned long mrth = -1;
1535#ifdef CONFIG_PPC64
1536 extern void mod_return_to_handler(void);
1537 rth = *(unsigned long *)rth;
1538 mrth = (unsigned long)mod_return_to_handler;
1539 mrth = *(unsigned long *)mrth;
1540#endif
1541#endif 1530#endif
1542 1531
1543 sp = (unsigned long) stack; 1532 sp = (unsigned long) stack;
@@ -1562,7 +1551,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1562 if (!firstframe || ip != lr) { 1551 if (!firstframe || ip != lr) {
1563 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); 1552 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
1564#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1553#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1565 if ((ip == rth || ip == mrth) && curr_frame >= 0) { 1554 if ((ip == rth) && curr_frame >= 0) {
1566 printk(" (%pS)", 1555 printk(" (%pS)",
1567 (void *)current->ret_stack[curr_frame].ret); 1556 (void *)current->ret_stack[curr_frame].ret);
1568 curr_frame--; 1557 curr_frame--;
@@ -1665,12 +1654,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
1665 return ret; 1654 return ret;
1666} 1655}
1667 1656
1668unsigned long randomize_et_dyn(unsigned long base)
1669{
1670 unsigned long ret = PAGE_ALIGN(base + brk_rnd());
1671
1672 if (ret < base)
1673 return base;
1674
1675 return ret;
1676}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 099f27e6d1b0..6a799b3cc6b4 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -160,6 +160,12 @@ static struct ibm_pa_feature {
160 {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, 160 {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1},
161 {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, 161 {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0},
162 {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, 162 {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
163 /*
164 * If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n),
165 * we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP
166 * which is 0 if the kernel doesn't support TM.
167 */
168 {CPU_FTR_TM_COMP, 0, 0, 22, 0, 0},
163}; 169};
164 170
165static void __init scan_features(unsigned long node, const unsigned char *ftrs, 171static void __init scan_features(unsigned long node, const unsigned char *ftrs,
@@ -696,10 +702,7 @@ void __init early_init_devtree(void *params)
696 reserve_crashkernel(); 702 reserve_crashkernel();
697 early_reserve_mem(); 703 early_reserve_mem();
698 704
699 /* 705 /* Ensure that total memory size is page-aligned. */
700 * Ensure that total memory size is page-aligned, because otherwise
701 * mark_bootmem() gets upset.
702 */
703 limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE); 706 limit = ALIGN(memory_limit ?: memblock_phys_mem_size(), PAGE_SIZE);
704 memblock_enforce_memory_limit(limit); 707 memblock_enforce_memory_limit(limit);
705 708
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 8777fb02349f..fb2fb3ea85e5 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -113,17 +113,6 @@
113#define SENSOR_PREFIX "ibm,sensor-" 113#define SENSOR_PREFIX "ibm,sensor-"
114#define cel_to_fahr(x) ((x*9/5)+32) 114#define cel_to_fahr(x) ((x*9/5)+32)
115 115
116
117/* Globals */
118static struct rtas_sensors sensors;
119static struct device_node *rtas_node = NULL;
120static unsigned long power_on_time = 0; /* Save the time the user set */
121static char progress_led[MAX_LINELENGTH];
122
123static unsigned long rtas_tone_frequency = 1000;
124static unsigned long rtas_tone_volume = 0;
125
126/* ****************STRUCTS******************************************* */
127struct individual_sensor { 116struct individual_sensor {
128 unsigned int token; 117 unsigned int token;
129 unsigned int quant; 118 unsigned int quant;
@@ -134,6 +123,15 @@ struct rtas_sensors {
134 unsigned int quant; 123 unsigned int quant;
135}; 124};
136 125
126/* Globals */
127static struct rtas_sensors sensors;
128static struct device_node *rtas_node = NULL;
129static unsigned long power_on_time = 0; /* Save the time the user set */
130static char progress_led[MAX_LINELENGTH];
131
132static unsigned long rtas_tone_frequency = 1000;
133static unsigned long rtas_tone_volume = 0;
134
137/* ****************************************************************** */ 135/* ****************************************************************** */
138/* Declarations */ 136/* Declarations */
139static int ppc_rtas_sensors_show(struct seq_file *m, void *v); 137static int ppc_rtas_sensors_show(struct seq_file *m, void *v);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8b4c857c1421..4af905e81ab0 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -1091,8 +1091,8 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
1091} 1091}
1092 1092
1093/* 1093/*
1094 * Call early during boot, before mem init or bootmem, to retrieve the RTAS 1094 * Call early during boot, before mem init, to retrieve the RTAS
1095 * informations from the device-tree and allocate the RMO buffer for userland 1095 * information from the device-tree and allocate the RMO buffer for userland
1096 * accesses. 1096 * accesses.
1097 */ 1097 */
1098void __init rtas_initialize(void) 1098void __init rtas_initialize(void)
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 7c55b86206b3..ce230da2c015 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -26,7 +26,6 @@
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/string.h> 27#include <linux/string.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/bootmem.h>
30 29
31#include <asm/io.h> 30#include <asm/io.h>
32#include <asm/pgtable.h> 31#include <asm/pgtable.h>
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1362cd62b3fa..44c8d03558ac 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -139,8 +139,8 @@ void machine_restart(char *cmd)
139void machine_power_off(void) 139void machine_power_off(void)
140{ 140{
141 machine_shutdown(); 141 machine_shutdown();
142 if (ppc_md.power_off) 142 if (pm_power_off)
143 ppc_md.power_off(); 143 pm_power_off();
144#ifdef CONFIG_SMP 144#ifdef CONFIG_SMP
145 smp_send_stop(); 145 smp_send_stop();
146#endif 146#endif
@@ -151,7 +151,7 @@ void machine_power_off(void)
151/* Used by the G5 thermal driver */ 151/* Used by the G5 thermal driver */
152EXPORT_SYMBOL_GPL(machine_power_off); 152EXPORT_SYMBOL_GPL(machine_power_off);
153 153
154void (*pm_power_off)(void) = machine_power_off; 154void (*pm_power_off)(void);
155EXPORT_SYMBOL_GPL(pm_power_off); 155EXPORT_SYMBOL_GPL(pm_power_off);
156 156
157void machine_halt(void) 157void machine_halt(void)
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 07831ed0d9ef..bb02e9f6944e 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -11,7 +11,6 @@
11#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/initrd.h> 12#include <linux/initrd.h>
13#include <linux/tty.h> 13#include <linux/tty.h>
14#include <linux/bootmem.h>
15#include <linux/seq_file.h> 14#include <linux/seq_file.h>
16#include <linux/root_dev.h> 15#include <linux/root_dev.h>
17#include <linux/cpu.h> 16#include <linux/cpu.h>
@@ -53,11 +52,6 @@ unsigned long ISA_DMA_THRESHOLD;
53unsigned int DMA_MODE_READ; 52unsigned int DMA_MODE_READ;
54unsigned int DMA_MODE_WRITE; 53unsigned int DMA_MODE_WRITE;
55 54
56#ifdef CONFIG_VGA_CONSOLE
57unsigned long vgacon_remap_base;
58EXPORT_SYMBOL(vgacon_remap_base);
59#endif
60
61/* 55/*
62 * These are used in binfmt_elf.c to put aux entries on the stack 56 * These are used in binfmt_elf.c to put aux entries on the stack
63 * for each elf executable being started. 57 * for each elf executable being started.
@@ -311,9 +305,8 @@ void __init setup_arch(char **cmdline_p)
311 305
312 irqstack_early_init(); 306 irqstack_early_init();
313 307
314 /* set up the bootmem stuff with available memory */ 308 initmem_init();
315 do_init_bootmem(); 309 if ( ppc_md.progress ) ppc_md.progress("setup_arch: initmem", 0x3eab);
316 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
317 310
318#ifdef CONFIG_DUMMY_CONSOLE 311#ifdef CONFIG_DUMMY_CONSOLE
319 conswitchp = &dummy_con; 312 conswitchp = &dummy_con;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 4f3cfe1b6a33..49f553bbb360 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -660,13 +660,11 @@ static void __init emergency_stack_init(void)
660} 660}
661 661
662/* 662/*
663 * Called into from start_kernel this initializes bootmem, which is used 663 * Called into from start_kernel this initializes memblock, which is used
664 * to manage page allocation until mem_init is called. 664 * to manage page allocation until mem_init is called.
665 */ 665 */
666void __init setup_arch(char **cmdline_p) 666void __init setup_arch(char **cmdline_p)
667{ 667{
668 ppc64_boot_msg(0x12, "Setup Arch");
669
670 *cmdline_p = boot_command_line; 668 *cmdline_p = boot_command_line;
671 669
672 /* 670 /*
@@ -691,9 +689,7 @@ void __init setup_arch(char **cmdline_p)
691 exc_lvl_early_init(); 689 exc_lvl_early_init();
692 emergency_stack_init(); 690 emergency_stack_init();
693 691
694 /* set up the bootmem stuff with available memory */ 692 initmem_init();
695 do_init_bootmem();
696 sparse_init();
697 693
698#ifdef CONFIG_DUMMY_CONSOLE 694#ifdef CONFIG_DUMMY_CONSOLE
699 conswitchp = &dummy_con; 695 conswitchp = &dummy_con;
@@ -711,33 +707,6 @@ void __init setup_arch(char **cmdline_p)
711 if ((unsigned long)_stext & 0xffff) 707 if ((unsigned long)_stext & 0xffff)
712 panic("Kernelbase not 64K-aligned (0x%lx)!\n", 708 panic("Kernelbase not 64K-aligned (0x%lx)!\n",
713 (unsigned long)_stext); 709 (unsigned long)_stext);
714
715 ppc64_boot_msg(0x15, "Setup Done");
716}
717
718
719/* ToDo: do something useful if ppc_md is not yet setup. */
720#define PPC64_LINUX_FUNCTION 0x0f000000
721#define PPC64_IPL_MESSAGE 0xc0000000
722#define PPC64_TERM_MESSAGE 0xb0000000
723
724static void ppc64_do_msg(unsigned int src, const char *msg)
725{
726 if (ppc_md.progress) {
727 char buf[128];
728
729 sprintf(buf, "%08X\n", src);
730 ppc_md.progress(buf, 0);
731 snprintf(buf, 128, "%s", msg);
732 ppc_md.progress(buf, 0);
733 }
734}
735
736/* Print a boot progress message. */
737void ppc64_boot_msg(unsigned int src, const char *msg)
738{
739 ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg);
740 printk("[boot]%04x %s\n", src, msg);
741} 710}
742 711
743#ifdef CONFIG_SMP 712#ifdef CONFIG_SMP
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 71e186d5f331..8b2d2dc8ef10 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -243,7 +243,7 @@ void smp_muxed_ipi_message_pass(int cpu, int msg)
243 243
244irqreturn_t smp_ipi_demux(void) 244irqreturn_t smp_ipi_demux(void)
245{ 245{
246 struct cpu_messages *info = &__get_cpu_var(ipi_message); 246 struct cpu_messages *info = this_cpu_ptr(&ipi_message);
247 unsigned int all; 247 unsigned int all;
248 248
249 mb(); /* order any irq clear */ 249 mb(); /* order any irq clear */
@@ -442,9 +442,9 @@ void generic_mach_cpu_die(void)
442 idle_task_exit(); 442 idle_task_exit();
443 cpu = smp_processor_id(); 443 cpu = smp_processor_id();
444 printk(KERN_DEBUG "CPU%d offline\n", cpu); 444 printk(KERN_DEBUG "CPU%d offline\n", cpu);
445 __get_cpu_var(cpu_state) = CPU_DEAD; 445 __this_cpu_write(cpu_state, CPU_DEAD);
446 smp_wmb(); 446 smp_wmb();
447 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) 447 while (__this_cpu_read(cpu_state) != CPU_UP_PREPARE)
448 cpu_relax(); 448 cpu_relax();
449} 449}
450 450
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 67fd2fd2620a..fa1fd8a0c867 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -394,10 +394,10 @@ void ppc_enable_pmcs(void)
394 ppc_set_pmu_inuse(1); 394 ppc_set_pmu_inuse(1);
395 395
396 /* Only need to enable them once */ 396 /* Only need to enable them once */
397 if (__get_cpu_var(pmcs_enabled)) 397 if (__this_cpu_read(pmcs_enabled))
398 return; 398 return;
399 399
400 __get_cpu_var(pmcs_enabled) = 1; 400 __this_cpu_write(pmcs_enabled, 1);
401 401
402 if (ppc_md.enable_pmcs) 402 if (ppc_md.enable_pmcs)
403 ppc_md.enable_pmcs(); 403 ppc_md.enable_pmcs();
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 7505599c2593..fa7c4f12104f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -458,9 +458,9 @@ static inline void clear_irq_work_pending(void)
458 458
459DEFINE_PER_CPU(u8, irq_work_pending); 459DEFINE_PER_CPU(u8, irq_work_pending);
460 460
461#define set_irq_work_pending_flag() __get_cpu_var(irq_work_pending) = 1 461#define set_irq_work_pending_flag() __this_cpu_write(irq_work_pending, 1)
462#define test_irq_work_pending() __get_cpu_var(irq_work_pending) 462#define test_irq_work_pending() __this_cpu_read(irq_work_pending)
463#define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0 463#define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0)
464 464
465#endif /* 32 vs 64 bit */ 465#endif /* 32 vs 64 bit */
466 466
@@ -482,8 +482,8 @@ void arch_irq_work_raise(void)
482static void __timer_interrupt(void) 482static void __timer_interrupt(void)
483{ 483{
484 struct pt_regs *regs = get_irq_regs(); 484 struct pt_regs *regs = get_irq_regs();
485 u64 *next_tb = &__get_cpu_var(decrementers_next_tb); 485 u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
486 struct clock_event_device *evt = &__get_cpu_var(decrementers); 486 struct clock_event_device *evt = this_cpu_ptr(&decrementers);
487 u64 now; 487 u64 now;
488 488
489 trace_timer_interrupt_entry(regs); 489 trace_timer_interrupt_entry(regs);
@@ -498,7 +498,7 @@ static void __timer_interrupt(void)
498 *next_tb = ~(u64)0; 498 *next_tb = ~(u64)0;
499 if (evt->event_handler) 499 if (evt->event_handler)
500 evt->event_handler(evt); 500 evt->event_handler(evt);
501 __get_cpu_var(irq_stat).timer_irqs_event++; 501 __this_cpu_inc(irq_stat.timer_irqs_event);
502 } else { 502 } else {
503 now = *next_tb - now; 503 now = *next_tb - now;
504 if (now <= DECREMENTER_MAX) 504 if (now <= DECREMENTER_MAX)
@@ -506,13 +506,13 @@ static void __timer_interrupt(void)
506 /* We may have raced with new irq work */ 506 /* We may have raced with new irq work */
507 if (test_irq_work_pending()) 507 if (test_irq_work_pending())
508 set_dec(1); 508 set_dec(1);
509 __get_cpu_var(irq_stat).timer_irqs_others++; 509 __this_cpu_inc(irq_stat.timer_irqs_others);
510 } 510 }
511 511
512#ifdef CONFIG_PPC64 512#ifdef CONFIG_PPC64
513 /* collect purr register values often, for accurate calculations */ 513 /* collect purr register values often, for accurate calculations */
514 if (firmware_has_feature(FW_FEATURE_SPLPAR)) { 514 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
515 struct cpu_usage *cu = &__get_cpu_var(cpu_usage_array); 515 struct cpu_usage *cu = this_cpu_ptr(&cpu_usage_array);
516 cu->current_tb = mfspr(SPRN_PURR); 516 cu->current_tb = mfspr(SPRN_PURR);
517 } 517 }
518#endif 518#endif
@@ -527,7 +527,7 @@ static void __timer_interrupt(void)
527void timer_interrupt(struct pt_regs * regs) 527void timer_interrupt(struct pt_regs * regs)
528{ 528{
529 struct pt_regs *old_regs; 529 struct pt_regs *old_regs;
530 u64 *next_tb = &__get_cpu_var(decrementers_next_tb); 530 u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
531 531
532 /* Ensure a positive value is written to the decrementer, or else 532 /* Ensure a positive value is written to the decrementer, or else
533 * some CPUs will continue to take decrementer exceptions. 533 * some CPUs will continue to take decrementer exceptions.
@@ -813,7 +813,7 @@ static void __init clocksource_init(void)
813static int decrementer_set_next_event(unsigned long evt, 813static int decrementer_set_next_event(unsigned long evt,
814 struct clock_event_device *dev) 814 struct clock_event_device *dev)
815{ 815{
816 __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; 816 __this_cpu_write(decrementers_next_tb, get_tb_or_rtc() + evt);
817 set_dec(evt); 817 set_dec(evt);
818 818
819 /* We may have raced with new irq work */ 819 /* We may have raced with new irq work */
@@ -833,7 +833,7 @@ static void decrementer_set_mode(enum clock_event_mode mode,
833/* Interrupt handler for the timer broadcast IPI */ 833/* Interrupt handler for the timer broadcast IPI */
834void tick_broadcast_ipi_handler(void) 834void tick_broadcast_ipi_handler(void)
835{ 835{
836 u64 *next_tb = &__get_cpu_var(decrementers_next_tb); 836 u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
837 837
838 *next_tb = get_tb_or_rtc(); 838 *next_tb = get_tb_or_rtc();
839 __timer_interrupt(); 839 __timer_interrupt();
@@ -989,6 +989,7 @@ void GregorianDay(struct rtc_time * tm)
989 989
990 tm->tm_wday = day % 7; 990 tm->tm_wday = day % 7;
991} 991}
992EXPORT_SYMBOL_GPL(GregorianDay);
992 993
993void to_tm(int tim, struct rtc_time * tm) 994void to_tm(int tim, struct rtc_time * tm)
994{ 995{
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 0dc43f9932cf..e6595b72269b 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -295,7 +295,7 @@ long machine_check_early(struct pt_regs *regs)
295{ 295{
296 long handled = 0; 296 long handled = 0;
297 297
298 __get_cpu_var(irq_stat).mce_exceptions++; 298 __this_cpu_inc(irq_stat.mce_exceptions);
299 299
300 if (cur_cpu_spec && cur_cpu_spec->machine_check_early) 300 if (cur_cpu_spec && cur_cpu_spec->machine_check_early)
301 handled = cur_cpu_spec->machine_check_early(regs); 301 handled = cur_cpu_spec->machine_check_early(regs);
@@ -304,7 +304,7 @@ long machine_check_early(struct pt_regs *regs)
304 304
305long hmi_exception_realmode(struct pt_regs *regs) 305long hmi_exception_realmode(struct pt_regs *regs)
306{ 306{
307 __get_cpu_var(irq_stat).hmi_exceptions++; 307 __this_cpu_inc(irq_stat.hmi_exceptions);
308 308
309 if (ppc_md.hmi_exception_early) 309 if (ppc_md.hmi_exception_early)
310 ppc_md.hmi_exception_early(regs); 310 ppc_md.hmi_exception_early(regs);
@@ -700,7 +700,7 @@ void machine_check_exception(struct pt_regs *regs)
700 enum ctx_state prev_state = exception_enter(); 700 enum ctx_state prev_state = exception_enter();
701 int recover = 0; 701 int recover = 0;
702 702
703 __get_cpu_var(irq_stat).mce_exceptions++; 703 __this_cpu_inc(irq_stat.mce_exceptions);
704 704
705 /* See if any machine dependent calls. In theory, we would want 705 /* See if any machine dependent calls. In theory, we would want
706 * to call the CPU first, and call the ppc_md. one if the CPU 706 * to call the CPU first, and call the ppc_md. one if the CPU
@@ -1519,7 +1519,7 @@ void vsx_unavailable_tm(struct pt_regs *regs)
1519 1519
1520void performance_monitor_exception(struct pt_regs *regs) 1520void performance_monitor_exception(struct pt_regs *regs)
1521{ 1521{
1522 __get_cpu_var(irq_stat).pmu_irqs++; 1522 __this_cpu_inc(irq_stat.pmu_irqs);
1523 1523
1524 perf_irq(regs); 1524 perf_irq(regs);
1525} 1525}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 6e7c4923b5ea..411116c38da4 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -69,8 +69,12 @@ static void udbg_uart_putc(char c)
69 69
70static int udbg_uart_getc_poll(void) 70static int udbg_uart_getc_poll(void)
71{ 71{
72 if (!udbg_uart_in || !(udbg_uart_in(UART_LSR) & LSR_DR)) 72 if (!udbg_uart_in)
73 return -1;
74
75 if (!(udbg_uart_in(UART_LSR) & LSR_DR))
73 return udbg_uart_in(UART_RBR); 76 return udbg_uart_in(UART_RBR);
77
74 return -1; 78 return -1;
75} 79}
76 80
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index f174351842cf..305eb0d9b768 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -20,7 +20,6 @@
20#include <linux/user.h> 20#include <linux/user.h>
21#include <linux/elf.h> 21#include <linux/elf.h>
22#include <linux/security.h> 22#include <linux/security.h>
23#include <linux/bootmem.h>
24#include <linux/memblock.h> 23#include <linux/memblock.h>
25 24
26#include <asm/pgtable.h> 25#include <asm/pgtable.h>
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 4fdc27c80f4c..3f1bb5a36c27 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -12,7 +12,6 @@
12#include <linux/export.h> 12#include <linux/export.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/bootmem.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/memblock.h> 16#include <linux/memblock.h>
18#include <linux/sizes.h> 17#include <linux/sizes.h>
@@ -154,7 +153,7 @@ EXPORT_SYMBOL_GPL(kvm_release_hpt);
154 * kvm_cma_reserve() - reserve area for kvm hash pagetable 153 * kvm_cma_reserve() - reserve area for kvm hash pagetable
155 * 154 *
156 * This function reserves memory from early allocator. It should be 155 * This function reserves memory from early allocator. It should be
157 * called by arch specific code once the early allocator (memblock or bootmem) 156 * called by arch specific code once the memblock allocator
158 * has been activated and all other subsystems have already allocated/reserved 157 * has been activated and all other subsystems have already allocated/reserved
159 * memory. 158 * memory.
160 */ 159 */
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index edb2ccdbb2ba..65c105b17a25 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -201,8 +201,6 @@ kvmppc_primary_no_guest:
201 bge kvm_novcpu_exit /* another thread already exiting */ 201 bge kvm_novcpu_exit /* another thread already exiting */
202 li r3, NAPPING_NOVCPU 202 li r3, NAPPING_NOVCPU
203 stb r3, HSTATE_NAPPING(r13) 203 stb r3, HSTATE_NAPPING(r13)
204 li r3, 1
205 stb r3, HSTATE_HWTHREAD_REQ(r13)
206 204
207 b kvm_do_nap 205 b kvm_do_nap
208 206
@@ -293,6 +291,8 @@ kvm_start_guest:
293 /* if we have no vcpu to run, go back to sleep */ 291 /* if we have no vcpu to run, go back to sleep */
294 beq kvm_no_guest 292 beq kvm_no_guest
295 293
294kvm_secondary_got_guest:
295
296 /* Set HSTATE_DSCR(r13) to something sensible */ 296 /* Set HSTATE_DSCR(r13) to something sensible */
297 ld r6, PACA_DSCR(r13) 297 ld r6, PACA_DSCR(r13)
298 std r6, HSTATE_DSCR(r13) 298 std r6, HSTATE_DSCR(r13)
@@ -318,27 +318,46 @@ kvm_start_guest:
318 stwcx. r3, 0, r4 318 stwcx. r3, 0, r4
319 bne 51b 319 bne 51b
320 320
321/*
322 * At this point we have finished executing in the guest.
323 * We need to wait for hwthread_req to become zero, since
324 * we may not turn on the MMU while hwthread_req is non-zero.
325 * While waiting we also need to check if we get given a vcpu to run.
326 */
321kvm_no_guest: 327kvm_no_guest:
322 li r0, KVM_HWTHREAD_IN_NAP 328 lbz r3, HSTATE_HWTHREAD_REQ(r13)
329 cmpwi r3, 0
330 bne 53f
331 HMT_MEDIUM
332 li r0, KVM_HWTHREAD_IN_KERNEL
323 stb r0, HSTATE_HWTHREAD_STATE(r13) 333 stb r0, HSTATE_HWTHREAD_STATE(r13)
324kvm_do_nap: 334 /* need to recheck hwthread_req after a barrier, to avoid race */
325 /* Clear the runlatch bit before napping */ 335 sync
326 mfspr r2, SPRN_CTRLF 336 lbz r3, HSTATE_HWTHREAD_REQ(r13)
327 clrrdi r2, r2, 1 337 cmpwi r3, 0
328 mtspr SPRN_CTRLT, r2 338 bne 54f
329 339/*
340 * We jump to power7_wakeup_loss, which will return to the caller
341 * of power7_nap in the powernv cpu offline loop. The value we
342 * put in r3 becomes the return value for power7_nap.
343 */
330 li r3, LPCR_PECE0 344 li r3, LPCR_PECE0
331 mfspr r4, SPRN_LPCR 345 mfspr r4, SPRN_LPCR
332 rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 346 rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
333 mtspr SPRN_LPCR, r4 347 mtspr SPRN_LPCR, r4
334 isync 348 li r3, 0
335 std r0, HSTATE_SCRATCH0(r13) 349 b power7_wakeup_loss
336 ptesync 350
337 ld r0, HSTATE_SCRATCH0(r13) 35153: HMT_LOW
3381: cmpd r0, r0 352 ld r4, HSTATE_KVM_VCPU(r13)
339 bne 1b 353 cmpdi r4, 0
340 nap 354 beq kvm_no_guest
341 b . 355 HMT_MEDIUM
356 b kvm_secondary_got_guest
357
35854: li r0, KVM_HWTHREAD_IN_KVM
359 stb r0, HSTATE_HWTHREAD_STATE(r13)
360 b kvm_no_guest
342 361
343/****************************************************************************** 362/******************************************************************************
344 * * 363 * *
@@ -2172,6 +2191,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
2172 * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the 2191 * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the
2173 * runlatch bit before napping. 2192 * runlatch bit before napping.
2174 */ 2193 */
2194kvm_do_nap:
2175 mfspr r2, SPRN_CTRLF 2195 mfspr r2, SPRN_CTRLF
2176 clrrdi r2, r2, 1 2196 clrrdi r2, r2, 1
2177 mtspr SPRN_CTRLT, r2 2197 mtspr SPRN_CTRLT, r2
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index 2e02ed849f36..16095841afe1 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -76,11 +76,11 @@ static inline int local_sid_setup_one(struct id *entry)
76 unsigned long sid; 76 unsigned long sid;
77 int ret = -1; 77 int ret = -1;
78 78
79 sid = ++(__get_cpu_var(pcpu_last_used_sid)); 79 sid = __this_cpu_inc_return(pcpu_last_used_sid);
80 if (sid < NUM_TIDS) { 80 if (sid < NUM_TIDS) {
81 __get_cpu_var(pcpu_sids).entry[sid] = entry; 81 __this_cpu_write(pcpu_sids)entry[sid], entry);
82 entry->val = sid; 82 entry->val = sid;
83 entry->pentry = &__get_cpu_var(pcpu_sids).entry[sid]; 83 entry->pentry = this_cpu_ptr(&pcpu_sids.entry[sid]);
84 ret = sid; 84 ret = sid;
85 } 85 }
86 86
@@ -108,8 +108,8 @@ static inline int local_sid_setup_one(struct id *entry)
108static inline int local_sid_lookup(struct id *entry) 108static inline int local_sid_lookup(struct id *entry)
109{ 109{
110 if (entry && entry->val != 0 && 110 if (entry && entry->val != 0 &&
111 __get_cpu_var(pcpu_sids).entry[entry->val] == entry && 111 __this_cpu_read(pcpu_sids.entry[entry->val]) == entry &&
112 entry->pentry == &__get_cpu_var(pcpu_sids).entry[entry->val]) 112 entry->pentry == this_cpu_ptr(&pcpu_sids.entry[entry->val]))
113 return entry->val; 113 return entry->val;
114 return -1; 114 return -1;
115} 115}
@@ -117,8 +117,8 @@ static inline int local_sid_lookup(struct id *entry)
117/* Invalidate all id mappings on local core -- call with preempt disabled */ 117/* Invalidate all id mappings on local core -- call with preempt disabled */
118static inline void local_sid_destroy_all(void) 118static inline void local_sid_destroy_all(void)
119{ 119{
120 __get_cpu_var(pcpu_last_used_sid) = 0; 120 __this_cpu_write(pcpu_last_used_sid, 0);
121 memset(&__get_cpu_var(pcpu_sids), 0, sizeof(__get_cpu_var(pcpu_sids))); 121 memset(this_cpu_ptr(&pcpu_sids), 0, sizeof(pcpu_sids));
122} 122}
123 123
124static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500) 124static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500)
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c
index 769778f855b0..cc536d4a75ef 100644
--- a/arch/powerpc/kvm/e500_mmu_host.c
+++ b/arch/powerpc/kvm/e500_mmu_host.c
@@ -661,7 +661,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type,
661 if (unlikely((pr && !(mas3 & MAS3_UX)) || 661 if (unlikely((pr && !(mas3 & MAS3_UX)) ||
662 (!pr && !(mas3 & MAS3_SX)))) { 662 (!pr && !(mas3 & MAS3_SX)))) {
663 pr_err_ratelimited( 663 pr_err_ratelimited(
664 "%s: Instuction emulation from guest addres %08lx without execute permission\n", 664 "%s: Instruction emulation from guest address %08lx without execute permission\n",
665 __func__, geaddr); 665 __func__, geaddr);
666 return EMULATE_AGAIN; 666 return EMULATE_AGAIN;
667 } 667 }
@@ -673,7 +673,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type,
673 if (has_feature(vcpu, VCPU_FTR_MMU_V2) && 673 if (has_feature(vcpu, VCPU_FTR_MMU_V2) &&
674 unlikely((mas2 & MAS2_I) || (mas2 & MAS2_W) || !(mas2 & MAS2_M))) { 674 unlikely((mas2 & MAS2_I) || (mas2 & MAS2_W) || !(mas2 & MAS2_M))) {
675 pr_err_ratelimited( 675 pr_err_ratelimited(
676 "%s: Instuction emulation from guest addres %08lx mismatches storage attributes\n", 676 "%s: Instruction emulation from guest address %08lx mismatches storage attributes\n",
677 __func__, geaddr); 677 __func__, geaddr);
678 return EMULATE_AGAIN; 678 return EMULATE_AGAIN;
679 } 679 }
@@ -686,7 +686,7 @@ int kvmppc_load_last_inst(struct kvm_vcpu *vcpu, enum instruction_type type,
686 686
687 /* Guard against emulation from devices area */ 687 /* Guard against emulation from devices area */
688 if (unlikely(!page_is_ram(pfn))) { 688 if (unlikely(!page_is_ram(pfn))) {
689 pr_err_ratelimited("%s: Instruction emulation from non-RAM host addres %08llx is not supported\n", 689 pr_err_ratelimited("%s: Instruction emulation from non-RAM host address %08llx is not supported\n",
690 __func__, addr); 690 __func__, addr);
691 return EMULATE_AGAIN; 691 return EMULATE_AGAIN;
692 } 692 }
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 2fdc8722e324..cda695de8aa7 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -144,9 +144,9 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu)
144 mtspr(SPRN_GESR, vcpu->arch.shared->esr); 144 mtspr(SPRN_GESR, vcpu->arch.shared->esr);
145 145
146 if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || 146 if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
147 __get_cpu_var(last_vcpu_of_lpid)[get_lpid(vcpu)] != vcpu) { 147 __this_cpu_read(last_vcpu_of_lpid[get_lpid(vcpu)]) != vcpu) {
148 kvmppc_e500_tlbil_all(vcpu_e500); 148 kvmppc_e500_tlbil_all(vcpu_e500);
149 __get_cpu_var(last_vcpu_of_lpid)[get_lpid(vcpu)] = vcpu; 149 __this_cpu_write(last_vcpu_of_lpid[get_lpid(vcpu)], vcpu);
150 } 150 }
151} 151}
152 152
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 9f342f134ae4..597562f69b2d 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -12,7 +12,6 @@ CFLAGS_REMOVE_feature-fixups.o = -pg
12obj-y := string.o alloc.o \ 12obj-y := string.o alloc.o \
13 crtsavres.o ppc_ksyms.o 13 crtsavres.o ppc_ksyms.o
14obj-$(CONFIG_PPC32) += div64.o copy_32.o 14obj-$(CONFIG_PPC32) += div64.o copy_32.o
15obj-$(CONFIG_HAS_IOMEM) += devres.o
16 15
17obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ 16obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
18 usercopy_64.o mem_64.o string.o \ 17 usercopy_64.o mem_64.o string.o \
diff --git a/arch/powerpc/lib/alloc.c b/arch/powerpc/lib/alloc.c
index da22c84a8fed..4a6c2cf890d9 100644
--- a/arch/powerpc/lib/alloc.c
+++ b/arch/powerpc/lib/alloc.c
@@ -13,9 +13,7 @@ void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask)
13 if (mem_init_done) 13 if (mem_init_done)
14 p = kzalloc(size, mask); 14 p = kzalloc(size, mask);
15 else { 15 else {
16 p = alloc_bootmem(size); 16 p = memblock_virt_alloc(size, 0);
17 if (p)
18 memset(p, 0, size);
19 } 17 }
20 return p; 18 return p;
21} 19}
diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S
index c46c876ac96a..92ee840529bc 100644
--- a/arch/powerpc/lib/copyuser_power7.S
+++ b/arch/powerpc/lib/copyuser_power7.S
@@ -718,4 +718,4 @@ err3; stb r0,0(r3)
718 718
71915: addi r1,r1,STACKFRAMESIZE 71915: addi r1,r1,STACKFRAMESIZE
720 b exit_vmx_usercopy /* tail call optimise */ 720 b exit_vmx_usercopy /* tail call optimise */
721#endif /* CONFiG_ALTIVEC */ 721#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/lib/devres.c b/arch/powerpc/lib/devres.c
deleted file mode 100644
index 8df55fc3aad6..000000000000
--- a/arch/powerpc/lib/devres.c
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * Copyright (C) 2008 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/device.h> /* devres_*(), devm_ioremap_release() */
11#include <linux/gfp.h>
12#include <linux/io.h> /* ioremap_prot() */
13#include <linux/export.h> /* EXPORT_SYMBOL() */
14
15/**
16 * devm_ioremap_prot - Managed ioremap_prot()
17 * @dev: Generic device to remap IO address for
18 * @offset: BUS offset to map
19 * @size: Size of map
20 * @flags: Page flags
21 *
22 * Managed ioremap_prot(). Map is automatically unmapped on driver
23 * detach.
24 */
25void __iomem *devm_ioremap_prot(struct device *dev, resource_size_t offset,
26 size_t size, unsigned long flags)
27{
28 void __iomem **ptr, *addr;
29
30 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
31 if (!ptr)
32 return NULL;
33
34 addr = ioremap_prot(offset, size, flags);
35 if (addr) {
36 *ptr = addr;
37 devres_add(dev, ptr);
38 } else
39 devres_free(ptr);
40
41 return addr;
42}
43EXPORT_SYMBOL(devm_ioremap_prot);
diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S
index 2ff5c142f87b..0830587df16e 100644
--- a/arch/powerpc/lib/memcpy_power7.S
+++ b/arch/powerpc/lib/memcpy_power7.S
@@ -653,4 +653,4 @@ _GLOBAL(memcpy_power7)
65315: addi r1,r1,STACKFRAMESIZE 65315: addi r1,r1,STACKFRAMESIZE
654 ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1) 654 ld r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
655 b exit_vmx_copy /* tail call optimise */ 655 b exit_vmx_copy /* tail call optimise */
656#endif /* CONFiG_ALTIVEC */ 656#endif /* CONFIG_ALTIVEC */
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 54651fc2d412..dc885b30f7a6 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1865,6 +1865,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1865 } 1865 }
1866 goto ldst_done; 1866 goto ldst_done;
1867 1867
1868#ifdef CONFIG_PPC_FPU
1868 case LOAD_FP: 1869 case LOAD_FP:
1869 if (regs->msr & MSR_LE) 1870 if (regs->msr & MSR_LE)
1870 return 0; 1871 return 0;
@@ -1873,7 +1874,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1873 else 1874 else
1874 err = do_fp_load(op.reg, do_lfd, op.ea, size, regs); 1875 err = do_fp_load(op.reg, do_lfd, op.ea, size, regs);
1875 goto ldst_done; 1876 goto ldst_done;
1876 1877#endif
1877#ifdef CONFIG_ALTIVEC 1878#ifdef CONFIG_ALTIVEC
1878 case LOAD_VMX: 1879 case LOAD_VMX:
1879 if (regs->msr & MSR_LE) 1880 if (regs->msr & MSR_LE)
@@ -1919,6 +1920,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1919 err = write_mem(op.val, op.ea, size, regs); 1920 err = write_mem(op.val, op.ea, size, regs);
1920 goto ldst_done; 1921 goto ldst_done;
1921 1922
1923#ifdef CONFIG_PPC_FPU
1922 case STORE_FP: 1924 case STORE_FP:
1923 if (regs->msr & MSR_LE) 1925 if (regs->msr & MSR_LE)
1924 return 0; 1926 return 0;
@@ -1927,7 +1929,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
1927 else 1929 else
1928 err = do_fp_store(op.reg, do_stfd, op.ea, size, regs); 1930 err = do_fp_store(op.reg, do_stfd, op.ea, size, regs);
1929 goto ldst_done; 1931 goto ldst_done;
1930 1932#endif
1931#ifdef CONFIG_ALTIVEC 1933#ifdef CONFIG_ALTIVEC
1932 case STORE_VMX: 1934 case STORE_VMX:
1933 if (regs->msr & MSR_LE) 1935 if (regs->msr & MSR_LE)
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 325e861616a1..438dcd3fd0d1 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -6,7 +6,7 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
6 6
7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) 7ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
8 8
9obj-y := fault.o mem.o pgtable.o gup.o mmap.o \ 9obj-y := fault.o mem.o pgtable.o mmap.o \
10 init_$(CONFIG_WORD_SIZE).o \ 10 init_$(CONFIG_WORD_SIZE).o \
11 pgtable_$(CONFIG_WORD_SIZE).o 11 pgtable_$(CONFIG_WORD_SIZE).o
12obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ 12obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 08d659a9fcdb..eb79907f34fa 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -43,7 +43,6 @@
43#include <asm/tlbflush.h> 43#include <asm/tlbflush.h>
44#include <asm/siginfo.h> 44#include <asm/siginfo.h>
45#include <asm/debug.h> 45#include <asm/debug.h>
46#include <mm/mmu_decl.h>
47 46
48#include "icswx.h" 47#include "icswx.h"
49 48
@@ -380,12 +379,6 @@ good_area:
380 goto bad_area; 379 goto bad_area;
381#endif /* CONFIG_6xx */ 380#endif /* CONFIG_6xx */
382#if defined(CONFIG_8xx) 381#if defined(CONFIG_8xx)
383 /* 8xx sometimes need to load a invalid/non-present TLBs.
384 * These must be invalidated separately as linux mm don't.
385 */
386 if (error_code & 0x40000000) /* no translation? */
387 _tlbil_va(address, 0, 0, 0);
388
389 /* The MPC8xx seems to always set 0x80000000, which is 382 /* The MPC8xx seems to always set 0x80000000, which is
390 * "undefined". Of those that can be set, this is the only 383 * "undefined". Of those that can be set, this is the only
391 * one which seems bad. 384 * one which seems bad.
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c
deleted file mode 100644
index d8746684f606..000000000000
--- a/arch/powerpc/mm/gup.c
+++ /dev/null
@@ -1,235 +0,0 @@
1/*
2 * Lockless get_user_pages_fast for powerpc
3 *
4 * Copyright (C) 2008 Nick Piggin
5 * Copyright (C) 2008 Novell Inc.
6 */
7#undef DEBUG
8
9#include <linux/sched.h>
10#include <linux/mm.h>
11#include <linux/hugetlb.h>
12#include <linux/vmstat.h>
13#include <linux/pagemap.h>
14#include <linux/rwsem.h>
15#include <asm/pgtable.h>
16
17#ifdef __HAVE_ARCH_PTE_SPECIAL
18
19/*
20 * The performance critical leaf functions are made noinline otherwise gcc
21 * inlines everything into a single function which results in too much
22 * register pressure.
23 */
24static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
25 unsigned long end, int write, struct page **pages, int *nr)
26{
27 unsigned long mask, result;
28 pte_t *ptep;
29
30 result = _PAGE_PRESENT|_PAGE_USER;
31 if (write)
32 result |= _PAGE_RW;
33 mask = result | _PAGE_SPECIAL;
34
35 ptep = pte_offset_kernel(&pmd, addr);
36 do {
37 pte_t pte = ACCESS_ONCE(*ptep);
38 struct page *page;
39 /*
40 * Similar to the PMD case, NUMA hinting must take slow path
41 */
42 if (pte_numa(pte))
43 return 0;
44
45 if ((pte_val(pte) & mask) != result)
46 return 0;
47 VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
48 page = pte_page(pte);
49 if (!page_cache_get_speculative(page))
50 return 0;
51 if (unlikely(pte_val(pte) != pte_val(*ptep))) {
52 put_page(page);
53 return 0;
54 }
55 pages[*nr] = page;
56 (*nr)++;
57
58 } while (ptep++, addr += PAGE_SIZE, addr != end);
59
60 return 1;
61}
62
63static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
64 int write, struct page **pages, int *nr)
65{
66 unsigned long next;
67 pmd_t *pmdp;
68
69 pmdp = pmd_offset(&pud, addr);
70 do {
71 pmd_t pmd = ACCESS_ONCE(*pmdp);
72
73 next = pmd_addr_end(addr, end);
74 /*
75 * If we find a splitting transparent hugepage we
76 * return zero. That will result in taking the slow
77 * path which will call wait_split_huge_page()
78 * if the pmd is still in splitting state
79 */
80 if (pmd_none(pmd) || pmd_trans_splitting(pmd))
81 return 0;
82 if (pmd_huge(pmd) || pmd_large(pmd)) {
83 /*
84 * NUMA hinting faults need to be handled in the GUP
85 * slowpath for accounting purposes and so that they
86 * can be serialised against THP migration.
87 */
88 if (pmd_numa(pmd))
89 return 0;
90
91 if (!gup_hugepte((pte_t *)pmdp, PMD_SIZE, addr, next,
92 write, pages, nr))
93 return 0;
94 } else if (is_hugepd(pmdp)) {
95 if (!gup_hugepd((hugepd_t *)pmdp, PMD_SHIFT,
96 addr, next, write, pages, nr))
97 return 0;
98 } else if (!gup_pte_range(pmd, addr, next, write, pages, nr))
99 return 0;
100 } while (pmdp++, addr = next, addr != end);
101
102 return 1;
103}
104
105static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,
106 int write, struct page **pages, int *nr)
107{
108 unsigned long next;
109 pud_t *pudp;
110
111 pudp = pud_offset(&pgd, addr);
112 do {
113 pud_t pud = ACCESS_ONCE(*pudp);
114
115 next = pud_addr_end(addr, end);
116 if (pud_none(pud))
117 return 0;
118 if (pud_huge(pud)) {
119 if (!gup_hugepte((pte_t *)pudp, PUD_SIZE, addr, next,
120 write, pages, nr))
121 return 0;
122 } else if (is_hugepd(pudp)) {
123 if (!gup_hugepd((hugepd_t *)pudp, PUD_SHIFT,
124 addr, next, write, pages, nr))
125 return 0;
126 } else if (!gup_pmd_range(pud, addr, next, write, pages, nr))
127 return 0;
128 } while (pudp++, addr = next, addr != end);
129
130 return 1;
131}
132
133int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
134 struct page **pages)
135{
136 struct mm_struct *mm = current->mm;
137 unsigned long addr, len, end;
138 unsigned long next;
139 unsigned long flags;
140 pgd_t *pgdp;
141 int nr = 0;
142
143 pr_devel("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
144
145 start &= PAGE_MASK;
146 addr = start;
147 len = (unsigned long) nr_pages << PAGE_SHIFT;
148 end = start + len;
149
150 if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
151 start, len)))
152 return 0;
153
154 pr_devel(" aligned: %lx .. %lx\n", start, end);
155
156 /*
157 * XXX: batch / limit 'nr', to avoid large irq off latency
158 * needs some instrumenting to determine the common sizes used by
159 * important workloads (eg. DB2), and whether limiting the batch size
160 * will decrease performance.
161 *
162 * It seems like we're in the clear for the moment. Direct-IO is
163 * the main guy that batches up lots of get_user_pages, and even
164 * they are limited to 64-at-a-time which is not so many.
165 */
166 /*
167 * This doesn't prevent pagetable teardown, but does prevent
168 * the pagetables from being freed on powerpc.
169 *
170 * So long as we atomically load page table pointers versus teardown,
171 * we can follow the address down to the the page and take a ref on it.
172 */
173 local_irq_save(flags);
174
175 pgdp = pgd_offset(mm, addr);
176 do {
177 pgd_t pgd = ACCESS_ONCE(*pgdp);
178
179 pr_devel(" %016lx: normal pgd %p\n", addr,
180 (void *)pgd_val(pgd));
181 next = pgd_addr_end(addr, end);
182 if (pgd_none(pgd))
183 break;
184 if (pgd_huge(pgd)) {
185 if (!gup_hugepte((pte_t *)pgdp, PGDIR_SIZE, addr, next,
186 write, pages, &nr))
187 break;
188 } else if (is_hugepd(pgdp)) {
189 if (!gup_hugepd((hugepd_t *)pgdp, PGDIR_SHIFT,
190 addr, next, write, pages, &nr))
191 break;
192 } else if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
193 break;
194 } while (pgdp++, addr = next, addr != end);
195
196 local_irq_restore(flags);
197
198 return nr;
199}
200
201int get_user_pages_fast(unsigned long start, int nr_pages, int write,
202 struct page **pages)
203{
204 struct mm_struct *mm = current->mm;
205 int nr, ret;
206
207 start &= PAGE_MASK;
208 nr = __get_user_pages_fast(start, nr_pages, write, pages);
209 ret = nr;
210
211 if (nr < nr_pages) {
212 pr_devel(" slow path ! nr = %d\n", nr);
213
214 /* Try to get the remaining pages with get_user_pages */
215 start += nr << PAGE_SHIFT;
216 pages += nr;
217
218 down_read(&mm->mmap_sem);
219 ret = get_user_pages(current, mm, start,
220 nr_pages - nr, write, 0, pages, NULL);
221 up_read(&mm->mmap_sem);
222
223 /* Have to be a bit careful with return values */
224 if (nr > 0) {
225 if (ret < 0)
226 ret = nr;
227 else
228 ret += nr;
229 }
230 }
231
232 return ret;
233}
234
235#endif /* __HAVE_ARCH_PTE_SPECIAL */
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index 057cbbb4c576..463174a4a647 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -46,7 +46,8 @@
46 46
47/* 47/*
48 * _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, 48 * _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
49 * pte_t *ptep, unsigned long trap, int local, int ssize) 49 * pte_t *ptep, unsigned long trap, unsigned long flags,
50 * int ssize)
50 * 51 *
51 * Adds a 4K page to the hash table in a segment of 4K pages only 52 * Adds a 4K page to the hash table in a segment of 4K pages only
52 */ 53 */
@@ -298,7 +299,7 @@ htab_modify_pte:
298 li r6,MMU_PAGE_4K /* base page size */ 299 li r6,MMU_PAGE_4K /* base page size */
299 li r7,MMU_PAGE_4K /* actual page size */ 300 li r7,MMU_PAGE_4K /* actual page size */
300 ld r8,STK_PARAM(R9)(r1) /* segment size */ 301 ld r8,STK_PARAM(R9)(r1) /* segment size */
301 ld r9,STK_PARAM(R8)(r1) /* get "local" param */ 302 ld r9,STK_PARAM(R8)(r1) /* get "flags" param */
302.globl htab_call_hpte_updatepp 303.globl htab_call_hpte_updatepp
303htab_call_hpte_updatepp: 304htab_call_hpte_updatepp:
304 bl . /* Patched by htab_finish_init() */ 305 bl . /* Patched by htab_finish_init() */
@@ -338,8 +339,8 @@ htab_pte_insert_failure:
338 *****************************************************************************/ 339 *****************************************************************************/
339 340
340/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, 341/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
341 * pte_t *ptep, unsigned long trap, int local, int ssize, 342 * pte_t *ptep, unsigned long trap, unsigned local flags,
342 * int subpg_prot) 343 * int ssize, int subpg_prot)
343 */ 344 */
344 345
345/* 346/*
@@ -514,7 +515,7 @@ htab_insert_pte:
514 andis. r0,r31,_PAGE_4K_PFN@h 515 andis. r0,r31,_PAGE_4K_PFN@h
515 srdi r5,r31,PTE_RPN_SHIFT 516 srdi r5,r31,PTE_RPN_SHIFT
516 bne- htab_special_pfn 517 bne- htab_special_pfn
517 sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT 518 sldi r5,r5,PAGE_FACTOR
518 add r5,r5,r25 519 add r5,r5,r25
519htab_special_pfn: 520htab_special_pfn:
520 sldi r5,r5,HW_PAGE_SHIFT 521 sldi r5,r5,HW_PAGE_SHIFT
@@ -544,7 +545,7 @@ htab_call_hpte_insert1:
544 andis. r0,r31,_PAGE_4K_PFN@h 545 andis. r0,r31,_PAGE_4K_PFN@h
545 srdi r5,r31,PTE_RPN_SHIFT 546 srdi r5,r31,PTE_RPN_SHIFT
546 bne- 3f 547 bne- 3f
547 sldi r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT 548 sldi r5,r5,PAGE_FACTOR
548 add r5,r5,r25 549 add r5,r5,r25
5493: sldi r5,r5,HW_PAGE_SHIFT 5503: sldi r5,r5,HW_PAGE_SHIFT
550 551
@@ -594,7 +595,7 @@ htab_inval_old_hpte:
594 li r5,0 /* PTE.hidx */ 595 li r5,0 /* PTE.hidx */
595 li r6,MMU_PAGE_64K /* psize */ 596 li r6,MMU_PAGE_64K /* psize */
596 ld r7,STK_PARAM(R9)(r1) /* ssize */ 597 ld r7,STK_PARAM(R9)(r1) /* ssize */
597 ld r8,STK_PARAM(R8)(r1) /* local */ 598 ld r8,STK_PARAM(R8)(r1) /* flags */
598 bl flush_hash_page 599 bl flush_hash_page
599 /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */ 600 /* Clear out _PAGE_HPTE_SUB bits in the new linux PTE */
600 lis r0,_PAGE_HPTE_SUB@h 601 lis r0,_PAGE_HPTE_SUB@h
@@ -666,7 +667,7 @@ htab_modify_pte:
666 li r6,MMU_PAGE_4K /* base page size */ 667 li r6,MMU_PAGE_4K /* base page size */
667 li r7,MMU_PAGE_4K /* actual page size */ 668 li r7,MMU_PAGE_4K /* actual page size */
668 ld r8,STK_PARAM(R9)(r1) /* segment size */ 669 ld r8,STK_PARAM(R9)(r1) /* segment size */
669 ld r9,STK_PARAM(R8)(r1) /* get "local" param */ 670 ld r9,STK_PARAM(R8)(r1) /* get "flags" param */
670.globl htab_call_hpte_updatepp 671.globl htab_call_hpte_updatepp
671htab_call_hpte_updatepp: 672htab_call_hpte_updatepp:
672 bl . /* patched by htab_finish_init() */ 673 bl . /* patched by htab_finish_init() */
@@ -962,7 +963,7 @@ ht64_modify_pte:
962 li r6,MMU_PAGE_64K /* base page size */ 963 li r6,MMU_PAGE_64K /* base page size */
963 li r7,MMU_PAGE_64K /* actual page size */ 964 li r7,MMU_PAGE_64K /* actual page size */
964 ld r8,STK_PARAM(R9)(r1) /* segment size */ 965 ld r8,STK_PARAM(R9)(r1) /* segment size */
965 ld r9,STK_PARAM(R8)(r1) /* get "local" param */ 966 ld r9,STK_PARAM(R8)(r1) /* get "flags" param */
966.globl ht64_call_hpte_updatepp 967.globl ht64_call_hpte_updatepp
967ht64_call_hpte_updatepp: 968ht64_call_hpte_updatepp:
968 bl . /* patched by htab_finish_init() */ 969 bl . /* patched by htab_finish_init() */
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index ae4962a06476..9c4880ddecd6 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -283,19 +283,17 @@ static long native_hpte_remove(unsigned long hpte_group)
283 283
284static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, 284static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
285 unsigned long vpn, int bpsize, 285 unsigned long vpn, int bpsize,
286 int apsize, int ssize, int local) 286 int apsize, int ssize, unsigned long flags)
287{ 287{
288 struct hash_pte *hptep = htab_address + slot; 288 struct hash_pte *hptep = htab_address + slot;
289 unsigned long hpte_v, want_v; 289 unsigned long hpte_v, want_v;
290 int ret = 0; 290 int ret = 0, local = 0;
291 291
292 want_v = hpte_encode_avpn(vpn, bpsize, ssize); 292 want_v = hpte_encode_avpn(vpn, bpsize, ssize);
293 293
294 DBG_LOW(" update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)", 294 DBG_LOW(" update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)",
295 vpn, want_v & HPTE_V_AVPN, slot, newpp); 295 vpn, want_v & HPTE_V_AVPN, slot, newpp);
296 296
297 native_lock_hpte(hptep);
298
299 hpte_v = be64_to_cpu(hptep->v); 297 hpte_v = be64_to_cpu(hptep->v);
300 /* 298 /*
301 * We need to invalidate the TLB always because hpte_remove doesn't do 299 * We need to invalidate the TLB always because hpte_remove doesn't do
@@ -308,15 +306,30 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
308 DBG_LOW(" -> miss\n"); 306 DBG_LOW(" -> miss\n");
309 ret = -1; 307 ret = -1;
310 } else { 308 } else {
311 DBG_LOW(" -> hit\n"); 309 native_lock_hpte(hptep);
312 /* Update the HPTE */ 310 /* recheck with locks held */
313 hptep->r = cpu_to_be64((be64_to_cpu(hptep->r) & ~(HPTE_R_PP | HPTE_R_N)) | 311 hpte_v = be64_to_cpu(hptep->v);
314 (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C))); 312 if (unlikely(!HPTE_V_COMPARE(hpte_v, want_v) ||
313 !(hpte_v & HPTE_V_VALID))) {
314 ret = -1;
315 } else {
316 DBG_LOW(" -> hit\n");
317 /* Update the HPTE */
318 hptep->r = cpu_to_be64((be64_to_cpu(hptep->r) &
319 ~(HPTE_R_PP | HPTE_R_N)) |
320 (newpp & (HPTE_R_PP | HPTE_R_N |
321 HPTE_R_C)));
322 }
323 native_unlock_hpte(hptep);
315 } 324 }
316 native_unlock_hpte(hptep);
317 325
318 /* Ensure it is out of the tlb too. */ 326 if (flags & HPTE_LOCAL_UPDATE)
319 tlbie(vpn, bpsize, apsize, ssize, local); 327 local = 1;
328 /*
329 * Ensure it is out of the tlb too if it is not a nohpte fault
330 */
331 if (!(flags & HPTE_NOHPTE_UPDATE))
332 tlbie(vpn, bpsize, apsize, ssize, local);
320 333
321 return ret; 334 return ret;
322} 335}
@@ -419,7 +432,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
419static void native_hugepage_invalidate(unsigned long vsid, 432static void native_hugepage_invalidate(unsigned long vsid,
420 unsigned long addr, 433 unsigned long addr,
421 unsigned char *hpte_slot_array, 434 unsigned char *hpte_slot_array,
422 int psize, int ssize) 435 int psize, int ssize, int local)
423{ 436{
424 int i; 437 int i;
425 struct hash_pte *hptep; 438 struct hash_pte *hptep;
@@ -465,7 +478,7 @@ static void native_hugepage_invalidate(unsigned long vsid,
465 * instruction compares entry_VA in tlb with the VA specified 478 * instruction compares entry_VA in tlb with the VA specified
466 * here 479 * here
467 */ 480 */
468 tlbie(vpn, psize, actual_psize, ssize, 0); 481 tlbie(vpn, psize, actual_psize, ssize, local);
469 } 482 }
470 local_irq_restore(flags); 483 local_irq_restore(flags);
471} 484}
@@ -629,7 +642,7 @@ static void native_flush_hash_range(unsigned long number, int local)
629 unsigned long want_v; 642 unsigned long want_v;
630 unsigned long flags; 643 unsigned long flags;
631 real_pte_t pte; 644 real_pte_t pte;
632 struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); 645 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
633 unsigned long psize = batch->psize; 646 unsigned long psize = batch->psize;
634 int ssize = batch->ssize; 647 int ssize = batch->ssize;
635 int i; 648 int i;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index d5339a3b9945..e56a307bc676 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -989,7 +989,9 @@ static void check_paca_psize(unsigned long ea, struct mm_struct *mm,
989 * -1 - critical hash insertion error 989 * -1 - critical hash insertion error
990 * -2 - access not permitted by subpage protection mechanism 990 * -2 - access not permitted by subpage protection mechanism
991 */ 991 */
992int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap) 992int hash_page_mm(struct mm_struct *mm, unsigned long ea,
993 unsigned long access, unsigned long trap,
994 unsigned long flags)
993{ 995{
994 enum ctx_state prev_state = exception_enter(); 996 enum ctx_state prev_state = exception_enter();
995 pgd_t *pgdir; 997 pgd_t *pgdir;
@@ -997,7 +999,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, u
997 pte_t *ptep; 999 pte_t *ptep;
998 unsigned hugeshift; 1000 unsigned hugeshift;
999 const struct cpumask *tmp; 1001 const struct cpumask *tmp;
1000 int rc, user_region = 0, local = 0; 1002 int rc, user_region = 0;
1001 int psize, ssize; 1003 int psize, ssize;
1002 1004
1003 DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n", 1005 DBG_LOW("hash_page(ea=%016lx, access=%lx, trap=%lx\n",
@@ -1049,7 +1051,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, u
1049 /* Check CPU locality */ 1051 /* Check CPU locality */
1050 tmp = cpumask_of(smp_processor_id()); 1052 tmp = cpumask_of(smp_processor_id());
1051 if (user_region && cpumask_equal(mm_cpumask(mm), tmp)) 1053 if (user_region && cpumask_equal(mm_cpumask(mm), tmp))
1052 local = 1; 1054 flags |= HPTE_LOCAL_UPDATE;
1053 1055
1054#ifndef CONFIG_PPC_64K_PAGES 1056#ifndef CONFIG_PPC_64K_PAGES
1055 /* If we use 4K pages and our psize is not 4K, then we might 1057 /* If we use 4K pages and our psize is not 4K, then we might
@@ -1086,11 +1088,11 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, u
1086 if (hugeshift) { 1088 if (hugeshift) {
1087 if (pmd_trans_huge(*(pmd_t *)ptep)) 1089 if (pmd_trans_huge(*(pmd_t *)ptep))
1088 rc = __hash_page_thp(ea, access, vsid, (pmd_t *)ptep, 1090 rc = __hash_page_thp(ea, access, vsid, (pmd_t *)ptep,
1089 trap, local, ssize, psize); 1091 trap, flags, ssize, psize);
1090#ifdef CONFIG_HUGETLB_PAGE 1092#ifdef CONFIG_HUGETLB_PAGE
1091 else 1093 else
1092 rc = __hash_page_huge(ea, access, vsid, ptep, trap, 1094 rc = __hash_page_huge(ea, access, vsid, ptep, trap,
1093 local, ssize, hugeshift, psize); 1095 flags, ssize, hugeshift, psize);
1094#else 1096#else
1095 else { 1097 else {
1096 /* 1098 /*
@@ -1149,7 +1151,8 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, u
1149 1151
1150#ifdef CONFIG_PPC_HAS_HASH_64K 1152#ifdef CONFIG_PPC_HAS_HASH_64K
1151 if (psize == MMU_PAGE_64K) 1153 if (psize == MMU_PAGE_64K)
1152 rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize); 1154 rc = __hash_page_64K(ea, access, vsid, ptep, trap,
1155 flags, ssize);
1153 else 1156 else
1154#endif /* CONFIG_PPC_HAS_HASH_64K */ 1157#endif /* CONFIG_PPC_HAS_HASH_64K */
1155 { 1158 {
@@ -1158,7 +1161,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long access, u
1158 rc = -2; 1161 rc = -2;
1159 else 1162 else
1160 rc = __hash_page_4K(ea, access, vsid, ptep, trap, 1163 rc = __hash_page_4K(ea, access, vsid, ptep, trap,
1161 local, ssize, spp); 1164 flags, ssize, spp);
1162 } 1165 }
1163 1166
1164 /* Dump some info in case of hash insertion failure, they should 1167 /* Dump some info in case of hash insertion failure, they should
@@ -1181,14 +1184,19 @@ bail:
1181} 1184}
1182EXPORT_SYMBOL_GPL(hash_page_mm); 1185EXPORT_SYMBOL_GPL(hash_page_mm);
1183 1186
1184int hash_page(unsigned long ea, unsigned long access, unsigned long trap) 1187int hash_page(unsigned long ea, unsigned long access, unsigned long trap,
1188 unsigned long dsisr)
1185{ 1189{
1190 unsigned long flags = 0;
1186 struct mm_struct *mm = current->mm; 1191 struct mm_struct *mm = current->mm;
1187 1192
1188 if (REGION_ID(ea) == VMALLOC_REGION_ID) 1193 if (REGION_ID(ea) == VMALLOC_REGION_ID)
1189 mm = &init_mm; 1194 mm = &init_mm;
1190 1195
1191 return hash_page_mm(mm, ea, access, trap); 1196 if (dsisr & DSISR_NOHPTE)
1197 flags |= HPTE_NOHPTE_UPDATE;
1198
1199 return hash_page_mm(mm, ea, access, trap, flags);
1192} 1200}
1193EXPORT_SYMBOL_GPL(hash_page); 1201EXPORT_SYMBOL_GPL(hash_page);
1194 1202
@@ -1200,7 +1208,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
1200 pgd_t *pgdir; 1208 pgd_t *pgdir;
1201 pte_t *ptep; 1209 pte_t *ptep;
1202 unsigned long flags; 1210 unsigned long flags;
1203 int rc, ssize, local = 0; 1211 int rc, ssize, update_flags = 0;
1204 1212
1205 BUG_ON(REGION_ID(ea) != USER_REGION_ID); 1213 BUG_ON(REGION_ID(ea) != USER_REGION_ID);
1206 1214
@@ -1251,16 +1259,17 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
1251 1259
1252 /* Is that local to this CPU ? */ 1260 /* Is that local to this CPU ? */
1253 if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) 1261 if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
1254 local = 1; 1262 update_flags |= HPTE_LOCAL_UPDATE;
1255 1263
1256 /* Hash it in */ 1264 /* Hash it in */
1257#ifdef CONFIG_PPC_HAS_HASH_64K 1265#ifdef CONFIG_PPC_HAS_HASH_64K
1258 if (mm->context.user_psize == MMU_PAGE_64K) 1266 if (mm->context.user_psize == MMU_PAGE_64K)
1259 rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize); 1267 rc = __hash_page_64K(ea, access, vsid, ptep, trap,
1268 update_flags, ssize);
1260 else 1269 else
1261#endif /* CONFIG_PPC_HAS_HASH_64K */ 1270#endif /* CONFIG_PPC_HAS_HASH_64K */
1262 rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize, 1271 rc = __hash_page_4K(ea, access, vsid, ptep, trap, update_flags,
1263 subpage_protection(mm, ea)); 1272 ssize, subpage_protection(mm, ea));
1264 1273
1265 /* Dump some info in case of hash insertion failure, they should 1274 /* Dump some info in case of hash insertion failure, they should
1266 * never happen so it is really useful to know if/when they do 1275 * never happen so it is really useful to know if/when they do
@@ -1278,9 +1287,10 @@ out_exit:
1278 * do not forget to update the assembly call site ! 1287 * do not forget to update the assembly call site !
1279 */ 1288 */
1280void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize, 1289void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,
1281 int local) 1290 unsigned long flags)
1282{ 1291{
1283 unsigned long hash, index, shift, hidx, slot; 1292 unsigned long hash, index, shift, hidx, slot;
1293 int local = flags & HPTE_LOCAL_UPDATE;
1284 1294
1285 DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn); 1295 DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn);
1286 pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) { 1296 pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
@@ -1315,6 +1325,78 @@ void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,
1315#endif 1325#endif
1316} 1326}
1317 1327
1328#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1329void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
1330 pmd_t *pmdp, unsigned int psize, int ssize,
1331 unsigned long flags)
1332{
1333 int i, max_hpte_count, valid;
1334 unsigned long s_addr;
1335 unsigned char *hpte_slot_array;
1336 unsigned long hidx, shift, vpn, hash, slot;
1337 int local = flags & HPTE_LOCAL_UPDATE;
1338
1339 s_addr = addr & HPAGE_PMD_MASK;
1340 hpte_slot_array = get_hpte_slot_array(pmdp);
1341 /*
1342 * IF we try to do a HUGE PTE update after a withdraw is done.
1343 * we will find the below NULL. This happens when we do
1344 * split_huge_page_pmd
1345 */
1346 if (!hpte_slot_array)
1347 return;
1348
1349 if (ppc_md.hugepage_invalidate) {
1350 ppc_md.hugepage_invalidate(vsid, s_addr, hpte_slot_array,
1351 psize, ssize, local);
1352 goto tm_abort;
1353 }
1354 /*
1355 * No bluk hpte removal support, invalidate each entry
1356 */
1357 shift = mmu_psize_defs[psize].shift;
1358 max_hpte_count = HPAGE_PMD_SIZE >> shift;
1359 for (i = 0; i < max_hpte_count; i++) {
1360 /*
1361 * 8 bits per each hpte entries
1362 * 000| [ secondary group (one bit) | hidx (3 bits) | valid bit]
1363 */
1364 valid = hpte_valid(hpte_slot_array, i);
1365 if (!valid)
1366 continue;
1367 hidx = hpte_hash_index(hpte_slot_array, i);
1368
1369 /* get the vpn */
1370 addr = s_addr + (i * (1ul << shift));
1371 vpn = hpt_vpn(addr, vsid, ssize);
1372 hash = hpt_hash(vpn, shift, ssize);
1373 if (hidx & _PTEIDX_SECONDARY)
1374 hash = ~hash;
1375
1376 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
1377 slot += hidx & _PTEIDX_GROUP_IX;
1378 ppc_md.hpte_invalidate(slot, vpn, psize,
1379 MMU_PAGE_16M, ssize, local);
1380 }
1381tm_abort:
1382#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1383 /* Transactions are not aborted by tlbiel, only tlbie.
1384 * Without, syncing a page back to a block device w/ PIO could pick up
1385 * transactional data (bad!) so we force an abort here. Before the
1386 * sync the page will be made read-only, which will flush_hash_page.
1387 * BIG ISSUE here: if the kernel uses a page from userspace without
1388 * unmapping it first, it may see the speculated version.
1389 */
1390 if (local && cpu_has_feature(CPU_FTR_TM) &&
1391 current->thread.regs &&
1392 MSR_TM_ACTIVE(current->thread.regs->msr)) {
1393 tm_enable();
1394 tm_abort(TM_CAUSE_TLBI);
1395 }
1396#endif
1397}
1398#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
1399
1318void flush_hash_range(unsigned long number, int local) 1400void flush_hash_range(unsigned long number, int local)
1319{ 1401{
1320 if (ppc_md.flush_hash_range) 1402 if (ppc_md.flush_hash_range)
@@ -1322,7 +1404,7 @@ void flush_hash_range(unsigned long number, int local)
1322 else { 1404 else {
1323 int i; 1405 int i;
1324 struct ppc64_tlb_batch *batch = 1406 struct ppc64_tlb_batch *batch =
1325 &__get_cpu_var(ppc64_tlb_batch); 1407 this_cpu_ptr(&ppc64_tlb_batch);
1326 1408
1327 for (i = 0; i < number; i++) 1409 for (i = 0; i < number; i++)
1328 flush_hash_page(batch->vpn[i], batch->pte[i], 1410 flush_hash_page(batch->vpn[i], batch->pte[i],
diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c
index 5f5e6328c21c..86686514ae13 100644
--- a/arch/powerpc/mm/hugepage-hash64.c
+++ b/arch/powerpc/mm/hugepage-hash64.c
@@ -18,60 +18,9 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <asm/machdep.h> 19#include <asm/machdep.h>
20 20
21static void invalidate_old_hpte(unsigned long vsid, unsigned long addr,
22 pmd_t *pmdp, unsigned int psize, int ssize)
23{
24 int i, max_hpte_count, valid;
25 unsigned long s_addr;
26 unsigned char *hpte_slot_array;
27 unsigned long hidx, shift, vpn, hash, slot;
28
29 s_addr = addr & HPAGE_PMD_MASK;
30 hpte_slot_array = get_hpte_slot_array(pmdp);
31 /*
32 * IF we try to do a HUGE PTE update after a withdraw is done.
33 * we will find the below NULL. This happens when we do
34 * split_huge_page_pmd
35 */
36 if (!hpte_slot_array)
37 return;
38
39 if (ppc_md.hugepage_invalidate)
40 return ppc_md.hugepage_invalidate(vsid, s_addr, hpte_slot_array,
41 psize, ssize);
42 /*
43 * No bluk hpte removal support, invalidate each entry
44 */
45 shift = mmu_psize_defs[psize].shift;
46 max_hpte_count = HPAGE_PMD_SIZE >> shift;
47 for (i = 0; i < max_hpte_count; i++) {
48 /*
49 * 8 bits per each hpte entries
50 * 000| [ secondary group (one bit) | hidx (3 bits) | valid bit]
51 */
52 valid = hpte_valid(hpte_slot_array, i);
53 if (!valid)
54 continue;
55 hidx = hpte_hash_index(hpte_slot_array, i);
56
57 /* get the vpn */
58 addr = s_addr + (i * (1ul << shift));
59 vpn = hpt_vpn(addr, vsid, ssize);
60 hash = hpt_hash(vpn, shift, ssize);
61 if (hidx & _PTEIDX_SECONDARY)
62 hash = ~hash;
63
64 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
65 slot += hidx & _PTEIDX_GROUP_IX;
66 ppc_md.hpte_invalidate(slot, vpn, psize,
67 MMU_PAGE_16M, ssize, 0);
68 }
69}
70
71
72int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, 21int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
73 pmd_t *pmdp, unsigned long trap, int local, int ssize, 22 pmd_t *pmdp, unsigned long trap, unsigned long flags,
74 unsigned int psize) 23 int ssize, unsigned int psize)
75{ 24{
76 unsigned int index, valid; 25 unsigned int index, valid;
77 unsigned char *hpte_slot_array; 26 unsigned char *hpte_slot_array;
@@ -145,7 +94,8 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
145 * hash page table entries. 94 * hash page table entries.
146 */ 95 */
147 if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO)) 96 if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO))
148 invalidate_old_hpte(vsid, ea, pmdp, MMU_PAGE_64K, ssize); 97 flush_hash_hugepage(vsid, ea, pmdp, MMU_PAGE_64K,
98 ssize, flags);
149 } 99 }
150 100
151 valid = hpte_valid(hpte_slot_array, index); 101 valid = hpte_valid(hpte_slot_array, index);
@@ -158,7 +108,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
158 slot += hidx & _PTEIDX_GROUP_IX; 108 slot += hidx & _PTEIDX_GROUP_IX;
159 109
160 ret = ppc_md.hpte_updatepp(slot, rflags, vpn, 110 ret = ppc_md.hpte_updatepp(slot, rflags, vpn,
161 psize, lpsize, ssize, local); 111 psize, lpsize, ssize, flags);
162 /* 112 /*
163 * We failed to update, try to insert a new entry. 113 * We failed to update, try to insert a new entry.
164 */ 114 */
diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c
index 5e4ee2573903..ba47aaf33a4b 100644
--- a/arch/powerpc/mm/hugetlbpage-book3e.c
+++ b/arch/powerpc/mm/hugetlbpage-book3e.c
@@ -33,13 +33,13 @@ static inline int tlb1_next(void)
33 33
34 ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY; 34 ncams = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
35 35
36 index = __get_cpu_var(next_tlbcam_idx); 36 index = this_cpu_read(next_tlbcam_idx);
37 37
38 /* Just round-robin the entries and wrap when we hit the end */ 38 /* Just round-robin the entries and wrap when we hit the end */
39 if (unlikely(index == ncams - 1)) 39 if (unlikely(index == ncams - 1))
40 __get_cpu_var(next_tlbcam_idx) = tlbcam_index; 40 __this_cpu_write(next_tlbcam_idx, tlbcam_index);
41 else 41 else
42 __get_cpu_var(next_tlbcam_idx)++; 42 __this_cpu_inc(next_tlbcam_idx);
43 43
44 return index; 44 return index;
45} 45}
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index a5bcf9301196..d94b1af53a93 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -19,8 +19,8 @@ extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
19 unsigned long vflags, int psize, int ssize); 19 unsigned long vflags, int psize, int ssize);
20 20
21int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, 21int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
22 pte_t *ptep, unsigned long trap, int local, int ssize, 22 pte_t *ptep, unsigned long trap, unsigned long flags,
23 unsigned int shift, unsigned int mmu_psize) 23 int ssize, unsigned int shift, unsigned int mmu_psize)
24{ 24{
25 unsigned long vpn; 25 unsigned long vpn;
26 unsigned long old_pte, new_pte; 26 unsigned long old_pte, new_pte;
@@ -81,7 +81,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
81 slot += (old_pte & _PAGE_F_GIX) >> 12; 81 slot += (old_pte & _PAGE_F_GIX) >> 12;
82 82
83 if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize, 83 if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize,
84 mmu_psize, ssize, local) == -1) 84 mmu_psize, ssize, flags) == -1)
85 old_pte &= ~_PAGE_HPTEFLAGS; 85 old_pte &= ~_PAGE_HPTEFLAGS;
86 } 86 }
87 87
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 6a4a5fcb9730..5ff4e07d920a 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -62,6 +62,9 @@ static unsigned nr_gpages;
62/* 62/*
63 * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have 63 * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have
64 * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD; 64 * 16GB hugepage pte in PGD and 16MB hugepage pte at PMD;
65 *
66 * Defined in such a way that we can optimize away code block at build time
67 * if CONFIG_HUGETLB_PAGE=n.
65 */ 68 */
66int pmd_huge(pmd_t pmd) 69int pmd_huge(pmd_t pmd)
67{ 70{
@@ -230,7 +233,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz
230 if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift)) 233 if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift))
231 return NULL; 234 return NULL;
232 235
233 return hugepte_offset(hpdp, addr, pdshift); 236 return hugepte_offset(*hpdp, addr, pdshift);
234} 237}
235 238
236#else 239#else
@@ -270,13 +273,13 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz
270 if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift)) 273 if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr, pdshift, pshift))
271 return NULL; 274 return NULL;
272 275
273 return hugepte_offset(hpdp, addr, pdshift); 276 return hugepte_offset(*hpdp, addr, pdshift);
274} 277}
275#endif 278#endif
276 279
277#ifdef CONFIG_PPC_FSL_BOOK3E 280#ifdef CONFIG_PPC_FSL_BOOK3E
278/* Build list of addresses of gigantic pages. This function is used in early 281/* Build list of addresses of gigantic pages. This function is used in early
279 * boot before the buddy or bootmem allocator is setup. 282 * boot before the buddy allocator is setup.
280 */ 283 */
281void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) 284void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
282{ 285{
@@ -312,7 +315,7 @@ int alloc_bootmem_huge_page(struct hstate *hstate)
312 * If gpages can be in highmem we can't use the trick of storing the 315 * If gpages can be in highmem we can't use the trick of storing the
313 * data structure in the page; allocate space for this 316 * data structure in the page; allocate space for this
314 */ 317 */
315 m = alloc_bootmem(sizeof(struct huge_bootmem_page)); 318 m = memblock_virt_alloc(sizeof(struct huge_bootmem_page), 0);
316 m->phys = gpage_freearray[idx].gpage_list[--nr_gpages]; 319 m->phys = gpage_freearray[idx].gpage_list[--nr_gpages];
317#else 320#else
318 m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]); 321 m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]);
@@ -352,6 +355,13 @@ static int __init do_gpage_early_setup(char *param, char *val,
352 if (size != 0) { 355 if (size != 0) {
353 if (sscanf(val, "%lu", &npages) <= 0) 356 if (sscanf(val, "%lu", &npages) <= 0)
354 npages = 0; 357 npages = 0;
358 if (npages > MAX_NUMBER_GPAGES) {
359 pr_warn("MMU: %lu pages requested for page "
360 "size %llu KB, limiting to "
361 __stringify(MAX_NUMBER_GPAGES) "\n",
362 npages, size / 1024);
363 npages = MAX_NUMBER_GPAGES;
364 }
355 gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages; 365 gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages;
356 size = 0; 366 size = 0;
357 } 367 }
@@ -399,7 +409,7 @@ void __init reserve_hugetlb_gpages(void)
399#else /* !PPC_FSL_BOOK3E */ 409#else /* !PPC_FSL_BOOK3E */
400 410
401/* Build list of addresses of gigantic pages. This function is used in early 411/* Build list of addresses of gigantic pages. This function is used in early
402 * boot before the buddy or bootmem allocator is setup. 412 * boot before the buddy allocator is setup.
403 */ 413 */
404void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) 414void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages)
405{ 415{
@@ -462,7 +472,7 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
462{ 472{
463 struct hugepd_freelist **batchp; 473 struct hugepd_freelist **batchp;
464 474
465 batchp = &get_cpu_var(hugepd_freelist_cur); 475 batchp = this_cpu_ptr(&hugepd_freelist_cur);
466 476
467 if (atomic_read(&tlb->mm->mm_users) < 2 || 477 if (atomic_read(&tlb->mm->mm_users) < 2 ||
468 cpumask_equal(mm_cpumask(tlb->mm), 478 cpumask_equal(mm_cpumask(tlb->mm),
@@ -536,7 +546,7 @@ static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
536 do { 546 do {
537 pmd = pmd_offset(pud, addr); 547 pmd = pmd_offset(pud, addr);
538 next = pmd_addr_end(addr, end); 548 next = pmd_addr_end(addr, end);
539 if (!is_hugepd(pmd)) { 549 if (!is_hugepd(__hugepd(pmd_val(*pmd)))) {
540 /* 550 /*
541 * if it is not hugepd pointer, we should already find 551 * if it is not hugepd pointer, we should already find
542 * it cleared. 552 * it cleared.
@@ -585,7 +595,7 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
585 do { 595 do {
586 pud = pud_offset(pgd, addr); 596 pud = pud_offset(pgd, addr);
587 next = pud_addr_end(addr, end); 597 next = pud_addr_end(addr, end);
588 if (!is_hugepd(pud)) { 598 if (!is_hugepd(__hugepd(pud_val(*pud)))) {
589 if (pud_none_or_clear_bad(pud)) 599 if (pud_none_or_clear_bad(pud))
590 continue; 600 continue;
591 hugetlb_free_pmd_range(tlb, pud, addr, next, floor, 601 hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
@@ -651,7 +661,7 @@ void hugetlb_free_pgd_range(struct mmu_gather *tlb,
651 do { 661 do {
652 next = pgd_addr_end(addr, end); 662 next = pgd_addr_end(addr, end);
653 pgd = pgd_offset(tlb->mm, addr); 663 pgd = pgd_offset(tlb->mm, addr);
654 if (!is_hugepd(pgd)) { 664 if (!is_hugepd(__hugepd(pgd_val(*pgd)))) {
655 if (pgd_none_or_clear_bad(pgd)) 665 if (pgd_none_or_clear_bad(pgd))
656 continue; 666 continue;
657 hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling); 667 hugetlb_free_pud_range(tlb, pgd, addr, next, floor, ceiling);
@@ -711,12 +721,11 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end,
711 return (__boundary - 1 < end - 1) ? __boundary : end; 721 return (__boundary - 1 < end - 1) ? __boundary : end;
712} 722}
713 723
714int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, 724int gup_huge_pd(hugepd_t hugepd, unsigned long addr, unsigned pdshift,
715 unsigned long addr, unsigned long end, 725 unsigned long end, int write, struct page **pages, int *nr)
716 int write, struct page **pages, int *nr)
717{ 726{
718 pte_t *ptep; 727 pte_t *ptep;
719 unsigned long sz = 1UL << hugepd_shift(*hugepd); 728 unsigned long sz = 1UL << hugepd_shift(hugepd);
720 unsigned long next; 729 unsigned long next;
721 730
722 ptep = hugepte_offset(hugepd, addr, pdshift); 731 ptep = hugepte_offset(hugepd, addr, pdshift);
@@ -959,7 +968,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift
959 else if (pgd_huge(pgd)) { 968 else if (pgd_huge(pgd)) {
960 ret_pte = (pte_t *) pgdp; 969 ret_pte = (pte_t *) pgdp;
961 goto out; 970 goto out;
962 } else if (is_hugepd(&pgd)) 971 } else if (is_hugepd(__hugepd(pgd_val(pgd))))
963 hpdp = (hugepd_t *)&pgd; 972 hpdp = (hugepd_t *)&pgd;
964 else { 973 else {
965 /* 974 /*
@@ -976,7 +985,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift
976 else if (pud_huge(pud)) { 985 else if (pud_huge(pud)) {
977 ret_pte = (pte_t *) pudp; 986 ret_pte = (pte_t *) pudp;
978 goto out; 987 goto out;
979 } else if (is_hugepd(&pud)) 988 } else if (is_hugepd(__hugepd(pud_val(pud))))
980 hpdp = (hugepd_t *)&pud; 989 hpdp = (hugepd_t *)&pud;
981 else { 990 else {
982 pdshift = PMD_SHIFT; 991 pdshift = PMD_SHIFT;
@@ -997,7 +1006,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift
997 if (pmd_huge(pmd) || pmd_large(pmd)) { 1006 if (pmd_huge(pmd) || pmd_large(pmd)) {
998 ret_pte = (pte_t *) pmdp; 1007 ret_pte = (pte_t *) pmdp;
999 goto out; 1008 goto out;
1000 } else if (is_hugepd(&pmd)) 1009 } else if (is_hugepd(__hugepd(pmd_val(pmd))))
1001 hpdp = (hugepd_t *)&pmd; 1010 hpdp = (hugepd_t *)&pmd;
1002 else 1011 else
1003 return pte_offset_kernel(&pmd, ea); 1012 return pte_offset_kernel(&pmd, ea);
@@ -1006,7 +1015,7 @@ pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, unsigned *shift
1006 if (!hpdp) 1015 if (!hpdp)
1007 return NULL; 1016 return NULL;
1008 1017
1009 ret_pte = hugepte_offset(hpdp, ea, pdshift); 1018 ret_pte = hugepte_offset(*hpdp, ea, pdshift);
1010 pdshift = hugepd_shift(*hpdp); 1019 pdshift = hugepd_shift(*hpdp);
1011out: 1020out:
1012 if (shift) 1021 if (shift)
@@ -1036,14 +1045,6 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
1036 if ((pte_val(pte) & mask) != mask) 1045 if ((pte_val(pte) & mask) != mask)
1037 return 0; 1046 return 0;
1038 1047
1039#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1040 /*
1041 * check for splitting here
1042 */
1043 if (pmd_trans_splitting(pte_pmd(pte)))
1044 return 0;
1045#endif
1046
1047 /* hugepages are never "special" */ 1048 /* hugepages are never "special" */
1048 VM_BUG_ON(!pfn_valid(pte_pfn(pte))); 1049 VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
1049 1050
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 415a51b028b9..a10be665b645 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -26,7 +26,6 @@
26#include <linux/mm.h> 26#include <linux/mm.h>
27#include <linux/stddef.h> 27#include <linux/stddef.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/bootmem.h>
30#include <linux/highmem.h> 29#include <linux/highmem.h>
31#include <linux/initrd.h> 30#include <linux/initrd.h>
32#include <linux/pagemap.h> 31#include <linux/pagemap.h>
@@ -195,15 +194,6 @@ void __init MMU_init(void)
195 memblock_set_current_limit(lowmem_end_addr); 194 memblock_set_current_limit(lowmem_end_addr);
196} 195}
197 196
198/* This is only called until mem_init is done. */
199void __init *early_get_page(void)
200{
201 if (init_bootmem_done)
202 return alloc_bootmem_pages(PAGE_SIZE);
203 else
204 return __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
205}
206
207#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */ 197#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
208void setup_initial_memory_limit(phys_addr_t first_memblock_base, 198void setup_initial_memory_limit(phys_addr_t first_memblock_base,
209 phys_addr_t first_memblock_size) 199 phys_addr_t first_memblock_size)
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 3481556a1880..10471f9bb63f 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -34,7 +34,6 @@
34#include <linux/vmalloc.h> 34#include <linux/vmalloc.h>
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/bootmem.h>
38#include <linux/highmem.h> 37#include <linux/highmem.h>
39#include <linux/idr.h> 38#include <linux/idr.h>
40#include <linux/nodemask.h> 39#include <linux/nodemask.h>
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 8ebaac75c940..b7285a5870f8 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -35,6 +35,7 @@
35#include <linux/memblock.h> 35#include <linux/memblock.h>
36#include <linux/hugetlb.h> 36#include <linux/hugetlb.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/vmalloc.h>
38 39
39#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
40#include <asm/prom.h> 41#include <asm/prom.h>
@@ -60,7 +61,6 @@
60#define CPU_FTR_NOEXECUTE 0 61#define CPU_FTR_NOEXECUTE 0
61#endif 62#endif
62 63
63int init_bootmem_done;
64int mem_init_done; 64int mem_init_done;
65unsigned long long memory_limit; 65unsigned long long memory_limit;
66 66
@@ -144,8 +144,17 @@ int arch_remove_memory(u64 start, u64 size)
144 144
145 zone = page_zone(pfn_to_page(start_pfn)); 145 zone = page_zone(pfn_to_page(start_pfn));
146 ret = __remove_pages(zone, start_pfn, nr_pages); 146 ret = __remove_pages(zone, start_pfn, nr_pages);
147 if (!ret && (ppc_md.remove_memory)) 147 if (ret)
148 ret = ppc_md.remove_memory(start, size); 148 return ret;
149
150 /* Remove htab bolted mappings for this section of memory */
151 start = (unsigned long)__va(start);
152 ret = remove_section_mapping(start, start + size);
153
154 /* Ensure all vmalloc mappings are flushed in case they also
155 * hit that section of memory
156 */
157 vm_unmap_aliases();
149 158
150 return ret; 159 return ret;
151} 160}
@@ -180,70 +189,23 @@ walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
180} 189}
181EXPORT_SYMBOL_GPL(walk_system_ram_range); 190EXPORT_SYMBOL_GPL(walk_system_ram_range);
182 191
183/*
184 * Initialize the bootmem system and give it all the memory we
185 * have available. If we are using highmem, we only put the
186 * lowmem into the bootmem system.
187 */
188#ifndef CONFIG_NEED_MULTIPLE_NODES 192#ifndef CONFIG_NEED_MULTIPLE_NODES
189void __init do_init_bootmem(void) 193void __init initmem_init(void)
190{ 194{
191 unsigned long start, bootmap_pages;
192 unsigned long total_pages;
193 struct memblock_region *reg;
194 int boot_mapsize;
195
196 max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; 195 max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
197 total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT; 196 min_low_pfn = MEMORY_START >> PAGE_SHIFT;
198#ifdef CONFIG_HIGHMEM 197#ifdef CONFIG_HIGHMEM
199 total_pages = total_lowmem >> PAGE_SHIFT;
200 max_low_pfn = lowmem_end_addr >> PAGE_SHIFT; 198 max_low_pfn = lowmem_end_addr >> PAGE_SHIFT;
201#endif 199#endif
202 200
203 /*
204 * Find an area to use for the bootmem bitmap. Calculate the size of
205 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
206 * Add 1 additional page in case the address isn't page-aligned.
207 */
208 bootmap_pages = bootmem_bootmap_pages(total_pages);
209
210 start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
211
212 min_low_pfn = MEMORY_START >> PAGE_SHIFT;
213 boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
214
215 /* Place all memblock_regions in the same node and merge contiguous 201 /* Place all memblock_regions in the same node and merge contiguous
216 * memblock_regions 202 * memblock_regions
217 */ 203 */
218 memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0); 204 memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
219 205
220 /* Add all physical memory to the bootmem map, mark each area
221 * present.
222 */
223#ifdef CONFIG_HIGHMEM
224 free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT);
225
226 /* reserve the sections we're already using */
227 for_each_memblock(reserved, reg) {
228 unsigned long top = reg->base + reg->size - 1;
229 if (top < lowmem_end_addr)
230 reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
231 else if (reg->base < lowmem_end_addr) {
232 unsigned long trunc_size = lowmem_end_addr - reg->base;
233 reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
234 }
235 }
236#else
237 free_bootmem_with_active_regions(0, max_pfn);
238
239 /* reserve the sections we're already using */
240 for_each_memblock(reserved, reg)
241 reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
242#endif
243 /* XXX need to clip this if using highmem? */ 206 /* XXX need to clip this if using highmem? */
244 sparse_memory_present_with_active_regions(0); 207 sparse_memory_present_with_active_regions(0);
245 208 sparse_init();
246 init_bootmem_done = 1;
247} 209}
248 210
249/* mark pages that don't exist as nosave */ 211/* mark pages that don't exist as nosave */
@@ -359,14 +321,6 @@ void __init paging_init(void)
359 mark_nonram_nosave(); 321 mark_nonram_nosave();
360} 322}
361 323
362static void __init register_page_bootmem_info(void)
363{
364 int i;
365
366 for_each_online_node(i)
367 register_page_bootmem_info_node(NODE_DATA(i));
368}
369
370void __init mem_init(void) 324void __init mem_init(void)
371{ 325{
372 /* 326 /*
@@ -379,7 +333,6 @@ void __init mem_init(void)
379 swiotlb_init(0); 333 swiotlb_init(0);
380#endif 334#endif
381 335
382 register_page_bootmem_info();
383 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); 336 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
384 set_max_mapnr(max_pfn); 337 set_max_mapnr(max_pfn);
385 free_all_bootmem(); 338 free_all_bootmem();
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 928ebe79668b..9cba6cba2e50 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -421,12 +421,12 @@ void __init mmu_context_init(void)
421 /* 421 /*
422 * Allocate the maps used by context management 422 * Allocate the maps used by context management
423 */ 423 */
424 context_map = alloc_bootmem(CTX_MAP_SIZE); 424 context_map = memblock_virt_alloc(CTX_MAP_SIZE, 0);
425 context_mm = alloc_bootmem(sizeof(void *) * (last_context + 1)); 425 context_mm = memblock_virt_alloc(sizeof(void *) * (last_context + 1), 0);
426#ifndef CONFIG_SMP 426#ifndef CONFIG_SMP
427 stale_map[0] = alloc_bootmem(CTX_MAP_SIZE); 427 stale_map[0] = memblock_virt_alloc(CTX_MAP_SIZE, 0);
428#else 428#else
429 stale_map[boot_cpuid] = alloc_bootmem(CTX_MAP_SIZE); 429 stale_map[boot_cpuid] = memblock_virt_alloc(CTX_MAP_SIZE, 0);
430 430
431 register_cpu_notifier(&mmu_context_cpu_nb); 431 register_cpu_notifier(&mmu_context_cpu_nb);
432#endif 432#endif
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 9615d82919b8..78c45f392f5b 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -67,7 +67,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid,
67{ 67{
68 __tlbil_va(address, pid); 68 __tlbil_va(address, pid);
69} 69}
70#endif /* CONIFG_8xx */ 70#endif /* CONFIG_8xx */
71 71
72#if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x) 72#if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x)
73extern void _tlbivax_bcast(unsigned long address, unsigned int pid, 73extern void _tlbivax_bcast(unsigned long address, unsigned int pid,
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 9fe6002c1d5a..0257a7d659ef 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -134,28 +134,6 @@ static int __init fake_numa_create_new_node(unsigned long end_pfn,
134 return 0; 134 return 0;
135} 135}
136 136
137/*
138 * get_node_active_region - Return active region containing pfn
139 * Active range returned is empty if none found.
140 * @pfn: The page to return the region for
141 * @node_ar: Returned set to the active region containing @pfn
142 */
143static void __init get_node_active_region(unsigned long pfn,
144 struct node_active_region *node_ar)
145{
146 unsigned long start_pfn, end_pfn;
147 int i, nid;
148
149 for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid) {
150 if (pfn >= start_pfn && pfn < end_pfn) {
151 node_ar->nid = nid;
152 node_ar->start_pfn = start_pfn;
153 node_ar->end_pfn = end_pfn;
154 break;
155 }
156 }
157}
158
159static void reset_numa_cpu_lookup_table(void) 137static void reset_numa_cpu_lookup_table(void)
160{ 138{
161 unsigned int cpu; 139 unsigned int cpu;
@@ -928,134 +906,48 @@ static void __init dump_numa_memory_topology(void)
928 } 906 }
929} 907}
930 908
931/*
932 * Allocate some memory, satisfying the memblock or bootmem allocator where
933 * required. nid is the preferred node and end is the physical address of
934 * the highest address in the node.
935 *
936 * Returns the virtual address of the memory.
937 */
938static void __init *careful_zallocation(int nid, unsigned long size,
939 unsigned long align,
940 unsigned long end_pfn)
941{
942 void *ret;
943 int new_nid;
944 unsigned long ret_paddr;
945
946 ret_paddr = __memblock_alloc_base(size, align, end_pfn << PAGE_SHIFT);
947
948 /* retry over all memory */
949 if (!ret_paddr)
950 ret_paddr = __memblock_alloc_base(size, align, memblock_end_of_DRAM());
951
952 if (!ret_paddr)
953 panic("numa.c: cannot allocate %lu bytes for node %d",
954 size, nid);
955
956 ret = __va(ret_paddr);
957
958 /*
959 * We initialize the nodes in numeric order: 0, 1, 2...
960 * and hand over control from the MEMBLOCK allocator to the
961 * bootmem allocator. If this function is called for
962 * node 5, then we know that all nodes <5 are using the
963 * bootmem allocator instead of the MEMBLOCK allocator.
964 *
965 * So, check the nid from which this allocation came
966 * and double check to see if we need to use bootmem
967 * instead of the MEMBLOCK. We don't free the MEMBLOCK memory
968 * since it would be useless.
969 */
970 new_nid = early_pfn_to_nid(ret_paddr >> PAGE_SHIFT);
971 if (new_nid < nid) {
972 ret = __alloc_bootmem_node(NODE_DATA(new_nid),
973 size, align, 0);
974
975 dbg("alloc_bootmem %p %lx\n", ret, size);
976 }
977
978 memset(ret, 0, size);
979 return ret;
980}
981
982static struct notifier_block ppc64_numa_nb = { 909static struct notifier_block ppc64_numa_nb = {
983 .notifier_call = cpu_numa_callback, 910 .notifier_call = cpu_numa_callback,
984 .priority = 1 /* Must run before sched domains notifier. */ 911 .priority = 1 /* Must run before sched domains notifier. */
985}; 912};
986 913
987static void __init mark_reserved_regions_for_nid(int nid) 914/* Initialize NODE_DATA for a node on the local memory */
915static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
988{ 916{
989 struct pglist_data *node = NODE_DATA(nid); 917 u64 spanned_pages = end_pfn - start_pfn;
990 struct memblock_region *reg; 918 const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES);
991 919 u64 nd_pa;
992 for_each_memblock(reserved, reg) { 920 void *nd;
993 unsigned long physbase = reg->base; 921 int tnid;
994 unsigned long size = reg->size; 922
995 unsigned long start_pfn = physbase >> PAGE_SHIFT; 923 if (spanned_pages)
996 unsigned long end_pfn = PFN_UP(physbase + size); 924 pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
997 struct node_active_region node_ar; 925 nid, start_pfn << PAGE_SHIFT,
998 unsigned long node_end_pfn = pgdat_end_pfn(node); 926 (end_pfn << PAGE_SHIFT) - 1);
999 927 else
1000 /* 928 pr_info("Initmem setup node %d\n", nid);
1001 * Check to make sure that this memblock.reserved area is 929
1002 * within the bounds of the node that we care about. 930 nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
1003 * Checking the nid of the start and end points is not 931 nd = __va(nd_pa);
1004 * sufficient because the reserved area could span the 932
1005 * entire node. 933 /* report and initialize */
1006 */ 934 pr_info(" NODE_DATA [mem %#010Lx-%#010Lx]\n",
1007 if (end_pfn <= node->node_start_pfn || 935 nd_pa, nd_pa + nd_size - 1);
1008 start_pfn >= node_end_pfn) 936 tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
1009 continue; 937 if (tnid != nid)
1010 938 pr_info(" NODE_DATA(%d) on node %d\n", nid, tnid);
1011 get_node_active_region(start_pfn, &node_ar); 939
1012 while (start_pfn < end_pfn && 940 node_data[nid] = nd;
1013 node_ar.start_pfn < node_ar.end_pfn) { 941 memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
1014 unsigned long reserve_size = size; 942 NODE_DATA(nid)->node_id = nid;
1015 /* 943 NODE_DATA(nid)->node_start_pfn = start_pfn;
1016 * if reserved region extends past active region 944 NODE_DATA(nid)->node_spanned_pages = spanned_pages;
1017 * then trim size to active region
1018 */
1019 if (end_pfn > node_ar.end_pfn)
1020 reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
1021 - physbase;
1022 /*
1023 * Only worry about *this* node, others may not
1024 * yet have valid NODE_DATA().
1025 */
1026 if (node_ar.nid == nid) {
1027 dbg("reserve_bootmem %lx %lx nid=%d\n",
1028 physbase, reserve_size, node_ar.nid);
1029 reserve_bootmem_node(NODE_DATA(node_ar.nid),
1030 physbase, reserve_size,
1031 BOOTMEM_DEFAULT);
1032 }
1033 /*
1034 * if reserved region is contained in the active region
1035 * then done.
1036 */
1037 if (end_pfn <= node_ar.end_pfn)
1038 break;
1039
1040 /*
1041 * reserved region extends past the active region
1042 * get next active region that contains this
1043 * reserved region
1044 */
1045 start_pfn = node_ar.end_pfn;
1046 physbase = start_pfn << PAGE_SHIFT;
1047 size = size - reserve_size;
1048 get_node_active_region(start_pfn, &node_ar);
1049 }
1050 }
1051} 945}
1052 946
1053 947void __init initmem_init(void)
1054void __init do_init_bootmem(void)
1055{ 948{
1056 int nid, cpu; 949 int nid, cpu;
1057 950
1058 min_low_pfn = 0;
1059 max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT; 951 max_low_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
1060 max_pfn = max_low_pfn; 952 max_pfn = max_low_pfn;
1061 953
@@ -1064,64 +956,18 @@ void __init do_init_bootmem(void)
1064 else 956 else
1065 dump_numa_memory_topology(); 957 dump_numa_memory_topology();
1066 958
959 memblock_dump_all();
960
1067 for_each_online_node(nid) { 961 for_each_online_node(nid) {
1068 unsigned long start_pfn, end_pfn; 962 unsigned long start_pfn, end_pfn;
1069 void *bootmem_vaddr;
1070 unsigned long bootmap_pages;
1071 963
1072 get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); 964 get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
1073 965 setup_node_data(nid, start_pfn, end_pfn);
1074 /*
1075 * Allocate the node structure node local if possible
1076 *
1077 * Be careful moving this around, as it relies on all
1078 * previous nodes' bootmem to be initialized and have
1079 * all reserved areas marked.
1080 */
1081 NODE_DATA(nid) = careful_zallocation(nid,
1082 sizeof(struct pglist_data),
1083 SMP_CACHE_BYTES, end_pfn);
1084
1085 dbg("node %d\n", nid);
1086 dbg("NODE_DATA() = %p\n", NODE_DATA(nid));
1087
1088 NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
1089 NODE_DATA(nid)->node_start_pfn = start_pfn;
1090 NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
1091
1092 if (NODE_DATA(nid)->node_spanned_pages == 0)
1093 continue;
1094
1095 dbg("start_paddr = %lx\n", start_pfn << PAGE_SHIFT);
1096 dbg("end_paddr = %lx\n", end_pfn << PAGE_SHIFT);
1097
1098 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
1099 bootmem_vaddr = careful_zallocation(nid,
1100 bootmap_pages << PAGE_SHIFT,
1101 PAGE_SIZE, end_pfn);
1102
1103 dbg("bootmap_vaddr = %p\n", bootmem_vaddr);
1104
1105 init_bootmem_node(NODE_DATA(nid),
1106 __pa(bootmem_vaddr) >> PAGE_SHIFT,
1107 start_pfn, end_pfn);
1108
1109 free_bootmem_with_active_regions(nid, end_pfn);
1110 /*
1111 * Be very careful about moving this around. Future
1112 * calls to careful_zallocation() depend on this getting
1113 * done correctly.
1114 */
1115 mark_reserved_regions_for_nid(nid);
1116 sparse_memory_present_with_active_regions(nid); 966 sparse_memory_present_with_active_regions(nid);
1117 } 967 }
1118 968
1119 init_bootmem_done = 1; 969 sparse_init();
1120 970
1121 /*
1122 * Now bootmem is initialised we can create the node to cpumask
1123 * lookup tables and setup the cpu callback to populate them.
1124 */
1125 setup_node_to_cpumask_map(); 971 setup_node_to_cpumask_map();
1126 972
1127 reset_numa_cpu_lookup_table(); 973 reset_numa_cpu_lookup_table();
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index cf11342bf519..d545b1231594 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -100,12 +100,11 @@ __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long add
100{ 100{
101 pte_t *pte; 101 pte_t *pte;
102 extern int mem_init_done; 102 extern int mem_init_done;
103 extern void *early_get_page(void);
104 103
105 if (mem_init_done) { 104 if (mem_init_done) {
106 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 105 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
107 } else { 106 } else {
108 pte = (pte_t *)early_get_page(); 107 pte = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
109 if (pte) 108 if (pte)
110 clear_page(pte); 109 clear_page(pte);
111 } 110 }
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index c8d709ab489d..4fe5f64cc179 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -33,9 +33,9 @@
33#include <linux/swap.h> 33#include <linux/swap.h>
34#include <linux/stddef.h> 34#include <linux/stddef.h>
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/bootmem.h>
37#include <linux/memblock.h> 36#include <linux/memblock.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/hugetlb.h>
39 39
40#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
41#include <asm/page.h> 41#include <asm/page.h>
@@ -51,6 +51,7 @@
51#include <asm/cputable.h> 51#include <asm/cputable.h>
52#include <asm/sections.h> 52#include <asm/sections.h>
53#include <asm/firmware.h> 53#include <asm/firmware.h>
54#include <asm/dma.h>
54 55
55#include "mmu_decl.h" 56#include "mmu_decl.h"
56 57
@@ -75,11 +76,7 @@ static __ref void *early_alloc_pgtable(unsigned long size)
75{ 76{
76 void *pt; 77 void *pt;
77 78
78 if (init_bootmem_done) 79 pt = __va(memblock_alloc_base(size, size, __pa(MAX_DMA_ADDRESS)));
79 pt = __alloc_bootmem(size, size, __pa(MAX_DMA_ADDRESS));
80 else
81 pt = __va(memblock_alloc_base(size, size,
82 __pa(MAX_DMA_ADDRESS)));
83 memset(pt, 0, size); 80 memset(pt, 0, size);
84 81
85 return pt; 82 return pt;
@@ -113,10 +110,6 @@ int map_kernel_page(unsigned long ea, unsigned long pa, int flags)
113 __pgprot(flags))); 110 __pgprot(flags)));
114 } else { 111 } else {
115#ifdef CONFIG_PPC_MMU_NOHASH 112#ifdef CONFIG_PPC_MMU_NOHASH
116 /* Warning ! This will blow up if bootmem is not initialized
117 * which our ppc64 code is keen to do that, we'll need to
118 * fix it and/or be more careful
119 */
120 pgdp = pgd_offset_k(ea); 113 pgdp = pgd_offset_k(ea);
121#ifdef PUD_TABLE_SIZE 114#ifdef PUD_TABLE_SIZE
122 if (pgd_none(*pgdp)) { 115 if (pgd_none(*pgdp)) {
@@ -352,16 +345,31 @@ EXPORT_SYMBOL(iounmap);
352EXPORT_SYMBOL(__iounmap); 345EXPORT_SYMBOL(__iounmap);
353EXPORT_SYMBOL(__iounmap_at); 346EXPORT_SYMBOL(__iounmap_at);
354 347
348#ifndef __PAGETABLE_PUD_FOLDED
349/* 4 level page table */
350struct page *pgd_page(pgd_t pgd)
351{
352 if (pgd_huge(pgd))
353 return pte_page(pgd_pte(pgd));
354 return virt_to_page(pgd_page_vaddr(pgd));
355}
356#endif
357
358struct page *pud_page(pud_t pud)
359{
360 if (pud_huge(pud))
361 return pte_page(pud_pte(pud));
362 return virt_to_page(pud_page_vaddr(pud));
363}
364
355/* 365/*
356 * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags 366 * For hugepage we have pfn in the pmd, we use PTE_RPN_SHIFT bits for flags
357 * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address. 367 * For PTE page, we have a PTE_FRAG_SIZE (4K) aligned virtual address.
358 */ 368 */
359struct page *pmd_page(pmd_t pmd) 369struct page *pmd_page(pmd_t pmd)
360{ 370{
361#ifdef CONFIG_TRANSPARENT_HUGEPAGE 371 if (pmd_trans_huge(pmd) || pmd_huge(pmd))
362 if (pmd_trans_huge(pmd))
363 return pfn_to_page(pmd_pfn(pmd)); 372 return pfn_to_page(pmd_pfn(pmd));
364#endif
365 return virt_to_page(pmd_page_vaddr(pmd)); 373 return virt_to_page(pmd_page_vaddr(pmd));
366} 374}
367 375
@@ -731,29 +739,15 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
731void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, 739void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
732 pmd_t *pmdp, unsigned long old_pmd) 740 pmd_t *pmdp, unsigned long old_pmd)
733{ 741{
734 int ssize, i; 742 int ssize;
735 unsigned long s_addr; 743 unsigned int psize;
736 int max_hpte_count; 744 unsigned long vsid;
737 unsigned int psize, valid; 745 unsigned long flags = 0;
738 unsigned char *hpte_slot_array; 746 const struct cpumask *tmp;
739 unsigned long hidx, vpn, vsid, hash, shift, slot;
740
741 /*
742 * Flush all the hptes mapping this hugepage
743 */
744 s_addr = addr & HPAGE_PMD_MASK;
745 hpte_slot_array = get_hpte_slot_array(pmdp);
746 /*
747 * IF we try to do a HUGE PTE update after a withdraw is done.
748 * we will find the below NULL. This happens when we do
749 * split_huge_page_pmd
750 */
751 if (!hpte_slot_array)
752 return;
753 747
754 /* get the base page size,vsid and segment size */ 748 /* get the base page size,vsid and segment size */
755#ifdef CONFIG_DEBUG_VM 749#ifdef CONFIG_DEBUG_VM
756 psize = get_slice_psize(mm, s_addr); 750 psize = get_slice_psize(mm, addr);
757 BUG_ON(psize == MMU_PAGE_16M); 751 BUG_ON(psize == MMU_PAGE_16M);
758#endif 752#endif
759 if (old_pmd & _PAGE_COMBO) 753 if (old_pmd & _PAGE_COMBO)
@@ -761,46 +755,20 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
761 else 755 else
762 psize = MMU_PAGE_64K; 756 psize = MMU_PAGE_64K;
763 757
764 if (!is_kernel_addr(s_addr)) { 758 if (!is_kernel_addr(addr)) {
765 ssize = user_segment_size(s_addr); 759 ssize = user_segment_size(addr);
766 vsid = get_vsid(mm->context.id, s_addr, ssize); 760 vsid = get_vsid(mm->context.id, addr, ssize);
767 WARN_ON(vsid == 0); 761 WARN_ON(vsid == 0);
768 } else { 762 } else {
769 vsid = get_kernel_vsid(s_addr, mmu_kernel_ssize); 763 vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
770 ssize = mmu_kernel_ssize; 764 ssize = mmu_kernel_ssize;
771 } 765 }
772 766
773 if (ppc_md.hugepage_invalidate) 767 tmp = cpumask_of(smp_processor_id());
774 return ppc_md.hugepage_invalidate(vsid, s_addr, 768 if (cpumask_equal(mm_cpumask(mm), tmp))
775 hpte_slot_array, 769 flags |= HPTE_LOCAL_UPDATE;
776 psize, ssize); 770
777 /* 771 return flush_hash_hugepage(vsid, addr, pmdp, psize, ssize, flags);
778 * No bluk hpte removal support, invalidate each entry
779 */
780 shift = mmu_psize_defs[psize].shift;
781 max_hpte_count = HPAGE_PMD_SIZE >> shift;
782 for (i = 0; i < max_hpte_count; i++) {
783 /*
784 * 8 bits per each hpte entries
785 * 000| [ secondary group (one bit) | hidx (3 bits) | valid bit]
786 */
787 valid = hpte_valid(hpte_slot_array, i);
788 if (!valid)
789 continue;
790 hidx = hpte_hash_index(hpte_slot_array, i);
791
792 /* get the vpn */
793 addr = s_addr + (i * (1ul << shift));
794 vpn = hpt_vpn(addr, vsid, ssize);
795 hash = hpt_hash(vpn, shift, ssize);
796 if (hidx & _PTEIDX_SECONDARY)
797 hash = ~hash;
798
799 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
800 slot += hidx & _PTEIDX_GROUP_IX;
801 ppc_md.hpte_invalidate(slot, vpn, psize,
802 MMU_PAGE_16M, ssize, 0);
803 }
804} 772}
805 773
806static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) 774static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot)
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c
index 6adf55fa5d88..ecc66d5f02c9 100644
--- a/arch/powerpc/oprofile/backtrace.c
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -10,7 +10,7 @@
10#include <linux/oprofile.h> 10#include <linux/oprofile.h>
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <asm/processor.h> 12#include <asm/processor.h>
13#include <asm/uaccess.h> 13#include <linux/uaccess.h>
14#include <asm/compat.h> 14#include <asm/compat.h>
15#include <asm/oprofile_impl.h> 15#include <asm/oprofile_impl.h>
16 16
@@ -105,6 +105,7 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
105 first_frame = 0; 105 first_frame = 0;
106 } 106 }
107 } else { 107 } else {
108 pagefault_disable();
108#ifdef CONFIG_PPC64 109#ifdef CONFIG_PPC64
109 if (!is_32bit_task()) { 110 if (!is_32bit_task()) {
110 while (depth--) { 111 while (depth--) {
@@ -113,7 +114,7 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
113 break; 114 break;
114 first_frame = 0; 115 first_frame = 0;
115 } 116 }
116 117 pagefault_enable();
117 return; 118 return;
118 } 119 }
119#endif 120#endif
@@ -124,5 +125,6 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
124 break; 125 break;
125 first_frame = 0; 126 first_frame = 0;
126 } 127 }
128 pagefault_enable();
127 } 129 }
128} 130}
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index a6995d4e93d4..7c4f6690533a 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -339,7 +339,7 @@ static void power_pmu_bhrb_reset(void)
339 339
340static void power_pmu_bhrb_enable(struct perf_event *event) 340static void power_pmu_bhrb_enable(struct perf_event *event)
341{ 341{
342 struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); 342 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
343 343
344 if (!ppmu->bhrb_nr) 344 if (!ppmu->bhrb_nr)
345 return; 345 return;
@@ -354,7 +354,7 @@ static void power_pmu_bhrb_enable(struct perf_event *event)
354 354
355static void power_pmu_bhrb_disable(struct perf_event *event) 355static void power_pmu_bhrb_disable(struct perf_event *event)
356{ 356{
357 struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); 357 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
358 358
359 if (!ppmu->bhrb_nr) 359 if (!ppmu->bhrb_nr)
360 return; 360 return;
@@ -1144,7 +1144,7 @@ static void power_pmu_disable(struct pmu *pmu)
1144 if (!ppmu) 1144 if (!ppmu)
1145 return; 1145 return;
1146 local_irq_save(flags); 1146 local_irq_save(flags);
1147 cpuhw = &__get_cpu_var(cpu_hw_events); 1147 cpuhw = this_cpu_ptr(&cpu_hw_events);
1148 1148
1149 if (!cpuhw->disabled) { 1149 if (!cpuhw->disabled) {
1150 /* 1150 /*
@@ -1211,7 +1211,7 @@ static void power_pmu_enable(struct pmu *pmu)
1211 return; 1211 return;
1212 local_irq_save(flags); 1212 local_irq_save(flags);
1213 1213
1214 cpuhw = &__get_cpu_var(cpu_hw_events); 1214 cpuhw = this_cpu_ptr(&cpu_hw_events);
1215 if (!cpuhw->disabled) 1215 if (!cpuhw->disabled)
1216 goto out; 1216 goto out;
1217 1217
@@ -1403,7 +1403,7 @@ static int power_pmu_add(struct perf_event *event, int ef_flags)
1403 * Add the event to the list (if there is room) 1403 * Add the event to the list (if there is room)
1404 * and check whether the total set is still feasible. 1404 * and check whether the total set is still feasible.
1405 */ 1405 */
1406 cpuhw = &__get_cpu_var(cpu_hw_events); 1406 cpuhw = this_cpu_ptr(&cpu_hw_events);
1407 n0 = cpuhw->n_events; 1407 n0 = cpuhw->n_events;
1408 if (n0 >= ppmu->n_counter) 1408 if (n0 >= ppmu->n_counter)
1409 goto out; 1409 goto out;
@@ -1469,7 +1469,7 @@ static void power_pmu_del(struct perf_event *event, int ef_flags)
1469 1469
1470 power_pmu_read(event); 1470 power_pmu_read(event);
1471 1471
1472 cpuhw = &__get_cpu_var(cpu_hw_events); 1472 cpuhw = this_cpu_ptr(&cpu_hw_events);
1473 for (i = 0; i < cpuhw->n_events; ++i) { 1473 for (i = 0; i < cpuhw->n_events; ++i) {
1474 if (event == cpuhw->event[i]) { 1474 if (event == cpuhw->event[i]) {
1475 while (++i < cpuhw->n_events) { 1475 while (++i < cpuhw->n_events) {
@@ -1575,7 +1575,7 @@ static void power_pmu_stop(struct perf_event *event, int ef_flags)
1575 */ 1575 */
1576static void power_pmu_start_txn(struct pmu *pmu) 1576static void power_pmu_start_txn(struct pmu *pmu)
1577{ 1577{
1578 struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); 1578 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
1579 1579
1580 perf_pmu_disable(pmu); 1580 perf_pmu_disable(pmu);
1581 cpuhw->group_flag |= PERF_EVENT_TXN; 1581 cpuhw->group_flag |= PERF_EVENT_TXN;
@@ -1589,7 +1589,7 @@ static void power_pmu_start_txn(struct pmu *pmu)
1589 */ 1589 */
1590static void power_pmu_cancel_txn(struct pmu *pmu) 1590static void power_pmu_cancel_txn(struct pmu *pmu)
1591{ 1591{
1592 struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); 1592 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
1593 1593
1594 cpuhw->group_flag &= ~PERF_EVENT_TXN; 1594 cpuhw->group_flag &= ~PERF_EVENT_TXN;
1595 perf_pmu_enable(pmu); 1595 perf_pmu_enable(pmu);
@@ -1607,7 +1607,7 @@ static int power_pmu_commit_txn(struct pmu *pmu)
1607 1607
1608 if (!ppmu) 1608 if (!ppmu)
1609 return -EAGAIN; 1609 return -EAGAIN;
1610 cpuhw = &__get_cpu_var(cpu_hw_events); 1610 cpuhw = this_cpu_ptr(&cpu_hw_events);
1611 n = cpuhw->n_events; 1611 n = cpuhw->n_events;
1612 if (check_excludes(cpuhw->event, cpuhw->flags, 0, n)) 1612 if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
1613 return -EAGAIN; 1613 return -EAGAIN;
@@ -1964,7 +1964,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
1964 1964
1965 if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) { 1965 if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) {
1966 struct cpu_hw_events *cpuhw; 1966 struct cpu_hw_events *cpuhw;
1967 cpuhw = &__get_cpu_var(cpu_hw_events); 1967 cpuhw = this_cpu_ptr(&cpu_hw_events);
1968 power_pmu_bhrb_read(cpuhw); 1968 power_pmu_bhrb_read(cpuhw);
1969 data.br_stack = &cpuhw->bhrb_stack; 1969 data.br_stack = &cpuhw->bhrb_stack;
1970 } 1970 }
@@ -2037,7 +2037,7 @@ static bool pmc_overflow(unsigned long val)
2037static void perf_event_interrupt(struct pt_regs *regs) 2037static void perf_event_interrupt(struct pt_regs *regs)
2038{ 2038{
2039 int i, j; 2039 int i, j;
2040 struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); 2040 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
2041 struct perf_event *event; 2041 struct perf_event *event;
2042 unsigned long val[8]; 2042 unsigned long val[8];
2043 int found, active; 2043 int found, active;
diff --git a/arch/powerpc/perf/core-fsl-emb.c b/arch/powerpc/perf/core-fsl-emb.c
index d35ae52c69dc..4acaea01fe03 100644
--- a/arch/powerpc/perf/core-fsl-emb.c
+++ b/arch/powerpc/perf/core-fsl-emb.c
@@ -210,7 +210,7 @@ static void fsl_emb_pmu_disable(struct pmu *pmu)
210 unsigned long flags; 210 unsigned long flags;
211 211
212 local_irq_save(flags); 212 local_irq_save(flags);
213 cpuhw = &__get_cpu_var(cpu_hw_events); 213 cpuhw = this_cpu_ptr(&cpu_hw_events);
214 214
215 if (!cpuhw->disabled) { 215 if (!cpuhw->disabled) {
216 cpuhw->disabled = 1; 216 cpuhw->disabled = 1;
@@ -249,7 +249,7 @@ static void fsl_emb_pmu_enable(struct pmu *pmu)
249 unsigned long flags; 249 unsigned long flags;
250 250
251 local_irq_save(flags); 251 local_irq_save(flags);
252 cpuhw = &__get_cpu_var(cpu_hw_events); 252 cpuhw = this_cpu_ptr(&cpu_hw_events);
253 if (!cpuhw->disabled) 253 if (!cpuhw->disabled)
254 goto out; 254 goto out;
255 255
@@ -653,7 +653,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
653static void perf_event_interrupt(struct pt_regs *regs) 653static void perf_event_interrupt(struct pt_regs *regs)
654{ 654{
655 int i; 655 int i;
656 struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events); 656 struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events);
657 struct perf_event *event; 657 struct perf_event *event;
658 unsigned long val; 658 unsigned long val;
659 int found = 0; 659 int found = 0;
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 82f2da28cd27..d2ac1c116454 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -220,7 +220,6 @@ config AKEBONO
220 select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD 220 select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
221 select MMC_SDHCI 221 select MMC_SDHCI
222 select MMC_SDHCI_PLTFM 222 select MMC_SDHCI_PLTFM
223 select MMC_SDHCI_OF_476GTR
224 select ATA 223 select ATA
225 select SATA_AHCI_PLATFORM 224 select SATA_AHCI_PLATFORM
226 help 225 help
diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
index 58db9d083969..c11ce6516c8f 100644
--- a/arch/powerpc/platforms/44x/ppc476.c
+++ b/arch/powerpc/platforms/44x/ppc476.c
@@ -94,7 +94,7 @@ static int avr_probe(struct i2c_client *client,
94{ 94{
95 avr_i2c_client = client; 95 avr_i2c_client = client;
96 ppc_md.restart = avr_reset_system; 96 ppc_md.restart = avr_reset_system;
97 ppc_md.power_off = avr_power_off_system; 97 pm_power_off = avr_power_off_system;
98 return 0; 98 return 0;
99} 99}
100 100
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c
index e996e007bc44..711f3d352af7 100644
--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
+++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
@@ -18,7 +18,7 @@
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/of_platform.h> 19#include <linux/of_platform.h>
20#include <linux/fsl-diu-fb.h> 20#include <linux/fsl-diu-fb.h>
21#include <linux/bootmem.h> 21#include <linux/memblock.h>
22#include <sysdev/fsl_soc.h> 22#include <sysdev/fsl_soc.h>
23 23
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
@@ -297,14 +297,13 @@ static void __init mpc512x_setup_diu(void)
297 * and so negatively affect boot time. Instead we reserve the 297 * and so negatively affect boot time. Instead we reserve the
298 * already configured frame buffer area so that it won't be 298 * already configured frame buffer area so that it won't be
299 * destroyed. The starting address of the area to reserve and 299 * destroyed. The starting address of the area to reserve and
300 * also it's length is passed to reserve_bootmem(). It will be 300 * also it's length is passed to memblock_reserve(). It will be
301 * freed later on first open of fbdev, when splash image is not 301 * freed later on first open of fbdev, when splash image is not
302 * needed any more. 302 * needed any more.
303 */ 303 */
304 if (diu_shared_fb.in_use) { 304 if (diu_shared_fb.in_use) {
305 ret = reserve_bootmem(diu_shared_fb.fb_phys, 305 ret = memblock_reserve(diu_shared_fb.fb_phys,
306 diu_shared_fb.fb_len, 306 diu_shared_fb.fb_len);
307 BOOTMEM_EXCLUSIVE);
308 if (ret) { 307 if (ret) {
309 pr_err("%s: reserve bootmem failed\n", __func__); 308 pr_err("%s: reserve bootmem failed\n", __func__);
310 diu_shared_fb.in_use = false; 309 diu_shared_fb.in_use = false;
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index 3feffde9128d..6af651e69129 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -212,6 +212,8 @@ static int __init efika_probe(void)
212 DMA_MODE_READ = 0x44; 212 DMA_MODE_READ = 0x44;
213 DMA_MODE_WRITE = 0x48; 213 DMA_MODE_WRITE = 0x48;
214 214
215 pm_power_off = rtas_power_off;
216
215 return 1; 217 return 1;
216} 218}
217 219
@@ -225,7 +227,6 @@ define_machine(efika)
225 .init_IRQ = mpc52xx_init_irq, 227 .init_IRQ = mpc52xx_init_irq,
226 .get_irq = mpc52xx_get_irq, 228 .get_irq = mpc52xx_get_irq,
227 .restart = rtas_restart, 229 .restart = rtas_restart,
228 .power_off = rtas_power_off,
229 .halt = rtas_halt, 230 .halt = rtas_halt,
230 .set_rtc_time = rtas_set_rtc_time, 231 .set_rtc_time = rtas_set_rtc_time,
231 .get_rtc_time = rtas_get_rtc_time, 232 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
index 463fa91ee5b6..15e8021ddef9 100644
--- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
+++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
@@ -167,10 +167,10 @@ static int mcu_probe(struct i2c_client *client, const struct i2c_device_id *id)
167 if (ret) 167 if (ret)
168 goto err; 168 goto err;
169 169
170 /* XXX: this is potentially racy, but there is no lock for ppc_md */ 170 /* XXX: this is potentially racy, but there is no lock for pm_power_off */
171 if (!ppc_md.power_off) { 171 if (!pm_power_off) {
172 glob_mcu = mcu; 172 glob_mcu = mcu;
173 ppc_md.power_off = mcu_power_off; 173 pm_power_off = mcu_power_off;
174 dev_info(&client->dev, "will provide power-off service\n"); 174 dev_info(&client->dev, "will provide power-off service\n");
175 } 175 }
176 176
@@ -197,7 +197,7 @@ static int mcu_remove(struct i2c_client *client)
197 device_remove_file(&client->dev, &dev_attr_status); 197 device_remove_file(&client->dev, &dev_attr_status);
198 198
199 if (glob_mcu == mcu) { 199 if (glob_mcu == mcu) {
200 ppc_md.power_off = NULL; 200 pm_power_off = NULL;
201 glob_mcu = NULL; 201 glob_mcu = NULL;
202 } 202 }
203 203
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index e56b89a792ed..1f309ccb096e 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -170,7 +170,7 @@ static int __init corenet_generic_probe(void)
170 170
171 ppc_md.get_irq = ehv_pic_get_irq; 171 ppc_md.get_irq = ehv_pic_get_irq;
172 ppc_md.restart = fsl_hv_restart; 172 ppc_md.restart = fsl_hv_restart;
173 ppc_md.power_off = fsl_hv_halt; 173 pm_power_off = fsl_hv_halt;
174 ppc_md.halt = fsl_hv_halt; 174 ppc_md.halt = fsl_hv_halt;
175#ifdef CONFIG_SMP 175#ifdef CONFIG_SMP
176 /* 176 /*
diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 8162b0412117..e149c9ec26ae 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -120,7 +120,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
120 120
121 /* Register our halt function */ 121 /* Register our halt function */
122 ppc_md.halt = gpio_halt_cb; 122 ppc_md.halt = gpio_halt_cb;
123 ppc_md.power_off = gpio_halt_cb; 123 pm_power_off = gpio_halt_cb;
124 124
125 printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d" 125 printk(KERN_INFO "gpio-halt: registered GPIO %d (%d trigger, %d"
126 " irq).\n", gpio, trigger, irq); 126 " irq).\n", gpio, trigger, irq);
@@ -137,7 +137,7 @@ static int gpio_halt_remove(struct platform_device *pdev)
137 free_irq(irq, halt_node); 137 free_irq(irq, halt_node);
138 138
139 ppc_md.halt = NULL; 139 ppc_md.halt = NULL;
140 ppc_md.power_off = NULL; 140 pm_power_off = NULL;
141 141
142 gpio_free(gpio); 142 gpio_free(gpio);
143 143
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index bd6f1a1cf922..157250426b56 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -1,6 +1,3 @@
1config FADS
2 bool
3
4config CPM1 1config CPM1
5 bool 2 bool
6 select CPM 3 select CPM
@@ -13,7 +10,6 @@ choice
13 10
14config MPC8XXFADS 11config MPC8XXFADS
15 bool "FADS" 12 bool "FADS"
16 select FADS
17 13
18config MPC86XADS 14config MPC86XADS
19 bool "MPC86XADS" 15 bool "MPC86XADS"
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index d4d245c0d787..bee9232fe619 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -186,7 +186,7 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
186 unsigned long newpp, 186 unsigned long newpp,
187 unsigned long vpn, 187 unsigned long vpn,
188 int psize, int apsize, 188 int psize, int apsize,
189 int ssize, int local) 189 int ssize, unsigned long flags)
190{ 190{
191 unsigned long lpar_rc; 191 unsigned long lpar_rc;
192 u64 dummy0, dummy1; 192 u64 dummy0, dummy1;
@@ -369,7 +369,7 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
369 unsigned long newpp, 369 unsigned long newpp,
370 unsigned long vpn, 370 unsigned long vpn,
371 int psize, int apsize, 371 int psize, int apsize,
372 int ssize, int local) 372 int ssize, unsigned long flags)
373{ 373{
374 unsigned long lpar_rc; 374 unsigned long lpar_rc;
375 unsigned long want_v; 375 unsigned long want_v;
diff --git a/arch/powerpc/platforms/cell/celleb_pci.c b/arch/powerpc/platforms/cell/celleb_pci.c
index 2b98a36ef8fb..3ce70ded2d6a 100644
--- a/arch/powerpc/platforms/cell/celleb_pci.c
+++ b/arch/powerpc/platforms/cell/celleb_pci.c
@@ -29,7 +29,7 @@
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/bootmem.h> 32#include <linux/memblock.h>
33#include <linux/pci_regs.h> 33#include <linux/pci_regs.h>
34#include <linux/of.h> 34#include <linux/of.h>
35#include <linux/of_device.h> 35#include <linux/of_device.h>
@@ -401,11 +401,11 @@ error:
401 } else { 401 } else {
402 if (config && *config) { 402 if (config && *config) {
403 size = 256; 403 size = 256;
404 free_bootmem(__pa(*config), size); 404 memblock_free(__pa(*config), size);
405 } 405 }
406 if (res && *res) { 406 if (res && *res) {
407 size = sizeof(struct celleb_pci_resource); 407 size = sizeof(struct celleb_pci_resource);
408 free_bootmem(__pa(*res), size); 408 memblock_free(__pa(*res), size);
409 } 409 }
410 } 410 }
411 411
diff --git a/arch/powerpc/platforms/cell/celleb_scc_epci.c b/arch/powerpc/platforms/cell/celleb_scc_epci.c
index 844c0facb4f7..9438bbed402f 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_epci.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c
@@ -25,7 +25,6 @@
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/pci_regs.h> 27#include <linux/pci_regs.h>
28#include <linux/bootmem.h>
29 28
30#include <asm/io.h> 29#include <asm/io.h>
31#include <asm/irq.h> 30#include <asm/irq.h>
diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
index 4278acfa2ede..f22387598040 100644
--- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
@@ -25,7 +25,6 @@
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/bootmem.h>
29#include <linux/delay.h> 28#include <linux/delay.h>
30#include <linux/interrupt.h> 29#include <linux/interrupt.h>
31 30
diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index 34e8ce2976aa..90be8ec51686 100644
--- a/arch/powerpc/platforms/cell/celleb_setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -142,6 +142,7 @@ static int __init celleb_probe_beat(void)
142 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS 142 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS
143 | FW_FEATURE_BEAT | FW_FEATURE_LPAR; 143 | FW_FEATURE_BEAT | FW_FEATURE_LPAR;
144 hpte_init_beat_v3(); 144 hpte_init_beat_v3();
145 pm_power_off = beat_power_off;
145 146
146 return 1; 147 return 1;
147} 148}
@@ -190,6 +191,7 @@ static int __init celleb_probe_native(void)
190 191
191 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS; 192 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS;
192 hpte_init_native(); 193 hpte_init_native();
194 pm_power_off = rtas_power_off;
193 195
194 return 1; 196 return 1;
195} 197}
@@ -204,7 +206,6 @@ define_machine(celleb_beat) {
204 .setup_arch = celleb_setup_arch_beat, 206 .setup_arch = celleb_setup_arch_beat,
205 .show_cpuinfo = celleb_show_cpuinfo, 207 .show_cpuinfo = celleb_show_cpuinfo,
206 .restart = beat_restart, 208 .restart = beat_restart,
207 .power_off = beat_power_off,
208 .halt = beat_halt, 209 .halt = beat_halt,
209 .get_rtc_time = beat_get_rtc_time, 210 .get_rtc_time = beat_get_rtc_time,
210 .set_rtc_time = beat_set_rtc_time, 211 .set_rtc_time = beat_set_rtc_time,
@@ -230,7 +231,6 @@ define_machine(celleb_native) {
230 .setup_arch = celleb_setup_arch_native, 231 .setup_arch = celleb_setup_arch_native,
231 .show_cpuinfo = celleb_show_cpuinfo, 232 .show_cpuinfo = celleb_show_cpuinfo,
232 .restart = rtas_restart, 233 .restart = rtas_restart,
233 .power_off = rtas_power_off,
234 .halt = rtas_halt, 234 .halt = rtas_halt,
235 .get_boot_time = rtas_get_boot_time, 235 .get_boot_time = rtas_get_boot_time,
236 .get_rtc_time = rtas_get_rtc_time, 236 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 8a106b4172e0..4c11421847be 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -82,7 +82,7 @@ static void iic_unmask(struct irq_data *d)
82 82
83static void iic_eoi(struct irq_data *d) 83static void iic_eoi(struct irq_data *d)
84{ 84{
85 struct iic *iic = &__get_cpu_var(cpu_iic); 85 struct iic *iic = this_cpu_ptr(&cpu_iic);
86 out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]); 86 out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
87 BUG_ON(iic->eoi_ptr < 0); 87 BUG_ON(iic->eoi_ptr < 0);
88} 88}
@@ -148,7 +148,7 @@ static unsigned int iic_get_irq(void)
148 struct iic *iic; 148 struct iic *iic;
149 unsigned int virq; 149 unsigned int virq;
150 150
151 iic = &__get_cpu_var(cpu_iic); 151 iic = this_cpu_ptr(&cpu_iic);
152 *(unsigned long *) &pending = 152 *(unsigned long *) &pending =
153 in_be64((u64 __iomem *) &iic->regs->pending_destr); 153 in_be64((u64 __iomem *) &iic->regs->pending_destr);
154 if (!(pending.flags & CBE_IIC_IRQ_VALID)) 154 if (!(pending.flags & CBE_IIC_IRQ_VALID))
@@ -163,7 +163,7 @@ static unsigned int iic_get_irq(void)
163 163
164void iic_setup_cpu(void) 164void iic_setup_cpu(void)
165{ 165{
166 out_be64(&__get_cpu_var(cpu_iic).regs->prio, 0xff); 166 out_be64(this_cpu_ptr(&cpu_iic.regs->prio), 0xff);
167} 167}
168 168
169u8 iic_get_target_id(int cpu) 169u8 iic_get_target_id(int cpu)
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c
index 6e3409d590ac..d328140dc6f5 100644
--- a/arch/powerpc/platforms/cell/qpace_setup.c
+++ b/arch/powerpc/platforms/cell/qpace_setup.c
@@ -127,6 +127,7 @@ static int __init qpace_probe(void)
127 return 0; 127 return 0;
128 128
129 hpte_init_native(); 129 hpte_init_native();
130 pm_power_off = rtas_power_off;
130 131
131 return 1; 132 return 1;
132} 133}
@@ -137,7 +138,6 @@ define_machine(qpace) {
137 .setup_arch = qpace_setup_arch, 138 .setup_arch = qpace_setup_arch,
138 .show_cpuinfo = qpace_show_cpuinfo, 139 .show_cpuinfo = qpace_show_cpuinfo,
139 .restart = rtas_restart, 140 .restart = rtas_restart,
140 .power_off = rtas_power_off,
141 .halt = rtas_halt, 141 .halt = rtas_halt,
142 .get_boot_time = rtas_get_boot_time, 142 .get_boot_time = rtas_get_boot_time,
143 .get_rtc_time = rtas_get_rtc_time, 143 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 6ae25fb62015..d62aa982d530 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -259,6 +259,7 @@ static int __init cell_probe(void)
259 return 0; 259 return 0;
260 260
261 hpte_init_native(); 261 hpte_init_native();
262 pm_power_off = rtas_power_off;
262 263
263 return 1; 264 return 1;
264} 265}
@@ -269,7 +270,6 @@ define_machine(cell) {
269 .setup_arch = cell_setup_arch, 270 .setup_arch = cell_setup_arch,
270 .show_cpuinfo = cell_show_cpuinfo, 271 .show_cpuinfo = cell_show_cpuinfo,
271 .restart = rtas_restart, 272 .restart = rtas_restart,
272 .power_off = rtas_power_off,
273 .halt = rtas_halt, 273 .halt = rtas_halt,
274 .get_boot_time = rtas_get_boot_time, 274 .get_boot_time = rtas_get_boot_time,
275 .get_rtc_time = rtas_get_rtc_time, 275 .get_rtc_time = rtas_get_rtc_time,
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index ffcbd242e669..f7af74f83693 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -181,7 +181,8 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
181 return 0; 181 return 0;
182} 182}
183 183
184extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX 184extern int hash_page(unsigned long ea, unsigned long access,
185 unsigned long trap, unsigned long dsisr); //XXX
185static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) 186static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
186{ 187{
187 int ret; 188 int ret;
@@ -196,7 +197,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
196 (REGION_ID(ea) != USER_REGION_ID)) { 197 (REGION_ID(ea) != USER_REGION_ID)) {
197 198
198 spin_unlock(&spu->register_lock); 199 spin_unlock(&spu->register_lock);
199 ret = hash_page(ea, _PAGE_PRESENT, 0x300); 200 ret = hash_page(ea, _PAGE_PRESENT, 0x300, dsisr);
200 spin_lock(&spu->register_lock); 201 spin_lock(&spu->register_lock);
201 202
202 if (!ret) { 203 if (!ret) {
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index e45894a08118..d98f845ac777 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -144,7 +144,7 @@ int spufs_handle_class1(struct spu_context *ctx)
144 access = (_PAGE_PRESENT | _PAGE_USER); 144 access = (_PAGE_PRESENT | _PAGE_USER);
145 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; 145 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
146 local_irq_save(flags); 146 local_irq_save(flags);
147 ret = hash_page(ea, access, 0x300); 147 ret = hash_page(ea, access, 0x300, dsisr);
148 local_irq_restore(flags); 148 local_irq_restore(flags);
149 149
150 /* hashing failed, so try the actual fault handler */ 150 /* hashing failed, so try the actual fault handler */
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 5b77b1919fd2..860a59eb8ea2 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -585,6 +585,8 @@ static int __init chrp_probe(void)
585 DMA_MODE_READ = 0x44; 585 DMA_MODE_READ = 0x44;
586 DMA_MODE_WRITE = 0x48; 586 DMA_MODE_WRITE = 0x48;
587 587
588 pm_power_off = rtas_power_off;
589
588 return 1; 590 return 1;
589} 591}
590 592
@@ -597,7 +599,6 @@ define_machine(chrp) {
597 .show_cpuinfo = chrp_show_cpuinfo, 599 .show_cpuinfo = chrp_show_cpuinfo,
598 .init_IRQ = chrp_init_IRQ, 600 .init_IRQ = chrp_init_IRQ,
599 .restart = rtas_restart, 601 .restart = rtas_restart,
600 .power_off = rtas_power_off,
601 .halt = rtas_halt, 602 .halt = rtas_halt,
602 .time_init = chrp_time_init, 603 .time_init = chrp_time_init,
603 .set_rtc_time = chrp_set_rtc_time, 604 .set_rtc_time = chrp_set_rtc_time,
diff --git a/arch/powerpc/platforms/embedded6xx/gamecube.c b/arch/powerpc/platforms/embedded6xx/gamecube.c
index bd4ba5d7d568..fe0ed6ee285e 100644
--- a/arch/powerpc/platforms/embedded6xx/gamecube.c
+++ b/arch/powerpc/platforms/embedded6xx/gamecube.c
@@ -67,6 +67,8 @@ static int __init gamecube_probe(void)
67 if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube")) 67 if (!of_flat_dt_is_compatible(dt_root, "nintendo,gamecube"))
68 return 0; 68 return 0;
69 69
70 pm_power_off = gamecube_power_off;
71
70 return 1; 72 return 1;
71} 73}
72 74
@@ -80,7 +82,6 @@ define_machine(gamecube) {
80 .probe = gamecube_probe, 82 .probe = gamecube_probe,
81 .init_early = gamecube_init_early, 83 .init_early = gamecube_init_early,
82 .restart = gamecube_restart, 84 .restart = gamecube_restart,
83 .power_off = gamecube_power_off,
84 .halt = gamecube_halt, 85 .halt = gamecube_halt,
85 .init_IRQ = flipper_pic_probe, 86 .init_IRQ = flipper_pic_probe,
86 .get_irq = flipper_pic_get_irq, 87 .get_irq = flipper_pic_get_irq,
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
index 168e1d80b2e5..540eeb58d3f0 100644
--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -147,6 +147,9 @@ static int __init linkstation_probe(void)
147 147
148 if (!of_flat_dt_is_compatible(root, "linkstation")) 148 if (!of_flat_dt_is_compatible(root, "linkstation"))
149 return 0; 149 return 0;
150
151 pm_power_off = linkstation_power_off;
152
150 return 1; 153 return 1;
151} 154}
152 155
@@ -158,7 +161,6 @@ define_machine(linkstation){
158 .show_cpuinfo = linkstation_show_cpuinfo, 161 .show_cpuinfo = linkstation_show_cpuinfo,
159 .get_irq = mpic_get_irq, 162 .get_irq = mpic_get_irq,
160 .restart = linkstation_restart, 163 .restart = linkstation_restart,
161 .power_off = linkstation_power_off,
162 .halt = linkstation_halt, 164 .halt = linkstation_halt,
163 .calibrate_decr = generic_calibrate_decr, 165 .calibrate_decr = generic_calibrate_decr,
164}; 166};
diff --git a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
index 20a8ed91962e..7feb325b636b 100644
--- a/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
+++ b/arch/powerpc/platforms/embedded6xx/usbgecko_udbg.c
@@ -247,7 +247,7 @@ void __init ug_udbg_init(void)
247 np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi"); 247 np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-exi");
248 if (!np) { 248 if (!np) {
249 udbg_printf("%s: EXI node not found\n", __func__); 249 udbg_printf("%s: EXI node not found\n", __func__);
250 goto done; 250 goto out;
251 } 251 }
252 252
253 exi_io_base = ug_udbg_setup_exi_io_base(np); 253 exi_io_base = ug_udbg_setup_exi_io_base(np);
@@ -267,8 +267,8 @@ void __init ug_udbg_init(void)
267 } 267 }
268 268
269done: 269done:
270 if (np) 270 of_node_put(np);
271 of_node_put(np); 271out:
272 return; 272 return;
273} 273}
274 274
diff --git a/arch/powerpc/platforms/embedded6xx/wii.c b/arch/powerpc/platforms/embedded6xx/wii.c
index 388e29bab8f6..352592d3e44e 100644
--- a/arch/powerpc/platforms/embedded6xx/wii.c
+++ b/arch/powerpc/platforms/embedded6xx/wii.c
@@ -211,6 +211,8 @@ static int __init wii_probe(void)
211 if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii")) 211 if (!of_flat_dt_is_compatible(dt_root, "nintendo,wii"))
212 return 0; 212 return 0;
213 213
214 pm_power_off = wii_power_off;
215
214 return 1; 216 return 1;
215} 217}
216 218
@@ -226,7 +228,6 @@ define_machine(wii) {
226 .init_early = wii_init_early, 228 .init_early = wii_init_early,
227 .setup_arch = wii_setup_arch, 229 .setup_arch = wii_setup_arch,
228 .restart = wii_restart, 230 .restart = wii_restart,
229 .power_off = wii_power_off,
230 .halt = wii_halt, 231 .halt = wii_halt,
231 .init_IRQ = wii_pic_probe, 232 .init_IRQ = wii_pic_probe,
232 .get_irq = flipper_pic_get_irq, 233 .get_irq = flipper_pic_get_irq,
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index f7136aae8bbf..d3a13067ec42 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/bootmem.h>
19#include <linux/irq.h> 18#include <linux/irq.h>
20 19
21#include <asm/sections.h> 20#include <asm/sections.h>
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index cb1b0b35a0c6..56b85cd61aaf 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -169,7 +169,7 @@ static void __init maple_use_rtas_reboot_and_halt_if_present(void)
169 if (rtas_service_present("system-reboot") && 169 if (rtas_service_present("system-reboot") &&
170 rtas_service_present("power-off")) { 170 rtas_service_present("power-off")) {
171 ppc_md.restart = rtas_restart; 171 ppc_md.restart = rtas_restart;
172 ppc_md.power_off = rtas_power_off; 172 pm_power_off = rtas_power_off;
173 ppc_md.halt = rtas_halt; 173 ppc_md.halt = rtas_halt;
174 } 174 }
175} 175}
@@ -312,6 +312,7 @@ static int __init maple_probe(void)
312 alloc_dart_table(); 312 alloc_dart_table();
313 313
314 hpte_init_native(); 314 hpte_init_native();
315 pm_power_off = maple_power_off;
315 316
316 return 1; 317 return 1;
317} 318}
@@ -325,7 +326,6 @@ define_machine(maple) {
325 .pci_irq_fixup = maple_pci_irq_fixup, 326 .pci_irq_fixup = maple_pci_irq_fixup,
326 .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, 327 .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
327 .restart = maple_restart, 328 .restart = maple_restart,
328 .power_off = maple_power_off,
329 .halt = maple_halt, 329 .halt = maple_halt,
330 .get_boot_time = maple_get_boot_time, 330 .get_boot_time = maple_get_boot_time,
331 .set_rtc_time = maple_set_rtc_time, 331 .set_rtc_time = maple_set_rtc_time,
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 014d06e6d46b..60b03a1703d1 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -513,11 +513,7 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
513 printk(KERN_ERR "nvram: no address\n"); 513 printk(KERN_ERR "nvram: no address\n");
514 return -EINVAL; 514 return -EINVAL;
515 } 515 }
516 nvram_image = alloc_bootmem(NVRAM_SIZE); 516 nvram_image = memblock_virt_alloc(NVRAM_SIZE, 0);
517 if (nvram_image == NULL) {
518 printk(KERN_ERR "nvram: can't allocate ram image\n");
519 return -ENOMEM;
520 }
521 nvram_data = ioremap(addr, NVRAM_SIZE*2); 517 nvram_data = ioremap(addr, NVRAM_SIZE*2);
522 nvram_naddrs = 1; /* Make sure we get the correct case */ 518 nvram_naddrs = 1; /* Make sure we get the correct case */
523 519
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 7e868ccf3b0d..04702db35d45 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/bootmem.h>
19#include <linux/irq.h> 18#include <linux/irq.h>
20#include <linux/of_pci.h> 19#include <linux/of_pci.h>
21 20
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index b127a29ac526..713d36d45d1d 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -632,6 +632,8 @@ static int __init pmac_probe(void)
632 smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL); 632 smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL);
633#endif /* CONFIG_PMAC_SMU */ 633#endif /* CONFIG_PMAC_SMU */
634 634
635 pm_power_off = pmac_power_off;
636
635 return 1; 637 return 1;
636} 638}
637 639
@@ -663,7 +665,6 @@ define_machine(powermac) {
663 .get_irq = NULL, /* changed later */ 665 .get_irq = NULL, /* changed later */
664 .pci_irq_fixup = pmac_pci_irq_fixup, 666 .pci_irq_fixup = pmac_pci_irq_fixup,
665 .restart = pmac_restart, 667 .restart = pmac_restart,
666 .power_off = pmac_power_off,
667 .halt = pmac_halt, 668 .halt = pmac_halt,
668 .time_init = pmac_time_init, 669 .time_init = pmac_time_init,
669 .get_boot_time = pmac_get_boot_time, 670 .get_boot_time = pmac_get_boot_time,
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index eba9cb10619c..2809c9895288 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -11,7 +11,6 @@
11 * (at your option) any later version. 11 * (at your option) any later version.
12 */ 12 */
13 13
14#include <linux/bootmem.h>
15#include <linux/debugfs.h> 14#include <linux/debugfs.h>
16#include <linux/delay.h> 15#include <linux/delay.h>
17#include <linux/io.h> 16#include <linux/io.h>
@@ -354,6 +353,9 @@ static int ioda_eeh_get_phb_state(struct eeh_pe *pe)
354 } else if (!(pe->state & EEH_PE_ISOLATED)) { 353 } else if (!(pe->state & EEH_PE_ISOLATED)) {
355 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 354 eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
356 ioda_eeh_phb_diag(pe); 355 ioda_eeh_phb_diag(pe);
356
357 if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
358 pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
357 } 359 }
358 360
359 return result; 361 return result;
@@ -373,7 +375,7 @@ static int ioda_eeh_get_pe_state(struct eeh_pe *pe)
373 * moving forward, we have to return operational 375 * moving forward, we have to return operational
374 * state during PE reset. 376 * state during PE reset.
375 */ 377 */
376 if (pe->state & EEH_PE_CFG_BLOCKED) { 378 if (pe->state & EEH_PE_RESET) {
377 result = (EEH_STATE_MMIO_ACTIVE | 379 result = (EEH_STATE_MMIO_ACTIVE |
378 EEH_STATE_DMA_ACTIVE | 380 EEH_STATE_DMA_ACTIVE |
379 EEH_STATE_MMIO_ENABLED | 381 EEH_STATE_MMIO_ENABLED |
@@ -452,6 +454,9 @@ static int ioda_eeh_get_pe_state(struct eeh_pe *pe)
452 454
453 eeh_pe_state_mark(pe, EEH_PE_ISOLATED); 455 eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
454 ioda_eeh_phb_diag(pe); 456 ioda_eeh_phb_diag(pe);
457
458 if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
459 pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
455 } 460 }
456 461
457 return result; 462 return result;
@@ -731,7 +736,8 @@ static int ioda_eeh_reset(struct eeh_pe *pe, int option)
731static int ioda_eeh_get_log(struct eeh_pe *pe, int severity, 736static int ioda_eeh_get_log(struct eeh_pe *pe, int severity,
732 char *drv_log, unsigned long len) 737 char *drv_log, unsigned long len)
733{ 738{
734 pnv_pci_dump_phb_diag_data(pe->phb, pe->data); 739 if (!eeh_has_flag(EEH_EARLY_DUMP_LOG))
740 pnv_pci_dump_phb_diag_data(pe->phb, pe->data);
735 741
736 return 0; 742 return 0;
737} 743}
@@ -1087,6 +1093,10 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
1087 !((*pe)->state & EEH_PE_ISOLATED)) { 1093 !((*pe)->state & EEH_PE_ISOLATED)) {
1088 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED); 1094 eeh_pe_state_mark(*pe, EEH_PE_ISOLATED);
1089 ioda_eeh_phb_diag(*pe); 1095 ioda_eeh_phb_diag(*pe);
1096
1097 if (eeh_has_flag(EEH_EARLY_DUMP_LOG))
1098 pnv_pci_dump_phb_diag_data((*pe)->phb,
1099 (*pe)->data);
1090 } 1100 }
1091 1101
1092 /* 1102 /*
diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c
index e462ab947d16..693b6cdac691 100644
--- a/arch/powerpc/platforms/powernv/opal-async.c
+++ b/arch/powerpc/platforms/powernv/opal-async.c
@@ -71,6 +71,7 @@ int opal_async_get_token_interruptible(void)
71 71
72 return token; 72 return token;
73} 73}
74EXPORT_SYMBOL_GPL(opal_async_get_token_interruptible);
74 75
75int __opal_async_release_token(int token) 76int __opal_async_release_token(int token)
76{ 77{
@@ -102,6 +103,7 @@ int opal_async_release_token(int token)
102 103
103 return 0; 104 return 0;
104} 105}
106EXPORT_SYMBOL_GPL(opal_async_release_token);
105 107
106int opal_async_wait_response(uint64_t token, struct opal_msg *msg) 108int opal_async_wait_response(uint64_t token, struct opal_msg *msg)
107{ 109{
@@ -120,6 +122,7 @@ int opal_async_wait_response(uint64_t token, struct opal_msg *msg)
120 122
121 return 0; 123 return 0;
122} 124}
125EXPORT_SYMBOL_GPL(opal_async_wait_response);
123 126
124static int opal_async_comp_event(struct notifier_block *nb, 127static int opal_async_comp_event(struct notifier_block *nb,
125 unsigned long msg_type, void *msg) 128 unsigned long msg_type, void *msg)
diff --git a/arch/powerpc/platforms/powernv/opal-rtc.c b/arch/powerpc/platforms/powernv/opal-rtc.c
index 499707ddaa9c..37dbee15769f 100644
--- a/arch/powerpc/platforms/powernv/opal-rtc.c
+++ b/arch/powerpc/platforms/powernv/opal-rtc.c
@@ -15,6 +15,8 @@
15#include <linux/bcd.h> 15#include <linux/bcd.h>
16#include <linux/rtc.h> 16#include <linux/rtc.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/platform_device.h>
19#include <linux/of_platform.h>
18 20
19#include <asm/opal.h> 21#include <asm/opal.h>
20#include <asm/firmware.h> 22#include <asm/firmware.h>
@@ -43,7 +45,7 @@ unsigned long __init opal_get_boot_time(void)
43 long rc = OPAL_BUSY; 45 long rc = OPAL_BUSY;
44 46
45 if (!opal_check_token(OPAL_RTC_READ)) 47 if (!opal_check_token(OPAL_RTC_READ))
46 goto out; 48 return 0;
47 49
48 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { 50 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
49 rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); 51 rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
@@ -53,62 +55,33 @@ unsigned long __init opal_get_boot_time(void)
53 mdelay(10); 55 mdelay(10);
54 } 56 }
55 if (rc != OPAL_SUCCESS) 57 if (rc != OPAL_SUCCESS)
56 goto out; 58 return 0;
57 59
58 y_m_d = be32_to_cpu(__y_m_d); 60 y_m_d = be32_to_cpu(__y_m_d);
59 h_m_s_ms = be64_to_cpu(__h_m_s_ms); 61 h_m_s_ms = be64_to_cpu(__h_m_s_ms);
60 opal_to_tm(y_m_d, h_m_s_ms, &tm); 62 opal_to_tm(y_m_d, h_m_s_ms, &tm);
61 return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 63 return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
62 tm.tm_hour, tm.tm_min, tm.tm_sec); 64 tm.tm_hour, tm.tm_min, tm.tm_sec);
63out:
64 ppc_md.get_rtc_time = NULL;
65 ppc_md.set_rtc_time = NULL;
66 return 0;
67} 65}
68 66
69void opal_get_rtc_time(struct rtc_time *tm) 67static __init int opal_time_init(void)
70{ 68{
71 long rc = OPAL_BUSY; 69 struct platform_device *pdev;
72 u32 y_m_d; 70 struct device_node *rtc;
73 u64 h_m_s_ms;
74 __be32 __y_m_d;
75 __be64 __h_m_s_ms;
76 71
77 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { 72 rtc = of_find_node_by_path("/ibm,opal/rtc");
78 rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms); 73 if (rtc) {
79 if (rc == OPAL_BUSY_EVENT) 74 pdev = of_platform_device_create(rtc, "opal-rtc", NULL);
80 opal_poll_events(NULL); 75 of_node_put(rtc);
76 } else {
77 if (opal_check_token(OPAL_RTC_READ) ||
78 opal_check_token(OPAL_READ_TPO))
79 pdev = platform_device_register_simple("opal-rtc", -1,
80 NULL, 0);
81 else 81 else
82 mdelay(10); 82 return -ENODEV;
83 } 83 }
84 if (rc != OPAL_SUCCESS)
85 return;
86 y_m_d = be32_to_cpu(__y_m_d);
87 h_m_s_ms = be64_to_cpu(__h_m_s_ms);
88 opal_to_tm(y_m_d, h_m_s_ms, tm);
89}
90
91int opal_set_rtc_time(struct rtc_time *tm)
92{
93 long rc = OPAL_BUSY;
94 u32 y_m_d = 0;
95 u64 h_m_s_ms = 0;
96
97 y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) / 100)) << 24;
98 y_m_d |= ((u32)bin2bcd((tm->tm_year + 1900) % 100)) << 16;
99 y_m_d |= ((u32)bin2bcd((tm->tm_mon + 1))) << 8;
100 y_m_d |= ((u32)bin2bcd(tm->tm_mday));
101
102 h_m_s_ms |= ((u64)bin2bcd(tm->tm_hour)) << 56;
103 h_m_s_ms |= ((u64)bin2bcd(tm->tm_min)) << 48;
104 h_m_s_ms |= ((u64)bin2bcd(tm->tm_sec)) << 40;
105 84
106 while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { 85 return PTR_ERR_OR_ZERO(pdev);
107 rc = opal_rtc_write(y_m_d, h_m_s_ms);
108 if (rc == OPAL_BUSY_EVENT)
109 opal_poll_events(NULL);
110 else
111 mdelay(10);
112 }
113 return rc == OPAL_SUCCESS ? 0 : -EIO;
114} 86}
87machine_subsys_initcall(powernv, opal_time_init);
diff --git a/arch/powerpc/platforms/powernv/opal-tracepoints.c b/arch/powerpc/platforms/powernv/opal-tracepoints.c
index ae14c40b4b1c..e11273b2386d 100644
--- a/arch/powerpc/platforms/powernv/opal-tracepoints.c
+++ b/arch/powerpc/platforms/powernv/opal-tracepoints.c
@@ -48,7 +48,7 @@ void __trace_opal_entry(unsigned long opcode, unsigned long *args)
48 48
49 local_irq_save(flags); 49 local_irq_save(flags);
50 50
51 depth = &__get_cpu_var(opal_trace_depth); 51 depth = this_cpu_ptr(&opal_trace_depth);
52 52
53 if (*depth) 53 if (*depth)
54 goto out; 54 goto out;
@@ -69,7 +69,7 @@ void __trace_opal_exit(long opcode, unsigned long retval)
69 69
70 local_irq_save(flags); 70 local_irq_save(flags);
71 71
72 depth = &__get_cpu_var(opal_trace_depth); 72 depth = this_cpu_ptr(&opal_trace_depth);
73 73
74 if (*depth) 74 if (*depth)
75 goto out; 75 goto out;
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index feb549aa3eea..0a299be588af 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -18,7 +18,7 @@
18 .section ".text" 18 .section ".text"
19 19
20#ifdef CONFIG_TRACEPOINTS 20#ifdef CONFIG_TRACEPOINTS
21#ifdef CONFIG_JUMP_LABEL 21#ifdef HAVE_JUMP_LABEL
22#define OPAL_BRANCH(LABEL) \ 22#define OPAL_BRANCH(LABEL) \
23 ARCH_STATIC_BRANCH(LABEL, opal_tracepoint_key) 23 ARCH_STATIC_BRANCH(LABEL, opal_tracepoint_key)
24#else 24#else
@@ -250,3 +250,7 @@ OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
250OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION); 250OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION);
251OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION); 251OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
252OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CXL_MODE); 252OPAL_CALL(opal_pci_set_phb_cxl_mode, OPAL_PCI_SET_PHB_CXL_MODE);
253OPAL_CALL(opal_tpo_write, OPAL_WRITE_TPO);
254OPAL_CALL(opal_tpo_read, OPAL_READ_TPO);
255OPAL_CALL(opal_ipmi_send, OPAL_IPMI_SEND);
256OPAL_CALL(opal_ipmi_recv, OPAL_IPMI_RECV);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index d019b081df9d..cb0b6de79cd4 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -50,7 +50,6 @@ static int mc_recoverable_range_len;
50 50
51struct device_node *opal_node; 51struct device_node *opal_node;
52static DEFINE_SPINLOCK(opal_write_lock); 52static DEFINE_SPINLOCK(opal_write_lock);
53extern u64 opal_mc_secondary_handler[];
54static unsigned int *opal_irqs; 53static unsigned int *opal_irqs;
55static unsigned int opal_irq_count; 54static unsigned int opal_irq_count;
56static ATOMIC_NOTIFIER_HEAD(opal_notifier_head); 55static ATOMIC_NOTIFIER_HEAD(opal_notifier_head);
@@ -644,6 +643,16 @@ static void __init opal_dump_region_init(void)
644 pr_warn("DUMP: Failed to register kernel log buffer. " 643 pr_warn("DUMP: Failed to register kernel log buffer. "
645 "rc = %d\n", rc); 644 "rc = %d\n", rc);
646} 645}
646
647static void opal_ipmi_init(struct device_node *opal_node)
648{
649 struct device_node *np;
650
651 for_each_child_of_node(opal_node, np)
652 if (of_device_is_compatible(np, "ibm,opal-ipmi"))
653 of_platform_device_create(np, NULL, NULL);
654}
655
647static int __init opal_init(void) 656static int __init opal_init(void)
648{ 657{
649 struct device_node *np, *consoles; 658 struct device_node *np, *consoles;
@@ -707,6 +716,8 @@ static int __init opal_init(void)
707 opal_msglog_init(); 716 opal_msglog_init();
708 } 717 }
709 718
719 opal_ipmi_init(opal_node);
720
710 return 0; 721 return 0;
711} 722}
712machine_subsys_initcall(powernv, opal_init); 723machine_subsys_initcall(powernv, opal_init);
@@ -742,6 +753,8 @@ void opal_shutdown(void)
742 753
743/* Export this so that test modules can use it */ 754/* Export this so that test modules can use it */
744EXPORT_SYMBOL_GPL(opal_invalid_call); 755EXPORT_SYMBOL_GPL(opal_invalid_call);
756EXPORT_SYMBOL_GPL(opal_ipmi_send);
757EXPORT_SYMBOL_GPL(opal_ipmi_recv);
745 758
746/* Convert a region of vmalloc memory to an opal sg list */ 759/* Convert a region of vmalloc memory to an opal sg list */
747struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, 760struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
@@ -805,3 +818,9 @@ void opal_free_sg_list(struct opal_sg_list *sg)
805 sg = NULL; 818 sg = NULL;
806 } 819 }
807} 820}
821
822EXPORT_SYMBOL_GPL(opal_poll_events);
823EXPORT_SYMBOL_GPL(opal_rtc_read);
824EXPORT_SYMBOL_GPL(opal_rtc_write);
825EXPORT_SYMBOL_GPL(opal_tpo_read);
826EXPORT_SYMBOL_GPL(opal_tpo_write);
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 3ba435ec3dcd..fac88ed8a915 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -91,6 +91,24 @@ static inline bool pnv_pci_is_mem_pref_64(unsigned long flags)
91 (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH)); 91 (IORESOURCE_MEM_64 | IORESOURCE_PREFETCH));
92} 92}
93 93
94static void pnv_ioda_reserve_pe(struct pnv_phb *phb, int pe_no)
95{
96 if (!(pe_no >= 0 && pe_no < phb->ioda.total_pe)) {
97 pr_warn("%s: Invalid PE %d on PHB#%x\n",
98 __func__, pe_no, phb->hose->global_number);
99 return;
100 }
101
102 if (test_and_set_bit(pe_no, phb->ioda.pe_alloc)) {
103 pr_warn("%s: PE %d was assigned on PHB#%x\n",
104 __func__, pe_no, phb->hose->global_number);
105 return;
106 }
107
108 phb->ioda.pe_array[pe_no].phb = phb;
109 phb->ioda.pe_array[pe_no].pe_number = pe_no;
110}
111
94static int pnv_ioda_alloc_pe(struct pnv_phb *phb) 112static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
95{ 113{
96 unsigned long pe; 114 unsigned long pe;
@@ -172,7 +190,7 @@ fail:
172 return -EIO; 190 return -EIO;
173} 191}
174 192
175static void pnv_ioda2_alloc_m64_pe(struct pnv_phb *phb) 193static void pnv_ioda2_reserve_m64_pe(struct pnv_phb *phb)
176{ 194{
177 resource_size_t sgsz = phb->ioda.m64_segsize; 195 resource_size_t sgsz = phb->ioda.m64_segsize;
178 struct pci_dev *pdev; 196 struct pci_dev *pdev;
@@ -185,16 +203,15 @@ static void pnv_ioda2_alloc_m64_pe(struct pnv_phb *phb)
185 * instead of root bus. 203 * instead of root bus.
186 */ 204 */
187 list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) { 205 list_for_each_entry(pdev, &phb->hose->bus->devices, bus_list) {
188 for (i = PCI_BRIDGE_RESOURCES; 206 for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
189 i <= PCI_BRIDGE_RESOURCE_END; i++) { 207 r = &pdev->resource[PCI_BRIDGE_RESOURCES + i];
190 r = &pdev->resource[i];
191 if (!r->parent || 208 if (!r->parent ||
192 !pnv_pci_is_mem_pref_64(r->flags)) 209 !pnv_pci_is_mem_pref_64(r->flags))
193 continue; 210 continue;
194 211
195 base = (r->start - phb->ioda.m64_base) / sgsz; 212 base = (r->start - phb->ioda.m64_base) / sgsz;
196 for (step = 0; step < resource_size(r) / sgsz; step++) 213 for (step = 0; step < resource_size(r) / sgsz; step++)
197 set_bit(base + step, phb->ioda.pe_alloc); 214 pnv_ioda_reserve_pe(phb, base + step);
198 } 215 }
199 } 216 }
200} 217}
@@ -287,8 +304,6 @@ done:
287 while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) < 304 while ((i = find_next_bit(pe_alloc, phb->ioda.total_pe, i + 1)) <
288 phb->ioda.total_pe) { 305 phb->ioda.total_pe) {
289 pe = &phb->ioda.pe_array[i]; 306 pe = &phb->ioda.pe_array[i];
290 pe->phb = phb;
291 pe->pe_number = i;
292 307
293 if (!master_pe) { 308 if (!master_pe) {
294 pe->flags |= PNV_IODA_PE_MASTER; 309 pe->flags |= PNV_IODA_PE_MASTER;
@@ -313,6 +328,12 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
313 const u32 *r; 328 const u32 *r;
314 u64 pci_addr; 329 u64 pci_addr;
315 330
331 /* FIXME: Support M64 for P7IOC */
332 if (phb->type != PNV_PHB_IODA2) {
333 pr_info(" Not support M64 window\n");
334 return;
335 }
336
316 if (!firmware_has_feature(FW_FEATURE_OPALv3)) { 337 if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
317 pr_info(" Firmware too old to support M64 window\n"); 338 pr_info(" Firmware too old to support M64 window\n");
318 return; 339 return;
@@ -325,12 +346,6 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
325 return; 346 return;
326 } 347 }
327 348
328 /* FIXME: Support M64 for P7IOC */
329 if (phb->type != PNV_PHB_IODA2) {
330 pr_info(" Not support M64 window\n");
331 return;
332 }
333
334 res = &hose->mem_resources[1]; 349 res = &hose->mem_resources[1];
335 res->start = of_translate_address(dn, r + 2); 350 res->start = of_translate_address(dn, r + 2);
336 res->end = res->start + of_read_number(r + 4, 2) - 1; 351 res->end = res->start + of_read_number(r + 4, 2) - 1;
@@ -345,7 +360,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb)
345 /* Use last M64 BAR to cover M64 window */ 360 /* Use last M64 BAR to cover M64 window */
346 phb->ioda.m64_bar_idx = 15; 361 phb->ioda.m64_bar_idx = 15;
347 phb->init_m64 = pnv_ioda2_init_m64; 362 phb->init_m64 = pnv_ioda2_init_m64;
348 phb->alloc_m64_pe = pnv_ioda2_alloc_m64_pe; 363 phb->reserve_m64_pe = pnv_ioda2_reserve_m64_pe;
349 phb->pick_m64_pe = pnv_ioda2_pick_m64_pe; 364 phb->pick_m64_pe = pnv_ioda2_pick_m64_pe;
350} 365}
351 366
@@ -358,7 +373,9 @@ static void pnv_ioda_freeze_pe(struct pnv_phb *phb, int pe_no)
358 /* Fetch master PE */ 373 /* Fetch master PE */
359 if (pe->flags & PNV_IODA_PE_SLAVE) { 374 if (pe->flags & PNV_IODA_PE_SLAVE) {
360 pe = pe->master; 375 pe = pe->master;
361 WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER)); 376 if (WARN_ON(!pe || !(pe->flags & PNV_IODA_PE_MASTER)))
377 return;
378
362 pe_no = pe->pe_number; 379 pe_no = pe->pe_number;
363 } 380 }
364 381
@@ -507,6 +524,106 @@ static struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev)
507} 524}
508#endif /* CONFIG_PCI_MSI */ 525#endif /* CONFIG_PCI_MSI */
509 526
527static int pnv_ioda_set_one_peltv(struct pnv_phb *phb,
528 struct pnv_ioda_pe *parent,
529 struct pnv_ioda_pe *child,
530 bool is_add)
531{
532 const char *desc = is_add ? "adding" : "removing";
533 uint8_t op = is_add ? OPAL_ADD_PE_TO_DOMAIN :
534 OPAL_REMOVE_PE_FROM_DOMAIN;
535 struct pnv_ioda_pe *slave;
536 long rc;
537
538 /* Parent PE affects child PE */
539 rc = opal_pci_set_peltv(phb->opal_id, parent->pe_number,
540 child->pe_number, op);
541 if (rc != OPAL_SUCCESS) {
542 pe_warn(child, "OPAL error %ld %s to parent PELTV\n",
543 rc, desc);
544 return -ENXIO;
545 }
546
547 if (!(child->flags & PNV_IODA_PE_MASTER))
548 return 0;
549
550 /* Compound case: parent PE affects slave PEs */
551 list_for_each_entry(slave, &child->slaves, list) {
552 rc = opal_pci_set_peltv(phb->opal_id, parent->pe_number,
553 slave->pe_number, op);
554 if (rc != OPAL_SUCCESS) {
555 pe_warn(slave, "OPAL error %ld %s to parent PELTV\n",
556 rc, desc);
557 return -ENXIO;
558 }
559 }
560
561 return 0;
562}
563
564static int pnv_ioda_set_peltv(struct pnv_phb *phb,
565 struct pnv_ioda_pe *pe,
566 bool is_add)
567{
568 struct pnv_ioda_pe *slave;
569 struct pci_dev *pdev;
570 int ret;
571
572 /*
573 * Clear PE frozen state. If it's master PE, we need
574 * clear slave PE frozen state as well.
575 */
576 if (is_add) {
577 opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
578 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
579 if (pe->flags & PNV_IODA_PE_MASTER) {
580 list_for_each_entry(slave, &pe->slaves, list)
581 opal_pci_eeh_freeze_clear(phb->opal_id,
582 slave->pe_number,
583 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
584 }
585 }
586
587 /*
588 * Associate PE in PELT. We need add the PE into the
589 * corresponding PELT-V as well. Otherwise, the error
590 * originated from the PE might contribute to other
591 * PEs.
592 */
593 ret = pnv_ioda_set_one_peltv(phb, pe, pe, is_add);
594 if (ret)
595 return ret;
596
597 /* For compound PEs, any one affects all of them */
598 if (pe->flags & PNV_IODA_PE_MASTER) {
599 list_for_each_entry(slave, &pe->slaves, list) {
600 ret = pnv_ioda_set_one_peltv(phb, slave, pe, is_add);
601 if (ret)
602 return ret;
603 }
604 }
605
606 if (pe->flags & (PNV_IODA_PE_BUS_ALL | PNV_IODA_PE_BUS))
607 pdev = pe->pbus->self;
608 else
609 pdev = pe->pdev->bus->self;
610 while (pdev) {
611 struct pci_dn *pdn = pci_get_pdn(pdev);
612 struct pnv_ioda_pe *parent;
613
614 if (pdn && pdn->pe_number != IODA_INVALID_PE) {
615 parent = &phb->ioda.pe_array[pdn->pe_number];
616 ret = pnv_ioda_set_one_peltv(phb, parent, pe, is_add);
617 if (ret)
618 return ret;
619 }
620
621 pdev = pdev->bus->self;
622 }
623
624 return 0;
625}
626
510static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) 627static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
511{ 628{
512 struct pci_dev *parent; 629 struct pci_dev *parent;
@@ -561,48 +678,36 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
561 return -ENXIO; 678 return -ENXIO;
562 } 679 }
563 680
564 rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number, 681 /* Configure PELTV */
565 pe->pe_number, OPAL_ADD_PE_TO_DOMAIN); 682 pnv_ioda_set_peltv(phb, pe, true);
566 if (rc)
567 pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc);
568 opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
569 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
570 683
571 /* Add to all parents PELT-V */
572 while (parent) {
573 struct pci_dn *pdn = pci_get_pdn(parent);
574 if (pdn && pdn->pe_number != IODA_INVALID_PE) {
575 rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number,
576 pe->pe_number, OPAL_ADD_PE_TO_DOMAIN);
577 /* XXX What to do in case of error ? */
578 }
579 parent = parent->bus->self;
580 }
581 /* Setup reverse map */ 684 /* Setup reverse map */
582 for (rid = pe->rid; rid < rid_end; rid++) 685 for (rid = pe->rid; rid < rid_end; rid++)
583 phb->ioda.pe_rmap[rid] = pe->pe_number; 686 phb->ioda.pe_rmap[rid] = pe->pe_number;
584 687
585 /* Setup one MVTs on IODA1 */ 688 /* Setup one MVTs on IODA1 */
586 if (phb->type == PNV_PHB_IODA1) { 689 if (phb->type != PNV_PHB_IODA1) {
587 pe->mve_number = pe->pe_number; 690 pe->mve_number = 0;
588 rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, 691 goto out;
589 pe->pe_number); 692 }
693
694 pe->mve_number = pe->pe_number;
695 rc = opal_pci_set_mve(phb->opal_id, pe->mve_number, pe->pe_number);
696 if (rc != OPAL_SUCCESS) {
697 pe_err(pe, "OPAL error %ld setting up MVE %d\n",
698 rc, pe->mve_number);
699 pe->mve_number = -1;
700 } else {
701 rc = opal_pci_set_mve_enable(phb->opal_id,
702 pe->mve_number, OPAL_ENABLE_MVE);
590 if (rc) { 703 if (rc) {
591 pe_err(pe, "OPAL error %ld setting up MVE %d\n", 704 pe_err(pe, "OPAL error %ld enabling MVE %d\n",
592 rc, pe->mve_number); 705 rc, pe->mve_number);
593 pe->mve_number = -1; 706 pe->mve_number = -1;
594 } else {
595 rc = opal_pci_set_mve_enable(phb->opal_id,
596 pe->mve_number, OPAL_ENABLE_MVE);
597 if (rc) {
598 pe_err(pe, "OPAL error %ld enabling MVE %d\n",
599 rc, pe->mve_number);
600 pe->mve_number = -1;
601 }
602 } 707 }
603 } else if (phb->type == PNV_PHB_IODA2) 708 }
604 pe->mve_number = 0;
605 709
710out:
606 return 0; 711 return 0;
607} 712}
608 713
@@ -837,8 +942,8 @@ static void pnv_pci_ioda_setup_PEs(void)
837 phb = hose->private_data; 942 phb = hose->private_data;
838 943
839 /* M64 layout might affect PE allocation */ 944 /* M64 layout might affect PE allocation */
840 if (phb->alloc_m64_pe) 945 if (phb->reserve_m64_pe)
841 phb->alloc_m64_pe(phb); 946 phb->reserve_m64_pe(phb);
842 947
843 pnv_ioda_setup_PEs(hose->bus); 948 pnv_ioda_setup_PEs(hose->bus);
844 } 949 }
@@ -1834,19 +1939,14 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
1834 phb_id = be64_to_cpup(prop64); 1939 phb_id = be64_to_cpup(prop64);
1835 pr_debug(" PHB-ID : 0x%016llx\n", phb_id); 1940 pr_debug(" PHB-ID : 0x%016llx\n", phb_id);
1836 1941
1837 phb = alloc_bootmem(sizeof(struct pnv_phb)); 1942 phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0);
1838 if (!phb) {
1839 pr_err(" Out of memory !\n");
1840 return;
1841 }
1842 1943
1843 /* Allocate PCI controller */ 1944 /* Allocate PCI controller */
1844 memset(phb, 0, sizeof(struct pnv_phb));
1845 phb->hose = hose = pcibios_alloc_controller(np); 1945 phb->hose = hose = pcibios_alloc_controller(np);
1846 if (!phb->hose) { 1946 if (!phb->hose) {
1847 pr_err(" Can't allocate PCI controller for %s\n", 1947 pr_err(" Can't allocate PCI controller for %s\n",
1848 np->full_name); 1948 np->full_name);
1849 free_bootmem((unsigned long)phb, sizeof(struct pnv_phb)); 1949 memblock_free(__pa(phb), sizeof(struct pnv_phb));
1850 return; 1950 return;
1851 } 1951 }
1852 1952
@@ -1913,8 +2013,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
1913 } 2013 }
1914 pemap_off = size; 2014 pemap_off = size;
1915 size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe); 2015 size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe);
1916 aux = alloc_bootmem(size); 2016 aux = memblock_virt_alloc(size, 0);
1917 memset(aux, 0, size);
1918 phb->ioda.pe_alloc = aux; 2017 phb->ioda.pe_alloc = aux;
1919 phb->ioda.m32_segmap = aux + m32map_off; 2018 phb->ioda.m32_segmap = aux + m32map_off;
1920 if (phb->type == PNV_PHB_IODA1) 2019 if (phb->type == PNV_PHB_IODA1)
@@ -1999,8 +2098,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
1999 ioda_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE); 2098 ioda_eeh_phb_reset(hose, EEH_RESET_DEACTIVATE);
2000 } 2099 }
2001 2100
2002 /* Configure M64 window */ 2101 /* Remove M64 resource if we can't configure it successfully */
2003 if (phb->init_m64 && phb->init_m64(phb)) 2102 if (!phb->init_m64 || phb->init_m64(phb))
2004 hose->mem_resources[1].flags = 0; 2103 hose->mem_resources[1].flags = 0;
2005} 2104}
2006 2105
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index 94ce3481490b..6ef6d4d8e7e2 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -122,12 +122,9 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
122 return; 122 return;
123 } 123 }
124 124
125 phb = alloc_bootmem(sizeof(struct pnv_phb)); 125 phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0);
126 if (phb) { 126 phb->hose = pcibios_alloc_controller(np);
127 memset(phb, 0, sizeof(struct pnv_phb)); 127 if (!phb->hose) {
128 phb->hose = pcibios_alloc_controller(np);
129 }
130 if (!phb || !phb->hose) {
131 pr_err(" Failed to allocate PCI controller\n"); 128 pr_err(" Failed to allocate PCI controller\n");
132 return; 129 return;
133 } 130 }
@@ -196,16 +193,27 @@ void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
196 hub_id = be64_to_cpup(prop64); 193 hub_id = be64_to_cpup(prop64);
197 pr_info(" HUB-ID : 0x%016llx\n", hub_id); 194 pr_info(" HUB-ID : 0x%016llx\n", hub_id);
198 195
196 /* Count child PHBs and calculate TCE space per PHB */
197 for_each_child_of_node(np, phbn) {
198 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
199 of_device_is_compatible(phbn, "ibm,p5ioc2-pciex"))
200 phb_count++;
201 }
202
203 if (phb_count <= 0) {
204 pr_info(" No PHBs for Hub %s\n", np->full_name);
205 return;
206 }
207
208 tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count);
209 pr_info(" Allocating %lld MB of TCE memory per PHB\n",
210 tce_per_phb >> 20);
211
199 /* Currently allocate 16M of TCE memory for every Hub 212 /* Currently allocate 16M of TCE memory for every Hub
200 * 213 *
201 * XXX TODO: Make it chip local if possible 214 * XXX TODO: Make it chip local if possible
202 */ 215 */
203 tce_mem = __alloc_bootmem(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY, 216 tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY);
204 __pa(MAX_DMA_ADDRESS));
205 if (!tce_mem) {
206 pr_err(" Failed to allocate TCE Memory !\n");
207 return;
208 }
209 pr_debug(" TCE : 0x%016lx..0x%016lx\n", 217 pr_debug(" TCE : 0x%016lx..0x%016lx\n",
210 __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1); 218 __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1);
211 rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem), 219 rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem),
@@ -215,18 +223,6 @@ void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
215 return; 223 return;
216 } 224 }
217 225
218 /* Count child PHBs */
219 for_each_child_of_node(np, phbn) {
220 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
221 of_device_is_compatible(phbn, "ibm,p5ioc2-pciex"))
222 phb_count++;
223 }
224
225 /* Calculate how much TCE space we can give per PHB */
226 tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count);
227 pr_info(" Allocating %lld MB of TCE memory per PHB\n",
228 tce_per_phb >> 20);
229
230 /* Initialize PHBs */ 226 /* Initialize PHBs */
231 for_each_child_of_node(np, phbn) { 227 for_each_child_of_node(np, phbn) {
232 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || 228 if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") ||
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 540fc6dd56b3..4945e87f12dc 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -16,7 +16,6 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/bootmem.h>
20#include <linux/irq.h> 19#include <linux/irq.h>
21#include <linux/io.h> 20#include <linux/io.h>
22#include <linux/msi.h> 21#include <linux/msi.h>
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 34d29eb2a4de..6c02ff8dd69f 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -130,7 +130,7 @@ struct pnv_phb {
130 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); 130 u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn);
131 void (*shutdown)(struct pnv_phb *phb); 131 void (*shutdown)(struct pnv_phb *phb);
132 int (*init_m64)(struct pnv_phb *phb); 132 int (*init_m64)(struct pnv_phb *phb);
133 void (*alloc_m64_pe)(struct pnv_phb *phb); 133 void (*reserve_m64_pe)(struct pnv_phb *phb);
134 int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all); 134 int (*pick_m64_pe)(struct pnv_phb *phb, struct pci_bus *bus, int all);
135 int (*get_pe_state)(struct pnv_phb *phb, int pe_no); 135 int (*get_pe_state)(struct pnv_phb *phb, int pe_no);
136 void (*freeze_pe)(struct pnv_phb *phb, int pe_no); 136 void (*freeze_pe)(struct pnv_phb *phb, int pe_no);
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 3f9546d8a51f..30b1c3e298a6 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -265,10 +265,8 @@ static unsigned long pnv_memory_block_size(void)
265static void __init pnv_setup_machdep_opal(void) 265static void __init pnv_setup_machdep_opal(void)
266{ 266{
267 ppc_md.get_boot_time = opal_get_boot_time; 267 ppc_md.get_boot_time = opal_get_boot_time;
268 ppc_md.get_rtc_time = opal_get_rtc_time;
269 ppc_md.set_rtc_time = opal_set_rtc_time;
270 ppc_md.restart = pnv_restart; 268 ppc_md.restart = pnv_restart;
271 ppc_md.power_off = pnv_power_off; 269 pm_power_off = pnv_power_off;
272 ppc_md.halt = pnv_halt; 270 ppc_md.halt = pnv_halt;
273 ppc_md.machine_check_exception = opal_machine_check; 271 ppc_md.machine_check_exception = opal_machine_check;
274 ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery; 272 ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
@@ -285,7 +283,7 @@ static void __init pnv_setup_machdep_rtas(void)
285 ppc_md.set_rtc_time = rtas_set_rtc_time; 283 ppc_md.set_rtc_time = rtas_set_rtc_time;
286 } 284 }
287 ppc_md.restart = rtas_restart; 285 ppc_md.restart = rtas_restart;
288 ppc_md.power_off = rtas_power_off; 286 pm_power_off = rtas_power_off;
289 ppc_md.halt = rtas_halt; 287 ppc_md.halt = rtas_halt;
290} 288}
291#endif /* CONFIG_PPC_POWERNV_RTAS */ 289#endif /* CONFIG_PPC_POWERNV_RTAS */
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index 4753958cd509..b716f666e48a 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -149,6 +149,7 @@ static int pnv_smp_cpu_disable(void)
149static void pnv_smp_cpu_kill_self(void) 149static void pnv_smp_cpu_kill_self(void)
150{ 150{
151 unsigned int cpu; 151 unsigned int cpu;
152 unsigned long srr1;
152 153
153 /* Standard hot unplug procedure */ 154 /* Standard hot unplug procedure */
154 local_irq_disable(); 155 local_irq_disable();
@@ -165,13 +166,25 @@ static void pnv_smp_cpu_kill_self(void)
165 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); 166 mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
166 while (!generic_check_cpu_restart(cpu)) { 167 while (!generic_check_cpu_restart(cpu)) {
167 ppc64_runlatch_off(); 168 ppc64_runlatch_off();
168 power7_nap(1); 169 srr1 = power7_nap(1);
169 ppc64_runlatch_on(); 170 ppc64_runlatch_on();
170 171
171 /* Clear the IPI that woke us up */ 172 /*
172 icp_native_flush_interrupt(); 173 * If the SRR1 value indicates that we woke up due to
173 local_paca->irq_happened &= PACA_IRQ_HARD_DIS; 174 * an external interrupt, then clear the interrupt.
174 mb(); 175 * We clear the interrupt before checking for the
176 * reason, so as to avoid a race where we wake up for
177 * some other reason, find nothing and clear the interrupt
178 * just as some other cpu is sending us an interrupt.
179 * If we returned from power7_nap as a result of
180 * having finished executing in a KVM guest, then srr1
181 * contains 0.
182 */
183 if ((srr1 & SRR1_WAKEMASK) == SRR1_WAKEEE) {
184 icp_native_flush_interrupt();
185 local_paca->irq_happened &= PACA_IRQ_HARD_DIS;
186 smp_mb();
187 }
175 188
176 if (cpu_core_split_required()) 189 if (cpu_core_split_required())
177 continue; 190 continue;
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index 3e270e3412ae..2f95d33cf34a 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -110,7 +110,7 @@ static long ps3_hpte_remove(unsigned long hpte_group)
110 110
111static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, 111static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
112 unsigned long vpn, int psize, int apsize, 112 unsigned long vpn, int psize, int apsize,
113 int ssize, int local) 113 int ssize, unsigned long inv_flags)
114{ 114{
115 int result; 115 int result;
116 u64 hpte_v, want_v, hpte_rs; 116 u64 hpte_v, want_v, hpte_rs;
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 5f3b23220b8e..a6c42f34303a 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -711,7 +711,7 @@ void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq)
711 711
712static unsigned int ps3_get_irq(void) 712static unsigned int ps3_get_irq(void)
713{ 713{
714 struct ps3_private *pd = &__get_cpu_var(ps3_private); 714 struct ps3_private *pd = this_cpu_ptr(&ps3_private);
715 u64 x = (pd->bmp.status & pd->bmp.mask); 715 u64 x = (pd->bmp.status & pd->bmp.mask);
716 unsigned int plug; 716 unsigned int plug;
717 717
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 3f509f86432c..799c8580ab09 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -125,12 +125,7 @@ static void __init prealloc(struct ps3_prealloc *p)
125 if (!p->size) 125 if (!p->size)
126 return; 126 return;
127 127
128 p->address = __alloc_bootmem(p->size, p->align, __pa(MAX_DMA_ADDRESS)); 128 p->address = memblock_virt_alloc(p->size, p->align);
129 if (!p->address) {
130 printk(KERN_ERR "%s: Cannot allocate %s\n", __func__,
131 p->name);
132 return;
133 }
134 129
135 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, 130 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size,
136 p->address); 131 p->address);
@@ -248,6 +243,7 @@ static int __init ps3_probe(void)
248 ps3_mm_init(); 243 ps3_mm_init();
249 ps3_mm_vas_create(&htab_size); 244 ps3_mm_vas_create(&htab_size);
250 ps3_hpte_init(htab_size); 245 ps3_hpte_init(htab_size);
246 pm_power_off = ps3_power_off;
251 247
252 DBG(" <- %s:%d\n", __func__, __LINE__); 248 DBG(" <- %s:%d\n", __func__, __LINE__);
253 return 1; 249 return 1;
@@ -278,7 +274,6 @@ define_machine(ps3) {
278 .calibrate_decr = ps3_calibrate_decr, 274 .calibrate_decr = ps3_calibrate_decr,
279 .progress = ps3_progress, 275 .progress = ps3_progress,
280 .restart = ps3_restart, 276 .restart = ps3_restart,
281 .power_off = ps3_power_off,
282 .halt = ps3_halt, 277 .halt = ps3_halt,
283#if defined(CONFIG_KEXEC) 278#if defined(CONFIG_KEXEC)
284 .kexec_cpu_down = ps3_kexec_cpu_down, 279 .kexec_cpu_down = ps3_kexec_cpu_down,
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index 1062f71f5a85..39049e4884fb 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -75,7 +75,7 @@ static atomic_t dtl_count;
75 */ 75 */
76static void consume_dtle(struct dtl_entry *dtle, u64 index) 76static void consume_dtle(struct dtl_entry *dtle, u64 index)
77{ 77{
78 struct dtl_ring *dtlr = &__get_cpu_var(dtl_rings); 78 struct dtl_ring *dtlr = this_cpu_ptr(&dtl_rings);
79 struct dtl_entry *wp = dtlr->write_ptr; 79 struct dtl_entry *wp = dtlr->write_ptr;
80 struct lppaca *vpa = local_paca->lppaca_ptr; 80 struct lppaca *vpa = local_paca->lppaca_ptr;
81 81
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 1bbb78fab530..fa41f0da5b6f 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -12,7 +12,6 @@
12#include <linux/of.h> 12#include <linux/of.h>
13#include <linux/of_address.h> 13#include <linux/of_address.h>
14#include <linux/memblock.h> 14#include <linux/memblock.h>
15#include <linux/vmalloc.h>
16#include <linux/memory.h> 15#include <linux/memory.h>
17#include <linux/memory_hotplug.h> 16#include <linux/memory_hotplug.h>
18 17
@@ -66,22 +65,6 @@ unsigned long pseries_memory_block_size(void)
66} 65}
67 66
68#ifdef CONFIG_MEMORY_HOTREMOVE 67#ifdef CONFIG_MEMORY_HOTREMOVE
69static int pseries_remove_memory(u64 start, u64 size)
70{
71 int ret;
72
73 /* Remove htab bolted mappings for this section of memory */
74 start = (unsigned long)__va(start);
75 ret = remove_section_mapping(start, start + size);
76
77 /* Ensure all vmalloc mappings are flushed in case they also
78 * hit that section of memory
79 */
80 vm_unmap_aliases();
81
82 return ret;
83}
84
85static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) 68static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
86{ 69{
87 unsigned long block_sz, start_pfn; 70 unsigned long block_sz, start_pfn;
@@ -261,10 +244,6 @@ static int __init pseries_memory_hotplug_init(void)
261 if (firmware_has_feature(FW_FEATURE_LPAR)) 244 if (firmware_has_feature(FW_FEATURE_LPAR))
262 of_reconfig_notifier_register(&pseries_mem_nb); 245 of_reconfig_notifier_register(&pseries_mem_nb);
263 246
264#ifdef CONFIG_MEMORY_HOTREMOVE
265 ppc_md.remove_memory = pseries_remove_memory;
266#endif
267
268 return 0; 247 return 0;
269} 248}
270machine_device_initcall(pseries, pseries_memory_hotplug_init); 249machine_device_initcall(pseries, pseries_memory_hotplug_init);
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 3fda3f17b84e..ccd53f91e8aa 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -18,7 +18,7 @@
18 18
19#ifdef CONFIG_TRACEPOINTS 19#ifdef CONFIG_TRACEPOINTS
20 20
21#ifndef CONFIG_JUMP_LABEL 21#ifndef HAVE_JUMP_LABEL
22 .section ".toc","aw" 22 .section ".toc","aw"
23 23
24 .globl hcall_tracepoint_refcount 24 .globl hcall_tracepoint_refcount
@@ -78,7 +78,7 @@ hcall_tracepoint_refcount:
78 mr r5,BUFREG; \ 78 mr r5,BUFREG; \
79 __HCALL_INST_POSTCALL 79 __HCALL_INST_POSTCALL
80 80
81#ifdef CONFIG_JUMP_LABEL 81#ifdef HAVE_JUMP_LABEL
82#define HCALL_BRANCH(LABEL) \ 82#define HCALL_BRANCH(LABEL) \
83 ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key) 83 ARCH_STATIC_BRANCH(LABEL, hcall_tracepoint_key)
84#else 84#else
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index 4575f0c9e521..f02ec3ab428c 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -110,7 +110,7 @@ static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long
110 if (opcode > MAX_HCALL_OPCODE) 110 if (opcode > MAX_HCALL_OPCODE)
111 return; 111 return;
112 112
113 h = &__get_cpu_var(hcall_stats)[opcode / 4]; 113 h = this_cpu_ptr(&hcall_stats[opcode / 4]);
114 h->tb_start = mftb(); 114 h->tb_start = mftb();
115 h->purr_start = mfspr(SPRN_PURR); 115 h->purr_start = mfspr(SPRN_PURR);
116} 116}
@@ -123,7 +123,7 @@ static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long
123 if (opcode > MAX_HCALL_OPCODE) 123 if (opcode > MAX_HCALL_OPCODE)
124 return; 124 return;
125 125
126 h = &__get_cpu_var(hcall_stats)[opcode / 4]; 126 h = this_cpu_ptr(&hcall_stats[opcode / 4]);
127 h->num_calls++; 127 h->num_calls++;
128 h->tb_total += mftb() - h->tb_start; 128 h->tb_total += mftb() - h->tb_start;
129 h->purr_total += mfspr(SPRN_PURR) - h->purr_start; 129 h->purr_total += mfspr(SPRN_PURR) - h->purr_start;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 3e5bfdafee63..1d3d52dc3ff3 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -199,7 +199,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
199 199
200 local_irq_save(flags); /* to protect tcep and the page behind it */ 200 local_irq_save(flags); /* to protect tcep and the page behind it */
201 201
202 tcep = __get_cpu_var(tce_page); 202 tcep = __this_cpu_read(tce_page);
203 203
204 /* This is safe to do since interrupts are off when we're called 204 /* This is safe to do since interrupts are off when we're called
205 * from iommu_alloc{,_sg}() 205 * from iommu_alloc{,_sg}()
@@ -212,7 +212,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
212 return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, 212 return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
213 direction, attrs); 213 direction, attrs);
214 } 214 }
215 __get_cpu_var(tce_page) = tcep; 215 __this_cpu_write(tce_page, tcep);
216 } 216 }
217 217
218 rpn = __pa(uaddr) >> TCE_SHIFT; 218 rpn = __pa(uaddr) >> TCE_SHIFT;
@@ -398,7 +398,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
398 long l, limit; 398 long l, limit;
399 399
400 local_irq_disable(); /* to protect tcep and the page behind it */ 400 local_irq_disable(); /* to protect tcep and the page behind it */
401 tcep = __get_cpu_var(tce_page); 401 tcep = __this_cpu_read(tce_page);
402 402
403 if (!tcep) { 403 if (!tcep) {
404 tcep = (__be64 *)__get_free_page(GFP_ATOMIC); 404 tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
@@ -406,7 +406,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
406 local_irq_enable(); 406 local_irq_enable();
407 return -ENOMEM; 407 return -ENOMEM;
408 } 408 }
409 __get_cpu_var(tce_page) = tcep; 409 __this_cpu_write(tce_page, tcep);
410 } 410 }
411 411
412 proto_tce = TCE_PCI_READ | TCE_PCI_WRITE; 412 proto_tce = TCE_PCI_READ | TCE_PCI_WRITE;
@@ -574,8 +574,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
574 while (isa_dn && isa_dn != dn) 574 while (isa_dn && isa_dn != dn)
575 isa_dn = isa_dn->parent; 575 isa_dn = isa_dn->parent;
576 576
577 if (isa_dn_orig) 577 of_node_put(isa_dn_orig);
578 of_node_put(isa_dn_orig);
579 578
580 /* Count number of direct PCI children of the PHB. */ 579 /* Count number of direct PCI children of the PHB. */
581 for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) 580 for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index f6880d2a40fb..469751d92004 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -284,7 +284,7 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
284 unsigned long newpp, 284 unsigned long newpp,
285 unsigned long vpn, 285 unsigned long vpn,
286 int psize, int apsize, 286 int psize, int apsize,
287 int ssize, int local) 287 int ssize, unsigned long inv_flags)
288{ 288{
289 unsigned long lpar_rc; 289 unsigned long lpar_rc;
290 unsigned long flags = (newpp & 7) | H_AVPN; 290 unsigned long flags = (newpp & 7) | H_AVPN;
@@ -442,7 +442,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
442static void pSeries_lpar_hugepage_invalidate(unsigned long vsid, 442static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
443 unsigned long addr, 443 unsigned long addr,
444 unsigned char *hpte_slot_array, 444 unsigned char *hpte_slot_array,
445 int psize, int ssize) 445 int psize, int ssize, int local)
446{ 446{
447 int i, index = 0; 447 int i, index = 0;
448 unsigned long s_addr = addr; 448 unsigned long s_addr = addr;
@@ -515,7 +515,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
515 unsigned long vpn; 515 unsigned long vpn;
516 unsigned long i, pix, rc; 516 unsigned long i, pix, rc;
517 unsigned long flags = 0; 517 unsigned long flags = 0;
518 struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); 518 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
519 int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); 519 int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
520 unsigned long param[9]; 520 unsigned long param[9];
521 unsigned long hash, index, shift, hidx, slot; 521 unsigned long hash, index, shift, hidx, slot;
@@ -705,7 +705,7 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
705 705
706 local_irq_save(flags); 706 local_irq_save(flags);
707 707
708 depth = &__get_cpu_var(hcall_trace_depth); 708 depth = this_cpu_ptr(&hcall_trace_depth);
709 709
710 if (*depth) 710 if (*depth)
711 goto out; 711 goto out;
@@ -730,7 +730,7 @@ void __trace_hcall_exit(long opcode, unsigned long retval,
730 730
731 local_irq_save(flags); 731 local_irq_save(flags);
732 732
733 depth = &__get_cpu_var(hcall_trace_depth); 733 depth = this_cpu_ptr(&hcall_trace_depth);
734 734
735 if (*depth) 735 if (*depth)
736 goto out; 736 goto out;
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 11a3b617ef5d..054a0ed5c7ee 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -715,6 +715,8 @@ static int nvram_pstore_init(void)
715 nvram_pstore_info.buf = oops_data; 715 nvram_pstore_info.buf = oops_data;
716 nvram_pstore_info.bufsize = oops_data_sz; 716 nvram_pstore_info.bufsize = oops_data_sz;
717 717
718 spin_lock_init(&nvram_pstore_info.buf_lock);
719
718 rc = pstore_register(&nvram_pstore_info); 720 rc = pstore_register(&nvram_pstore_info);
719 if (rc != 0) 721 if (rc != 0)
720 pr_err("nvram: pstore_register() failed, defaults to " 722 pr_err("nvram: pstore_register() failed, defaults to "
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 67e48594040c..fe16a50700de 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -134,7 +134,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge)
134 of_node_put(pdn); 134 of_node_put(pdn);
135 135
136 if (rc) { 136 if (rc) {
137 pr_err("no ibm,pcie-link-speed-stats property\n"); 137 pr_debug("no ibm,pcie-link-speed-stats property\n");
138 return 0; 138 return 0;
139 } 139 }
140 140
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 5a4d0fc03b03..c3b2a7e81ddb 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -302,8 +302,8 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
302 /* If it isn't an extended log we can use the per cpu 64bit buffer */ 302 /* If it isn't an extended log we can use the per cpu 64bit buffer */
303 h = (struct rtas_error_log *)&savep[1]; 303 h = (struct rtas_error_log *)&savep[1];
304 if (!rtas_error_extended(h)) { 304 if (!rtas_error_extended(h)) {
305 memcpy(&__get_cpu_var(mce_data_buf), h, sizeof(__u64)); 305 memcpy(this_cpu_ptr(&mce_data_buf), h, sizeof(__u64));
306 errhdr = (struct rtas_error_log *)&__get_cpu_var(mce_data_buf); 306 errhdr = (struct rtas_error_log *)this_cpu_ptr(&mce_data_buf);
307 } else { 307 } else {
308 int len, error_log_length; 308 int len, error_log_length;
309 309
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ed8a90022a3d..e445b6701f50 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -500,7 +500,11 @@ static void __init pSeries_setup_arch(void)
500 500
501 if (firmware_has_feature(FW_FEATURE_SET_MODE)) { 501 if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
502 long rc; 502 long rc;
503 if ((rc = pSeries_enable_reloc_on_exc()) != H_SUCCESS) { 503
504 rc = pSeries_enable_reloc_on_exc();
505 if (rc == H_P2) {
506 pr_info("Relocation on exceptions not supported\n");
507 } else if (rc != H_SUCCESS) {
504 pr_warn("Unable to enable relocation on exceptions: " 508 pr_warn("Unable to enable relocation on exceptions: "
505 "%ld\n", rc); 509 "%ld\n", rc);
506 } 510 }
@@ -660,6 +664,34 @@ static void __init pSeries_init_early(void)
660 pr_debug(" <- pSeries_init_early()\n"); 664 pr_debug(" <- pSeries_init_early()\n");
661} 665}
662 666
667/**
668 * pseries_power_off - tell firmware about how to power off the system.
669 *
670 * This function calls either the power-off rtas token in normal cases
671 * or the ibm,power-off-ups token (if present & requested) in case of
672 * a power failure. If power-off token is used, power on will only be
673 * possible with power button press. If ibm,power-off-ups token is used
674 * it will allow auto poweron after power is restored.
675 */
676static void pseries_power_off(void)
677{
678 int rc;
679 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
680
681 if (rtas_flash_term_hook)
682 rtas_flash_term_hook(SYS_POWER_OFF);
683
684 if (rtas_poweron_auto == 0 ||
685 rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
686 rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
687 printk(KERN_INFO "RTAS power-off returned %d\n", rc);
688 } else {
689 rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
690 printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
691 }
692 for (;;);
693}
694
663/* 695/*
664 * Called very early, MMU is off, device-tree isn't unflattened 696 * Called very early, MMU is off, device-tree isn't unflattened
665 */ 697 */
@@ -742,6 +774,8 @@ static int __init pSeries_probe(void)
742 else 774 else
743 hpte_init_native(); 775 hpte_init_native();
744 776
777 pm_power_off = pseries_power_off;
778
745 pr_debug("Machine is%s LPAR !\n", 779 pr_debug("Machine is%s LPAR !\n",
746 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); 780 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
747 781
@@ -755,34 +789,6 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
755 return PCI_PROBE_NORMAL; 789 return PCI_PROBE_NORMAL;
756} 790}
757 791
758/**
759 * pSeries_power_off - tell firmware about how to power off the system.
760 *
761 * This function calls either the power-off rtas token in normal cases
762 * or the ibm,power-off-ups token (if present & requested) in case of
763 * a power failure. If power-off token is used, power on will only be
764 * possible with power button press. If ibm,power-off-ups token is used
765 * it will allow auto poweron after power is restored.
766 */
767static void pSeries_power_off(void)
768{
769 int rc;
770 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
771
772 if (rtas_flash_term_hook)
773 rtas_flash_term_hook(SYS_POWER_OFF);
774
775 if (rtas_poweron_auto == 0 ||
776 rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
777 rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
778 printk(KERN_INFO "RTAS power-off returned %d\n", rc);
779 } else {
780 rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
781 printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
782 }
783 for (;;);
784}
785
786#ifndef CONFIG_PCI 792#ifndef CONFIG_PCI
787void pSeries_final_fixup(void) { } 793void pSeries_final_fixup(void) { }
788#endif 794#endif
@@ -797,7 +803,6 @@ define_machine(pseries) {
797 .pcibios_fixup = pSeries_final_fixup, 803 .pcibios_fixup = pSeries_final_fixup,
798 .pci_probe_mode = pSeries_pci_probe_mode, 804 .pci_probe_mode = pSeries_pci_probe_mode,
799 .restart = rtas_restart, 805 .restart = rtas_restart,
800 .power_off = pSeries_power_off,
801 .halt = rtas_halt, 806 .halt = rtas_halt,
802 .panic = rtas_os_term, 807 .panic = rtas_os_term,
803 .get_boot_time = rtas_get_boot_time, 808 .get_boot_time = rtas_get_boot_time,
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 7aed8d0876b7..d09f4fa2c3d1 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -13,7 +13,6 @@
13 * 13 *
14 */ 14 */
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/bootmem.h>
17#include <linux/msi.h> 16#include <linux/msi.h>
18#include <linux/pci.h> 17#include <linux/pci.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 65d2ed4549e6..6455c1eada1a 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -23,7 +23,6 @@
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/bootmem.h>
27#include <linux/memblock.h> 26#include <linux/memblock.h>
28#include <linux/log2.h> 27#include <linux/log2.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
@@ -152,7 +151,7 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
152 flags |= 0x10000000; /* enable relaxed ordering */ 151 flags |= 0x10000000; /* enable relaxed ordering */
153 152
154 for (i = 0; size > 0; i++) { 153 for (i = 0; size > 0; i++) {
155 unsigned int bits = min(ilog2(size), 154 unsigned int bits = min_t(u32, ilog2(size),
156 __ffs(pci_addr | phys_addr)); 155 __ffs(pci_addr | phys_addr));
157 156
158 if (index + i >= 5) 157 if (index + i >= 5)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index c04b718307c8..08d60f183dad 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -58,6 +58,19 @@
58#define RIO_ISR_AACR 0x10120 58#define RIO_ISR_AACR 0x10120
59#define RIO_ISR_AACR_AA 0x1 /* Accept All ID */ 59#define RIO_ISR_AACR_AA 0x1 /* Accept All ID */
60 60
61#define RIWTAR_TRAD_VAL_SHIFT 12
62#define RIWTAR_TRAD_MASK 0x00FFFFFF
63#define RIWBAR_BADD_VAL_SHIFT 12
64#define RIWBAR_BADD_MASK 0x003FFFFF
65#define RIWAR_ENABLE 0x80000000
66#define RIWAR_TGINT_LOCAL 0x00F00000
67#define RIWAR_RDTYP_NO_SNOOP 0x00040000
68#define RIWAR_RDTYP_SNOOP 0x00050000
69#define RIWAR_WRTYP_NO_SNOOP 0x00004000
70#define RIWAR_WRTYP_SNOOP 0x00005000
71#define RIWAR_WRTYP_ALLOC 0x00006000
72#define RIWAR_SIZE_MASK 0x0000003F
73
61#define __fsl_read_rio_config(x, addr, err, op) \ 74#define __fsl_read_rio_config(x, addr, err, op) \
62 __asm__ __volatile__( \ 75 __asm__ __volatile__( \
63 "1: "op" %1,0(%2)\n" \ 76 "1: "op" %1,0(%2)\n" \
@@ -266,6 +279,89 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
266 return 0; 279 return 0;
267} 280}
268 281
282static void fsl_rio_inbound_mem_init(struct rio_priv *priv)
283{
284 int i;
285
286 /* close inbound windows */
287 for (i = 0; i < RIO_INB_ATMU_COUNT; i++)
288 out_be32(&priv->inb_atmu_regs[i].riwar, 0);
289}
290
291int fsl_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
292 u64 rstart, u32 size, u32 flags)
293{
294 struct rio_priv *priv = mport->priv;
295 u32 base_size;
296 unsigned int base_size_log;
297 u64 win_start, win_end;
298 u32 riwar;
299 int i;
300
301 if ((size & (size - 1)) != 0)
302 return -EINVAL;
303
304 base_size_log = ilog2(size);
305 base_size = 1 << base_size_log;
306
307 /* check if addresses are aligned with the window size */
308 if (lstart & (base_size - 1))
309 return -EINVAL;
310 if (rstart & (base_size - 1))
311 return -EINVAL;
312
313 /* check for conflicting ranges */
314 for (i = 0; i < RIO_INB_ATMU_COUNT; i++) {
315 riwar = in_be32(&priv->inb_atmu_regs[i].riwar);
316 if ((riwar & RIWAR_ENABLE) == 0)
317 continue;
318 win_start = ((u64)(in_be32(&priv->inb_atmu_regs[i].riwbar) & RIWBAR_BADD_MASK))
319 << RIWBAR_BADD_VAL_SHIFT;
320 win_end = win_start + ((1 << ((riwar & RIWAR_SIZE_MASK) + 1)) - 1);
321 if (rstart < win_end && (rstart + size) > win_start)
322 return -EINVAL;
323 }
324
325 /* find unused atmu */
326 for (i = 0; i < RIO_INB_ATMU_COUNT; i++) {
327 riwar = in_be32(&priv->inb_atmu_regs[i].riwar);
328 if ((riwar & RIWAR_ENABLE) == 0)
329 break;
330 }
331 if (i >= RIO_INB_ATMU_COUNT)
332 return -ENOMEM;
333
334 out_be32(&priv->inb_atmu_regs[i].riwtar, lstart >> RIWTAR_TRAD_VAL_SHIFT);
335 out_be32(&priv->inb_atmu_regs[i].riwbar, rstart >> RIWBAR_BADD_VAL_SHIFT);
336 out_be32(&priv->inb_atmu_regs[i].riwar, RIWAR_ENABLE | RIWAR_TGINT_LOCAL |
337 RIWAR_RDTYP_SNOOP | RIWAR_WRTYP_SNOOP | (base_size_log - 1));
338
339 return 0;
340}
341
342void fsl_unmap_inb_mem(struct rio_mport *mport, dma_addr_t lstart)
343{
344 u32 win_start_shift, base_start_shift;
345 struct rio_priv *priv = mport->priv;
346 u32 riwar, riwtar;
347 int i;
348
349 /* skip default window */
350 base_start_shift = lstart >> RIWTAR_TRAD_VAL_SHIFT;
351 for (i = 0; i < RIO_INB_ATMU_COUNT; i++) {
352 riwar = in_be32(&priv->inb_atmu_regs[i].riwar);
353 if ((riwar & RIWAR_ENABLE) == 0)
354 continue;
355
356 riwtar = in_be32(&priv->inb_atmu_regs[i].riwtar);
357 win_start_shift = riwtar & RIWTAR_TRAD_MASK;
358 if (win_start_shift == base_start_shift) {
359 out_be32(&priv->inb_atmu_regs[i].riwar, riwar & ~RIWAR_ENABLE);
360 return;
361 }
362 }
363}
364
269void fsl_rio_port_error_handler(int offset) 365void fsl_rio_port_error_handler(int offset)
270{ 366{
271 /*XXX: Error recovery is not implemented, we just clear errors */ 367 /*XXX: Error recovery is not implemented, we just clear errors */
@@ -389,6 +485,8 @@ int fsl_rio_setup(struct platform_device *dev)
389 ops->add_outb_message = fsl_add_outb_message; 485 ops->add_outb_message = fsl_add_outb_message;
390 ops->add_inb_buffer = fsl_add_inb_buffer; 486 ops->add_inb_buffer = fsl_add_inb_buffer;
391 ops->get_inb_message = fsl_get_inb_message; 487 ops->get_inb_message = fsl_get_inb_message;
488 ops->map_inb = fsl_map_inb_mem;
489 ops->unmap_inb = fsl_unmap_inb_mem;
392 490
393 rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0); 491 rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0);
394 if (!rmu_node) { 492 if (!rmu_node) {
@@ -602,6 +700,11 @@ int fsl_rio_setup(struct platform_device *dev)
602 RIO_ATMU_REGS_PORT2_OFFSET)); 700 RIO_ATMU_REGS_PORT2_OFFSET));
603 701
604 priv->maint_atmu_regs = priv->atmu_regs + 1; 702 priv->maint_atmu_regs = priv->atmu_regs + 1;
703 priv->inb_atmu_regs = (struct rio_inb_atmu_regs __iomem *)
704 (priv->regs_win +
705 ((i == 0) ? RIO_INB_ATMU_REGS_PORT1_OFFSET :
706 RIO_INB_ATMU_REGS_PORT2_OFFSET));
707
605 708
606 /* Set to receive any dist ID for serial RapidIO controller. */ 709 /* Set to receive any dist ID for serial RapidIO controller. */
607 if (port->phy_type == RIO_PHY_SERIAL) 710 if (port->phy_type == RIO_PHY_SERIAL)
@@ -620,6 +723,7 @@ int fsl_rio_setup(struct platform_device *dev)
620 rio_law_start = range_start; 723 rio_law_start = range_start;
621 724
622 fsl_rio_setup_rmu(port, rmu_np[i]); 725 fsl_rio_setup_rmu(port, rmu_np[i]);
726 fsl_rio_inbound_mem_init(priv);
623 727
624 dbell->mport[i] = port; 728 dbell->mport[i] = port;
625 729
diff --git a/arch/powerpc/sysdev/fsl_rio.h b/arch/powerpc/sysdev/fsl_rio.h
index ae8e27405a0d..d53407a34f32 100644
--- a/arch/powerpc/sysdev/fsl_rio.h
+++ b/arch/powerpc/sysdev/fsl_rio.h
@@ -50,9 +50,12 @@
50#define RIO_S_DBELL_REGS_OFFSET 0x13400 50#define RIO_S_DBELL_REGS_OFFSET 0x13400
51#define RIO_S_PW_REGS_OFFSET 0x134e0 51#define RIO_S_PW_REGS_OFFSET 0x134e0
52#define RIO_ATMU_REGS_DBELL_OFFSET 0x10C40 52#define RIO_ATMU_REGS_DBELL_OFFSET 0x10C40
53#define RIO_INB_ATMU_REGS_PORT1_OFFSET 0x10d60
54#define RIO_INB_ATMU_REGS_PORT2_OFFSET 0x10f60
53 55
54#define MAX_MSG_UNIT_NUM 2 56#define MAX_MSG_UNIT_NUM 2
55#define MAX_PORT_NUM 4 57#define MAX_PORT_NUM 4
58#define RIO_INB_ATMU_COUNT 4
56 59
57struct rio_atmu_regs { 60struct rio_atmu_regs {
58 u32 rowtar; 61 u32 rowtar;
@@ -63,6 +66,15 @@ struct rio_atmu_regs {
63 u32 pad2[3]; 66 u32 pad2[3];
64}; 67};
65 68
69struct rio_inb_atmu_regs {
70 u32 riwtar;
71 u32 pad1;
72 u32 riwbar;
73 u32 pad2;
74 u32 riwar;
75 u32 pad3[3];
76};
77
66struct rio_dbell_ring { 78struct rio_dbell_ring {
67 void *virt; 79 void *virt;
68 dma_addr_t phys; 80 dma_addr_t phys;
@@ -99,6 +111,7 @@ struct rio_priv {
99 void __iomem *regs_win; 111 void __iomem *regs_win;
100 struct rio_atmu_regs __iomem *atmu_regs; 112 struct rio_atmu_regs __iomem *atmu_regs;
101 struct rio_atmu_regs __iomem *maint_atmu_regs; 113 struct rio_atmu_regs __iomem *maint_atmu_regs;
114 struct rio_inb_atmu_regs __iomem *inb_atmu_regs;
102 void __iomem *maint_win; 115 void __iomem *maint_win;
103 void *rmm_handle; /* RapidIO message manager(unit) Handle */ 116 void *rmm_handle; /* RapidIO message manager(unit) Handle */
104}; 117};
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ffd1169ebaab..99269c041615 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -197,8 +197,7 @@ static int __init setup_rstcr(void)
197 if (!rstcr && ppc_md.restart == fsl_rstcr_restart) 197 if (!rstcr && ppc_md.restart == fsl_rstcr_restart)
198 printk(KERN_ERR "No RSTCR register, warm reboot won't work\n"); 198 printk(KERN_ERR "No RSTCR register, warm reboot won't work\n");
199 199
200 if (np) 200 of_node_put(np);
201 of_node_put(np);
202 201
203 return 0; 202 return 0;
204} 203}
@@ -238,7 +237,7 @@ void fsl_hv_restart(char *cmd)
238/* 237/*
239 * Halt the current partition 238 * Halt the current partition
240 * 239 *
241 * This function should be assigned to the ppc_md.power_off and ppc_md.halt 240 * This function should be assigned to the pm_power_off and ppc_md.halt
242 * function pointers, to shut down the partition when we're running under 241 * function pointers, to shut down the partition when we're running under
243 * the Freescale hypervisor. 242 * the Freescale hypervisor.
244 */ 243 */
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index b50f97811c25..b28733727ed3 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -20,7 +20,6 @@
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/syscore_ops.h> 21#include <linux/syscore_ops.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/bootmem.h>
24#include <linux/spinlock.h> 23#include <linux/spinlock.h>
25#include <linux/fsl_devices.h> 24#include <linux/fsl_devices.h>
26#include <asm/irq.h> 25#include <asm/irq.h>
diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c
index 5492dc5f56f4..f4f0301b9a60 100644
--- a/arch/powerpc/sysdev/mpc5xxx_clocks.c
+++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c
@@ -26,8 +26,7 @@ unsigned long mpc5xxx_get_bus_frequency(struct device_node *node)
26 of_node_put(node); 26 of_node_put(node);
27 node = np; 27 node = np;
28 } 28 }
29 if (node) 29 of_node_put(node);
30 of_node_put(node);
31 30
32 return p_bus_freq ? *p_bus_freq : 0; 31 return p_bus_freq ? *p_bus_freq : 0;
33} 32}
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 89cec0ed6a58..c4648ad5c1f3 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -24,7 +24,6 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/bootmem.h>
28#include <linux/spinlock.h> 27#include <linux/spinlock.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 45c114bc430b..a3f660eed6de 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -16,7 +16,6 @@
16#undef DEBUG 16#undef DEBUG
17 17
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/bootmem.h>
20#include <linux/msi.h> 19#include <linux/msi.h>
21#include <asm/mpic.h> 20#include <asm/mpic.h>
22#include <asm/prom.h> 21#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index 0dff1cd44481..b2cef1809389 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <linux/bootmem.h>
14#include <linux/msi.h> 13#include <linux/msi.h>
15#include <asm/mpic.h> 14#include <asm/mpic.h>
16#include <asm/prom.h> 15#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/ppc4xx_cpm.c b/arch/powerpc/sysdev/ppc4xx_cpm.c
index 82e2cfe35c62..ba95adf81d8d 100644
--- a/arch/powerpc/sysdev/ppc4xx_cpm.c
+++ b/arch/powerpc/sysdev/ppc4xx_cpm.c
@@ -281,7 +281,7 @@ static int __init cpm_init(void)
281 printk(KERN_ERR "cpm: could not parse dcr property for %s\n", 281 printk(KERN_ERR "cpm: could not parse dcr property for %s\n",
282 np->full_name); 282 np->full_name);
283 ret = -EINVAL; 283 ret = -EINVAL;
284 goto out; 284 goto node_put;
285 } 285 }
286 286
287 cpm.dcr_host = dcr_map(np, dcr_base, dcr_len); 287 cpm.dcr_host = dcr_map(np, dcr_base, dcr_len);
@@ -290,7 +290,7 @@ static int __init cpm_init(void)
290 printk(KERN_ERR "cpm: failed to map dcr property for %s\n", 290 printk(KERN_ERR "cpm: failed to map dcr property for %s\n",
291 np->full_name); 291 np->full_name);
292 ret = -EINVAL; 292 ret = -EINVAL;
293 goto out; 293 goto node_put;
294 } 294 }
295 295
296 /* All 4xx SoCs with a CPM controller have one of two 296 /* All 4xx SoCs with a CPM controller have one of two
@@ -330,9 +330,9 @@ static int __init cpm_init(void)
330 330
331 if (cpm.standby || cpm.suspend) 331 if (cpm.standby || cpm.suspend)
332 suspend_set_ops(&cpm_suspend_ops); 332 suspend_set_ops(&cpm_suspend_ops);
333node_put:
334 of_node_put(np);
333out: 335out:
334 if (np)
335 of_node_put(np);
336 return ret; 336 return ret;
337} 337}
338 338
diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
index 518eabbe0bdc..5e622c0544c4 100644
--- a/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -22,7 +22,6 @@
22 */ 22 */
23 23
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/bootmem.h>
26#include <linux/pci.h> 25#include <linux/pci.h>
27#include <linux/msi.h> 26#include <linux/msi.h>
28#include <linux/of_platform.h> 27#include <linux/of_platform.h>
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index df6e2fc4ff92..086aca69ecae 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -22,7 +22,6 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/bootmem.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28 27
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 238a07b97f2c..b584debbcd9c 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -22,7 +22,6 @@
22#include <linux/spinlock.h> 22#include <linux/spinlock.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/bootmem.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <linux/ioport.h> 27#include <linux/ioport.h>
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index b2b87c30e266..543765e1ef14 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -23,7 +23,6 @@
23#include <linux/sched.h> 23#include <linux/sched.h>
24#include <linux/signal.h> 24#include <linux/signal.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/bootmem.h>
27#include <linux/spinlock.h> 26#include <linux/spinlock.h>
28#include <asm/irq.h> 27#include <asm/irq.h>
29#include <asm/io.h> 28#include <asm/io.h>
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 92033936a8f7..7c37157d4c24 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -19,7 +19,6 @@
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/bootmem.h>
23#include <linux/spinlock.h> 22#include <linux/spinlock.h>
24#include <linux/irq.h> 23#include <linux/irq.h>
25#include <linux/interrupt.h> 24#include <linux/interrupt.h>
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index fe0cca477164..365249cd346b 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -155,7 +155,7 @@ int __init xics_smp_probe(void)
155 155
156void xics_teardown_cpu(void) 156void xics_teardown_cpu(void)
157{ 157{
158 struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr); 158 struct xics_cppr *os_cppr = this_cpu_ptr(&xics_cppr);
159 159
160 /* 160 /*
161 * we have to reset the cppr index to 0 because we're 161 * we have to reset the cppr index to 0 because we're
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index c8efbb37d6e0..5b150f0c5df9 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -51,6 +51,12 @@
51#include <asm/paca.h> 51#include <asm/paca.h>
52#endif 52#endif
53 53
54#if defined(CONFIG_PPC_SPLPAR)
55#include <asm/plpar_wrappers.h>
56#else
57static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; };
58#endif
59
54#include "nonstdio.h" 60#include "nonstdio.h"
55#include "dis-asm.h" 61#include "dis-asm.h"
56 62
@@ -88,10 +94,9 @@ struct bpt {
88}; 94};
89 95
90/* Bits in bpt.enabled */ 96/* Bits in bpt.enabled */
91#define BP_IABR_TE 1 /* IABR translation enabled */ 97#define BP_CIABR 1
92#define BP_IABR 2 98#define BP_TRAP 2
93#define BP_TRAP 8 99#define BP_DABR 4
94#define BP_DABR 0x10
95 100
96#define NBPTS 256 101#define NBPTS 256
97static struct bpt bpts[NBPTS]; 102static struct bpt bpts[NBPTS];
@@ -270,6 +275,45 @@ static inline void cinval(void *p)
270 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); 275 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
271} 276}
272 277
278/**
279 * write_ciabr() - write the CIABR SPR
280 * @ciabr: The value to write.
281 *
282 * This function writes a value to the CIARB register either directly
283 * through mtspr instruction if the kernel is in HV privilege mode or
284 * call a hypervisor function to achieve the same in case the kernel
285 * is in supervisor privilege mode.
286 */
287static void write_ciabr(unsigned long ciabr)
288{
289 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
290 return;
291
292 if (cpu_has_feature(CPU_FTR_HVMODE)) {
293 mtspr(SPRN_CIABR, ciabr);
294 return;
295 }
296 plapr_set_ciabr(ciabr);
297}
298
299/**
300 * set_ciabr() - set the CIABR
301 * @addr: The value to set.
302 *
303 * This function sets the correct privilege value into the the HW
304 * breakpoint address before writing it up in the CIABR register.
305 */
306static void set_ciabr(unsigned long addr)
307{
308 addr &= ~CIABR_PRIV;
309
310 if (cpu_has_feature(CPU_FTR_HVMODE))
311 addr |= CIABR_PRIV_HYPER;
312 else
313 addr |= CIABR_PRIV_SUPER;
314 write_ciabr(addr);
315}
316
273/* 317/*
274 * Disable surveillance (the service processor watchdog function) 318 * Disable surveillance (the service processor watchdog function)
275 * while we are in xmon. 319 * while we are in xmon.
@@ -727,7 +771,7 @@ static void insert_bpts(void)
727 771
728 bp = bpts; 772 bp = bpts;
729 for (i = 0; i < NBPTS; ++i, ++bp) { 773 for (i = 0; i < NBPTS; ++i, ++bp) {
730 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0) 774 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
731 continue; 775 continue;
732 if (mread(bp->address, &bp->instr[0], 4) != 4) { 776 if (mread(bp->address, &bp->instr[0], 4) != 4) {
733 printf("Couldn't read instruction at %lx, " 777 printf("Couldn't read instruction at %lx, "
@@ -742,7 +786,7 @@ static void insert_bpts(void)
742 continue; 786 continue;
743 } 787 }
744 store_inst(&bp->instr[0]); 788 store_inst(&bp->instr[0]);
745 if (bp->enabled & BP_IABR) 789 if (bp->enabled & BP_CIABR)
746 continue; 790 continue;
747 if (mwrite(bp->address, &bpinstr, 4) != 4) { 791 if (mwrite(bp->address, &bpinstr, 4) != 4) {
748 printf("Couldn't write instruction at %lx, " 792 printf("Couldn't write instruction at %lx, "
@@ -764,9 +808,9 @@ static void insert_cpu_bpts(void)
764 brk.len = 8; 808 brk.len = 8;
765 __set_breakpoint(&brk); 809 __set_breakpoint(&brk);
766 } 810 }
767 if (iabr && cpu_has_feature(CPU_FTR_IABR)) 811
768 mtspr(SPRN_IABR, iabr->address 812 if (iabr)
769 | (iabr->enabled & (BP_IABR|BP_IABR_TE))); 813 set_ciabr(iabr->address);
770} 814}
771 815
772static void remove_bpts(void) 816static void remove_bpts(void)
@@ -777,7 +821,7 @@ static void remove_bpts(void)
777 821
778 bp = bpts; 822 bp = bpts;
779 for (i = 0; i < NBPTS; ++i, ++bp) { 823 for (i = 0; i < NBPTS; ++i, ++bp) {
780 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP) 824 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
781 continue; 825 continue;
782 if (mread(bp->address, &instr, 4) == 4 826 if (mread(bp->address, &instr, 4) == 4
783 && instr == bpinstr 827 && instr == bpinstr
@@ -792,8 +836,7 @@ static void remove_bpts(void)
792static void remove_cpu_bpts(void) 836static void remove_cpu_bpts(void)
793{ 837{
794 hw_breakpoint_disable(); 838 hw_breakpoint_disable();
795 if (cpu_has_feature(CPU_FTR_IABR)) 839 write_ciabr(0);
796 mtspr(SPRN_IABR, 0);
797} 840}
798 841
799/* Command interpreting routine */ 842/* Command interpreting routine */
@@ -907,7 +950,7 @@ cmds(struct pt_regs *excp)
907 case 'u': 950 case 'u':
908 dump_segments(); 951 dump_segments();
909 break; 952 break;
910#elif defined(CONFIG_4xx) 953#elif defined(CONFIG_44x)
911 case 'u': 954 case 'u':
912 dump_tlb_44x(); 955 dump_tlb_44x();
913 break; 956 break;
@@ -981,7 +1024,8 @@ static void bootcmds(void)
981 else if (cmd == 'h') 1024 else if (cmd == 'h')
982 ppc_md.halt(); 1025 ppc_md.halt();
983 else if (cmd == 'p') 1026 else if (cmd == 'p')
984 ppc_md.power_off(); 1027 if (pm_power_off)
1028 pm_power_off();
985} 1029}
986 1030
987static int cpu_cmd(void) 1031static int cpu_cmd(void)
@@ -1127,7 +1171,7 @@ static char *breakpoint_help_string =
1127 "b <addr> [cnt] set breakpoint at given instr addr\n" 1171 "b <addr> [cnt] set breakpoint at given instr addr\n"
1128 "bc clear all breakpoints\n" 1172 "bc clear all breakpoints\n"
1129 "bc <n/addr> clear breakpoint number n or at addr\n" 1173 "bc <n/addr> clear breakpoint number n or at addr\n"
1130 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" 1174 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1131 "bd <addr> [cnt] set hardware data breakpoint\n" 1175 "bd <addr> [cnt] set hardware data breakpoint\n"
1132 ""; 1176 "";
1133 1177
@@ -1166,13 +1210,13 @@ bpt_cmds(void)
1166 break; 1210 break;
1167 1211
1168 case 'i': /* bi - hardware instr breakpoint */ 1212 case 'i': /* bi - hardware instr breakpoint */
1169 if (!cpu_has_feature(CPU_FTR_IABR)) { 1213 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1170 printf("Hardware instruction breakpoint " 1214 printf("Hardware instruction breakpoint "
1171 "not supported on this cpu\n"); 1215 "not supported on this cpu\n");
1172 break; 1216 break;
1173 } 1217 }
1174 if (iabr) { 1218 if (iabr) {
1175 iabr->enabled &= ~(BP_IABR | BP_IABR_TE); 1219 iabr->enabled &= ~BP_CIABR;
1176 iabr = NULL; 1220 iabr = NULL;
1177 } 1221 }
1178 if (!scanhex(&a)) 1222 if (!scanhex(&a))
@@ -1181,7 +1225,7 @@ bpt_cmds(void)
1181 break; 1225 break;
1182 bp = new_breakpoint(a); 1226 bp = new_breakpoint(a);
1183 if (bp != NULL) { 1227 if (bp != NULL) {
1184 bp->enabled |= BP_IABR | BP_IABR_TE; 1228 bp->enabled |= BP_CIABR;
1185 iabr = bp; 1229 iabr = bp;
1186 } 1230 }
1187 break; 1231 break;
@@ -1238,7 +1282,7 @@ bpt_cmds(void)
1238 if (!bp->enabled) 1282 if (!bp->enabled)
1239 continue; 1283 continue;
1240 printf("%2x %s ", BP_NUM(bp), 1284 printf("%2x %s ", BP_NUM(bp),
1241 (bp->enabled & BP_IABR)? "inst": "trap"); 1285 (bp->enabled & BP_CIABR) ? "inst": "trap");
1242 xmon_print_symbol(bp->address, " ", "\n"); 1286 xmon_print_symbol(bp->address, " ", "\n");
1243 } 1287 }
1244 break; 1288 break;
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h
index 4236408070e5..6259895fcd97 100644
--- a/arch/s390/include/asm/cmpxchg.h
+++ b/arch/s390/include/asm/cmpxchg.h
@@ -11,200 +11,28 @@
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/bug.h> 12#include <linux/bug.h>
13 13
14extern void __xchg_called_with_bad_pointer(void); 14#define cmpxchg(ptr, o, n) \
15 15({ \
16static inline unsigned long __xchg(unsigned long x, void *ptr, int size) 16 __typeof__(*(ptr)) __o = (o); \
17{ 17 __typeof__(*(ptr)) __n = (n); \
18 unsigned long addr, old; 18 (__typeof__(*(ptr))) __sync_val_compare_and_swap((ptr),__o,__n);\
19 int shift;
20
21 switch (size) {
22 case 1:
23 addr = (unsigned long) ptr;
24 shift = (3 ^ (addr & 3)) << 3;
25 addr ^= addr & 3;
26 asm volatile(
27 " l %0,%4\n"
28 "0: lr 0,%0\n"
29 " nr 0,%3\n"
30 " or 0,%2\n"
31 " cs %0,0,%4\n"
32 " jl 0b\n"
33 : "=&d" (old), "=Q" (*(int *) addr)
34 : "d" ((x & 0xff) << shift), "d" (~(0xff << shift)),
35 "Q" (*(int *) addr) : "memory", "cc", "0");
36 return old >> shift;
37 case 2:
38 addr = (unsigned long) ptr;
39 shift = (2 ^ (addr & 2)) << 3;
40 addr ^= addr & 2;
41 asm volatile(
42 " l %0,%4\n"
43 "0: lr 0,%0\n"
44 " nr 0,%3\n"
45 " or 0,%2\n"
46 " cs %0,0,%4\n"
47 " jl 0b\n"
48 : "=&d" (old), "=Q" (*(int *) addr)
49 : "d" ((x & 0xffff) << shift), "d" (~(0xffff << shift)),
50 "Q" (*(int *) addr) : "memory", "cc", "0");
51 return old >> shift;
52 case 4:
53 asm volatile(
54 " l %0,%3\n"
55 "0: cs %0,%2,%3\n"
56 " jl 0b\n"
57 : "=&d" (old), "=Q" (*(int *) ptr)
58 : "d" (x), "Q" (*(int *) ptr)
59 : "memory", "cc");
60 return old;
61#ifdef CONFIG_64BIT
62 case 8:
63 asm volatile(
64 " lg %0,%3\n"
65 "0: csg %0,%2,%3\n"
66 " jl 0b\n"
67 : "=&d" (old), "=m" (*(long *) ptr)
68 : "d" (x), "Q" (*(long *) ptr)
69 : "memory", "cc");
70 return old;
71#endif /* CONFIG_64BIT */
72 }
73 __xchg_called_with_bad_pointer();
74 return x;
75}
76
77#define xchg(ptr, x) \
78({ \
79 __typeof__(*(ptr)) __ret; \
80 __ret = (__typeof__(*(ptr))) \
81 __xchg((unsigned long)(x), (void *)(ptr), sizeof(*(ptr)));\
82 __ret; \
83}) 19})
84 20
85/* 21#define cmpxchg64 cmpxchg
86 * Atomic compare and exchange. Compare OLD with MEM, if identical, 22#define cmpxchg_local cmpxchg
87 * store NEW in MEM. Return the initial value in MEM. Success is 23#define cmpxchg64_local cmpxchg
88 * indicated by comparing RETURN with OLD.
89 */
90
91#define __HAVE_ARCH_CMPXCHG
92
93extern void __cmpxchg_called_with_bad_pointer(void);
94
95static inline unsigned long __cmpxchg(void *ptr, unsigned long old,
96 unsigned long new, int size)
97{
98 unsigned long addr, prev, tmp;
99 int shift;
100
101 switch (size) {
102 case 1:
103 addr = (unsigned long) ptr;
104 shift = (3 ^ (addr & 3)) << 3;
105 addr ^= addr & 3;
106 asm volatile(
107 " l %0,%2\n"
108 "0: nr %0,%5\n"
109 " lr %1,%0\n"
110 " or %0,%3\n"
111 " or %1,%4\n"
112 " cs %0,%1,%2\n"
113 " jnl 1f\n"
114 " xr %1,%0\n"
115 " nr %1,%5\n"
116 " jnz 0b\n"
117 "1:"
118 : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr)
119 : "d" ((old & 0xff) << shift),
120 "d" ((new & 0xff) << shift),
121 "d" (~(0xff << shift))
122 : "memory", "cc");
123 return prev >> shift;
124 case 2:
125 addr = (unsigned long) ptr;
126 shift = (2 ^ (addr & 2)) << 3;
127 addr ^= addr & 2;
128 asm volatile(
129 " l %0,%2\n"
130 "0: nr %0,%5\n"
131 " lr %1,%0\n"
132 " or %0,%3\n"
133 " or %1,%4\n"
134 " cs %0,%1,%2\n"
135 " jnl 1f\n"
136 " xr %1,%0\n"
137 " nr %1,%5\n"
138 " jnz 0b\n"
139 "1:"
140 : "=&d" (prev), "=&d" (tmp), "+Q" (*(int *) addr)
141 : "d" ((old & 0xffff) << shift),
142 "d" ((new & 0xffff) << shift),
143 "d" (~(0xffff << shift))
144 : "memory", "cc");
145 return prev >> shift;
146 case 4:
147 asm volatile(
148 " cs %0,%3,%1\n"
149 : "=&d" (prev), "=Q" (*(int *) ptr)
150 : "0" (old), "d" (new), "Q" (*(int *) ptr)
151 : "memory", "cc");
152 return prev;
153#ifdef CONFIG_64BIT
154 case 8:
155 asm volatile(
156 " csg %0,%3,%1\n"
157 : "=&d" (prev), "=Q" (*(long *) ptr)
158 : "0" (old), "d" (new), "Q" (*(long *) ptr)
159 : "memory", "cc");
160 return prev;
161#endif /* CONFIG_64BIT */
162 }
163 __cmpxchg_called_with_bad_pointer();
164 return old;
165}
166
167#define cmpxchg(ptr, o, n) \
168({ \
169 __typeof__(*(ptr)) __ret; \
170 __ret = (__typeof__(*(ptr))) \
171 __cmpxchg((ptr), (unsigned long)(o), (unsigned long)(n), \
172 sizeof(*(ptr))); \
173 __ret; \
174})
175 24
176#ifdef CONFIG_64BIT 25#define xchg(ptr, x) \
177#define cmpxchg64(ptr, o, n) \
178({ \ 26({ \
179 cmpxchg((ptr), (o), (n)); \ 27 __typeof__(ptr) __ptr = (ptr); \
28 __typeof__(*(ptr)) __old; \
29 do { \
30 __old = *__ptr; \
31 } while (!__sync_bool_compare_and_swap(__ptr, __old, x)); \
32 __old; \
180}) 33})
181#else /* CONFIG_64BIT */
182static inline unsigned long long __cmpxchg64(void *ptr,
183 unsigned long long old,
184 unsigned long long new)
185{
186 register_pair rp_old = {.pair = old};
187 register_pair rp_new = {.pair = new};
188 unsigned long long *ullptr = ptr;
189 34
190 asm volatile( 35#define __HAVE_ARCH_CMPXCHG
191 " cds %0,%2,%1"
192 : "+d" (rp_old), "+Q" (*ullptr)
193 : "d" (rp_new)
194 : "memory", "cc");
195 return rp_old.pair;
196}
197
198#define cmpxchg64(ptr, o, n) \
199({ \
200 __typeof__(*(ptr)) __ret; \
201 __ret = (__typeof__(*(ptr))) \
202 __cmpxchg64((ptr), \
203 (unsigned long long)(o), \
204 (unsigned long long)(n)); \
205 __ret; \
206})
207#endif /* CONFIG_64BIT */
208 36
209#define __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, insn) \ 37#define __cmpxchg_double_op(p1, p2, o1, o2, n1, n2, insn) \
210({ \ 38({ \
@@ -265,40 +93,4 @@ extern void __cmpxchg_double_called_with_bad_pointer(void);
265 93
266#define system_has_cmpxchg_double() 1 94#define system_has_cmpxchg_double() 1
267 95
268#include <asm-generic/cmpxchg-local.h>
269
270static inline unsigned long __cmpxchg_local(void *ptr,
271 unsigned long old,
272 unsigned long new, int size)
273{
274 switch (size) {
275 case 1:
276 case 2:
277 case 4:
278#ifdef CONFIG_64BIT
279 case 8:
280#endif
281 return __cmpxchg(ptr, old, new, size);
282 default:
283 return __cmpxchg_local_generic(ptr, old, new, size);
284 }
285
286 return old;
287}
288
289/*
290 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
291 * them available.
292 */
293#define cmpxchg_local(ptr, o, n) \
294({ \
295 __typeof__(*(ptr)) __ret; \
296 __ret = (__typeof__(*(ptr))) \
297 __cmpxchg_local((ptr), (unsigned long)(o), \
298 (unsigned long)(n), sizeof(*(ptr))); \
299 __ret; \
300})
301
302#define cmpxchg64_local(ptr, o, n) cmpxchg64((ptr), (o), (n))
303
304#endif /* __ASM_CMPXCHG_H */ 96#endif /* __ASM_CMPXCHG_H */
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index f8c196984853..b91e960e4045 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -10,6 +10,8 @@
10#include <linux/types.h> 10#include <linux/types.h>
11#include <asm/div64.h> 11#include <asm/div64.h>
12 12
13#define CPUTIME_PER_USEC 4096ULL
14#define CPUTIME_PER_SEC (CPUTIME_PER_USEC * USEC_PER_SEC)
13 15
14/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ 16/* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */
15 17
@@ -38,24 +40,24 @@ static inline unsigned long __div(unsigned long long n, unsigned long base)
38 */ 40 */
39static inline unsigned long cputime_to_jiffies(const cputime_t cputime) 41static inline unsigned long cputime_to_jiffies(const cputime_t cputime)
40{ 42{
41 return __div((__force unsigned long long) cputime, 4096000000ULL / HZ); 43 return __div((__force unsigned long long) cputime, CPUTIME_PER_SEC / HZ);
42} 44}
43 45
44static inline cputime_t jiffies_to_cputime(const unsigned int jif) 46static inline cputime_t jiffies_to_cputime(const unsigned int jif)
45{ 47{
46 return (__force cputime_t)(jif * (4096000000ULL / HZ)); 48 return (__force cputime_t)(jif * (CPUTIME_PER_SEC / HZ));
47} 49}
48 50
49static inline u64 cputime64_to_jiffies64(cputime64_t cputime) 51static inline u64 cputime64_to_jiffies64(cputime64_t cputime)
50{ 52{
51 unsigned long long jif = (__force unsigned long long) cputime; 53 unsigned long long jif = (__force unsigned long long) cputime;
52 do_div(jif, 4096000000ULL / HZ); 54 do_div(jif, CPUTIME_PER_SEC / HZ);
53 return jif; 55 return jif;
54} 56}
55 57
56static inline cputime64_t jiffies64_to_cputime64(const u64 jif) 58static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
57{ 59{
58 return (__force cputime64_t)(jif * (4096000000ULL / HZ)); 60 return (__force cputime64_t)(jif * (CPUTIME_PER_SEC / HZ));
59} 61}
60 62
61/* 63/*
@@ -68,7 +70,7 @@ static inline unsigned int cputime_to_usecs(const cputime_t cputime)
68 70
69static inline cputime_t usecs_to_cputime(const unsigned int m) 71static inline cputime_t usecs_to_cputime(const unsigned int m)
70{ 72{
71 return (__force cputime_t)(m * 4096ULL); 73 return (__force cputime_t)(m * CPUTIME_PER_USEC);
72} 74}
73 75
74#define usecs_to_cputime64(m) usecs_to_cputime(m) 76#define usecs_to_cputime64(m) usecs_to_cputime(m)
@@ -78,12 +80,12 @@ static inline cputime_t usecs_to_cputime(const unsigned int m)
78 */ 80 */
79static inline unsigned int cputime_to_secs(const cputime_t cputime) 81static inline unsigned int cputime_to_secs(const cputime_t cputime)
80{ 82{
81 return __div((__force unsigned long long) cputime, 2048000000) >> 1; 83 return __div((__force unsigned long long) cputime, CPUTIME_PER_SEC / 2) >> 1;
82} 84}
83 85
84static inline cputime_t secs_to_cputime(const unsigned int s) 86static inline cputime_t secs_to_cputime(const unsigned int s)
85{ 87{
86 return (__force cputime_t)(s * 4096000000ULL); 88 return (__force cputime_t)(s * CPUTIME_PER_SEC);
87} 89}
88 90
89/* 91/*
@@ -91,8 +93,8 @@ static inline cputime_t secs_to_cputime(const unsigned int s)
91 */ 93 */
92static inline cputime_t timespec_to_cputime(const struct timespec *value) 94static inline cputime_t timespec_to_cputime(const struct timespec *value)
93{ 95{
94 unsigned long long ret = value->tv_sec * 4096000000ULL; 96 unsigned long long ret = value->tv_sec * CPUTIME_PER_SEC;
95 return (__force cputime_t)(ret + value->tv_nsec * 4096 / 1000); 97 return (__force cputime_t)(ret + __div(value->tv_nsec * CPUTIME_PER_USEC, NSEC_PER_USEC));
96} 98}
97 99
98static inline void cputime_to_timespec(const cputime_t cputime, 100static inline void cputime_to_timespec(const cputime_t cputime,
@@ -103,12 +105,12 @@ static inline void cputime_to_timespec(const cputime_t cputime,
103 register_pair rp; 105 register_pair rp;
104 106
105 rp.pair = __cputime >> 1; 107 rp.pair = __cputime >> 1;
106 asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); 108 asm ("dr %0,%1" : "+d" (rp) : "d" (CPUTIME_PER_SEC / 2));
107 value->tv_nsec = rp.subreg.even * 1000 / 4096; 109 value->tv_nsec = rp.subreg.even * NSEC_PER_USEC / CPUTIME_PER_USEC;
108 value->tv_sec = rp.subreg.odd; 110 value->tv_sec = rp.subreg.odd;
109#else 111#else
110 value->tv_nsec = (__cputime % 4096000000ULL) * 1000 / 4096; 112 value->tv_nsec = (__cputime % CPUTIME_PER_SEC) * NSEC_PER_USEC / CPUTIME_PER_USEC;
111 value->tv_sec = __cputime / 4096000000ULL; 113 value->tv_sec = __cputime / CPUTIME_PER_SEC;
112#endif 114#endif
113} 115}
114 116
@@ -119,8 +121,8 @@ static inline void cputime_to_timespec(const cputime_t cputime,
119 */ 121 */
120static inline cputime_t timeval_to_cputime(const struct timeval *value) 122static inline cputime_t timeval_to_cputime(const struct timeval *value)
121{ 123{
122 unsigned long long ret = value->tv_sec * 4096000000ULL; 124 unsigned long long ret = value->tv_sec * CPUTIME_PER_SEC;
123 return (__force cputime_t)(ret + value->tv_usec * 4096ULL); 125 return (__force cputime_t)(ret + value->tv_usec * CPUTIME_PER_USEC);
124} 126}
125 127
126static inline void cputime_to_timeval(const cputime_t cputime, 128static inline void cputime_to_timeval(const cputime_t cputime,
@@ -131,12 +133,12 @@ static inline void cputime_to_timeval(const cputime_t cputime,
131 register_pair rp; 133 register_pair rp;
132 134
133 rp.pair = __cputime >> 1; 135 rp.pair = __cputime >> 1;
134 asm ("dr %0,%1" : "+d" (rp) : "d" (2048000000UL)); 136 asm ("dr %0,%1" : "+d" (rp) : "d" (CPUTIME_PER_USEC / 2));
135 value->tv_usec = rp.subreg.even / 4096; 137 value->tv_usec = rp.subreg.even / CPUTIME_PER_USEC;
136 value->tv_sec = rp.subreg.odd; 138 value->tv_sec = rp.subreg.odd;
137#else 139#else
138 value->tv_usec = (__cputime % 4096000000ULL) / 4096; 140 value->tv_usec = (__cputime % CPUTIME_PER_SEC) / CPUTIME_PER_USEC;
139 value->tv_sec = __cputime / 4096000000ULL; 141 value->tv_sec = __cputime / CPUTIME_PER_SEC;
140#endif 142#endif
141} 143}
142 144
@@ -146,13 +148,13 @@ static inline void cputime_to_timeval(const cputime_t cputime,
146static inline clock_t cputime_to_clock_t(cputime_t cputime) 148static inline clock_t cputime_to_clock_t(cputime_t cputime)
147{ 149{
148 unsigned long long clock = (__force unsigned long long) cputime; 150 unsigned long long clock = (__force unsigned long long) cputime;
149 do_div(clock, 4096000000ULL / USER_HZ); 151 do_div(clock, CPUTIME_PER_SEC / USER_HZ);
150 return clock; 152 return clock;
151} 153}
152 154
153static inline cputime_t clock_t_to_cputime(unsigned long x) 155static inline cputime_t clock_t_to_cputime(unsigned long x)
154{ 156{
155 return (__force cputime_t)(x * (4096000000ULL / USER_HZ)); 157 return (__force cputime_t)(x * (CPUTIME_PER_SEC / USER_HZ));
156} 158}
157 159
158/* 160/*
@@ -161,7 +163,7 @@ static inline cputime_t clock_t_to_cputime(unsigned long x)
161static inline clock_t cputime64_to_clock_t(cputime64_t cputime) 163static inline clock_t cputime64_to_clock_t(cputime64_t cputime)
162{ 164{
163 unsigned long long clock = (__force unsigned long long) cputime; 165 unsigned long long clock = (__force unsigned long long) cputime;
164 do_div(clock, 4096000000ULL / USER_HZ); 166 do_div(clock, CPUTIME_PER_SEC / USER_HZ);
165 return clock; 167 return clock;
166} 168}
167 169
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
index 530c15eb01e9..0206c8052328 100644
--- a/arch/s390/include/asm/debug.h
+++ b/arch/s390/include/asm/debug.h
@@ -151,9 +151,21 @@ debug_text_event(debug_info_t* id, int level, const char* txt)
151 * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! 151 * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details!
152 */ 152 */
153extern debug_entry_t * 153extern debug_entry_t *
154debug_sprintf_event(debug_info_t* id,int level,char *string,...) 154__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
155 __attribute__ ((format(printf, 3, 4))); 155 __attribute__ ((format(printf, 3, 4)));
156 156
157#define debug_sprintf_event(_id, _level, _fmt, ...) \
158({ \
159 debug_entry_t *__ret; \
160 debug_info_t *__id = _id; \
161 int __level = _level; \
162 if ((!__id) || (__level > __id->level)) \
163 __ret = NULL; \
164 else \
165 __ret = __debug_sprintf_event(__id, __level, \
166 _fmt, ## __VA_ARGS__); \
167 __ret; \
168})
157 169
158static inline debug_entry_t* 170static inline debug_entry_t*
159debug_exception(debug_info_t* id, int level, void* data, int length) 171debug_exception(debug_info_t* id, int level, void* data, int length)
@@ -194,9 +206,22 @@ debug_text_exception(debug_info_t* id, int level, const char* txt)
194 * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! 206 * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details!
195 */ 207 */
196extern debug_entry_t * 208extern debug_entry_t *
197debug_sprintf_exception(debug_info_t* id,int level,char *string,...) 209__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
198 __attribute__ ((format(printf, 3, 4))); 210 __attribute__ ((format(printf, 3, 4)));
199 211
212#define debug_sprintf_exception(_id, _level, _fmt, ...) \
213({ \
214 debug_entry_t *__ret; \
215 debug_info_t *__id = _id; \
216 int __level = _level; \
217 if ((!__id) || (__level > __id->level)) \
218 __ret = NULL; \
219 else \
220 __ret = __debug_sprintf_exception(__id, __level, \
221 _fmt, ## __VA_ARGS__);\
222 __ret; \
223})
224
200int debug_register_view(debug_info_t* id, struct debug_view* view); 225int debug_register_view(debug_info_t* id, struct debug_view* view);
201int debug_unregister_view(debug_info_t* id, struct debug_view* view); 226int debug_unregister_view(debug_info_t* id, struct debug_view* view);
202 227
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
index 3aef8afec336..abb618f1ead2 100644
--- a/arch/s390/include/asm/ftrace.h
+++ b/arch/s390/include/asm/ftrace.h
@@ -1,25 +1,69 @@
1#ifndef _ASM_S390_FTRACE_H 1#ifndef _ASM_S390_FTRACE_H
2#define _ASM_S390_FTRACE_H 2#define _ASM_S390_FTRACE_H
3 3
4#define ARCH_SUPPORTS_FTRACE_OPS 1
5
6#define MCOUNT_INSN_SIZE 24
7#define MCOUNT_RETURN_FIXUP 18
8
4#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
5 10
6extern void _mcount(void); 11#define ftrace_return_address(n) __builtin_return_address(n)
12
13void _mcount(void);
14void ftrace_caller(void);
15
7extern char ftrace_graph_caller_end; 16extern char ftrace_graph_caller_end;
17extern unsigned long ftrace_plt;
8 18
9struct dyn_arch_ftrace { }; 19struct dyn_arch_ftrace { };
10 20
11#define MCOUNT_ADDR ((long)_mcount) 21#define MCOUNT_ADDR ((unsigned long)_mcount)
22#define FTRACE_ADDR ((unsigned long)ftrace_caller)
12 23
24#define KPROBE_ON_FTRACE_NOP 0
25#define KPROBE_ON_FTRACE_CALL 1
13 26
14static inline unsigned long ftrace_call_adjust(unsigned long addr) 27static inline unsigned long ftrace_call_adjust(unsigned long addr)
15{ 28{
16 return addr; 29 return addr;
17} 30}
18 31
19#endif /* __ASSEMBLY__ */ 32struct ftrace_insn {
33 u16 opc;
34 s32 disp;
35} __packed;
36
37static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn)
38{
39#ifdef CONFIG_FUNCTION_TRACER
40 /* jg .+24 */
41 insn->opc = 0xc0f4;
42 insn->disp = MCOUNT_INSN_SIZE / 2;
43#endif
44}
20 45
21#define MCOUNT_INSN_SIZE 18 46static inline int is_ftrace_nop(struct ftrace_insn *insn)
47{
48#ifdef CONFIG_FUNCTION_TRACER
49 if (insn->disp == MCOUNT_INSN_SIZE / 2)
50 return 1;
51#endif
52 return 0;
53}
22 54
23#define ARCH_SUPPORTS_FTRACE_OPS 1 55static inline void ftrace_generate_call_insn(struct ftrace_insn *insn,
56 unsigned long ip)
57{
58#ifdef CONFIG_FUNCTION_TRACER
59 unsigned long target;
60
61 /* brasl r0,ftrace_caller */
62 target = is_module_addr((void *) ip) ? ftrace_plt : FTRACE_ADDR;
63 insn->opc = 0xc005;
64 insn->disp = (target - ip) / 2;
65#endif
66}
24 67
68#endif /* __ASSEMBLY__ */
25#endif /* _ASM_S390_FTRACE_H */ 69#endif /* _ASM_S390_FTRACE_H */
diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h
index 6af037f574b8..113cd963dbbe 100644
--- a/arch/s390/include/asm/idle.h
+++ b/arch/s390/include/asm/idle.h
@@ -9,9 +9,10 @@
9 9
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/seqlock.h>
12 13
13struct s390_idle_data { 14struct s390_idle_data {
14 unsigned int sequence; 15 seqcount_t seqcount;
15 unsigned long long idle_count; 16 unsigned long long idle_count;
16 unsigned long long idle_time; 17 unsigned long long idle_time;
17 unsigned long long clock_idle_enter; 18 unsigned long long clock_idle_enter;
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index 6ad9013c67e7..30fd5c84680e 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -39,6 +39,15 @@ static inline void iounmap(volatile void __iomem *addr)
39{ 39{
40} 40}
41 41
42static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
43{
44 return NULL;
45}
46
47static inline void ioport_unmap(void __iomem *p)
48{
49}
50
42/* 51/*
43 * s390 needs a private implementation of pci_iomap since ioremap with its 52 * s390 needs a private implementation of pci_iomap since ioremap with its
44 * offset parameter isn't sufficient. That's because BAR spaces are not 53 * offset parameter isn't sufficient. That's because BAR spaces are not
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index b0d5f0a97a01..343ea7c987aa 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -1,11 +1,11 @@
1#ifndef _ASM_IRQ_H 1#ifndef _ASM_IRQ_H
2#define _ASM_IRQ_H 2#define _ASM_IRQ_H
3 3
4#define EXT_INTERRUPT 1 4#define EXT_INTERRUPT 0
5#define IO_INTERRUPT 2 5#define IO_INTERRUPT 1
6#define THIN_INTERRUPT 3 6#define THIN_INTERRUPT 2
7 7
8#define NR_IRQS_BASE 4 8#define NR_IRQS_BASE 3
9 9
10#ifdef CONFIG_PCI_NR_MSI 10#ifdef CONFIG_PCI_NR_MSI
11# define NR_IRQS (NR_IRQS_BASE + CONFIG_PCI_NR_MSI) 11# define NR_IRQS (NR_IRQS_BASE + CONFIG_PCI_NR_MSI)
@@ -13,9 +13,6 @@
13# define NR_IRQS NR_IRQS_BASE 13# define NR_IRQS NR_IRQS_BASE
14#endif 14#endif
15 15
16/* This number is used when no interrupt has been assigned */
17#define NO_IRQ 0
18
19/* External interruption codes */ 16/* External interruption codes */
20#define EXT_IRQ_INTERRUPT_KEY 0x0040 17#define EXT_IRQ_INTERRUPT_KEY 0x0040
21#define EXT_IRQ_CLK_COMP 0x1004 18#define EXT_IRQ_CLK_COMP 0x1004
diff --git a/arch/s390/include/asm/kprobes.h b/arch/s390/include/asm/kprobes.h
index 98629173ce3b..b47ad3b642cc 100644
--- a/arch/s390/include/asm/kprobes.h
+++ b/arch/s390/include/asm/kprobes.h
@@ -60,6 +60,7 @@ typedef u16 kprobe_opcode_t;
60struct arch_specific_insn { 60struct arch_specific_insn {
61 /* copy of original instruction */ 61 /* copy of original instruction */
62 kprobe_opcode_t *insn; 62 kprobe_opcode_t *insn;
63 unsigned int is_ftrace_insn : 1;
63}; 64};
64 65
65struct prev_kprobe { 66struct prev_kprobe {
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 6cc51fe84410..34fbcac61133 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -147,7 +147,7 @@ struct _lowcore {
147 __u32 softirq_pending; /* 0x02ec */ 147 __u32 softirq_pending; /* 0x02ec */
148 __u32 percpu_offset; /* 0x02f0 */ 148 __u32 percpu_offset; /* 0x02f0 */
149 __u32 machine_flags; /* 0x02f4 */ 149 __u32 machine_flags; /* 0x02f4 */
150 __u32 ftrace_func; /* 0x02f8 */ 150 __u8 pad_0x02f8[0x02fc-0x02f8]; /* 0x02f8 */
151 __u32 spinlock_lockval; /* 0x02fc */ 151 __u32 spinlock_lockval; /* 0x02fc */
152 152
153 __u8 pad_0x0300[0x0e00-0x0300]; /* 0x0300 */ 153 __u8 pad_0x0300[0x0e00-0x0300]; /* 0x0300 */
@@ -297,7 +297,7 @@ struct _lowcore {
297 __u64 percpu_offset; /* 0x0378 */ 297 __u64 percpu_offset; /* 0x0378 */
298 __u64 vdso_per_cpu_data; /* 0x0380 */ 298 __u64 vdso_per_cpu_data; /* 0x0380 */
299 __u64 machine_flags; /* 0x0388 */ 299 __u64 machine_flags; /* 0x0388 */
300 __u64 ftrace_func; /* 0x0390 */ 300 __u8 pad_0x0390[0x0398-0x0390]; /* 0x0390 */
301 __u64 gmap; /* 0x0398 */ 301 __u64 gmap; /* 0x0398 */
302 __u32 spinlock_lockval; /* 0x03a0 */ 302 __u32 spinlock_lockval; /* 0x03a0 */
303 __u8 pad_0x03a0[0x0400-0x03a4]; /* 0x03a4 */ 303 __u8 pad_0x03a0[0x0400-0x03a4]; /* 0x03a4 */
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index c030900320e0..ef803c202d42 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -50,10 +50,6 @@ struct zpci_fmb {
50 atomic64_t unmapped_pages; 50 atomic64_t unmapped_pages;
51} __packed __aligned(16); 51} __packed __aligned(16);
52 52
53#define ZPCI_MSI_VEC_BITS 11
54#define ZPCI_MSI_VEC_MAX (1 << ZPCI_MSI_VEC_BITS)
55#define ZPCI_MSI_VEC_MASK (ZPCI_MSI_VEC_MAX - 1)
56
57enum zpci_state { 53enum zpci_state {
58 ZPCI_FN_STATE_RESERVED, 54 ZPCI_FN_STATE_RESERVED,
59 ZPCI_FN_STATE_STANDBY, 55 ZPCI_FN_STATE_STANDBY,
@@ -90,6 +86,7 @@ struct zpci_dev {
90 86
91 /* IRQ stuff */ 87 /* IRQ stuff */
92 u64 msi_addr; /* MSI address */ 88 u64 msi_addr; /* MSI address */
89 unsigned int max_msi; /* maximum number of MSI's */
93 struct airq_iv *aibv; /* adapter interrupt bit vector */ 90 struct airq_iv *aibv; /* adapter interrupt bit vector */
94 unsigned int aisb; /* number of the summary bit */ 91 unsigned int aisb; /* number of the summary bit */
95 92
diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h
index d194d544d694..f664e96f48c7 100644
--- a/arch/s390/include/asm/pci_io.h
+++ b/arch/s390/include/asm/pci_io.h
@@ -139,7 +139,8 @@ static inline int zpci_memcpy_fromio(void *dst,
139 int size, rc = 0; 139 int size, rc = 0;
140 140
141 while (n > 0) { 141 while (n > 0) {
142 size = zpci_get_max_write_size((u64) src, (u64) dst, n, 8); 142 size = zpci_get_max_write_size((u64 __force) src,
143 (u64) dst, n, 8);
143 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); 144 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size);
144 rc = zpci_read_single(req, dst, offset, size); 145 rc = zpci_read_single(req, dst, offset, size);
145 if (rc) 146 if (rc)
@@ -162,7 +163,8 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst,
162 return -EINVAL; 163 return -EINVAL;
163 164
164 while (n > 0) { 165 while (n > 0) {
165 size = zpci_get_max_write_size((u64) dst, (u64) src, n, 128); 166 size = zpci_get_max_write_size((u64 __force) dst,
167 (u64) src, n, 128);
166 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); 168 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size);
167 169
168 if (size > 8) /* main path */ 170 if (size > 8) /* main path */
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index d39a31c3cdf2..e510b9460efa 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -22,8 +22,6 @@ unsigned long *page_table_alloc(struct mm_struct *);
22void page_table_free(struct mm_struct *, unsigned long *); 22void page_table_free(struct mm_struct *, unsigned long *);
23void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long); 23void page_table_free_rcu(struct mmu_gather *, unsigned long *, unsigned long);
24 24
25void page_table_reset_pgste(struct mm_struct *, unsigned long, unsigned long,
26 bool init_skey);
27int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, 25int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
28 unsigned long key, bool nq); 26 unsigned long key, bool nq);
29 27
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 57c882761dea..5e102422c9ab 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -133,6 +133,18 @@ extern unsigned long MODULES_END;
133#define MODULES_LEN (1UL << 31) 133#define MODULES_LEN (1UL << 31)
134#endif 134#endif
135 135
136static inline int is_module_addr(void *addr)
137{
138#ifdef CONFIG_64BIT
139 BUILD_BUG_ON(MODULES_LEN > (1UL << 31));
140 if (addr < (void *)MODULES_VADDR)
141 return 0;
142 if (addr > (void *)MODULES_END)
143 return 0;
144#endif
145 return 1;
146}
147
136/* 148/*
137 * A 31 bit pagetable entry of S390 has following format: 149 * A 31 bit pagetable entry of S390 has following format:
138 * | PFRA | | OS | 150 * | PFRA | | OS |
@@ -479,6 +491,11 @@ static inline int mm_has_pgste(struct mm_struct *mm)
479 return 0; 491 return 0;
480} 492}
481 493
494/*
495 * In the case that a guest uses storage keys
496 * faults should no longer be backed by zero pages
497 */
498#define mm_forbids_zeropage mm_use_skey
482static inline int mm_use_skey(struct mm_struct *mm) 499static inline int mm_use_skey(struct mm_struct *mm)
483{ 500{
484#ifdef CONFIG_PGSTE 501#ifdef CONFIG_PGSTE
@@ -1634,6 +1651,19 @@ static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
1634 return pmd; 1651 return pmd;
1635} 1652}
1636 1653
1654#define __HAVE_ARCH_PMDP_GET_AND_CLEAR_FULL
1655static inline pmd_t pmdp_get_and_clear_full(struct mm_struct *mm,
1656 unsigned long address,
1657 pmd_t *pmdp, int full)
1658{
1659 pmd_t pmd = *pmdp;
1660
1661 if (!full)
1662 pmdp_flush_lazy(mm, address, pmdp);
1663 pmd_clear(pmdp);
1664 return pmd;
1665}
1666
1637#define __HAVE_ARCH_PMDP_CLEAR_FLUSH 1667#define __HAVE_ARCH_PMDP_CLEAR_FLUSH
1638static inline pmd_t pmdp_clear_flush(struct vm_area_struct *vma, 1668static inline pmd_t pmdp_clear_flush(struct vm_area_struct *vma,
1639 unsigned long address, pmd_t *pmdp) 1669 unsigned long address, pmd_t *pmdp)
@@ -1746,7 +1776,8 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
1746extern int vmem_add_mapping(unsigned long start, unsigned long size); 1776extern int vmem_add_mapping(unsigned long start, unsigned long size);
1747extern int vmem_remove_mapping(unsigned long start, unsigned long size); 1777extern int vmem_remove_mapping(unsigned long start, unsigned long size);
1748extern int s390_enable_sie(void); 1778extern int s390_enable_sie(void);
1749extern void s390_enable_skey(void); 1779extern int s390_enable_skey(void);
1780extern void s390_reset_cmma(struct mm_struct *mm);
1750 1781
1751/* 1782/*
1752 * No page table caches to initialise 1783 * No page table caches to initialise
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index d559bdb03d18..bed05ea7ec27 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -217,8 +217,6 @@ static inline unsigned short stap(void)
217 */ 217 */
218static inline void cpu_relax(void) 218static inline void cpu_relax(void)
219{ 219{
220 if (MACHINE_HAS_DIAG44)
221 asm volatile("diag 0,0,68");
222 barrier(); 220 barrier();
223} 221}
224 222
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index d6bdf906caa5..0e37cd041241 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -18,14 +18,7 @@ extern int spin_retry;
18static inline int 18static inline int
19_raw_compare_and_swap(unsigned int *lock, unsigned int old, unsigned int new) 19_raw_compare_and_swap(unsigned int *lock, unsigned int old, unsigned int new)
20{ 20{
21 unsigned int old_expected = old; 21 return __sync_bool_compare_and_swap(lock, old, new);
22
23 asm volatile(
24 " cs %0,%3,%1"
25 : "=d" (old), "=Q" (*lock)
26 : "0" (old), "d" (new), "Q" (*lock)
27 : "cc", "memory" );
28 return old == old_expected;
29} 22}
30 23
31/* 24/*
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index 572c59949004..06d8741ad6f4 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -121,6 +121,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
121#ifdef CONFIG_64BIT 121#ifdef CONFIG_64BIT
122 if (tlb->mm->context.asce_limit <= (1UL << 31)) 122 if (tlb->mm->context.asce_limit <= (1UL << 31))
123 return; 123 return;
124 pgtable_pmd_page_dtor(virt_to_page(pmd));
124 tlb_remove_table(tlb, pmd); 125 tlb_remove_table(tlb, pmd);
125#endif 126#endif
126} 127}
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
index 4197c89c52d4..2b446cf0cc65 100644
--- a/arch/s390/include/uapi/asm/unistd.h
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -287,7 +287,9 @@
287#define __NR_getrandom 349 287#define __NR_getrandom 349
288#define __NR_memfd_create 350 288#define __NR_memfd_create 350
289#define __NR_bpf 351 289#define __NR_bpf 351
290#define NR_syscalls 352 290#define __NR_s390_pci_mmio_write 352
291#define __NR_s390_pci_mmio_read 353
292#define NR_syscalls 354
291 293
292/* 294/*
293 * There are some system calls that are not present on 64 bit, some 295 * There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index ef279a136801..e07e91605353 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -17,8 +17,8 @@
17 * Make sure that the compiler is new enough. We want a compiler that 17 * Make sure that the compiler is new enough. We want a compiler that
18 * is known to work with the "Q" assembler constraint. 18 * is known to work with the "Q" assembler constraint.
19 */ 19 */
20#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) 20#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
21#error Your compiler is too old; please use version 3.3.3 or newer 21#error Your compiler is too old; please use version 4.3 or newer
22#endif 22#endif
23 23
24int main(void) 24int main(void)
@@ -156,7 +156,6 @@ int main(void)
156 DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock)); 156 DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
157 DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); 157 DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
158 DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); 158 DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
159 DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
160 DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib)); 159 DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
161 BLANK(); 160 BLANK();
162 DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); 161 DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 009f5eb11125..34d5fa7b01b5 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -434,7 +434,7 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
434 ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE; 434 ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
435 } else { 435 } else {
436 /* Signal frames without vectors registers are short ! */ 436 /* Signal frames without vectors registers are short ! */
437 __u16 __user *svc = (void *) frame + frame_size - 2; 437 __u16 __user *svc = (void __user *) frame + frame_size - 2;
438 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc)) 438 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
439 return -EFAULT; 439 return -EFAULT;
440 restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE; 440 restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c
index c4f7a3d655b8..d7fa2f0f1425 100644
--- a/arch/s390/kernel/compat_wrapper.c
+++ b/arch/s390/kernel/compat_wrapper.c
@@ -218,3 +218,5 @@ COMPAT_SYSCALL_WRAP3(seccomp, unsigned int, op, unsigned int, flags, const char
218COMPAT_SYSCALL_WRAP3(getrandom, char __user *, buf, size_t, count, unsigned int, flags) 218COMPAT_SYSCALL_WRAP3(getrandom, char __user *, buf, size_t, count, unsigned int, flags)
219COMPAT_SYSCALL_WRAP2(memfd_create, const char __user *, uname, unsigned int, flags) 219COMPAT_SYSCALL_WRAP2(memfd_create, const char __user *, uname, unsigned int, flags)
220COMPAT_SYSCALL_WRAP3(bpf, int, cmd, union bpf_attr *, attr, unsigned int, size); 220COMPAT_SYSCALL_WRAP3(bpf, int, cmd, union bpf_attr *, attr, unsigned int, size);
221COMPAT_SYSCALL_WRAP3(s390_pci_mmio_write, const unsigned long, mmio_addr, const void __user *, user_buffer, const size_t, length);
222COMPAT_SYSCALL_WRAP3(s390_pci_mmio_read, const unsigned long, mmio_addr, void __user *, user_buffer, const size_t, length);
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index ee8390da6ea7..c1f21aca76e7 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -1019,7 +1019,7 @@ debug_count_numargs(char *string)
1019 */ 1019 */
1020 1020
1021debug_entry_t* 1021debug_entry_t*
1022debug_sprintf_event(debug_info_t* id, int level,char *string,...) 1022__debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
1023{ 1023{
1024 va_list ap; 1024 va_list ap;
1025 int numargs,idx; 1025 int numargs,idx;
@@ -1027,8 +1027,6 @@ debug_sprintf_event(debug_info_t* id, int level,char *string,...)
1027 debug_sprintf_entry_t *curr_event; 1027 debug_sprintf_entry_t *curr_event;
1028 debug_entry_t *active; 1028 debug_entry_t *active;
1029 1029
1030 if((!id) || (level > id->level))
1031 return NULL;
1032 if (!debug_active || !id->areas) 1030 if (!debug_active || !id->areas)
1033 return NULL; 1031 return NULL;
1034 numargs=debug_count_numargs(string); 1032 numargs=debug_count_numargs(string);
@@ -1050,14 +1048,14 @@ debug_sprintf_event(debug_info_t* id, int level,char *string,...)
1050 1048
1051 return active; 1049 return active;
1052} 1050}
1053EXPORT_SYMBOL(debug_sprintf_event); 1051EXPORT_SYMBOL(__debug_sprintf_event);
1054 1052
1055/* 1053/*
1056 * debug_sprintf_exception: 1054 * debug_sprintf_exception:
1057 */ 1055 */
1058 1056
1059debug_entry_t* 1057debug_entry_t*
1060debug_sprintf_exception(debug_info_t* id, int level,char *string,...) 1058__debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
1061{ 1059{
1062 va_list ap; 1060 va_list ap;
1063 int numargs,idx; 1061 int numargs,idx;
@@ -1065,8 +1063,6 @@ debug_sprintf_exception(debug_info_t* id, int level,char *string,...)
1065 debug_sprintf_entry_t *curr_event; 1063 debug_sprintf_entry_t *curr_event;
1066 debug_entry_t *active; 1064 debug_entry_t *active;
1067 1065
1068 if((!id) || (level > id->level))
1069 return NULL;
1070 if (!debug_active || !id->areas) 1066 if (!debug_active || !id->areas)
1071 return NULL; 1067 return NULL;
1072 1068
@@ -1089,7 +1085,7 @@ debug_sprintf_exception(debug_info_t* id, int level,char *string,...)
1089 1085
1090 return active; 1086 return active;
1091} 1087}
1092EXPORT_SYMBOL(debug_sprintf_exception); 1088EXPORT_SYMBOL(__debug_sprintf_exception);
1093 1089
1094/* 1090/*
1095 * debug_register_view: 1091 * debug_register_view:
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index acb412442e5e..a99852e96a77 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -191,7 +191,8 @@ void die(struct pt_regs *regs, const char *str)
191 console_verbose(); 191 console_verbose();
192 spin_lock_irq(&die_lock); 192 spin_lock_irq(&die_lock);
193 bust_spinlocks(1); 193 bust_spinlocks(1);
194 printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); 194 printk("%s: %04x ilc:%d [#%d] ", str, regs->int_code & 0xffff,
195 regs->int_code >> 17, ++die_counter);
195#ifdef CONFIG_PREEMPT 196#ifdef CONFIG_PREEMPT
196 printk("PREEMPT "); 197 printk("PREEMPT ");
197#endif 198#endif
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index cef2879edff3..302ac1f7f8e7 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -12,7 +12,6 @@
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/string.h> 13#include <linux/string.h>
14#include <linux/ctype.h> 14#include <linux/ctype.h>
15#include <linux/ftrace.h>
16#include <linux/lockdep.h> 15#include <linux/lockdep.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/pfn.h> 17#include <linux/pfn.h>
@@ -490,8 +489,5 @@ void __init startup_init(void)
490 detect_machine_facilities(); 489 detect_machine_facilities();
491 setup_topology(); 490 setup_topology();
492 sclp_early_detect(); 491 sclp_early_detect();
493#ifdef CONFIG_DYNAMIC_FTRACE
494 S390_lowcore.ftrace_func = (unsigned long)ftrace_caller;
495#endif
496 lockdep_on(); 492 lockdep_on();
497} 493}
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 70203265196f..398329b2b518 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -53,7 +53,7 @@ _PIF_WORK = (_PIF_PER_TRAP)
53 .macro TRACE_IRQS_ON 53 .macro TRACE_IRQS_ON
54#ifdef CONFIG_TRACE_IRQFLAGS 54#ifdef CONFIG_TRACE_IRQFLAGS
55 basr %r2,%r0 55 basr %r2,%r0
56 l %r1,BASED(.Lhardirqs_on) 56 l %r1,BASED(.Lc_hardirqs_on)
57 basr %r14,%r1 # call trace_hardirqs_on_caller 57 basr %r14,%r1 # call trace_hardirqs_on_caller
58#endif 58#endif
59 .endm 59 .endm
@@ -61,7 +61,7 @@ _PIF_WORK = (_PIF_PER_TRAP)
61 .macro TRACE_IRQS_OFF 61 .macro TRACE_IRQS_OFF
62#ifdef CONFIG_TRACE_IRQFLAGS 62#ifdef CONFIG_TRACE_IRQFLAGS
63 basr %r2,%r0 63 basr %r2,%r0
64 l %r1,BASED(.Lhardirqs_off) 64 l %r1,BASED(.Lc_hardirqs_off)
65 basr %r14,%r1 # call trace_hardirqs_off_caller 65 basr %r14,%r1 # call trace_hardirqs_off_caller
66#endif 66#endif
67 .endm 67 .endm
@@ -70,7 +70,7 @@ _PIF_WORK = (_PIF_PER_TRAP)
70#ifdef CONFIG_LOCKDEP 70#ifdef CONFIG_LOCKDEP
71 tm __PT_PSW+1(%r11),0x01 # returning to user ? 71 tm __PT_PSW+1(%r11),0x01 # returning to user ?
72 jz .+10 72 jz .+10
73 l %r1,BASED(.Llockdep_sys_exit) 73 l %r1,BASED(.Lc_lockdep_sys_exit)
74 basr %r14,%r1 # call lockdep_sys_exit 74 basr %r14,%r1 # call lockdep_sys_exit
75#endif 75#endif
76 .endm 76 .endm
@@ -87,8 +87,8 @@ _PIF_WORK = (_PIF_PER_TRAP)
87 tmh %r8,0x0001 # interrupting from user ? 87 tmh %r8,0x0001 # interrupting from user ?
88 jnz 1f 88 jnz 1f
89 lr %r14,%r9 89 lr %r14,%r9
90 sl %r14,BASED(.Lcritical_start) 90 sl %r14,BASED(.Lc_critical_start)
91 cl %r14,BASED(.Lcritical_length) 91 cl %r14,BASED(.Lc_critical_length)
92 jhe 0f 92 jhe 0f
93 la %r11,\savearea # inside critical section, do cleanup 93 la %r11,\savearea # inside critical section, do cleanup
94 bras %r14,cleanup_critical 94 bras %r14,cleanup_critical
@@ -162,7 +162,7 @@ ENTRY(__switch_to)
162 lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 162 lm %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
163 br %r14 163 br %r14
164 164
165__critical_start: 165.L__critical_start:
166/* 166/*
167 * SVC interrupt handler routine. System calls are synchronous events and 167 * SVC interrupt handler routine. System calls are synchronous events and
168 * are executed with interrupts enabled. 168 * are executed with interrupts enabled.
@@ -170,145 +170,145 @@ __critical_start:
170 170
171ENTRY(system_call) 171ENTRY(system_call)
172 stpt __LC_SYNC_ENTER_TIMER 172 stpt __LC_SYNC_ENTER_TIMER
173sysc_stm: 173.Lsysc_stm:
174 stm %r8,%r15,__LC_SAVE_AREA_SYNC 174 stm %r8,%r15,__LC_SAVE_AREA_SYNC
175 l %r12,__LC_THREAD_INFO 175 l %r12,__LC_THREAD_INFO
176 l %r13,__LC_SVC_NEW_PSW+4 176 l %r13,__LC_SVC_NEW_PSW+4
177 lhi %r14,_PIF_SYSCALL 177 lhi %r14,_PIF_SYSCALL
178sysc_per: 178.Lsysc_per:
179 l %r15,__LC_KERNEL_STACK 179 l %r15,__LC_KERNEL_STACK
180 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 180 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
181sysc_vtime: 181.Lsysc_vtime:
182 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER 182 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
183 stm %r0,%r7,__PT_R0(%r11) 183 stm %r0,%r7,__PT_R0(%r11)
184 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC 184 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
185 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW 185 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW
186 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC 186 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
187 st %r14,__PT_FLAGS(%r11) 187 st %r14,__PT_FLAGS(%r11)
188sysc_do_svc: 188.Lsysc_do_svc:
189 l %r10,__TI_sysc_table(%r12) # 31 bit system call table 189 l %r10,__TI_sysc_table(%r12) # 31 bit system call table
190 lh %r8,__PT_INT_CODE+2(%r11) 190 lh %r8,__PT_INT_CODE+2(%r11)
191 sla %r8,2 # shift and test for svc0 191 sla %r8,2 # shift and test for svc0
192 jnz sysc_nr_ok 192 jnz .Lsysc_nr_ok
193 # svc 0: system call number in %r1 193 # svc 0: system call number in %r1
194 cl %r1,BASED(.Lnr_syscalls) 194 cl %r1,BASED(.Lnr_syscalls)
195 jnl sysc_nr_ok 195 jnl .Lsysc_nr_ok
196 sth %r1,__PT_INT_CODE+2(%r11) 196 sth %r1,__PT_INT_CODE+2(%r11)
197 lr %r8,%r1 197 lr %r8,%r1
198 sla %r8,2 198 sla %r8,2
199sysc_nr_ok: 199.Lsysc_nr_ok:
200 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 200 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
201 st %r2,__PT_ORIG_GPR2(%r11) 201 st %r2,__PT_ORIG_GPR2(%r11)
202 st %r7,STACK_FRAME_OVERHEAD(%r15) 202 st %r7,STACK_FRAME_OVERHEAD(%r15)
203 l %r9,0(%r8,%r10) # get system call addr. 203 l %r9,0(%r8,%r10) # get system call addr.
204 tm __TI_flags+3(%r12),_TIF_TRACE 204 tm __TI_flags+3(%r12),_TIF_TRACE
205 jnz sysc_tracesys 205 jnz .Lsysc_tracesys
206 basr %r14,%r9 # call sys_xxxx 206 basr %r14,%r9 # call sys_xxxx
207 st %r2,__PT_R2(%r11) # store return value 207 st %r2,__PT_R2(%r11) # store return value
208 208
209sysc_return: 209.Lsysc_return:
210 LOCKDEP_SYS_EXIT 210 LOCKDEP_SYS_EXIT
211sysc_tif: 211.Lsysc_tif:
212 tm __PT_PSW+1(%r11),0x01 # returning to user ? 212 tm __PT_PSW+1(%r11),0x01 # returning to user ?
213 jno sysc_restore 213 jno .Lsysc_restore
214 tm __PT_FLAGS+3(%r11),_PIF_WORK 214 tm __PT_FLAGS+3(%r11),_PIF_WORK
215 jnz sysc_work 215 jnz .Lsysc_work
216 tm __TI_flags+3(%r12),_TIF_WORK 216 tm __TI_flags+3(%r12),_TIF_WORK
217 jnz sysc_work # check for thread work 217 jnz .Lsysc_work # check for thread work
218 tm __LC_CPU_FLAGS+3,_CIF_WORK 218 tm __LC_CPU_FLAGS+3,_CIF_WORK
219 jnz sysc_work 219 jnz .Lsysc_work
220sysc_restore: 220.Lsysc_restore:
221 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11) 221 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
222 stpt __LC_EXIT_TIMER 222 stpt __LC_EXIT_TIMER
223 lm %r0,%r15,__PT_R0(%r11) 223 lm %r0,%r15,__PT_R0(%r11)
224 lpsw __LC_RETURN_PSW 224 lpsw __LC_RETURN_PSW
225sysc_done: 225.Lsysc_done:
226 226
227# 227#
228# One of the work bits is on. Find out which one. 228# One of the work bits is on. Find out which one.
229# 229#
230sysc_work: 230.Lsysc_work:
231 tm __LC_CPU_FLAGS+3,_CIF_MCCK_PENDING 231 tm __LC_CPU_FLAGS+3,_CIF_MCCK_PENDING
232 jo sysc_mcck_pending 232 jo .Lsysc_mcck_pending
233 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 233 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
234 jo sysc_reschedule 234 jo .Lsysc_reschedule
235 tm __PT_FLAGS+3(%r11),_PIF_PER_TRAP 235 tm __PT_FLAGS+3(%r11),_PIF_PER_TRAP
236 jo sysc_singlestep 236 jo .Lsysc_singlestep
237 tm __TI_flags+3(%r12),_TIF_SIGPENDING 237 tm __TI_flags+3(%r12),_TIF_SIGPENDING
238 jo sysc_sigpending 238 jo .Lsysc_sigpending
239 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 239 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
240 jo sysc_notify_resume 240 jo .Lsysc_notify_resume
241 tm __LC_CPU_FLAGS+3,_CIF_ASCE 241 tm __LC_CPU_FLAGS+3,_CIF_ASCE
242 jo sysc_uaccess 242 jo .Lsysc_uaccess
243 j sysc_return # beware of critical section cleanup 243 j .Lsysc_return # beware of critical section cleanup
244 244
245# 245#
246# _TIF_NEED_RESCHED is set, call schedule 246# _TIF_NEED_RESCHED is set, call schedule
247# 247#
248sysc_reschedule: 248.Lsysc_reschedule:
249 l %r1,BASED(.Lschedule) 249 l %r1,BASED(.Lc_schedule)
250 la %r14,BASED(sysc_return) 250 la %r14,BASED(.Lsysc_return)
251 br %r1 # call schedule 251 br %r1 # call schedule
252 252
253# 253#
254# _CIF_MCCK_PENDING is set, call handler 254# _CIF_MCCK_PENDING is set, call handler
255# 255#
256sysc_mcck_pending: 256.Lsysc_mcck_pending:
257 l %r1,BASED(.Lhandle_mcck) 257 l %r1,BASED(.Lc_handle_mcck)
258 la %r14,BASED(sysc_return) 258 la %r14,BASED(.Lsysc_return)
259 br %r1 # TIF bit will be cleared by handler 259 br %r1 # TIF bit will be cleared by handler
260 260
261# 261#
262# _CIF_ASCE is set, load user space asce 262# _CIF_ASCE is set, load user space asce
263# 263#
264sysc_uaccess: 264.Lsysc_uaccess:
265 ni __LC_CPU_FLAGS+3,255-_CIF_ASCE 265 ni __LC_CPU_FLAGS+3,255-_CIF_ASCE
266 lctl %c1,%c1,__LC_USER_ASCE # load primary asce 266 lctl %c1,%c1,__LC_USER_ASCE # load primary asce
267 j sysc_return 267 j .Lsysc_return
268 268
269# 269#
270# _TIF_SIGPENDING is set, call do_signal 270# _TIF_SIGPENDING is set, call do_signal
271# 271#
272sysc_sigpending: 272.Lsysc_sigpending:
273 lr %r2,%r11 # pass pointer to pt_regs 273 lr %r2,%r11 # pass pointer to pt_regs
274 l %r1,BASED(.Ldo_signal) 274 l %r1,BASED(.Lc_do_signal)
275 basr %r14,%r1 # call do_signal 275 basr %r14,%r1 # call do_signal
276 tm __PT_FLAGS+3(%r11),_PIF_SYSCALL 276 tm __PT_FLAGS+3(%r11),_PIF_SYSCALL
277 jno sysc_return 277 jno .Lsysc_return
278 lm %r2,%r7,__PT_R2(%r11) # load svc arguments 278 lm %r2,%r7,__PT_R2(%r11) # load svc arguments
279 l %r10,__TI_sysc_table(%r12) # 31 bit system call table 279 l %r10,__TI_sysc_table(%r12) # 31 bit system call table
280 xr %r8,%r8 # svc 0 returns -ENOSYS 280 xr %r8,%r8 # svc 0 returns -ENOSYS
281 clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2) 281 clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
282 jnl sysc_nr_ok # invalid svc number -> do svc 0 282 jnl .Lsysc_nr_ok # invalid svc number -> do svc 0
283 lh %r8,__PT_INT_CODE+2(%r11) # load new svc number 283 lh %r8,__PT_INT_CODE+2(%r11) # load new svc number
284 sla %r8,2 284 sla %r8,2
285 j sysc_nr_ok # restart svc 285 j .Lsysc_nr_ok # restart svc
286 286
287# 287#
288# _TIF_NOTIFY_RESUME is set, call do_notify_resume 288# _TIF_NOTIFY_RESUME is set, call do_notify_resume
289# 289#
290sysc_notify_resume: 290.Lsysc_notify_resume:
291 lr %r2,%r11 # pass pointer to pt_regs 291 lr %r2,%r11 # pass pointer to pt_regs
292 l %r1,BASED(.Ldo_notify_resume) 292 l %r1,BASED(.Lc_do_notify_resume)
293 la %r14,BASED(sysc_return) 293 la %r14,BASED(.Lsysc_return)
294 br %r1 # call do_notify_resume 294 br %r1 # call do_notify_resume
295 295
296# 296#
297# _PIF_PER_TRAP is set, call do_per_trap 297# _PIF_PER_TRAP is set, call do_per_trap
298# 298#
299sysc_singlestep: 299.Lsysc_singlestep:
300 ni __PT_FLAGS+3(%r11),255-_PIF_PER_TRAP 300 ni __PT_FLAGS+3(%r11),255-_PIF_PER_TRAP
301 lr %r2,%r11 # pass pointer to pt_regs 301 lr %r2,%r11 # pass pointer to pt_regs
302 l %r1,BASED(.Ldo_per_trap) 302 l %r1,BASED(.Lc_do_per_trap)
303 la %r14,BASED(sysc_return) 303 la %r14,BASED(.Lsysc_return)
304 br %r1 # call do_per_trap 304 br %r1 # call do_per_trap
305 305
306# 306#
307# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 307# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
308# and after the system call 308# and after the system call
309# 309#
310sysc_tracesys: 310.Lsysc_tracesys:
311 l %r1,BASED(.Ltrace_enter) 311 l %r1,BASED(.Lc_trace_enter)
312 lr %r2,%r11 # pass pointer to pt_regs 312 lr %r2,%r11 # pass pointer to pt_regs
313 la %r3,0 313 la %r3,0
314 xr %r0,%r0 314 xr %r0,%r0
@@ -316,22 +316,22 @@ sysc_tracesys:
316 st %r0,__PT_R2(%r11) 316 st %r0,__PT_R2(%r11)
317 basr %r14,%r1 # call do_syscall_trace_enter 317 basr %r14,%r1 # call do_syscall_trace_enter
318 cl %r2,BASED(.Lnr_syscalls) 318 cl %r2,BASED(.Lnr_syscalls)
319 jnl sysc_tracenogo 319 jnl .Lsysc_tracenogo
320 lr %r8,%r2 320 lr %r8,%r2
321 sll %r8,2 321 sll %r8,2
322 l %r9,0(%r8,%r10) 322 l %r9,0(%r8,%r10)
323sysc_tracego: 323.Lsysc_tracego:
324 lm %r3,%r7,__PT_R3(%r11) 324 lm %r3,%r7,__PT_R3(%r11)
325 st %r7,STACK_FRAME_OVERHEAD(%r15) 325 st %r7,STACK_FRAME_OVERHEAD(%r15)
326 l %r2,__PT_ORIG_GPR2(%r11) 326 l %r2,__PT_ORIG_GPR2(%r11)
327 basr %r14,%r9 # call sys_xxx 327 basr %r14,%r9 # call sys_xxx
328 st %r2,__PT_R2(%r11) # store return value 328 st %r2,__PT_R2(%r11) # store return value
329sysc_tracenogo: 329.Lsysc_tracenogo:
330 tm __TI_flags+3(%r12),_TIF_TRACE 330 tm __TI_flags+3(%r12),_TIF_TRACE
331 jz sysc_return 331 jz .Lsysc_return
332 l %r1,BASED(.Ltrace_exit) 332 l %r1,BASED(.Lc_trace_exit)
333 lr %r2,%r11 # pass pointer to pt_regs 333 lr %r2,%r11 # pass pointer to pt_regs
334 la %r14,BASED(sysc_return) 334 la %r14,BASED(.Lsysc_return)
335 br %r1 # call do_syscall_trace_exit 335 br %r1 # call do_syscall_trace_exit
336 336
337# 337#
@@ -341,18 +341,18 @@ ENTRY(ret_from_fork)
341 la %r11,STACK_FRAME_OVERHEAD(%r15) 341 la %r11,STACK_FRAME_OVERHEAD(%r15)
342 l %r12,__LC_THREAD_INFO 342 l %r12,__LC_THREAD_INFO
343 l %r13,__LC_SVC_NEW_PSW+4 343 l %r13,__LC_SVC_NEW_PSW+4
344 l %r1,BASED(.Lschedule_tail) 344 l %r1,BASED(.Lc_schedule_tail)
345 basr %r14,%r1 # call schedule_tail 345 basr %r14,%r1 # call schedule_tail
346 TRACE_IRQS_ON 346 TRACE_IRQS_ON
347 ssm __LC_SVC_NEW_PSW # reenable interrupts 347 ssm __LC_SVC_NEW_PSW # reenable interrupts
348 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? 348 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
349 jne sysc_tracenogo 349 jne .Lsysc_tracenogo
350 # it's a kernel thread 350 # it's a kernel thread
351 lm %r9,%r10,__PT_R9(%r11) # load gprs 351 lm %r9,%r10,__PT_R9(%r11) # load gprs
352ENTRY(kernel_thread_starter) 352ENTRY(kernel_thread_starter)
353 la %r2,0(%r10) 353 la %r2,0(%r10)
354 basr %r14,%r9 354 basr %r14,%r9
355 j sysc_tracenogo 355 j .Lsysc_tracenogo
356 356
357/* 357/*
358 * Program check handler routine 358 * Program check handler routine
@@ -369,7 +369,7 @@ ENTRY(pgm_check_handler)
369 tmh %r8,0x4000 # PER bit set in old PSW ? 369 tmh %r8,0x4000 # PER bit set in old PSW ?
370 jnz 0f # -> enabled, can't be a double fault 370 jnz 0f # -> enabled, can't be a double fault
371 tm __LC_PGM_ILC+3,0x80 # check for per exception 371 tm __LC_PGM_ILC+3,0x80 # check for per exception
372 jnz pgm_svcper # -> single stepped svc 372 jnz .Lpgm_svcper # -> single stepped svc
3730: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC 3730: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
374 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 374 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
375 j 2f 375 j 2f
@@ -386,42 +386,42 @@ ENTRY(pgm_check_handler)
386 jz 0f 386 jz 0f
387 l %r1,__TI_task(%r12) 387 l %r1,__TI_task(%r12)
388 tmh %r8,0x0001 # kernel per event ? 388 tmh %r8,0x0001 # kernel per event ?
389 jz pgm_kprobe 389 jz .Lpgm_kprobe
390 oi __PT_FLAGS+3(%r11),_PIF_PER_TRAP 390 oi __PT_FLAGS+3(%r11),_PIF_PER_TRAP
391 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS 391 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
392 mvc __THREAD_per_cause(2,%r1),__LC_PER_CODE 392 mvc __THREAD_per_cause(2,%r1),__LC_PER_CODE
393 mvc __THREAD_per_paid(1,%r1),__LC_PER_ACCESS_ID 393 mvc __THREAD_per_paid(1,%r1),__LC_PER_ACCESS_ID
3940: REENABLE_IRQS 3940: REENABLE_IRQS
395 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 395 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
396 l %r1,BASED(.Ljump_table) 396 l %r1,BASED(.Lc_jump_table)
397 la %r10,0x7f 397 la %r10,0x7f
398 n %r10,__PT_INT_CODE(%r11) 398 n %r10,__PT_INT_CODE(%r11)
399 je sysc_return 399 je .Lsysc_return
400 sll %r10,2 400 sll %r10,2
401 l %r1,0(%r10,%r1) # load address of handler routine 401 l %r1,0(%r10,%r1) # load address of handler routine
402 lr %r2,%r11 # pass pointer to pt_regs 402 lr %r2,%r11 # pass pointer to pt_regs
403 basr %r14,%r1 # branch to interrupt-handler 403 basr %r14,%r1 # branch to interrupt-handler
404 j sysc_return 404 j .Lsysc_return
405 405
406# 406#
407# PER event in supervisor state, must be kprobes 407# PER event in supervisor state, must be kprobes
408# 408#
409pgm_kprobe: 409.Lpgm_kprobe:
410 REENABLE_IRQS 410 REENABLE_IRQS
411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
412 l %r1,BASED(.Ldo_per_trap) 412 l %r1,BASED(.Lc_do_per_trap)
413 lr %r2,%r11 # pass pointer to pt_regs 413 lr %r2,%r11 # pass pointer to pt_regs
414 basr %r14,%r1 # call do_per_trap 414 basr %r14,%r1 # call do_per_trap
415 j sysc_return 415 j .Lsysc_return
416 416
417# 417#
418# single stepped system call 418# single stepped system call
419# 419#
420pgm_svcper: 420.Lpgm_svcper:
421 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW 421 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW
422 mvc __LC_RETURN_PSW+4(4),BASED(.Lsysc_per) 422 mvc __LC_RETURN_PSW+4(4),BASED(.Lc_sysc_per)
423 lhi %r14,_PIF_SYSCALL | _PIF_PER_TRAP 423 lhi %r14,_PIF_SYSCALL | _PIF_PER_TRAP
424 lpsw __LC_RETURN_PSW # branch to sysc_per and enable irqs 424 lpsw __LC_RETURN_PSW # branch to .Lsysc_per and enable irqs
425 425
426/* 426/*
427 * IO interrupt handler routine 427 * IO interrupt handler routine
@@ -435,9 +435,9 @@ ENTRY(io_int_handler)
435 l %r13,__LC_SVC_NEW_PSW+4 435 l %r13,__LC_SVC_NEW_PSW+4
436 lm %r8,%r9,__LC_IO_OLD_PSW 436 lm %r8,%r9,__LC_IO_OLD_PSW
437 tmh %r8,0x0001 # interrupting from user ? 437 tmh %r8,0x0001 # interrupting from user ?
438 jz io_skip 438 jz .Lio_skip
439 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER 439 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
440io_skip: 440.Lio_skip:
441 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 441 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
442 stm %r0,%r7,__PT_R0(%r11) 442 stm %r0,%r7,__PT_R0(%r11)
443 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC 443 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
@@ -446,35 +446,35 @@ io_skip:
446 xc __PT_FLAGS(4,%r11),__PT_FLAGS(%r11) 446 xc __PT_FLAGS(4,%r11),__PT_FLAGS(%r11)
447 TRACE_IRQS_OFF 447 TRACE_IRQS_OFF
448 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 448 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
449io_loop: 449.Lio_loop:
450 l %r1,BASED(.Ldo_IRQ) 450 l %r1,BASED(.Lc_do_IRQ)
451 lr %r2,%r11 # pass pointer to pt_regs 451 lr %r2,%r11 # pass pointer to pt_regs
452 lhi %r3,IO_INTERRUPT 452 lhi %r3,IO_INTERRUPT
453 tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ? 453 tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ?
454 jz io_call 454 jz .Lio_call
455 lhi %r3,THIN_INTERRUPT 455 lhi %r3,THIN_INTERRUPT
456io_call: 456.Lio_call:
457 basr %r14,%r1 # call do_IRQ 457 basr %r14,%r1 # call do_IRQ
458 tm __LC_MACHINE_FLAGS+2,0x10 # MACHINE_FLAG_LPAR 458 tm __LC_MACHINE_FLAGS+2,0x10 # MACHINE_FLAG_LPAR
459 jz io_return 459 jz .Lio_return
460 tpi 0 460 tpi 0
461 jz io_return 461 jz .Lio_return
462 mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID 462 mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
463 j io_loop 463 j .Lio_loop
464io_return: 464.Lio_return:
465 LOCKDEP_SYS_EXIT 465 LOCKDEP_SYS_EXIT
466 TRACE_IRQS_ON 466 TRACE_IRQS_ON
467io_tif: 467.Lio_tif:
468 tm __TI_flags+3(%r12),_TIF_WORK 468 tm __TI_flags+3(%r12),_TIF_WORK
469 jnz io_work # there is work to do (signals etc.) 469 jnz .Lio_work # there is work to do (signals etc.)
470 tm __LC_CPU_FLAGS+3,_CIF_WORK 470 tm __LC_CPU_FLAGS+3,_CIF_WORK
471 jnz io_work 471 jnz .Lio_work
472io_restore: 472.Lio_restore:
473 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11) 473 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
474 stpt __LC_EXIT_TIMER 474 stpt __LC_EXIT_TIMER
475 lm %r0,%r15,__PT_R0(%r11) 475 lm %r0,%r15,__PT_R0(%r11)
476 lpsw __LC_RETURN_PSW 476 lpsw __LC_RETURN_PSW
477io_done: 477.Lio_done:
478 478
479# 479#
480# There is work todo, find out in which context we have been interrupted: 480# There is work todo, find out in which context we have been interrupted:
@@ -483,15 +483,15 @@ io_done:
483# the preemption counter and if it is zero call preempt_schedule_irq 483# the preemption counter and if it is zero call preempt_schedule_irq
484# Before any work can be done, a switch to the kernel stack is required. 484# Before any work can be done, a switch to the kernel stack is required.
485# 485#
486io_work: 486.Lio_work:
487 tm __PT_PSW+1(%r11),0x01 # returning to user ? 487 tm __PT_PSW+1(%r11),0x01 # returning to user ?
488 jo io_work_user # yes -> do resched & signal 488 jo .Lio_work_user # yes -> do resched & signal
489#ifdef CONFIG_PREEMPT 489#ifdef CONFIG_PREEMPT
490 # check for preemptive scheduling 490 # check for preemptive scheduling
491 icm %r0,15,__TI_precount(%r12) 491 icm %r0,15,__TI_precount(%r12)
492 jnz io_restore # preemption disabled 492 jnz .Lio_restore # preemption disabled
493 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 493 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
494 jno io_restore 494 jno .Lio_restore
495 # switch to kernel stack 495 # switch to kernel stack
496 l %r1,__PT_R15(%r11) 496 l %r1,__PT_R15(%r11)
497 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 497 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
@@ -499,20 +499,20 @@ io_work:
499 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) 499 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
500 la %r11,STACK_FRAME_OVERHEAD(%r1) 500 la %r11,STACK_FRAME_OVERHEAD(%r1)
501 lr %r15,%r1 501 lr %r15,%r1
502 # TRACE_IRQS_ON already done at io_return, call 502 # TRACE_IRQS_ON already done at .Lio_return, call
503 # TRACE_IRQS_OFF to keep things symmetrical 503 # TRACE_IRQS_OFF to keep things symmetrical
504 TRACE_IRQS_OFF 504 TRACE_IRQS_OFF
505 l %r1,BASED(.Lpreempt_irq) 505 l %r1,BASED(.Lc_preempt_irq)
506 basr %r14,%r1 # call preempt_schedule_irq 506 basr %r14,%r1 # call preempt_schedule_irq
507 j io_return 507 j .Lio_return
508#else 508#else
509 j io_restore 509 j .Lio_restore
510#endif 510#endif
511 511
512# 512#
513# Need to do work before returning to userspace, switch to kernel stack 513# Need to do work before returning to userspace, switch to kernel stack
514# 514#
515io_work_user: 515.Lio_work_user:
516 l %r1,__LC_KERNEL_STACK 516 l %r1,__LC_KERNEL_STACK
517 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 517 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
518 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) 518 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
@@ -522,74 +522,74 @@ io_work_user:
522# 522#
523# One of the work bits is on. Find out which one. 523# One of the work bits is on. Find out which one.
524# 524#
525io_work_tif: 525.Lio_work_tif:
526 tm __LC_CPU_FLAGS+3(%r12),_CIF_MCCK_PENDING 526 tm __LC_CPU_FLAGS+3(%r12),_CIF_MCCK_PENDING
527 jo io_mcck_pending 527 jo .Lio_mcck_pending
528 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 528 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
529 jo io_reschedule 529 jo .Lio_reschedule
530 tm __TI_flags+3(%r12),_TIF_SIGPENDING 530 tm __TI_flags+3(%r12),_TIF_SIGPENDING
531 jo io_sigpending 531 jo .Lio_sigpending
532 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 532 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
533 jo io_notify_resume 533 jo .Lio_notify_resume
534 tm __LC_CPU_FLAGS+3,_CIF_ASCE 534 tm __LC_CPU_FLAGS+3,_CIF_ASCE
535 jo io_uaccess 535 jo .Lio_uaccess
536 j io_return # beware of critical section cleanup 536 j .Lio_return # beware of critical section cleanup
537 537
538# 538#
539# _CIF_MCCK_PENDING is set, call handler 539# _CIF_MCCK_PENDING is set, call handler
540# 540#
541io_mcck_pending: 541.Lio_mcck_pending:
542 # TRACE_IRQS_ON already done at io_return 542 # TRACE_IRQS_ON already done at .Lio_return
543 l %r1,BASED(.Lhandle_mcck) 543 l %r1,BASED(.Lc_handle_mcck)
544 basr %r14,%r1 # TIF bit will be cleared by handler 544 basr %r14,%r1 # TIF bit will be cleared by handler
545 TRACE_IRQS_OFF 545 TRACE_IRQS_OFF
546 j io_return 546 j .Lio_return
547 547
548# 548#
549# _CIF_ASCE is set, load user space asce 549# _CIF_ASCE is set, load user space asce
550# 550#
551io_uaccess: 551.Lio_uaccess:
552 ni __LC_CPU_FLAGS+3,255-_CIF_ASCE 552 ni __LC_CPU_FLAGS+3,255-_CIF_ASCE
553 lctl %c1,%c1,__LC_USER_ASCE # load primary asce 553 lctl %c1,%c1,__LC_USER_ASCE # load primary asce
554 j io_return 554 j .Lio_return
555 555
556# 556#
557# _TIF_NEED_RESCHED is set, call schedule 557# _TIF_NEED_RESCHED is set, call schedule
558# 558#
559io_reschedule: 559.Lio_reschedule:
560 # TRACE_IRQS_ON already done at io_return 560 # TRACE_IRQS_ON already done at .Lio_return
561 l %r1,BASED(.Lschedule) 561 l %r1,BASED(.Lc_schedule)
562 ssm __LC_SVC_NEW_PSW # reenable interrupts 562 ssm __LC_SVC_NEW_PSW # reenable interrupts
563 basr %r14,%r1 # call scheduler 563 basr %r14,%r1 # call scheduler
564 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts 564 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
565 TRACE_IRQS_OFF 565 TRACE_IRQS_OFF
566 j io_return 566 j .Lio_return
567 567
568# 568#
569# _TIF_SIGPENDING is set, call do_signal 569# _TIF_SIGPENDING is set, call do_signal
570# 570#
571io_sigpending: 571.Lio_sigpending:
572 # TRACE_IRQS_ON already done at io_return 572 # TRACE_IRQS_ON already done at .Lio_return
573 l %r1,BASED(.Ldo_signal) 573 l %r1,BASED(.Lc_do_signal)
574 ssm __LC_SVC_NEW_PSW # reenable interrupts 574 ssm __LC_SVC_NEW_PSW # reenable interrupts
575 lr %r2,%r11 # pass pointer to pt_regs 575 lr %r2,%r11 # pass pointer to pt_regs
576 basr %r14,%r1 # call do_signal 576 basr %r14,%r1 # call do_signal
577 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts 577 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
578 TRACE_IRQS_OFF 578 TRACE_IRQS_OFF
579 j io_return 579 j .Lio_return
580 580
581# 581#
582# _TIF_SIGPENDING is set, call do_signal 582# _TIF_SIGPENDING is set, call do_signal
583# 583#
584io_notify_resume: 584.Lio_notify_resume:
585 # TRACE_IRQS_ON already done at io_return 585 # TRACE_IRQS_ON already done at .Lio_return
586 l %r1,BASED(.Ldo_notify_resume) 586 l %r1,BASED(.Lc_do_notify_resume)
587 ssm __LC_SVC_NEW_PSW # reenable interrupts 587 ssm __LC_SVC_NEW_PSW # reenable interrupts
588 lr %r2,%r11 # pass pointer to pt_regs 588 lr %r2,%r11 # pass pointer to pt_regs
589 basr %r14,%r1 # call do_notify_resume 589 basr %r14,%r1 # call do_notify_resume
590 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts 590 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
591 TRACE_IRQS_OFF 591 TRACE_IRQS_OFF
592 j io_return 592 j .Lio_return
593 593
594/* 594/*
595 * External interrupt handler routine 595 * External interrupt handler routine
@@ -603,9 +603,9 @@ ENTRY(ext_int_handler)
603 l %r13,__LC_SVC_NEW_PSW+4 603 l %r13,__LC_SVC_NEW_PSW+4
604 lm %r8,%r9,__LC_EXT_OLD_PSW 604 lm %r8,%r9,__LC_EXT_OLD_PSW
605 tmh %r8,0x0001 # interrupting from user ? 605 tmh %r8,0x0001 # interrupting from user ?
606 jz ext_skip 606 jz .Lext_skip
607 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER 607 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
608ext_skip: 608.Lext_skip:
609 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 609 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
610 stm %r0,%r7,__PT_R0(%r11) 610 stm %r0,%r7,__PT_R0(%r11)
611 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC 611 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
@@ -614,29 +614,29 @@ ext_skip:
614 mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS 614 mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
615 xc __PT_FLAGS(4,%r11),__PT_FLAGS(%r11) 615 xc __PT_FLAGS(4,%r11),__PT_FLAGS(%r11)
616 TRACE_IRQS_OFF 616 TRACE_IRQS_OFF
617 l %r1,BASED(.Ldo_IRQ) 617 l %r1,BASED(.Lc_do_IRQ)
618 lr %r2,%r11 # pass pointer to pt_regs 618 lr %r2,%r11 # pass pointer to pt_regs
619 lhi %r3,EXT_INTERRUPT 619 lhi %r3,EXT_INTERRUPT
620 basr %r14,%r1 # call do_IRQ 620 basr %r14,%r1 # call do_IRQ
621 j io_return 621 j .Lio_return
622 622
623/* 623/*
624 * Load idle PSW. The second "half" of this function is in cleanup_idle. 624 * Load idle PSW. The second "half" of this function is in .Lcleanup_idle.
625 */ 625 */
626ENTRY(psw_idle) 626ENTRY(psw_idle)
627 st %r3,__SF_EMPTY(%r15) 627 st %r3,__SF_EMPTY(%r15)
628 basr %r1,0 628 basr %r1,0
629 la %r1,psw_idle_lpsw+4-.(%r1) 629 la %r1,.Lpsw_idle_lpsw+4-.(%r1)
630 st %r1,__SF_EMPTY+4(%r15) 630 st %r1,__SF_EMPTY+4(%r15)
631 oi __SF_EMPTY+4(%r15),0x80 631 oi __SF_EMPTY+4(%r15),0x80
632 stck __CLOCK_IDLE_ENTER(%r2) 632 stck __CLOCK_IDLE_ENTER(%r2)
633 stpt __TIMER_IDLE_ENTER(%r2) 633 stpt __TIMER_IDLE_ENTER(%r2)
634psw_idle_lpsw: 634.Lpsw_idle_lpsw:
635 lpsw __SF_EMPTY(%r15) 635 lpsw __SF_EMPTY(%r15)
636 br %r14 636 br %r14
637psw_idle_end: 637.Lpsw_idle_end:
638 638
639__critical_end: 639.L__critical_end:
640 640
641/* 641/*
642 * Machine check handler routines 642 * Machine check handler routines
@@ -650,7 +650,7 @@ ENTRY(mcck_int_handler)
650 l %r13,__LC_SVC_NEW_PSW+4 650 l %r13,__LC_SVC_NEW_PSW+4
651 lm %r8,%r9,__LC_MCK_OLD_PSW 651 lm %r8,%r9,__LC_MCK_OLD_PSW
652 tm __LC_MCCK_CODE,0x80 # system damage? 652 tm __LC_MCCK_CODE,0x80 # system damage?
653 jo mcck_panic # yes -> rest of mcck code invalid 653 jo .Lmcck_panic # yes -> rest of mcck code invalid
654 la %r14,__LC_CPU_TIMER_SAVE_AREA 654 la %r14,__LC_CPU_TIMER_SAVE_AREA
655 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 655 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
656 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 656 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
@@ -668,22 +668,22 @@ ENTRY(mcck_int_handler)
6682: spt 0(%r14) 6682: spt 0(%r14)
669 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 669 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
6703: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6703: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
671 jno mcck_panic # no -> skip cleanup critical 671 jno .Lmcck_panic # no -> skip cleanup critical
672 tm %r8,0x0001 # interrupting from user ? 672 tm %r8,0x0001 # interrupting from user ?
673 jz mcck_skip 673 jz .Lmcck_skip
674 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER 674 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
675mcck_skip: 675.Lmcck_skip:
676 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT 676 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
677 stm %r0,%r7,__PT_R0(%r11) 677 stm %r0,%r7,__PT_R0(%r11)
678 mvc __PT_R8(32,%r11),__LC_GPREGS_SAVE_AREA+32 678 mvc __PT_R8(32,%r11),__LC_GPREGS_SAVE_AREA+32
679 stm %r8,%r9,__PT_PSW(%r11) 679 stm %r8,%r9,__PT_PSW(%r11)
680 xc __PT_FLAGS(4,%r11),__PT_FLAGS(%r11) 680 xc __PT_FLAGS(4,%r11),__PT_FLAGS(%r11)
681 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 681 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
682 l %r1,BASED(.Ldo_machine_check) 682 l %r1,BASED(.Lc_do_machine_check)
683 lr %r2,%r11 # pass pointer to pt_regs 683 lr %r2,%r11 # pass pointer to pt_regs
684 basr %r14,%r1 # call s390_do_machine_check 684 basr %r14,%r1 # call s390_do_machine_check
685 tm __PT_PSW+1(%r11),0x01 # returning to user ? 685 tm __PT_PSW+1(%r11),0x01 # returning to user ?
686 jno mcck_return 686 jno .Lmcck_return
687 l %r1,__LC_KERNEL_STACK # switch to kernel stack 687 l %r1,__LC_KERNEL_STACK # switch to kernel stack
688 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 688 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
689 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) 689 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
@@ -691,12 +691,12 @@ mcck_skip:
691 lr %r15,%r1 691 lr %r15,%r1
692 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off 692 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
693 tm __LC_CPU_FLAGS+3,_CIF_MCCK_PENDING 693 tm __LC_CPU_FLAGS+3,_CIF_MCCK_PENDING
694 jno mcck_return 694 jno .Lmcck_return
695 TRACE_IRQS_OFF 695 TRACE_IRQS_OFF
696 l %r1,BASED(.Lhandle_mcck) 696 l %r1,BASED(.Lc_handle_mcck)
697 basr %r14,%r1 # call s390_handle_mcck 697 basr %r14,%r1 # call s390_handle_mcck
698 TRACE_IRQS_ON 698 TRACE_IRQS_ON
699mcck_return: 699.Lmcck_return:
700 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW 700 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
701 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 701 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
702 jno 0f 702 jno 0f
@@ -706,15 +706,15 @@ mcck_return:
7060: lm %r0,%r15,__PT_R0(%r11) 7060: lm %r0,%r15,__PT_R0(%r11)
707 lpsw __LC_RETURN_MCCK_PSW 707 lpsw __LC_RETURN_MCCK_PSW
708 708
709mcck_panic: 709.Lmcck_panic:
710 l %r14,__LC_PANIC_STACK 710 l %r14,__LC_PANIC_STACK
711 slr %r14,%r15 711 slr %r14,%r15
712 sra %r14,PAGE_SHIFT 712 sra %r14,PAGE_SHIFT
713 jz 0f 713 jz 0f
714 l %r15,__LC_PANIC_STACK 714 l %r15,__LC_PANIC_STACK
715 j mcck_skip 715 j .Lmcck_skip
7160: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 7160: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
717 j mcck_skip 717 j .Lmcck_skip
718 718
719# 719#
720# PSW restart interrupt handler 720# PSW restart interrupt handler
@@ -764,58 +764,58 @@ stack_overflow:
7641: .long kernel_stack_overflow 7641: .long kernel_stack_overflow
765#endif 765#endif
766 766
767cleanup_table: 767.Lcleanup_table:
768 .long system_call + 0x80000000 768 .long system_call + 0x80000000
769 .long sysc_do_svc + 0x80000000 769 .long .Lsysc_do_svc + 0x80000000
770 .long sysc_tif + 0x80000000 770 .long .Lsysc_tif + 0x80000000
771 .long sysc_restore + 0x80000000 771 .long .Lsysc_restore + 0x80000000
772 .long sysc_done + 0x80000000 772 .long .Lsysc_done + 0x80000000
773 .long io_tif + 0x80000000 773 .long .Lio_tif + 0x80000000
774 .long io_restore + 0x80000000 774 .long .Lio_restore + 0x80000000
775 .long io_done + 0x80000000 775 .long .Lio_done + 0x80000000
776 .long psw_idle + 0x80000000 776 .long psw_idle + 0x80000000
777 .long psw_idle_end + 0x80000000 777 .long .Lpsw_idle_end + 0x80000000
778 778
779cleanup_critical: 779cleanup_critical:
780 cl %r9,BASED(cleanup_table) # system_call 780 cl %r9,BASED(.Lcleanup_table) # system_call
781 jl 0f 781 jl 0f
782 cl %r9,BASED(cleanup_table+4) # sysc_do_svc 782 cl %r9,BASED(.Lcleanup_table+4) # .Lsysc_do_svc
783 jl cleanup_system_call 783 jl .Lcleanup_system_call
784 cl %r9,BASED(cleanup_table+8) # sysc_tif 784 cl %r9,BASED(.Lcleanup_table+8) # .Lsysc_tif
785 jl 0f 785 jl 0f
786 cl %r9,BASED(cleanup_table+12) # sysc_restore 786 cl %r9,BASED(.Lcleanup_table+12) # .Lsysc_restore
787 jl cleanup_sysc_tif 787 jl .Lcleanup_sysc_tif
788 cl %r9,BASED(cleanup_table+16) # sysc_done 788 cl %r9,BASED(.Lcleanup_table+16) # .Lsysc_done
789 jl cleanup_sysc_restore 789 jl .Lcleanup_sysc_restore
790 cl %r9,BASED(cleanup_table+20) # io_tif 790 cl %r9,BASED(.Lcleanup_table+20) # .Lio_tif
791 jl 0f 791 jl 0f
792 cl %r9,BASED(cleanup_table+24) # io_restore 792 cl %r9,BASED(.Lcleanup_table+24) # .Lio_restore
793 jl cleanup_io_tif 793 jl .Lcleanup_io_tif
794 cl %r9,BASED(cleanup_table+28) # io_done 794 cl %r9,BASED(.Lcleanup_table+28) # .Lio_done
795 jl cleanup_io_restore 795 jl .Lcleanup_io_restore
796 cl %r9,BASED(cleanup_table+32) # psw_idle 796 cl %r9,BASED(.Lcleanup_table+32) # psw_idle
797 jl 0f 797 jl 0f
798 cl %r9,BASED(cleanup_table+36) # psw_idle_end 798 cl %r9,BASED(.Lcleanup_table+36) # .Lpsw_idle_end
799 jl cleanup_idle 799 jl .Lcleanup_idle
8000: br %r14 8000: br %r14
801 801
802cleanup_system_call: 802.Lcleanup_system_call:
803 # check if stpt has been executed 803 # check if stpt has been executed
804 cl %r9,BASED(cleanup_system_call_insn) 804 cl %r9,BASED(.Lcleanup_system_call_insn)
805 jh 0f 805 jh 0f
806 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 806 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
807 chi %r11,__LC_SAVE_AREA_ASYNC 807 chi %r11,__LC_SAVE_AREA_ASYNC
808 je 0f 808 je 0f
809 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER 809 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
8100: # check if stm has been executed 8100: # check if stm has been executed
811 cl %r9,BASED(cleanup_system_call_insn+4) 811 cl %r9,BASED(.Lcleanup_system_call_insn+4)
812 jh 0f 812 jh 0f
813 mvc __LC_SAVE_AREA_SYNC(32),0(%r11) 813 mvc __LC_SAVE_AREA_SYNC(32),0(%r11)
8140: # set up saved registers r12, and r13 8140: # set up saved registers r12, and r13
815 st %r12,16(%r11) # r12 thread-info pointer 815 st %r12,16(%r11) # r12 thread-info pointer
816 st %r13,20(%r11) # r13 literal-pool pointer 816 st %r13,20(%r11) # r13 literal-pool pointer
817 # check if the user time calculation has been done 817 # check if the user time calculation has been done
818 cl %r9,BASED(cleanup_system_call_insn+8) 818 cl %r9,BASED(.Lcleanup_system_call_insn+8)
819 jh 0f 819 jh 0f
820 l %r10,__LC_EXIT_TIMER 820 l %r10,__LC_EXIT_TIMER
821 l %r15,__LC_EXIT_TIMER+4 821 l %r15,__LC_EXIT_TIMER+4
@@ -824,7 +824,7 @@ cleanup_system_call:
824 st %r10,__LC_USER_TIMER 824 st %r10,__LC_USER_TIMER
825 st %r15,__LC_USER_TIMER+4 825 st %r15,__LC_USER_TIMER+4
8260: # check if the system time calculation has been done 8260: # check if the system time calculation has been done
827 cl %r9,BASED(cleanup_system_call_insn+12) 827 cl %r9,BASED(.Lcleanup_system_call_insn+12)
828 jh 0f 828 jh 0f
829 l %r10,__LC_LAST_UPDATE_TIMER 829 l %r10,__LC_LAST_UPDATE_TIMER
830 l %r15,__LC_LAST_UPDATE_TIMER+4 830 l %r15,__LC_LAST_UPDATE_TIMER+4
@@ -848,20 +848,20 @@ cleanup_system_call:
848 # setup saved register 15 848 # setup saved register 15
849 st %r15,28(%r11) # r15 stack pointer 849 st %r15,28(%r11) # r15 stack pointer
850 # set new psw address and exit 850 # set new psw address and exit
851 l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000 851 l %r9,BASED(.Lcleanup_table+4) # .Lsysc_do_svc + 0x80000000
852 br %r14 852 br %r14
853cleanup_system_call_insn: 853.Lcleanup_system_call_insn:
854 .long system_call + 0x80000000 854 .long system_call + 0x80000000
855 .long sysc_stm + 0x80000000 855 .long .Lsysc_stm + 0x80000000
856 .long sysc_vtime + 0x80000000 + 36 856 .long .Lsysc_vtime + 0x80000000 + 36
857 .long sysc_vtime + 0x80000000 + 76 857 .long .Lsysc_vtime + 0x80000000 + 76
858 858
859cleanup_sysc_tif: 859.Lcleanup_sysc_tif:
860 l %r9,BASED(cleanup_table+8) # sysc_tif + 0x80000000 860 l %r9,BASED(.Lcleanup_table+8) # .Lsysc_tif + 0x80000000
861 br %r14 861 br %r14
862 862
863cleanup_sysc_restore: 863.Lcleanup_sysc_restore:
864 cl %r9,BASED(cleanup_sysc_restore_insn) 864 cl %r9,BASED(.Lcleanup_sysc_restore_insn)
865 jhe 0f 865 jhe 0f
866 l %r9,12(%r11) # get saved pointer to pt_regs 866 l %r9,12(%r11) # get saved pointer to pt_regs
867 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9) 867 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
@@ -869,15 +869,15 @@ cleanup_sysc_restore:
869 lm %r0,%r7,__PT_R0(%r9) 869 lm %r0,%r7,__PT_R0(%r9)
8700: lm %r8,%r9,__LC_RETURN_PSW 8700: lm %r8,%r9,__LC_RETURN_PSW
871 br %r14 871 br %r14
872cleanup_sysc_restore_insn: 872.Lcleanup_sysc_restore_insn:
873 .long sysc_done - 4 + 0x80000000 873 .long .Lsysc_done - 4 + 0x80000000
874 874
875cleanup_io_tif: 875.Lcleanup_io_tif:
876 l %r9,BASED(cleanup_table+20) # io_tif + 0x80000000 876 l %r9,BASED(.Lcleanup_table+20) # .Lio_tif + 0x80000000
877 br %r14 877 br %r14
878 878
879cleanup_io_restore: 879.Lcleanup_io_restore:
880 cl %r9,BASED(cleanup_io_restore_insn) 880 cl %r9,BASED(.Lcleanup_io_restore_insn)
881 jhe 0f 881 jhe 0f
882 l %r9,12(%r11) # get saved r11 pointer to pt_regs 882 l %r9,12(%r11) # get saved r11 pointer to pt_regs
883 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9) 883 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
@@ -885,10 +885,10 @@ cleanup_io_restore:
885 lm %r0,%r7,__PT_R0(%r9) 885 lm %r0,%r7,__PT_R0(%r9)
8860: lm %r8,%r9,__LC_RETURN_PSW 8860: lm %r8,%r9,__LC_RETURN_PSW
887 br %r14 887 br %r14
888cleanup_io_restore_insn: 888.Lcleanup_io_restore_insn:
889 .long io_done - 4 + 0x80000000 889 .long .Lio_done - 4 + 0x80000000
890 890
891cleanup_idle: 891.Lcleanup_idle:
892 # copy interrupt clock & cpu timer 892 # copy interrupt clock & cpu timer
893 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK 893 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
894 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER 894 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
@@ -897,7 +897,7 @@ cleanup_idle:
897 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK 897 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
898 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER 898 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
8990: # check if stck has been executed 8990: # check if stck has been executed
900 cl %r9,BASED(cleanup_idle_insn) 900 cl %r9,BASED(.Lcleanup_idle_insn)
901 jhe 1f 901 jhe 1f
902 mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2) 902 mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
903 mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r3) 903 mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r3)
@@ -913,12 +913,12 @@ cleanup_idle:
913 stm %r9,%r10,__LC_SYSTEM_TIMER 913 stm %r9,%r10,__LC_SYSTEM_TIMER
914 mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) 914 mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
915 # prepare return psw 915 # prepare return psw
916 n %r8,BASED(cleanup_idle_wait) # clear irq & wait state bits 916 n %r8,BASED(.Lcleanup_idle_wait) # clear irq & wait state bits
917 l %r9,24(%r11) # return from psw_idle 917 l %r9,24(%r11) # return from psw_idle
918 br %r14 918 br %r14
919cleanup_idle_insn: 919.Lcleanup_idle_insn:
920 .long psw_idle_lpsw + 0x80000000 920 .long .Lpsw_idle_lpsw + 0x80000000
921cleanup_idle_wait: 921.Lcleanup_idle_wait:
922 .long 0xfcfdffff 922 .long 0xfcfdffff
923 923
924/* 924/*
@@ -933,30 +933,30 @@ cleanup_idle_wait:
933/* 933/*
934 * Symbol constants 934 * Symbol constants
935 */ 935 */
936.Ldo_machine_check: .long s390_do_machine_check 936.Lc_do_machine_check: .long s390_do_machine_check
937.Lhandle_mcck: .long s390_handle_mcck 937.Lc_handle_mcck: .long s390_handle_mcck
938.Ldo_IRQ: .long do_IRQ 938.Lc_do_IRQ: .long do_IRQ
939.Ldo_signal: .long do_signal 939.Lc_do_signal: .long do_signal
940.Ldo_notify_resume: .long do_notify_resume 940.Lc_do_notify_resume: .long do_notify_resume
941.Ldo_per_trap: .long do_per_trap 941.Lc_do_per_trap: .long do_per_trap
942.Ljump_table: .long pgm_check_table 942.Lc_jump_table: .long pgm_check_table
943.Lschedule: .long schedule 943.Lc_schedule: .long schedule
944#ifdef CONFIG_PREEMPT 944#ifdef CONFIG_PREEMPT
945.Lpreempt_irq: .long preempt_schedule_irq 945.Lc_preempt_irq: .long preempt_schedule_irq
946#endif 946#endif
947.Ltrace_enter: .long do_syscall_trace_enter 947.Lc_trace_enter: .long do_syscall_trace_enter
948.Ltrace_exit: .long do_syscall_trace_exit 948.Lc_trace_exit: .long do_syscall_trace_exit
949.Lschedule_tail: .long schedule_tail 949.Lc_schedule_tail: .long schedule_tail
950.Lsysc_per: .long sysc_per + 0x80000000 950.Lc_sysc_per: .long .Lsysc_per + 0x80000000
951#ifdef CONFIG_TRACE_IRQFLAGS 951#ifdef CONFIG_TRACE_IRQFLAGS
952.Lhardirqs_on: .long trace_hardirqs_on_caller 952.Lc_hardirqs_on: .long trace_hardirqs_on_caller
953.Lhardirqs_off: .long trace_hardirqs_off_caller 953.Lc_hardirqs_off: .long trace_hardirqs_off_caller
954#endif 954#endif
955#ifdef CONFIG_LOCKDEP 955#ifdef CONFIG_LOCKDEP
956.Llockdep_sys_exit: .long lockdep_sys_exit 956.Lc_lockdep_sys_exit: .long lockdep_sys_exit
957#endif 957#endif
958.Lcritical_start: .long __critical_start + 0x80000000 958.Lc_critical_start: .long .L__critical_start + 0x80000000
959.Lcritical_length: .long __critical_end - __critical_start 959.Lc_critical_length: .long .L__critical_end - .L__critical_start
960 960
961 .section .rodata, "a" 961 .section .rodata, "a"
962#define SYSCALL(esa,esame,emu) .long esa 962#define SYSCALL(esa,esame,emu) .long esa
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 0554b9771c9f..8e61393c8275 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -74,4 +74,6 @@ struct old_sigaction;
74long sys_s390_personality(unsigned int personality); 74long sys_s390_personality(unsigned int personality);
75long sys_s390_runtime_instr(int command, int signum); 75long sys_s390_runtime_instr(int command, int signum);
76 76
77long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t);
78long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t);
77#endif /* _ENTRY_H */ 79#endif /* _ENTRY_H */
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7b2e03afd017..c329446a951d 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -91,7 +91,7 @@ _PIF_WORK = (_PIF_PER_TRAP)
91 .if \reason==1 91 .if \reason==1
92 # Some program interrupts are suppressing (e.g. protection). 92 # Some program interrupts are suppressing (e.g. protection).
93 # We must also check the instruction after SIE in that case. 93 # We must also check the instruction after SIE in that case.
94 # do_protection_exception will rewind to rewind_pad 94 # do_protection_exception will rewind to .Lrewind_pad
95 jh .+42 95 jh .+42
96 .else 96 .else
97 jhe .+42 97 jhe .+42
@@ -192,7 +192,7 @@ ENTRY(__switch_to)
192 lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task 192 lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
193 br %r14 193 br %r14
194 194
195__critical_start: 195.L__critical_start:
196/* 196/*
197 * SVC interrupt handler routine. System calls are synchronous events and 197 * SVC interrupt handler routine. System calls are synchronous events and
198 * are executed with interrupts enabled. 198 * are executed with interrupts enabled.
@@ -200,15 +200,15 @@ __critical_start:
200 200
201ENTRY(system_call) 201ENTRY(system_call)
202 stpt __LC_SYNC_ENTER_TIMER 202 stpt __LC_SYNC_ENTER_TIMER
203sysc_stmg: 203.Lsysc_stmg:
204 stmg %r8,%r15,__LC_SAVE_AREA_SYNC 204 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
205 lg %r10,__LC_LAST_BREAK 205 lg %r10,__LC_LAST_BREAK
206 lg %r12,__LC_THREAD_INFO 206 lg %r12,__LC_THREAD_INFO
207 lghi %r14,_PIF_SYSCALL 207 lghi %r14,_PIF_SYSCALL
208sysc_per: 208.Lsysc_per:
209 lg %r15,__LC_KERNEL_STACK 209 lg %r15,__LC_KERNEL_STACK
210 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs 210 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
211sysc_vtime: 211.Lsysc_vtime:
212 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER 212 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
213 LAST_BREAK %r13 213 LAST_BREAK %r13
214 stmg %r0,%r7,__PT_R0(%r11) 214 stmg %r0,%r7,__PT_R0(%r11)
@@ -216,39 +216,39 @@ sysc_vtime:
216 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW 216 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
217 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC 217 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
218 stg %r14,__PT_FLAGS(%r11) 218 stg %r14,__PT_FLAGS(%r11)
219sysc_do_svc: 219.Lsysc_do_svc:
220 lg %r10,__TI_sysc_table(%r12) # address of system call table 220 lg %r10,__TI_sysc_table(%r12) # address of system call table
221 llgh %r8,__PT_INT_CODE+2(%r11) 221 llgh %r8,__PT_INT_CODE+2(%r11)
222 slag %r8,%r8,2 # shift and test for svc 0 222 slag %r8,%r8,2 # shift and test for svc 0
223 jnz sysc_nr_ok 223 jnz .Lsysc_nr_ok
224 # svc 0: system call number in %r1 224 # svc 0: system call number in %r1
225 llgfr %r1,%r1 # clear high word in r1 225 llgfr %r1,%r1 # clear high word in r1
226 cghi %r1,NR_syscalls 226 cghi %r1,NR_syscalls
227 jnl sysc_nr_ok 227 jnl .Lsysc_nr_ok
228 sth %r1,__PT_INT_CODE+2(%r11) 228 sth %r1,__PT_INT_CODE+2(%r11)
229 slag %r8,%r1,2 229 slag %r8,%r1,2
230sysc_nr_ok: 230.Lsysc_nr_ok:
231 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 231 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
232 stg %r2,__PT_ORIG_GPR2(%r11) 232 stg %r2,__PT_ORIG_GPR2(%r11)
233 stg %r7,STACK_FRAME_OVERHEAD(%r15) 233 stg %r7,STACK_FRAME_OVERHEAD(%r15)
234 lgf %r9,0(%r8,%r10) # get system call add. 234 lgf %r9,0(%r8,%r10) # get system call add.
235 tm __TI_flags+7(%r12),_TIF_TRACE 235 tm __TI_flags+7(%r12),_TIF_TRACE
236 jnz sysc_tracesys 236 jnz .Lsysc_tracesys
237 basr %r14,%r9 # call sys_xxxx 237 basr %r14,%r9 # call sys_xxxx
238 stg %r2,__PT_R2(%r11) # store return value 238 stg %r2,__PT_R2(%r11) # store return value
239 239
240sysc_return: 240.Lsysc_return:
241 LOCKDEP_SYS_EXIT 241 LOCKDEP_SYS_EXIT
242sysc_tif: 242.Lsysc_tif:
243 tm __PT_PSW+1(%r11),0x01 # returning to user ? 243 tm __PT_PSW+1(%r11),0x01 # returning to user ?
244 jno sysc_restore 244 jno .Lsysc_restore
245 tm __PT_FLAGS+7(%r11),_PIF_WORK 245 tm __PT_FLAGS+7(%r11),_PIF_WORK
246 jnz sysc_work 246 jnz .Lsysc_work
247 tm __TI_flags+7(%r12),_TIF_WORK 247 tm __TI_flags+7(%r12),_TIF_WORK
248 jnz sysc_work # check for work 248 jnz .Lsysc_work # check for work
249 tm __LC_CPU_FLAGS+7,_CIF_WORK 249 tm __LC_CPU_FLAGS+7,_CIF_WORK
250 jnz sysc_work 250 jnz .Lsysc_work
251sysc_restore: 251.Lsysc_restore:
252 lg %r14,__LC_VDSO_PER_CPU 252 lg %r14,__LC_VDSO_PER_CPU
253 lmg %r0,%r10,__PT_R0(%r11) 253 lmg %r0,%r10,__PT_R0(%r11)
254 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 254 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
@@ -256,101 +256,101 @@ sysc_restore:
256 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 256 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
257 lmg %r11,%r15,__PT_R11(%r11) 257 lmg %r11,%r15,__PT_R11(%r11)
258 lpswe __LC_RETURN_PSW 258 lpswe __LC_RETURN_PSW
259sysc_done: 259.Lsysc_done:
260 260
261# 261#
262# One of the work bits is on. Find out which one. 262# One of the work bits is on. Find out which one.
263# 263#
264sysc_work: 264.Lsysc_work:
265 tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING 265 tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING
266 jo sysc_mcck_pending 266 jo .Lsysc_mcck_pending
267 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 267 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
268 jo sysc_reschedule 268 jo .Lsysc_reschedule
269#ifdef CONFIG_UPROBES 269#ifdef CONFIG_UPROBES
270 tm __TI_flags+7(%r12),_TIF_UPROBE 270 tm __TI_flags+7(%r12),_TIF_UPROBE
271 jo sysc_uprobe_notify 271 jo .Lsysc_uprobe_notify
272#endif 272#endif
273 tm __PT_FLAGS+7(%r11),_PIF_PER_TRAP 273 tm __PT_FLAGS+7(%r11),_PIF_PER_TRAP
274 jo sysc_singlestep 274 jo .Lsysc_singlestep
275 tm __TI_flags+7(%r12),_TIF_SIGPENDING 275 tm __TI_flags+7(%r12),_TIF_SIGPENDING
276 jo sysc_sigpending 276 jo .Lsysc_sigpending
277 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME 277 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
278 jo sysc_notify_resume 278 jo .Lsysc_notify_resume
279 tm __LC_CPU_FLAGS+7,_CIF_ASCE 279 tm __LC_CPU_FLAGS+7,_CIF_ASCE
280 jo sysc_uaccess 280 jo .Lsysc_uaccess
281 j sysc_return # beware of critical section cleanup 281 j .Lsysc_return # beware of critical section cleanup
282 282
283# 283#
284# _TIF_NEED_RESCHED is set, call schedule 284# _TIF_NEED_RESCHED is set, call schedule
285# 285#
286sysc_reschedule: 286.Lsysc_reschedule:
287 larl %r14,sysc_return 287 larl %r14,.Lsysc_return
288 jg schedule 288 jg schedule
289 289
290# 290#
291# _CIF_MCCK_PENDING is set, call handler 291# _CIF_MCCK_PENDING is set, call handler
292# 292#
293sysc_mcck_pending: 293.Lsysc_mcck_pending:
294 larl %r14,sysc_return 294 larl %r14,.Lsysc_return
295 jg s390_handle_mcck # TIF bit will be cleared by handler 295 jg s390_handle_mcck # TIF bit will be cleared by handler
296 296
297# 297#
298# _CIF_ASCE is set, load user space asce 298# _CIF_ASCE is set, load user space asce
299# 299#
300sysc_uaccess: 300.Lsysc_uaccess:
301 ni __LC_CPU_FLAGS+7,255-_CIF_ASCE 301 ni __LC_CPU_FLAGS+7,255-_CIF_ASCE
302 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 302 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
303 j sysc_return 303 j .Lsysc_return
304 304
305# 305#
306# _TIF_SIGPENDING is set, call do_signal 306# _TIF_SIGPENDING is set, call do_signal
307# 307#
308sysc_sigpending: 308.Lsysc_sigpending:
309 lgr %r2,%r11 # pass pointer to pt_regs 309 lgr %r2,%r11 # pass pointer to pt_regs
310 brasl %r14,do_signal 310 brasl %r14,do_signal
311 tm __PT_FLAGS+7(%r11),_PIF_SYSCALL 311 tm __PT_FLAGS+7(%r11),_PIF_SYSCALL
312 jno sysc_return 312 jno .Lsysc_return
313 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments 313 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
314 lg %r10,__TI_sysc_table(%r12) # address of system call table 314 lg %r10,__TI_sysc_table(%r12) # address of system call table
315 lghi %r8,0 # svc 0 returns -ENOSYS 315 lghi %r8,0 # svc 0 returns -ENOSYS
316 llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number 316 llgh %r1,__PT_INT_CODE+2(%r11) # load new svc number
317 cghi %r1,NR_syscalls 317 cghi %r1,NR_syscalls
318 jnl sysc_nr_ok # invalid svc number -> do svc 0 318 jnl .Lsysc_nr_ok # invalid svc number -> do svc 0
319 slag %r8,%r1,2 319 slag %r8,%r1,2
320 j sysc_nr_ok # restart svc 320 j .Lsysc_nr_ok # restart svc
321 321
322# 322#
323# _TIF_NOTIFY_RESUME is set, call do_notify_resume 323# _TIF_NOTIFY_RESUME is set, call do_notify_resume
324# 324#
325sysc_notify_resume: 325.Lsysc_notify_resume:
326 lgr %r2,%r11 # pass pointer to pt_regs 326 lgr %r2,%r11 # pass pointer to pt_regs
327 larl %r14,sysc_return 327 larl %r14,.Lsysc_return
328 jg do_notify_resume 328 jg do_notify_resume
329 329
330# 330#
331# _TIF_UPROBE is set, call uprobe_notify_resume 331# _TIF_UPROBE is set, call uprobe_notify_resume
332# 332#
333#ifdef CONFIG_UPROBES 333#ifdef CONFIG_UPROBES
334sysc_uprobe_notify: 334.Lsysc_uprobe_notify:
335 lgr %r2,%r11 # pass pointer to pt_regs 335 lgr %r2,%r11 # pass pointer to pt_regs
336 larl %r14,sysc_return 336 larl %r14,.Lsysc_return
337 jg uprobe_notify_resume 337 jg uprobe_notify_resume
338#endif 338#endif
339 339
340# 340#
341# _PIF_PER_TRAP is set, call do_per_trap 341# _PIF_PER_TRAP is set, call do_per_trap
342# 342#
343sysc_singlestep: 343.Lsysc_singlestep:
344 ni __PT_FLAGS+7(%r11),255-_PIF_PER_TRAP 344 ni __PT_FLAGS+7(%r11),255-_PIF_PER_TRAP
345 lgr %r2,%r11 # pass pointer to pt_regs 345 lgr %r2,%r11 # pass pointer to pt_regs
346 larl %r14,sysc_return 346 larl %r14,.Lsysc_return
347 jg do_per_trap 347 jg do_per_trap
348 348
349# 349#
350# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 350# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
351# and after the system call 351# and after the system call
352# 352#
353sysc_tracesys: 353.Lsysc_tracesys:
354 lgr %r2,%r11 # pass pointer to pt_regs 354 lgr %r2,%r11 # pass pointer to pt_regs
355 la %r3,0 355 la %r3,0
356 llgh %r0,__PT_INT_CODE+2(%r11) 356 llgh %r0,__PT_INT_CODE+2(%r11)
@@ -358,20 +358,20 @@ sysc_tracesys:
358 brasl %r14,do_syscall_trace_enter 358 brasl %r14,do_syscall_trace_enter
359 lghi %r0,NR_syscalls 359 lghi %r0,NR_syscalls
360 clgr %r0,%r2 360 clgr %r0,%r2
361 jnh sysc_tracenogo 361 jnh .Lsysc_tracenogo
362 sllg %r8,%r2,2 362 sllg %r8,%r2,2
363 lgf %r9,0(%r8,%r10) 363 lgf %r9,0(%r8,%r10)
364sysc_tracego: 364.Lsysc_tracego:
365 lmg %r3,%r7,__PT_R3(%r11) 365 lmg %r3,%r7,__PT_R3(%r11)
366 stg %r7,STACK_FRAME_OVERHEAD(%r15) 366 stg %r7,STACK_FRAME_OVERHEAD(%r15)
367 lg %r2,__PT_ORIG_GPR2(%r11) 367 lg %r2,__PT_ORIG_GPR2(%r11)
368 basr %r14,%r9 # call sys_xxx 368 basr %r14,%r9 # call sys_xxx
369 stg %r2,__PT_R2(%r11) # store return value 369 stg %r2,__PT_R2(%r11) # store return value
370sysc_tracenogo: 370.Lsysc_tracenogo:
371 tm __TI_flags+7(%r12),_TIF_TRACE 371 tm __TI_flags+7(%r12),_TIF_TRACE
372 jz sysc_return 372 jz .Lsysc_return
373 lgr %r2,%r11 # pass pointer to pt_regs 373 lgr %r2,%r11 # pass pointer to pt_regs
374 larl %r14,sysc_return 374 larl %r14,.Lsysc_return
375 jg do_syscall_trace_exit 375 jg do_syscall_trace_exit
376 376
377# 377#
@@ -384,13 +384,13 @@ ENTRY(ret_from_fork)
384 TRACE_IRQS_ON 384 TRACE_IRQS_ON
385 ssm __LC_SVC_NEW_PSW # reenable interrupts 385 ssm __LC_SVC_NEW_PSW # reenable interrupts
386 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ? 386 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
387 jne sysc_tracenogo 387 jne .Lsysc_tracenogo
388 # it's a kernel thread 388 # it's a kernel thread
389 lmg %r9,%r10,__PT_R9(%r11) # load gprs 389 lmg %r9,%r10,__PT_R9(%r11) # load gprs
390ENTRY(kernel_thread_starter) 390ENTRY(kernel_thread_starter)
391 la %r2,0(%r10) 391 la %r2,0(%r10)
392 basr %r14,%r9 392 basr %r14,%r9
393 j sysc_tracenogo 393 j .Lsysc_tracenogo
394 394
395/* 395/*
396 * Program check handler routine 396 * Program check handler routine
@@ -409,7 +409,7 @@ ENTRY(pgm_check_handler)
409 tmhh %r8,0x4000 # PER bit set in old PSW ? 409 tmhh %r8,0x4000 # PER bit set in old PSW ?
410 jnz 0f # -> enabled, can't be a double fault 410 jnz 0f # -> enabled, can't be a double fault
411 tm __LC_PGM_ILC+3,0x80 # check for per exception 411 tm __LC_PGM_ILC+3,0x80 # check for per exception
412 jnz pgm_svcper # -> single stepped svc 412 jnz .Lpgm_svcper # -> single stepped svc
4130: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC 4130: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
414 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 414 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
415 j 2f 415 j 2f
@@ -432,7 +432,7 @@ ENTRY(pgm_check_handler)
432 tm __LC_PGM_ILC+3,0x80 # check for per exception 432 tm __LC_PGM_ILC+3,0x80 # check for per exception
433 jz 0f 433 jz 0f
434 tmhh %r8,0x0001 # kernel per event ? 434 tmhh %r8,0x0001 # kernel per event ?
435 jz pgm_kprobe 435 jz .Lpgm_kprobe
436 oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP 436 oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP
437 mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS 437 mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS
438 mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE 438 mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE
@@ -443,31 +443,31 @@ ENTRY(pgm_check_handler)
443 llgh %r10,__PT_INT_CODE+2(%r11) 443 llgh %r10,__PT_INT_CODE+2(%r11)
444 nill %r10,0x007f 444 nill %r10,0x007f
445 sll %r10,2 445 sll %r10,2
446 je sysc_return 446 je .Lsysc_return
447 lgf %r1,0(%r10,%r1) # load address of handler routine 447 lgf %r1,0(%r10,%r1) # load address of handler routine
448 lgr %r2,%r11 # pass pointer to pt_regs 448 lgr %r2,%r11 # pass pointer to pt_regs
449 basr %r14,%r1 # branch to interrupt-handler 449 basr %r14,%r1 # branch to interrupt-handler
450 j sysc_return 450 j .Lsysc_return
451 451
452# 452#
453# PER event in supervisor state, must be kprobes 453# PER event in supervisor state, must be kprobes
454# 454#
455pgm_kprobe: 455.Lpgm_kprobe:
456 REENABLE_IRQS 456 REENABLE_IRQS
457 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 457 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
458 lgr %r2,%r11 # pass pointer to pt_regs 458 lgr %r2,%r11 # pass pointer to pt_regs
459 brasl %r14,do_per_trap 459 brasl %r14,do_per_trap
460 j sysc_return 460 j .Lsysc_return
461 461
462# 462#
463# single stepped system call 463# single stepped system call
464# 464#
465pgm_svcper: 465.Lpgm_svcper:
466 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW 466 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
467 larl %r14,sysc_per 467 larl %r14,.Lsysc_per
468 stg %r14,__LC_RETURN_PSW+8 468 stg %r14,__LC_RETURN_PSW+8
469 lghi %r14,_PIF_SYSCALL | _PIF_PER_TRAP 469 lghi %r14,_PIF_SYSCALL | _PIF_PER_TRAP
470 lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs 470 lpswe __LC_RETURN_PSW # branch to .Lsysc_per and enable irqs
471 471
472/* 472/*
473 * IO interrupt handler routine 473 * IO interrupt handler routine
@@ -483,10 +483,10 @@ ENTRY(io_int_handler)
483 HANDLE_SIE_INTERCEPT %r14,2 483 HANDLE_SIE_INTERCEPT %r14,2
484 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 484 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
485 tmhh %r8,0x0001 # interrupting from user? 485 tmhh %r8,0x0001 # interrupting from user?
486 jz io_skip 486 jz .Lio_skip
487 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER 487 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
488 LAST_BREAK %r14 488 LAST_BREAK %r14
489io_skip: 489.Lio_skip:
490 stmg %r0,%r7,__PT_R0(%r11) 490 stmg %r0,%r7,__PT_R0(%r11)
491 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 491 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
492 stmg %r8,%r9,__PT_PSW(%r11) 492 stmg %r8,%r9,__PT_PSW(%r11)
@@ -494,29 +494,29 @@ io_skip:
494 xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) 494 xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11)
495 TRACE_IRQS_OFF 495 TRACE_IRQS_OFF
496 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 496 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
497io_loop: 497.Lio_loop:
498 lgr %r2,%r11 # pass pointer to pt_regs 498 lgr %r2,%r11 # pass pointer to pt_regs
499 lghi %r3,IO_INTERRUPT 499 lghi %r3,IO_INTERRUPT
500 tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ? 500 tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ?
501 jz io_call 501 jz .Lio_call
502 lghi %r3,THIN_INTERRUPT 502 lghi %r3,THIN_INTERRUPT
503io_call: 503.Lio_call:
504 brasl %r14,do_IRQ 504 brasl %r14,do_IRQ
505 tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR 505 tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR
506 jz io_return 506 jz .Lio_return
507 tpi 0 507 tpi 0
508 jz io_return 508 jz .Lio_return
509 mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID 509 mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID
510 j io_loop 510 j .Lio_loop
511io_return: 511.Lio_return:
512 LOCKDEP_SYS_EXIT 512 LOCKDEP_SYS_EXIT
513 TRACE_IRQS_ON 513 TRACE_IRQS_ON
514io_tif: 514.Lio_tif:
515 tm __TI_flags+7(%r12),_TIF_WORK 515 tm __TI_flags+7(%r12),_TIF_WORK
516 jnz io_work # there is work to do (signals etc.) 516 jnz .Lio_work # there is work to do (signals etc.)
517 tm __LC_CPU_FLAGS+7,_CIF_WORK 517 tm __LC_CPU_FLAGS+7,_CIF_WORK
518 jnz io_work 518 jnz .Lio_work
519io_restore: 519.Lio_restore:
520 lg %r14,__LC_VDSO_PER_CPU 520 lg %r14,__LC_VDSO_PER_CPU
521 lmg %r0,%r10,__PT_R0(%r11) 521 lmg %r0,%r10,__PT_R0(%r11)
522 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 522 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
@@ -524,7 +524,7 @@ io_restore:
524 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 524 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
525 lmg %r11,%r15,__PT_R11(%r11) 525 lmg %r11,%r15,__PT_R11(%r11)
526 lpswe __LC_RETURN_PSW 526 lpswe __LC_RETURN_PSW
527io_done: 527.Lio_done:
528 528
529# 529#
530# There is work todo, find out in which context we have been interrupted: 530# There is work todo, find out in which context we have been interrupted:
@@ -535,15 +535,15 @@ io_done:
535# the preemption counter and if it is zero call preempt_schedule_irq 535# the preemption counter and if it is zero call preempt_schedule_irq
536# Before any work can be done, a switch to the kernel stack is required. 536# Before any work can be done, a switch to the kernel stack is required.
537# 537#
538io_work: 538.Lio_work:
539 tm __PT_PSW+1(%r11),0x01 # returning to user ? 539 tm __PT_PSW+1(%r11),0x01 # returning to user ?
540 jo io_work_user # yes -> do resched & signal 540 jo .Lio_work_user # yes -> do resched & signal
541#ifdef CONFIG_PREEMPT 541#ifdef CONFIG_PREEMPT
542 # check for preemptive scheduling 542 # check for preemptive scheduling
543 icm %r0,15,__TI_precount(%r12) 543 icm %r0,15,__TI_precount(%r12)
544 jnz io_restore # preemption is disabled 544 jnz .Lio_restore # preemption is disabled
545 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 545 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
546 jno io_restore 546 jno .Lio_restore
547 # switch to kernel stack 547 # switch to kernel stack
548 lg %r1,__PT_R15(%r11) 548 lg %r1,__PT_R15(%r11)
549 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 549 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
@@ -551,19 +551,19 @@ io_work:
551 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 551 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
552 la %r11,STACK_FRAME_OVERHEAD(%r1) 552 la %r11,STACK_FRAME_OVERHEAD(%r1)
553 lgr %r15,%r1 553 lgr %r15,%r1
554 # TRACE_IRQS_ON already done at io_return, call 554 # TRACE_IRQS_ON already done at .Lio_return, call
555 # TRACE_IRQS_OFF to keep things symmetrical 555 # TRACE_IRQS_OFF to keep things symmetrical
556 TRACE_IRQS_OFF 556 TRACE_IRQS_OFF
557 brasl %r14,preempt_schedule_irq 557 brasl %r14,preempt_schedule_irq
558 j io_return 558 j .Lio_return
559#else 559#else
560 j io_restore 560 j .Lio_restore
561#endif 561#endif
562 562
563# 563#
564# Need to do work before returning to userspace, switch to kernel stack 564# Need to do work before returning to userspace, switch to kernel stack
565# 565#
566io_work_user: 566.Lio_work_user:
567 lg %r1,__LC_KERNEL_STACK 567 lg %r1,__LC_KERNEL_STACK
568 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 568 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
569 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 569 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
@@ -573,70 +573,70 @@ io_work_user:
573# 573#
574# One of the work bits is on. Find out which one. 574# One of the work bits is on. Find out which one.
575# 575#
576io_work_tif: 576.Lio_work_tif:
577 tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING 577 tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING
578 jo io_mcck_pending 578 jo .Lio_mcck_pending
579 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 579 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
580 jo io_reschedule 580 jo .Lio_reschedule
581 tm __TI_flags+7(%r12),_TIF_SIGPENDING 581 tm __TI_flags+7(%r12),_TIF_SIGPENDING
582 jo io_sigpending 582 jo .Lio_sigpending
583 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME 583 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
584 jo io_notify_resume 584 jo .Lio_notify_resume
585 tm __LC_CPU_FLAGS+7,_CIF_ASCE 585 tm __LC_CPU_FLAGS+7,_CIF_ASCE
586 jo io_uaccess 586 jo .Lio_uaccess
587 j io_return # beware of critical section cleanup 587 j .Lio_return # beware of critical section cleanup
588 588
589# 589#
590# _CIF_MCCK_PENDING is set, call handler 590# _CIF_MCCK_PENDING is set, call handler
591# 591#
592io_mcck_pending: 592.Lio_mcck_pending:
593 # TRACE_IRQS_ON already done at io_return 593 # TRACE_IRQS_ON already done at .Lio_return
594 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler 594 brasl %r14,s390_handle_mcck # TIF bit will be cleared by handler
595 TRACE_IRQS_OFF 595 TRACE_IRQS_OFF
596 j io_return 596 j .Lio_return
597 597
598# 598#
599# _CIF_ASCE is set, load user space asce 599# _CIF_ASCE is set, load user space asce
600# 600#
601io_uaccess: 601.Lio_uaccess:
602 ni __LC_CPU_FLAGS+7,255-_CIF_ASCE 602 ni __LC_CPU_FLAGS+7,255-_CIF_ASCE
603 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 603 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
604 j io_return 604 j .Lio_return
605 605
606# 606#
607# _TIF_NEED_RESCHED is set, call schedule 607# _TIF_NEED_RESCHED is set, call schedule
608# 608#
609io_reschedule: 609.Lio_reschedule:
610 # TRACE_IRQS_ON already done at io_return 610 # TRACE_IRQS_ON already done at .Lio_return
611 ssm __LC_SVC_NEW_PSW # reenable interrupts 611 ssm __LC_SVC_NEW_PSW # reenable interrupts
612 brasl %r14,schedule # call scheduler 612 brasl %r14,schedule # call scheduler
613 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts 613 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
614 TRACE_IRQS_OFF 614 TRACE_IRQS_OFF
615 j io_return 615 j .Lio_return
616 616
617# 617#
618# _TIF_SIGPENDING or is set, call do_signal 618# _TIF_SIGPENDING or is set, call do_signal
619# 619#
620io_sigpending: 620.Lio_sigpending:
621 # TRACE_IRQS_ON already done at io_return 621 # TRACE_IRQS_ON already done at .Lio_return
622 ssm __LC_SVC_NEW_PSW # reenable interrupts 622 ssm __LC_SVC_NEW_PSW # reenable interrupts
623 lgr %r2,%r11 # pass pointer to pt_regs 623 lgr %r2,%r11 # pass pointer to pt_regs
624 brasl %r14,do_signal 624 brasl %r14,do_signal
625 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts 625 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
626 TRACE_IRQS_OFF 626 TRACE_IRQS_OFF
627 j io_return 627 j .Lio_return
628 628
629# 629#
630# _TIF_NOTIFY_RESUME or is set, call do_notify_resume 630# _TIF_NOTIFY_RESUME or is set, call do_notify_resume
631# 631#
632io_notify_resume: 632.Lio_notify_resume:
633 # TRACE_IRQS_ON already done at io_return 633 # TRACE_IRQS_ON already done at .Lio_return
634 ssm __LC_SVC_NEW_PSW # reenable interrupts 634 ssm __LC_SVC_NEW_PSW # reenable interrupts
635 lgr %r2,%r11 # pass pointer to pt_regs 635 lgr %r2,%r11 # pass pointer to pt_regs
636 brasl %r14,do_notify_resume 636 brasl %r14,do_notify_resume
637 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts 637 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
638 TRACE_IRQS_OFF 638 TRACE_IRQS_OFF
639 j io_return 639 j .Lio_return
640 640
641/* 641/*
642 * External interrupt handler routine 642 * External interrupt handler routine
@@ -652,10 +652,10 @@ ENTRY(ext_int_handler)
652 HANDLE_SIE_INTERCEPT %r14,3 652 HANDLE_SIE_INTERCEPT %r14,3
653 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 653 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
654 tmhh %r8,0x0001 # interrupting from user ? 654 tmhh %r8,0x0001 # interrupting from user ?
655 jz ext_skip 655 jz .Lext_skip
656 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER 656 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
657 LAST_BREAK %r14 657 LAST_BREAK %r14
658ext_skip: 658.Lext_skip:
659 stmg %r0,%r7,__PT_R0(%r11) 659 stmg %r0,%r7,__PT_R0(%r11)
660 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC 660 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
661 stmg %r8,%r9,__PT_PSW(%r11) 661 stmg %r8,%r9,__PT_PSW(%r11)
@@ -669,23 +669,23 @@ ext_skip:
669 lgr %r2,%r11 # pass pointer to pt_regs 669 lgr %r2,%r11 # pass pointer to pt_regs
670 lghi %r3,EXT_INTERRUPT 670 lghi %r3,EXT_INTERRUPT
671 brasl %r14,do_IRQ 671 brasl %r14,do_IRQ
672 j io_return 672 j .Lio_return
673 673
674/* 674/*
675 * Load idle PSW. The second "half" of this function is in cleanup_idle. 675 * Load idle PSW. The second "half" of this function is in .Lcleanup_idle.
676 */ 676 */
677ENTRY(psw_idle) 677ENTRY(psw_idle)
678 stg %r3,__SF_EMPTY(%r15) 678 stg %r3,__SF_EMPTY(%r15)
679 larl %r1,psw_idle_lpsw+4 679 larl %r1,.Lpsw_idle_lpsw+4
680 stg %r1,__SF_EMPTY+8(%r15) 680 stg %r1,__SF_EMPTY+8(%r15)
681 STCK __CLOCK_IDLE_ENTER(%r2) 681 STCK __CLOCK_IDLE_ENTER(%r2)
682 stpt __TIMER_IDLE_ENTER(%r2) 682 stpt __TIMER_IDLE_ENTER(%r2)
683psw_idle_lpsw: 683.Lpsw_idle_lpsw:
684 lpswe __SF_EMPTY(%r15) 684 lpswe __SF_EMPTY(%r15)
685 br %r14 685 br %r14
686psw_idle_end: 686.Lpsw_idle_end:
687 687
688__critical_end: 688.L__critical_end:
689 689
690/* 690/*
691 * Machine check handler routines 691 * Machine check handler routines
@@ -701,7 +701,7 @@ ENTRY(mcck_int_handler)
701 lmg %r8,%r9,__LC_MCK_OLD_PSW 701 lmg %r8,%r9,__LC_MCK_OLD_PSW
702 HANDLE_SIE_INTERCEPT %r14,4 702 HANDLE_SIE_INTERCEPT %r14,4
703 tm __LC_MCCK_CODE,0x80 # system damage? 703 tm __LC_MCCK_CODE,0x80 # system damage?
704 jo mcck_panic # yes -> rest of mcck code invalid 704 jo .Lmcck_panic # yes -> rest of mcck code invalid
705 lghi %r14,__LC_CPU_TIMER_SAVE_AREA 705 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
706 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 706 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
707 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 707 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
@@ -719,13 +719,13 @@ ENTRY(mcck_int_handler)
7192: spt 0(%r14) 7192: spt 0(%r14)
720 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 720 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7213: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 7213: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
722 jno mcck_panic # no -> skip cleanup critical 722 jno .Lmcck_panic # no -> skip cleanup critical
723 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT 723 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT
724 tm %r8,0x0001 # interrupting from user ? 724 tm %r8,0x0001 # interrupting from user ?
725 jz mcck_skip 725 jz .Lmcck_skip
726 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER 726 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
727 LAST_BREAK %r14 727 LAST_BREAK %r14
728mcck_skip: 728.Lmcck_skip:
729 lghi %r14,__LC_GPREGS_SAVE_AREA+64 729 lghi %r14,__LC_GPREGS_SAVE_AREA+64
730 stmg %r0,%r7,__PT_R0(%r11) 730 stmg %r0,%r7,__PT_R0(%r11)
731 mvc __PT_R8(64,%r11),0(%r14) 731 mvc __PT_R8(64,%r11),0(%r14)
@@ -735,7 +735,7 @@ mcck_skip:
735 lgr %r2,%r11 # pass pointer to pt_regs 735 lgr %r2,%r11 # pass pointer to pt_regs
736 brasl %r14,s390_do_machine_check 736 brasl %r14,s390_do_machine_check
737 tm __PT_PSW+1(%r11),0x01 # returning to user ? 737 tm __PT_PSW+1(%r11),0x01 # returning to user ?
738 jno mcck_return 738 jno .Lmcck_return
739 lg %r1,__LC_KERNEL_STACK # switch to kernel stack 739 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
740 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) 740 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
741 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) 741 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
@@ -743,11 +743,11 @@ mcck_skip:
743 lgr %r15,%r1 743 lgr %r15,%r1
744 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off 744 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
745 tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING 745 tm __LC_CPU_FLAGS+7,_CIF_MCCK_PENDING
746 jno mcck_return 746 jno .Lmcck_return
747 TRACE_IRQS_OFF 747 TRACE_IRQS_OFF
748 brasl %r14,s390_handle_mcck 748 brasl %r14,s390_handle_mcck
749 TRACE_IRQS_ON 749 TRACE_IRQS_ON
750mcck_return: 750.Lmcck_return:
751 lg %r14,__LC_VDSO_PER_CPU 751 lg %r14,__LC_VDSO_PER_CPU
752 lmg %r0,%r10,__PT_R0(%r11) 752 lmg %r0,%r10,__PT_R0(%r11)
753 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 753 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
@@ -758,14 +758,14 @@ mcck_return:
7580: lmg %r11,%r15,__PT_R11(%r11) 7580: lmg %r11,%r15,__PT_R11(%r11)
759 lpswe __LC_RETURN_MCCK_PSW 759 lpswe __LC_RETURN_MCCK_PSW
760 760
761mcck_panic: 761.Lmcck_panic:
762 lg %r14,__LC_PANIC_STACK 762 lg %r14,__LC_PANIC_STACK
763 slgr %r14,%r15 763 slgr %r14,%r15
764 srag %r14,%r14,PAGE_SHIFT 764 srag %r14,%r14,PAGE_SHIFT
765 jz 0f 765 jz 0f
766 lg %r15,__LC_PANIC_STACK 766 lg %r15,__LC_PANIC_STACK
7670: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 7670: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
768 j mcck_skip 768 j .Lmcck_skip
769 769
770# 770#
771# PSW restart interrupt handler 771# PSW restart interrupt handler
@@ -815,69 +815,69 @@ stack_overflow:
815#endif 815#endif
816 816
817 .align 8 817 .align 8
818cleanup_table: 818.Lcleanup_table:
819 .quad system_call 819 .quad system_call
820 .quad sysc_do_svc 820 .quad .Lsysc_do_svc
821 .quad sysc_tif 821 .quad .Lsysc_tif
822 .quad sysc_restore 822 .quad .Lsysc_restore
823 .quad sysc_done 823 .quad .Lsysc_done
824 .quad io_tif 824 .quad .Lio_tif
825 .quad io_restore 825 .quad .Lio_restore
826 .quad io_done 826 .quad .Lio_done
827 .quad psw_idle 827 .quad psw_idle
828 .quad psw_idle_end 828 .quad .Lpsw_idle_end
829 829
830cleanup_critical: 830cleanup_critical:
831 clg %r9,BASED(cleanup_table) # system_call 831 clg %r9,BASED(.Lcleanup_table) # system_call
832 jl 0f 832 jl 0f
833 clg %r9,BASED(cleanup_table+8) # sysc_do_svc 833 clg %r9,BASED(.Lcleanup_table+8) # .Lsysc_do_svc
834 jl cleanup_system_call 834 jl .Lcleanup_system_call
835 clg %r9,BASED(cleanup_table+16) # sysc_tif 835 clg %r9,BASED(.Lcleanup_table+16) # .Lsysc_tif
836 jl 0f 836 jl 0f
837 clg %r9,BASED(cleanup_table+24) # sysc_restore 837 clg %r9,BASED(.Lcleanup_table+24) # .Lsysc_restore
838 jl cleanup_sysc_tif 838 jl .Lcleanup_sysc_tif
839 clg %r9,BASED(cleanup_table+32) # sysc_done 839 clg %r9,BASED(.Lcleanup_table+32) # .Lsysc_done
840 jl cleanup_sysc_restore 840 jl .Lcleanup_sysc_restore
841 clg %r9,BASED(cleanup_table+40) # io_tif 841 clg %r9,BASED(.Lcleanup_table+40) # .Lio_tif
842 jl 0f 842 jl 0f
843 clg %r9,BASED(cleanup_table+48) # io_restore 843 clg %r9,BASED(.Lcleanup_table+48) # .Lio_restore
844 jl cleanup_io_tif 844 jl .Lcleanup_io_tif
845 clg %r9,BASED(cleanup_table+56) # io_done 845 clg %r9,BASED(.Lcleanup_table+56) # .Lio_done
846 jl cleanup_io_restore 846 jl .Lcleanup_io_restore
847 clg %r9,BASED(cleanup_table+64) # psw_idle 847 clg %r9,BASED(.Lcleanup_table+64) # psw_idle
848 jl 0f 848 jl 0f
849 clg %r9,BASED(cleanup_table+72) # psw_idle_end 849 clg %r9,BASED(.Lcleanup_table+72) # .Lpsw_idle_end
850 jl cleanup_idle 850 jl .Lcleanup_idle
8510: br %r14 8510: br %r14
852 852
853 853
854cleanup_system_call: 854.Lcleanup_system_call:
855 # check if stpt has been executed 855 # check if stpt has been executed
856 clg %r9,BASED(cleanup_system_call_insn) 856 clg %r9,BASED(.Lcleanup_system_call_insn)
857 jh 0f 857 jh 0f
858 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 858 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
859 cghi %r11,__LC_SAVE_AREA_ASYNC 859 cghi %r11,__LC_SAVE_AREA_ASYNC
860 je 0f 860 je 0f
861 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER 861 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
8620: # check if stmg has been executed 8620: # check if stmg has been executed
863 clg %r9,BASED(cleanup_system_call_insn+8) 863 clg %r9,BASED(.Lcleanup_system_call_insn+8)
864 jh 0f 864 jh 0f
865 mvc __LC_SAVE_AREA_SYNC(64),0(%r11) 865 mvc __LC_SAVE_AREA_SYNC(64),0(%r11)
8660: # check if base register setup + TIF bit load has been done 8660: # check if base register setup + TIF bit load has been done
867 clg %r9,BASED(cleanup_system_call_insn+16) 867 clg %r9,BASED(.Lcleanup_system_call_insn+16)
868 jhe 0f 868 jhe 0f
869 # set up saved registers r10 and r12 869 # set up saved registers r10 and r12
870 stg %r10,16(%r11) # r10 last break 870 stg %r10,16(%r11) # r10 last break
871 stg %r12,32(%r11) # r12 thread-info pointer 871 stg %r12,32(%r11) # r12 thread-info pointer
8720: # check if the user time update has been done 8720: # check if the user time update has been done
873 clg %r9,BASED(cleanup_system_call_insn+24) 873 clg %r9,BASED(.Lcleanup_system_call_insn+24)
874 jh 0f 874 jh 0f
875 lg %r15,__LC_EXIT_TIMER 875 lg %r15,__LC_EXIT_TIMER
876 slg %r15,__LC_SYNC_ENTER_TIMER 876 slg %r15,__LC_SYNC_ENTER_TIMER
877 alg %r15,__LC_USER_TIMER 877 alg %r15,__LC_USER_TIMER
878 stg %r15,__LC_USER_TIMER 878 stg %r15,__LC_USER_TIMER
8790: # check if the system time update has been done 8790: # check if the system time update has been done
880 clg %r9,BASED(cleanup_system_call_insn+32) 880 clg %r9,BASED(.Lcleanup_system_call_insn+32)
881 jh 0f 881 jh 0f
882 lg %r15,__LC_LAST_UPDATE_TIMER 882 lg %r15,__LC_LAST_UPDATE_TIMER
883 slg %r15,__LC_EXIT_TIMER 883 slg %r15,__LC_EXIT_TIMER
@@ -904,21 +904,21 @@ cleanup_system_call:
904 # setup saved register r15 904 # setup saved register r15
905 stg %r15,56(%r11) # r15 stack pointer 905 stg %r15,56(%r11) # r15 stack pointer
906 # set new psw address and exit 906 # set new psw address and exit
907 larl %r9,sysc_do_svc 907 larl %r9,.Lsysc_do_svc
908 br %r14 908 br %r14
909cleanup_system_call_insn: 909.Lcleanup_system_call_insn:
910 .quad system_call 910 .quad system_call
911 .quad sysc_stmg 911 .quad .Lsysc_stmg
912 .quad sysc_per 912 .quad .Lsysc_per
913 .quad sysc_vtime+18 913 .quad .Lsysc_vtime+18
914 .quad sysc_vtime+42 914 .quad .Lsysc_vtime+42
915 915
916cleanup_sysc_tif: 916.Lcleanup_sysc_tif:
917 larl %r9,sysc_tif 917 larl %r9,.Lsysc_tif
918 br %r14 918 br %r14
919 919
920cleanup_sysc_restore: 920.Lcleanup_sysc_restore:
921 clg %r9,BASED(cleanup_sysc_restore_insn) 921 clg %r9,BASED(.Lcleanup_sysc_restore_insn)
922 je 0f 922 je 0f
923 lg %r9,24(%r11) # get saved pointer to pt_regs 923 lg %r9,24(%r11) # get saved pointer to pt_regs
924 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) 924 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
@@ -926,15 +926,15 @@ cleanup_sysc_restore:
926 lmg %r0,%r7,__PT_R0(%r9) 926 lmg %r0,%r7,__PT_R0(%r9)
9270: lmg %r8,%r9,__LC_RETURN_PSW 9270: lmg %r8,%r9,__LC_RETURN_PSW
928 br %r14 928 br %r14
929cleanup_sysc_restore_insn: 929.Lcleanup_sysc_restore_insn:
930 .quad sysc_done - 4 930 .quad .Lsysc_done - 4
931 931
932cleanup_io_tif: 932.Lcleanup_io_tif:
933 larl %r9,io_tif 933 larl %r9,.Lio_tif
934 br %r14 934 br %r14
935 935
936cleanup_io_restore: 936.Lcleanup_io_restore:
937 clg %r9,BASED(cleanup_io_restore_insn) 937 clg %r9,BASED(.Lcleanup_io_restore_insn)
938 je 0f 938 je 0f
939 lg %r9,24(%r11) # get saved r11 pointer to pt_regs 939 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
940 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) 940 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
@@ -942,10 +942,10 @@ cleanup_io_restore:
942 lmg %r0,%r7,__PT_R0(%r9) 942 lmg %r0,%r7,__PT_R0(%r9)
9430: lmg %r8,%r9,__LC_RETURN_PSW 9430: lmg %r8,%r9,__LC_RETURN_PSW
944 br %r14 944 br %r14
945cleanup_io_restore_insn: 945.Lcleanup_io_restore_insn:
946 .quad io_done - 4 946 .quad .Lio_done - 4
947 947
948cleanup_idle: 948.Lcleanup_idle:
949 # copy interrupt clock & cpu timer 949 # copy interrupt clock & cpu timer
950 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK 950 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
951 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER 951 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
@@ -954,7 +954,7 @@ cleanup_idle:
954 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK 954 mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
955 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER 955 mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
9560: # check if stck & stpt have been executed 9560: # check if stck & stpt have been executed
957 clg %r9,BASED(cleanup_idle_insn) 957 clg %r9,BASED(.Lcleanup_idle_insn)
958 jhe 1f 958 jhe 1f
959 mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2) 959 mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
960 mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2) 960 mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r2)
@@ -973,17 +973,17 @@ cleanup_idle:
973 nihh %r8,0xfcfd # clear irq & wait state bits 973 nihh %r8,0xfcfd # clear irq & wait state bits
974 lg %r9,48(%r11) # return from psw_idle 974 lg %r9,48(%r11) # return from psw_idle
975 br %r14 975 br %r14
976cleanup_idle_insn: 976.Lcleanup_idle_insn:
977 .quad psw_idle_lpsw 977 .quad .Lpsw_idle_lpsw
978 978
979/* 979/*
980 * Integer constants 980 * Integer constants
981 */ 981 */
982 .align 8 982 .align 8
983.Lcritical_start: 983.Lcritical_start:
984 .quad __critical_start 984 .quad .L__critical_start
985.Lcritical_length: 985.Lcritical_length:
986 .quad __critical_end - __critical_start 986 .quad .L__critical_end - .L__critical_start
987 987
988 988
989#if IS_ENABLED(CONFIG_KVM) 989#if IS_ENABLED(CONFIG_KVM)
@@ -1000,25 +1000,25 @@ ENTRY(sie64a)
1000 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 1000 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
1001 lg %r14,__LC_GMAP # get gmap pointer 1001 lg %r14,__LC_GMAP # get gmap pointer
1002 ltgr %r14,%r14 1002 ltgr %r14,%r14
1003 jz sie_gmap 1003 jz .Lsie_gmap
1004 lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce 1004 lctlg %c1,%c1,__GMAP_ASCE(%r14) # load primary asce
1005sie_gmap: 1005.Lsie_gmap:
1006 lg %r14,__SF_EMPTY(%r15) # get control block pointer 1006 lg %r14,__SF_EMPTY(%r15) # get control block pointer
1007 oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now 1007 oi __SIE_PROG0C+3(%r14),1 # we are going into SIE now
1008 tm __SIE_PROG20+3(%r14),1 # last exit... 1008 tm __SIE_PROG20+3(%r14),1 # last exit...
1009 jnz sie_done 1009 jnz .Lsie_done
1010 LPP __SF_EMPTY(%r15) # set guest id 1010 LPP __SF_EMPTY(%r15) # set guest id
1011 sie 0(%r14) 1011 sie 0(%r14)
1012sie_done: 1012.Lsie_done:
1013 LPP __SF_EMPTY+16(%r15) # set host id 1013 LPP __SF_EMPTY+16(%r15) # set host id
1014 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE 1014 ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
1015 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 1015 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
1016# some program checks are suppressing. C code (e.g. do_protection_exception) 1016# some program checks are suppressing. C code (e.g. do_protection_exception)
1017# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other 1017# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
1018# instructions between sie64a and sie_done should not cause program 1018# instructions between sie64a and .Lsie_done should not cause program
1019# interrupts. So lets use a nop (47 00 00 00) as a landing pad. 1019# interrupts. So lets use a nop (47 00 00 00) as a landing pad.
1020# See also HANDLE_SIE_INTERCEPT 1020# See also HANDLE_SIE_INTERCEPT
1021rewind_pad: 1021.Lrewind_pad:
1022 nop 0 1022 nop 0
1023 .globl sie_exit 1023 .globl sie_exit
1024sie_exit: 1024sie_exit:
@@ -1027,19 +1027,19 @@ sie_exit:
1027 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers 1027 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
1028 lg %r2,__SF_EMPTY+24(%r15) # return exit reason code 1028 lg %r2,__SF_EMPTY+24(%r15) # return exit reason code
1029 br %r14 1029 br %r14
1030sie_fault: 1030.Lsie_fault:
1031 lghi %r14,-EFAULT 1031 lghi %r14,-EFAULT
1032 stg %r14,__SF_EMPTY+24(%r15) # set exit reason code 1032 stg %r14,__SF_EMPTY+24(%r15) # set exit reason code
1033 j sie_exit 1033 j sie_exit
1034 1034
1035 .align 8 1035 .align 8
1036.Lsie_critical: 1036.Lsie_critical:
1037 .quad sie_gmap 1037 .quad .Lsie_gmap
1038.Lsie_critical_length: 1038.Lsie_critical_length:
1039 .quad sie_done - sie_gmap 1039 .quad .Lsie_done - .Lsie_gmap
1040 1040
1041 EX_TABLE(rewind_pad,sie_fault) 1041 EX_TABLE(.Lrewind_pad,.Lsie_fault)
1042 EX_TABLE(sie_exit,sie_fault) 1042 EX_TABLE(sie_exit,.Lsie_fault)
1043#endif 1043#endif
1044 1044
1045 .section .rodata, "a" 1045 .section .rodata, "a"
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index ca1cabb3a96c..b86bb8823f15 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -7,6 +7,7 @@
7 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 */ 8 */
9 9
10#include <linux/moduleloader.h>
10#include <linux/hardirq.h> 11#include <linux/hardirq.h>
11#include <linux/uaccess.h> 12#include <linux/uaccess.h>
12#include <linux/ftrace.h> 13#include <linux/ftrace.h>
@@ -15,60 +16,39 @@
15#include <linux/kprobes.h> 16#include <linux/kprobes.h>
16#include <trace/syscall.h> 17#include <trace/syscall.h>
17#include <asm/asm-offsets.h> 18#include <asm/asm-offsets.h>
19#include <asm/cacheflush.h>
18#include "entry.h" 20#include "entry.h"
19 21
20void mcount_replace_code(void);
21void ftrace_disable_code(void);
22void ftrace_enable_insn(void);
23
24/* 22/*
25 * The mcount code looks like this: 23 * The mcount code looks like this:
26 * stg %r14,8(%r15) # offset 0 24 * stg %r14,8(%r15) # offset 0
27 * larl %r1,<&counter> # offset 6 25 * larl %r1,<&counter> # offset 6
28 * brasl %r14,_mcount # offset 12 26 * brasl %r14,_mcount # offset 12
29 * lg %r14,8(%r15) # offset 18 27 * lg %r14,8(%r15) # offset 18
30 * Total length is 24 bytes. The complete mcount block initially gets replaced 28 * Total length is 24 bytes. Only the first instruction will be patched
31 * by ftrace_make_nop. Subsequent calls to ftrace_make_call / ftrace_make_nop 29 * by ftrace_make_call / ftrace_make_nop.
32 * only patch the jg/lg instruction within the block.
33 * Note: we do not patch the first instruction to an unconditional branch,
34 * since that would break kprobes/jprobes. It is easier to leave the larl
35 * instruction in and only modify the second instruction.
36 * The enabled ftrace code block looks like this: 30 * The enabled ftrace code block looks like this:
37 * larl %r0,.+24 # offset 0 31 * > brasl %r0,ftrace_caller # offset 0
38 * > lg %r1,__LC_FTRACE_FUNC # offset 6 32 * larl %r1,<&counter> # offset 6
39 * br %r1 # offset 12 33 * brasl %r14,_mcount # offset 12
40 * brcl 0,0 # offset 14 34 * lg %r14,8(%r15) # offset 18
41 * brc 0,0 # offset 20
42 * The ftrace function gets called with a non-standard C function call ABI 35 * The ftrace function gets called with a non-standard C function call ABI
43 * where r0 contains the return address. It is also expected that the called 36 * where r0 contains the return address. It is also expected that the called
44 * function only clobbers r0 and r1, but restores r2-r15. 37 * function only clobbers r0 and r1, but restores r2-r15.
38 * For module code we can't directly jump to ftrace caller, but need a
39 * trampoline (ftrace_plt), which clobbers also r1.
45 * The return point of the ftrace function has offset 24, so execution 40 * The return point of the ftrace function has offset 24, so execution
46 * continues behind the mcount block. 41 * continues behind the mcount block.
47 * larl %r0,.+24 # offset 0 42 * The disabled ftrace code block looks like this:
48 * > jg .+18 # offset 6 43 * > jg .+24 # offset 0
49 * br %r1 # offset 12 44 * larl %r1,<&counter> # offset 6
50 * brcl 0,0 # offset 14 45 * brasl %r14,_mcount # offset 12
51 * brc 0,0 # offset 20 46 * lg %r14,8(%r15) # offset 18
52 * The jg instruction branches to offset 24 to skip as many instructions 47 * The jg instruction branches to offset 24 to skip as many instructions
53 * as possible. 48 * as possible.
54 */ 49 */
55asm( 50
56 " .align 4\n" 51unsigned long ftrace_plt;
57 "mcount_replace_code:\n"
58 " larl %r0,0f\n"
59 "ftrace_disable_code:\n"
60 " jg 0f\n"
61 " br %r1\n"
62 " brcl 0,0\n"
63 " brc 0,0\n"
64 "0:\n"
65 " .align 4\n"
66 "ftrace_enable_insn:\n"
67 " lg %r1,"__stringify(__LC_FTRACE_FUNC)"\n");
68
69#define MCOUNT_BLOCK_SIZE 24
70#define MCOUNT_INSN_OFFSET 6
71#define FTRACE_INSN_SIZE 6
72 52
73int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, 53int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
74 unsigned long addr) 54 unsigned long addr)
@@ -79,24 +59,62 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
79int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, 59int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
80 unsigned long addr) 60 unsigned long addr)
81{ 61{
82 /* Initial replacement of the whole mcount block */ 62 struct ftrace_insn insn;
83 if (addr == MCOUNT_ADDR) { 63 unsigned short op;
84 if (probe_kernel_write((void *) rec->ip - MCOUNT_INSN_OFFSET, 64 void *from, *to;
85 mcount_replace_code, 65 size_t size;
86 MCOUNT_BLOCK_SIZE)) 66
87 return -EPERM; 67 ftrace_generate_nop_insn(&insn);
88 return 0; 68 size = sizeof(insn);
69 from = &insn;
70 to = (void *) rec->ip;
71 if (probe_kernel_read(&op, (void *) rec->ip, sizeof(op)))
72 return -EFAULT;
73 /*
74 * If we find a breakpoint instruction, a kprobe has been placed
75 * at the beginning of the function. We write the constant
76 * KPROBE_ON_FTRACE_NOP into the remaining four bytes of the original
77 * instruction so that the kprobes handler can execute a nop, if it
78 * reaches this breakpoint.
79 */
80 if (op == BREAKPOINT_INSTRUCTION) {
81 size -= 2;
82 from += 2;
83 to += 2;
84 insn.disp = KPROBE_ON_FTRACE_NOP;
89 } 85 }
90 if (probe_kernel_write((void *) rec->ip, ftrace_disable_code, 86 if (probe_kernel_write(to, from, size))
91 MCOUNT_INSN_SIZE))
92 return -EPERM; 87 return -EPERM;
93 return 0; 88 return 0;
94} 89}
95 90
96int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 91int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
97{ 92{
98 if (probe_kernel_write((void *) rec->ip, ftrace_enable_insn, 93 struct ftrace_insn insn;
99 FTRACE_INSN_SIZE)) 94 unsigned short op;
95 void *from, *to;
96 size_t size;
97
98 ftrace_generate_call_insn(&insn, rec->ip);
99 size = sizeof(insn);
100 from = &insn;
101 to = (void *) rec->ip;
102 if (probe_kernel_read(&op, (void *) rec->ip, sizeof(op)))
103 return -EFAULT;
104 /*
105 * If we find a breakpoint instruction, a kprobe has been placed
106 * at the beginning of the function. We write the constant
107 * KPROBE_ON_FTRACE_CALL into the remaining four bytes of the original
108 * instruction so that the kprobes handler can execute a brasl if it
109 * reaches this breakpoint.
110 */
111 if (op == BREAKPOINT_INSTRUCTION) {
112 size -= 2;
113 from += 2;
114 to += 2;
115 insn.disp = KPROBE_ON_FTRACE_CALL;
116 }
117 if (probe_kernel_write(to, from, size))
100 return -EPERM; 118 return -EPERM;
101 return 0; 119 return 0;
102} 120}
@@ -111,13 +129,30 @@ int __init ftrace_dyn_arch_init(void)
111 return 0; 129 return 0;
112} 130}
113 131
132static int __init ftrace_plt_init(void)
133{
134 unsigned int *ip;
135
136 ftrace_plt = (unsigned long) module_alloc(PAGE_SIZE);
137 if (!ftrace_plt)
138 panic("cannot allocate ftrace plt\n");
139 ip = (unsigned int *) ftrace_plt;
140 ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
141 ip[1] = 0x100a0004;
142 ip[2] = 0x07f10000;
143 ip[3] = FTRACE_ADDR >> 32;
144 ip[4] = FTRACE_ADDR & 0xffffffff;
145 set_memory_ro(ftrace_plt, 1);
146 return 0;
147}
148device_initcall(ftrace_plt_init);
149
114#ifdef CONFIG_FUNCTION_GRAPH_TRACER 150#ifdef CONFIG_FUNCTION_GRAPH_TRACER
115/* 151/*
116 * Hook the return address and push it in the stack of return addresses 152 * Hook the return address and push it in the stack of return addresses
117 * in current thread info. 153 * in current thread info.
118 */ 154 */
119unsigned long __kprobes prepare_ftrace_return(unsigned long parent, 155unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
120 unsigned long ip)
121{ 156{
122 struct ftrace_graph_ent trace; 157 struct ftrace_graph_ent trace;
123 158
@@ -137,6 +172,7 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent,
137out: 172out:
138 return parent; 173 return parent;
139} 174}
175NOKPROBE_SYMBOL(prepare_ftrace_return);
140 176
141/* 177/*
142 * Patch the kernel code at ftrace_graph_caller location. The instruction 178 * Patch the kernel code at ftrace_graph_caller location. The instruction
diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c
index 7559f1beab29..7a55c29b0b33 100644
--- a/arch/s390/kernel/idle.c
+++ b/arch/s390/kernel/idle.c
@@ -19,7 +19,7 @@
19 19
20static DEFINE_PER_CPU(struct s390_idle_data, s390_idle); 20static DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
21 21
22void __kprobes enabled_wait(void) 22void enabled_wait(void)
23{ 23{
24 struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); 24 struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
25 unsigned long long idle_time; 25 unsigned long long idle_time;
@@ -35,31 +35,32 @@ void __kprobes enabled_wait(void)
35 /* Call the assembler magic in entry.S */ 35 /* Call the assembler magic in entry.S */
36 psw_idle(idle, psw_mask); 36 psw_idle(idle, psw_mask);
37 37
38 trace_hardirqs_off();
39
38 /* Account time spent with enabled wait psw loaded as idle time. */ 40 /* Account time spent with enabled wait psw loaded as idle time. */
39 idle->sequence++; 41 write_seqcount_begin(&idle->seqcount);
40 smp_wmb();
41 idle_time = idle->clock_idle_exit - idle->clock_idle_enter; 42 idle_time = idle->clock_idle_exit - idle->clock_idle_enter;
42 idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; 43 idle->clock_idle_enter = idle->clock_idle_exit = 0ULL;
43 idle->idle_time += idle_time; 44 idle->idle_time += idle_time;
44 idle->idle_count++; 45 idle->idle_count++;
45 account_idle_time(idle_time); 46 account_idle_time(idle_time);
46 smp_wmb(); 47 write_seqcount_end(&idle->seqcount);
47 idle->sequence++;
48} 48}
49NOKPROBE_SYMBOL(enabled_wait);
49 50
50static ssize_t show_idle_count(struct device *dev, 51static ssize_t show_idle_count(struct device *dev,
51 struct device_attribute *attr, char *buf) 52 struct device_attribute *attr, char *buf)
52{ 53{
53 struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); 54 struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
54 unsigned long long idle_count; 55 unsigned long long idle_count;
55 unsigned int sequence; 56 unsigned int seq;
56 57
57 do { 58 do {
58 sequence = ACCESS_ONCE(idle->sequence); 59 seq = read_seqcount_begin(&idle->seqcount);
59 idle_count = ACCESS_ONCE(idle->idle_count); 60 idle_count = ACCESS_ONCE(idle->idle_count);
60 if (ACCESS_ONCE(idle->clock_idle_enter)) 61 if (ACCESS_ONCE(idle->clock_idle_enter))
61 idle_count++; 62 idle_count++;
62 } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); 63 } while (read_seqcount_retry(&idle->seqcount, seq));
63 return sprintf(buf, "%llu\n", idle_count); 64 return sprintf(buf, "%llu\n", idle_count);
64} 65}
65DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); 66DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
@@ -69,15 +70,15 @@ static ssize_t show_idle_time(struct device *dev,
69{ 70{
70 struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); 71 struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
71 unsigned long long now, idle_time, idle_enter, idle_exit; 72 unsigned long long now, idle_time, idle_enter, idle_exit;
72 unsigned int sequence; 73 unsigned int seq;
73 74
74 do { 75 do {
75 now = get_tod_clock(); 76 now = get_tod_clock();
76 sequence = ACCESS_ONCE(idle->sequence); 77 seq = read_seqcount_begin(&idle->seqcount);
77 idle_time = ACCESS_ONCE(idle->idle_time); 78 idle_time = ACCESS_ONCE(idle->idle_time);
78 idle_enter = ACCESS_ONCE(idle->clock_idle_enter); 79 idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
79 idle_exit = ACCESS_ONCE(idle->clock_idle_exit); 80 idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
80 } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); 81 } while (read_seqcount_retry(&idle->seqcount, seq));
81 idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; 82 idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
82 return sprintf(buf, "%llu\n", idle_time >> 12); 83 return sprintf(buf, "%llu\n", idle_time >> 12);
83} 84}
@@ -87,14 +88,14 @@ cputime64_t arch_cpu_idle_time(int cpu)
87{ 88{
88 struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); 89 struct s390_idle_data *idle = &per_cpu(s390_idle, cpu);
89 unsigned long long now, idle_enter, idle_exit; 90 unsigned long long now, idle_enter, idle_exit;
90 unsigned int sequence; 91 unsigned int seq;
91 92
92 do { 93 do {
93 now = get_tod_clock(); 94 now = get_tod_clock();
94 sequence = ACCESS_ONCE(idle->sequence); 95 seq = read_seqcount_begin(&idle->seqcount);
95 idle_enter = ACCESS_ONCE(idle->clock_idle_enter); 96 idle_enter = ACCESS_ONCE(idle->clock_idle_enter);
96 idle_exit = ACCESS_ONCE(idle->clock_idle_exit); 97 idle_exit = ACCESS_ONCE(idle->clock_idle_exit);
97 } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); 98 } while (read_seqcount_retry(&idle->seqcount, seq));
98 return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0; 99 return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0;
99} 100}
100 101
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 1b8a38ab7861..f238720690f3 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -127,13 +127,10 @@ int show_interrupts(struct seq_file *p, void *v)
127 for_each_online_cpu(cpu) 127 for_each_online_cpu(cpu)
128 seq_printf(p, "CPU%d ", cpu); 128 seq_printf(p, "CPU%d ", cpu);
129 seq_putc(p, '\n'); 129 seq_putc(p, '\n');
130 goto out;
131 } 130 }
132 if (index < NR_IRQS) { 131 if (index < NR_IRQS) {
133 if (index >= NR_IRQS_BASE) 132 if (index >= NR_IRQS_BASE)
134 goto out; 133 goto out;
135 /* Adjust index to process irqclass_main_desc array entries */
136 index--;
137 seq_printf(p, "%s: ", irqclass_main_desc[index].name); 134 seq_printf(p, "%s: ", irqclass_main_desc[index].name);
138 irq = irqclass_main_desc[index].irq; 135 irq = irqclass_main_desc[index].irq;
139 for_each_online_cpu(cpu) 136 for_each_online_cpu(cpu)
@@ -158,7 +155,7 @@ out:
158 155
159unsigned int arch_dynirq_lower_bound(unsigned int from) 156unsigned int arch_dynirq_lower_bound(unsigned int from)
160{ 157{
161 return from < THIN_INTERRUPT ? THIN_INTERRUPT : from; 158 return from < NR_IRQS_BASE ? NR_IRQS_BASE : from;
162} 159}
163 160
164/* 161/*
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 014d4729b134..1e4c710dfb92 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -29,6 +29,7 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/hardirq.h> 31#include <linux/hardirq.h>
32#include <linux/ftrace.h>
32#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
33#include <asm/sections.h> 34#include <asm/sections.h>
34#include <asm/dis.h> 35#include <asm/dis.h>
@@ -58,12 +59,23 @@ struct kprobe_insn_cache kprobe_dmainsn_slots = {
58 .insn_size = MAX_INSN_SIZE, 59 .insn_size = MAX_INSN_SIZE,
59}; 60};
60 61
61static void __kprobes copy_instruction(struct kprobe *p) 62static void copy_instruction(struct kprobe *p)
62{ 63{
64 unsigned long ip = (unsigned long) p->addr;
63 s64 disp, new_disp; 65 s64 disp, new_disp;
64 u64 addr, new_addr; 66 u64 addr, new_addr;
65 67
66 memcpy(p->ainsn.insn, p->addr, insn_length(p->opcode >> 8)); 68 if (ftrace_location(ip) == ip) {
69 /*
70 * If kprobes patches the instruction that is morphed by
71 * ftrace make sure that kprobes always sees the branch
72 * "jg .+24" that skips the mcount block
73 */
74 ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn);
75 p->ainsn.is_ftrace_insn = 1;
76 } else
77 memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8));
78 p->opcode = p->ainsn.insn[0];
67 if (!probe_is_insn_relative_long(p->ainsn.insn)) 79 if (!probe_is_insn_relative_long(p->ainsn.insn))
68 return; 80 return;
69 /* 81 /*
@@ -79,25 +91,14 @@ static void __kprobes copy_instruction(struct kprobe *p)
79 new_disp = ((addr + (disp * 2)) - new_addr) / 2; 91 new_disp = ((addr + (disp * 2)) - new_addr) / 2;
80 *(s32 *)&p->ainsn.insn[1] = new_disp; 92 *(s32 *)&p->ainsn.insn[1] = new_disp;
81} 93}
94NOKPROBE_SYMBOL(copy_instruction);
82 95
83static inline int is_kernel_addr(void *addr) 96static inline int is_kernel_addr(void *addr)
84{ 97{
85 return addr < (void *)_end; 98 return addr < (void *)_end;
86} 99}
87 100
88static inline int is_module_addr(void *addr) 101static int s390_get_insn_slot(struct kprobe *p)
89{
90#ifdef CONFIG_64BIT
91 BUILD_BUG_ON(MODULES_LEN > (1UL << 31));
92 if (addr < (void *)MODULES_VADDR)
93 return 0;
94 if (addr > (void *)MODULES_END)
95 return 0;
96#endif
97 return 1;
98}
99
100static int __kprobes s390_get_insn_slot(struct kprobe *p)
101{ 102{
102 /* 103 /*
103 * Get an insn slot that is within the same 2GB area like the original 104 * Get an insn slot that is within the same 2GB area like the original
@@ -111,8 +112,9 @@ static int __kprobes s390_get_insn_slot(struct kprobe *p)
111 p->ainsn.insn = get_insn_slot(); 112 p->ainsn.insn = get_insn_slot();
112 return p->ainsn.insn ? 0 : -ENOMEM; 113 return p->ainsn.insn ? 0 : -ENOMEM;
113} 114}
115NOKPROBE_SYMBOL(s390_get_insn_slot);
114 116
115static void __kprobes s390_free_insn_slot(struct kprobe *p) 117static void s390_free_insn_slot(struct kprobe *p)
116{ 118{
117 if (!p->ainsn.insn) 119 if (!p->ainsn.insn)
118 return; 120 return;
@@ -122,8 +124,9 @@ static void __kprobes s390_free_insn_slot(struct kprobe *p)
122 free_insn_slot(p->ainsn.insn, 0); 124 free_insn_slot(p->ainsn.insn, 0);
123 p->ainsn.insn = NULL; 125 p->ainsn.insn = NULL;
124} 126}
127NOKPROBE_SYMBOL(s390_free_insn_slot);
125 128
126int __kprobes arch_prepare_kprobe(struct kprobe *p) 129int arch_prepare_kprobe(struct kprobe *p)
127{ 130{
128 if ((unsigned long) p->addr & 0x01) 131 if ((unsigned long) p->addr & 0x01)
129 return -EINVAL; 132 return -EINVAL;
@@ -132,54 +135,79 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
132 return -EINVAL; 135 return -EINVAL;
133 if (s390_get_insn_slot(p)) 136 if (s390_get_insn_slot(p))
134 return -ENOMEM; 137 return -ENOMEM;
135 p->opcode = *p->addr;
136 copy_instruction(p); 138 copy_instruction(p);
137 return 0; 139 return 0;
138} 140}
141NOKPROBE_SYMBOL(arch_prepare_kprobe);
139 142
140struct ins_replace_args { 143int arch_check_ftrace_location(struct kprobe *p)
141 kprobe_opcode_t *ptr; 144{
142 kprobe_opcode_t opcode; 145 return 0;
146}
147
148struct swap_insn_args {
149 struct kprobe *p;
150 unsigned int arm_kprobe : 1;
143}; 151};
144 152
145static int __kprobes swap_instruction(void *aref) 153static int swap_instruction(void *data)
146{ 154{
147 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 155 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
148 unsigned long status = kcb->kprobe_status; 156 unsigned long status = kcb->kprobe_status;
149 struct ins_replace_args *args = aref; 157 struct swap_insn_args *args = data;
150 158 struct ftrace_insn new_insn, *insn;
159 struct kprobe *p = args->p;
160 size_t len;
161
162 new_insn.opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode;
163 len = sizeof(new_insn.opc);
164 if (!p->ainsn.is_ftrace_insn)
165 goto skip_ftrace;
166 len = sizeof(new_insn);
167 insn = (struct ftrace_insn *) p->addr;
168 if (args->arm_kprobe) {
169 if (is_ftrace_nop(insn))
170 new_insn.disp = KPROBE_ON_FTRACE_NOP;
171 else
172 new_insn.disp = KPROBE_ON_FTRACE_CALL;
173 } else {
174 ftrace_generate_call_insn(&new_insn, (unsigned long)p->addr);
175 if (insn->disp == KPROBE_ON_FTRACE_NOP)
176 ftrace_generate_nop_insn(&new_insn);
177 }
178skip_ftrace:
151 kcb->kprobe_status = KPROBE_SWAP_INST; 179 kcb->kprobe_status = KPROBE_SWAP_INST;
152 probe_kernel_write(args->ptr, &args->opcode, sizeof(args->opcode)); 180 probe_kernel_write(p->addr, &new_insn, len);
153 kcb->kprobe_status = status; 181 kcb->kprobe_status = status;
154 return 0; 182 return 0;
155} 183}
184NOKPROBE_SYMBOL(swap_instruction);
156 185
157void __kprobes arch_arm_kprobe(struct kprobe *p) 186void arch_arm_kprobe(struct kprobe *p)
158{ 187{
159 struct ins_replace_args args; 188 struct swap_insn_args args = {.p = p, .arm_kprobe = 1};
160 189
161 args.ptr = p->addr;
162 args.opcode = BREAKPOINT_INSTRUCTION;
163 stop_machine(swap_instruction, &args, NULL); 190 stop_machine(swap_instruction, &args, NULL);
164} 191}
192NOKPROBE_SYMBOL(arch_arm_kprobe);
165 193
166void __kprobes arch_disarm_kprobe(struct kprobe *p) 194void arch_disarm_kprobe(struct kprobe *p)
167{ 195{
168 struct ins_replace_args args; 196 struct swap_insn_args args = {.p = p, .arm_kprobe = 0};
169 197
170 args.ptr = p->addr;
171 args.opcode = p->opcode;
172 stop_machine(swap_instruction, &args, NULL); 198 stop_machine(swap_instruction, &args, NULL);
173} 199}
200NOKPROBE_SYMBOL(arch_disarm_kprobe);
174 201
175void __kprobes arch_remove_kprobe(struct kprobe *p) 202void arch_remove_kprobe(struct kprobe *p)
176{ 203{
177 s390_free_insn_slot(p); 204 s390_free_insn_slot(p);
178} 205}
206NOKPROBE_SYMBOL(arch_remove_kprobe);
179 207
180static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb, 208static void enable_singlestep(struct kprobe_ctlblk *kcb,
181 struct pt_regs *regs, 209 struct pt_regs *regs,
182 unsigned long ip) 210 unsigned long ip)
183{ 211{
184 struct per_regs per_kprobe; 212 struct per_regs per_kprobe;
185 213
@@ -199,10 +227,11 @@ static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb,
199 regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT); 227 regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
200 regs->psw.addr = ip | PSW_ADDR_AMODE; 228 regs->psw.addr = ip | PSW_ADDR_AMODE;
201} 229}
230NOKPROBE_SYMBOL(enable_singlestep);
202 231
203static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb, 232static void disable_singlestep(struct kprobe_ctlblk *kcb,
204 struct pt_regs *regs, 233 struct pt_regs *regs,
205 unsigned long ip) 234 unsigned long ip)
206{ 235{
207 /* Restore control regs and psw mask, set new psw address */ 236 /* Restore control regs and psw mask, set new psw address */
208 __ctl_load(kcb->kprobe_saved_ctl, 9, 11); 237 __ctl_load(kcb->kprobe_saved_ctl, 9, 11);
@@ -210,41 +239,43 @@ static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb,
210 regs->psw.mask |= kcb->kprobe_saved_imask; 239 regs->psw.mask |= kcb->kprobe_saved_imask;
211 regs->psw.addr = ip | PSW_ADDR_AMODE; 240 regs->psw.addr = ip | PSW_ADDR_AMODE;
212} 241}
242NOKPROBE_SYMBOL(disable_singlestep);
213 243
214/* 244/*
215 * Activate a kprobe by storing its pointer to current_kprobe. The 245 * Activate a kprobe by storing its pointer to current_kprobe. The
216 * previous kprobe is stored in kcb->prev_kprobe. A stack of up to 246 * previous kprobe is stored in kcb->prev_kprobe. A stack of up to
217 * two kprobes can be active, see KPROBE_REENTER. 247 * two kprobes can be active, see KPROBE_REENTER.
218 */ 248 */
219static void __kprobes push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p) 249static void push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p)
220{ 250{
221 kcb->prev_kprobe.kp = __this_cpu_read(current_kprobe); 251 kcb->prev_kprobe.kp = __this_cpu_read(current_kprobe);
222 kcb->prev_kprobe.status = kcb->kprobe_status; 252 kcb->prev_kprobe.status = kcb->kprobe_status;
223 __this_cpu_write(current_kprobe, p); 253 __this_cpu_write(current_kprobe, p);
224} 254}
255NOKPROBE_SYMBOL(push_kprobe);
225 256
226/* 257/*
227 * Deactivate a kprobe by backing up to the previous state. If the 258 * Deactivate a kprobe by backing up to the previous state. If the
228 * current state is KPROBE_REENTER prev_kprobe.kp will be non-NULL, 259 * current state is KPROBE_REENTER prev_kprobe.kp will be non-NULL,
229 * for any other state prev_kprobe.kp will be NULL. 260 * for any other state prev_kprobe.kp will be NULL.
230 */ 261 */
231static void __kprobes pop_kprobe(struct kprobe_ctlblk *kcb) 262static void pop_kprobe(struct kprobe_ctlblk *kcb)
232{ 263{
233 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); 264 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
234 kcb->kprobe_status = kcb->prev_kprobe.status; 265 kcb->kprobe_status = kcb->prev_kprobe.status;
235} 266}
267NOKPROBE_SYMBOL(pop_kprobe);
236 268
237void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, 269void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
238 struct pt_regs *regs)
239{ 270{
240 ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14]; 271 ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
241 272
242 /* Replace the return addr with trampoline addr */ 273 /* Replace the return addr with trampoline addr */
243 regs->gprs[14] = (unsigned long) &kretprobe_trampoline; 274 regs->gprs[14] = (unsigned long) &kretprobe_trampoline;
244} 275}
276NOKPROBE_SYMBOL(arch_prepare_kretprobe);
245 277
246static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb, 278static void kprobe_reenter_check(struct kprobe_ctlblk *kcb, struct kprobe *p)
247 struct kprobe *p)
248{ 279{
249 switch (kcb->kprobe_status) { 280 switch (kcb->kprobe_status) {
250 case KPROBE_HIT_SSDONE: 281 case KPROBE_HIT_SSDONE:
@@ -264,8 +295,9 @@ static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb,
264 BUG(); 295 BUG();
265 } 296 }
266} 297}
298NOKPROBE_SYMBOL(kprobe_reenter_check);
267 299
268static int __kprobes kprobe_handler(struct pt_regs *regs) 300static int kprobe_handler(struct pt_regs *regs)
269{ 301{
270 struct kprobe_ctlblk *kcb; 302 struct kprobe_ctlblk *kcb;
271 struct kprobe *p; 303 struct kprobe *p;
@@ -339,6 +371,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
339 preempt_enable_no_resched(); 371 preempt_enable_no_resched();
340 return 0; 372 return 0;
341} 373}
374NOKPROBE_SYMBOL(kprobe_handler);
342 375
343/* 376/*
344 * Function return probe trampoline: 377 * Function return probe trampoline:
@@ -355,8 +388,7 @@ static void __used kretprobe_trampoline_holder(void)
355/* 388/*
356 * Called when the probe at kretprobe trampoline is hit 389 * Called when the probe at kretprobe trampoline is hit
357 */ 390 */
358static int __kprobes trampoline_probe_handler(struct kprobe *p, 391static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
359 struct pt_regs *regs)
360{ 392{
361 struct kretprobe_instance *ri; 393 struct kretprobe_instance *ri;
362 struct hlist_head *head, empty_rp; 394 struct hlist_head *head, empty_rp;
@@ -444,6 +476,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
444 */ 476 */
445 return 1; 477 return 1;
446} 478}
479NOKPROBE_SYMBOL(trampoline_probe_handler);
447 480
448/* 481/*
449 * Called after single-stepping. p->addr is the address of the 482 * Called after single-stepping. p->addr is the address of the
@@ -453,12 +486,30 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
453 * single-stepped a copy of the instruction. The address of this 486 * single-stepped a copy of the instruction. The address of this
454 * copy is p->ainsn.insn. 487 * copy is p->ainsn.insn.
455 */ 488 */
456static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) 489static void resume_execution(struct kprobe *p, struct pt_regs *regs)
457{ 490{
458 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 491 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
459 unsigned long ip = regs->psw.addr & PSW_ADDR_INSN; 492 unsigned long ip = regs->psw.addr & PSW_ADDR_INSN;
460 int fixup = probe_get_fixup_type(p->ainsn.insn); 493 int fixup = probe_get_fixup_type(p->ainsn.insn);
461 494
495 /* Check if the kprobes location is an enabled ftrace caller */
496 if (p->ainsn.is_ftrace_insn) {
497 struct ftrace_insn *insn = (struct ftrace_insn *) p->addr;
498 struct ftrace_insn call_insn;
499
500 ftrace_generate_call_insn(&call_insn, (unsigned long) p->addr);
501 /*
502 * A kprobe on an enabled ftrace call site actually single
503 * stepped an unconditional branch (ftrace nop equivalent).
504 * Now we need to fixup things and pretend that a brasl r0,...
505 * was executed instead.
506 */
507 if (insn->disp == KPROBE_ON_FTRACE_CALL) {
508 ip += call_insn.disp * 2 - MCOUNT_INSN_SIZE;
509 regs->gprs[0] = (unsigned long)p->addr + sizeof(*insn);
510 }
511 }
512
462 if (fixup & FIXUP_PSW_NORMAL) 513 if (fixup & FIXUP_PSW_NORMAL)
463 ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn; 514 ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn;
464 515
@@ -476,8 +527,9 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
476 527
477 disable_singlestep(kcb, regs, ip); 528 disable_singlestep(kcb, regs, ip);
478} 529}
530NOKPROBE_SYMBOL(resume_execution);
479 531
480static int __kprobes post_kprobe_handler(struct pt_regs *regs) 532static int post_kprobe_handler(struct pt_regs *regs)
481{ 533{
482 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 534 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
483 struct kprobe *p = kprobe_running(); 535 struct kprobe *p = kprobe_running();
@@ -504,8 +556,9 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
504 556
505 return 1; 557 return 1;
506} 558}
559NOKPROBE_SYMBOL(post_kprobe_handler);
507 560
508static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr) 561static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
509{ 562{
510 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 563 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
511 struct kprobe *p = kprobe_running(); 564 struct kprobe *p = kprobe_running();
@@ -567,8 +620,9 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
567 } 620 }
568 return 0; 621 return 0;
569} 622}
623NOKPROBE_SYMBOL(kprobe_trap_handler);
570 624
571int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 625int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
572{ 626{
573 int ret; 627 int ret;
574 628
@@ -579,12 +633,13 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
579 local_irq_restore(regs->psw.mask & ~PSW_MASK_PER); 633 local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
580 return ret; 634 return ret;
581} 635}
636NOKPROBE_SYMBOL(kprobe_fault_handler);
582 637
583/* 638/*
584 * Wrapper routine to for handling exceptions. 639 * Wrapper routine to for handling exceptions.
585 */ 640 */
586int __kprobes kprobe_exceptions_notify(struct notifier_block *self, 641int kprobe_exceptions_notify(struct notifier_block *self,
587 unsigned long val, void *data) 642 unsigned long val, void *data)
588{ 643{
589 struct die_args *args = (struct die_args *) data; 644 struct die_args *args = (struct die_args *) data;
590 struct pt_regs *regs = args->regs; 645 struct pt_regs *regs = args->regs;
@@ -616,8 +671,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
616 671
617 return ret; 672 return ret;
618} 673}
674NOKPROBE_SYMBOL(kprobe_exceptions_notify);
619 675
620int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 676int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
621{ 677{
622 struct jprobe *jp = container_of(p, struct jprobe, kp); 678 struct jprobe *jp = container_of(p, struct jprobe, kp);
623 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 679 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -635,13 +691,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
635 memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack)); 691 memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack));
636 return 1; 692 return 1;
637} 693}
694NOKPROBE_SYMBOL(setjmp_pre_handler);
638 695
639void __kprobes jprobe_return(void) 696void jprobe_return(void)
640{ 697{
641 asm volatile(".word 0x0002"); 698 asm volatile(".word 0x0002");
642} 699}
700NOKPROBE_SYMBOL(jprobe_return);
643 701
644int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 702int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
645{ 703{
646 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 704 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
647 unsigned long stack; 705 unsigned long stack;
@@ -655,6 +713,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
655 preempt_enable_no_resched(); 713 preempt_enable_no_resched();
656 return 1; 714 return 1;
657} 715}
716NOKPROBE_SYMBOL(longjmp_break_handler);
658 717
659static struct kprobe trampoline = { 718static struct kprobe trampoline = {
660 .addr = (kprobe_opcode_t *) &kretprobe_trampoline, 719 .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
@@ -666,7 +725,8 @@ int __init arch_init_kprobes(void)
666 return register_kprobe(&trampoline); 725 return register_kprobe(&trampoline);
667} 726}
668 727
669int __kprobes arch_trampoline_kprobe(struct kprobe *p) 728int arch_trampoline_kprobe(struct kprobe *p)
670{ 729{
671 return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline; 730 return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline;
672} 731}
732NOKPROBE_SYMBOL(arch_trampoline_kprobe);
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
index 4300ea374826..b6dfc5bfcb89 100644
--- a/arch/s390/kernel/mcount.S
+++ b/arch/s390/kernel/mcount.S
@@ -27,6 +27,7 @@ ENTRY(ftrace_caller)
27 .globl ftrace_regs_caller 27 .globl ftrace_regs_caller
28 .set ftrace_regs_caller,ftrace_caller 28 .set ftrace_regs_caller,ftrace_caller
29 lgr %r1,%r15 29 lgr %r1,%r15
30 aghi %r0,MCOUNT_RETURN_FIXUP
30 aghi %r15,-STACK_FRAME_SIZE 31 aghi %r15,-STACK_FRAME_SIZE
31 stg %r1,__SF_BACKCHAIN(%r15) 32 stg %r1,__SF_BACKCHAIN(%r15)
32 stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) 33 stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15)
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index b878f12a9597..c3f8d157cb0d 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -1383,7 +1383,6 @@ static int cpumsf_pmu_add(struct perf_event *event, int flags)
1383 cpuhw->lsctl.ed = 1; 1383 cpuhw->lsctl.ed = 1;
1384 1384
1385 /* Set in_use flag and store event */ 1385 /* Set in_use flag and store event */
1386 event->hw.idx = 0; /* only one sampling event per CPU supported */
1387 cpuhw->event = event; 1386 cpuhw->event = event;
1388 cpuhw->flags |= PMU_F_IN_USE; 1387 cpuhw->flags |= PMU_F_IN_USE;
1389 1388
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index ed84cc224899..aa7a83948c7b 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -61,7 +61,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
61 return sf->gprs[8]; 61 return sf->gprs[8];
62} 62}
63 63
64extern void __kprobes kernel_thread_starter(void); 64extern void kernel_thread_starter(void);
65 65
66/* 66/*
67 * Free current thread data structures etc.. 67 * Free current thread data structures etc..
@@ -153,6 +153,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
153 save_fp_ctl(&p->thread.fp_regs.fpc); 153 save_fp_ctl(&p->thread.fp_regs.fpc);
154 save_fp_regs(p->thread.fp_regs.fprs); 154 save_fp_regs(p->thread.fp_regs.fprs);
155 p->thread.fp_regs.pad = 0; 155 p->thread.fp_regs.pad = 0;
156 p->thread.vxrs = NULL;
156 /* Set a new TLS ? */ 157 /* Set a new TLS ? */
157 if (clone_flags & CLONE_SETTLS) { 158 if (clone_flags & CLONE_SETTLS) {
158 unsigned long tls = frame->childregs.gprs[6]; 159 unsigned long tls = frame->childregs.gprs[6];
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 99a567b70d16..eabfb4594517 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -248,14 +248,27 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
248 */ 248 */
249 tmp = 0; 249 tmp = 0;
250 250
251 } else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) {
252 /*
253 * floating point control reg. is in the thread structure
254 */
255 tmp = child->thread.fp_regs.fpc;
256 tmp <<= BITS_PER_LONG - 32;
257
251 } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { 258 } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
252 /* 259 /*
253 * floating point regs. are stored in the thread structure 260 * floating point regs. are either in child->thread.fp_regs
261 * or the child->thread.vxrs array
254 */ 262 */
255 offset = addr - (addr_t) &dummy->regs.fp_regs; 263 offset = addr - (addr_t) &dummy->regs.fp_regs.fprs;
256 tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); 264#ifdef CONFIG_64BIT
257 if (addr == (addr_t) &dummy->regs.fp_regs.fpc) 265 if (child->thread.vxrs)
258 tmp <<= BITS_PER_LONG - 32; 266 tmp = *(addr_t *)
267 ((addr_t) child->thread.vxrs + 2*offset);
268 else
269#endif
270 tmp = *(addr_t *)
271 ((addr_t) &child->thread.fp_regs.fprs + offset);
259 272
260 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { 273 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
261 /* 274 /*
@@ -383,16 +396,29 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
383 */ 396 */
384 return 0; 397 return 0;
385 398
399 } else if (addr == (addr_t) &dummy->regs.fp_regs.fpc) {
400 /*
401 * floating point control reg. is in the thread structure
402 */
403 if ((unsigned int) data != 0 ||
404 test_fp_ctl(data >> (BITS_PER_LONG - 32)))
405 return -EINVAL;
406 child->thread.fp_regs.fpc = data >> (BITS_PER_LONG - 32);
407
386 } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { 408 } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
387 /* 409 /*
388 * floating point regs. are stored in the thread structure 410 * floating point regs. are either in child->thread.fp_regs
411 * or the child->thread.vxrs array
389 */ 412 */
390 if (addr == (addr_t) &dummy->regs.fp_regs.fpc) 413 offset = addr - (addr_t) &dummy->regs.fp_regs.fprs;
391 if ((unsigned int) data != 0 || 414#ifdef CONFIG_64BIT
392 test_fp_ctl(data >> (BITS_PER_LONG - 32))) 415 if (child->thread.vxrs)
393 return -EINVAL; 416 *(addr_t *)((addr_t)
394 offset = addr - (addr_t) &dummy->regs.fp_regs; 417 child->thread.vxrs + 2*offset) = data;
395 *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; 418 else
419#endif
420 *(addr_t *)((addr_t)
421 &child->thread.fp_regs.fprs + offset) = data;
396 422
397 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { 423 } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
398 /* 424 /*
@@ -611,12 +637,26 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
611 */ 637 */
612 tmp = 0; 638 tmp = 0;
613 639
640 } else if (addr == (addr_t) &dummy32->regs.fp_regs.fpc) {
641 /*
642 * floating point control reg. is in the thread structure
643 */
644 tmp = child->thread.fp_regs.fpc;
645
614 } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { 646 } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
615 /* 647 /*
616 * floating point regs. are stored in the thread structure 648 * floating point regs. are either in child->thread.fp_regs
649 * or the child->thread.vxrs array
617 */ 650 */
618 offset = addr - (addr_t) &dummy32->regs.fp_regs; 651 offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs;
619 tmp = *(__u32 *)((addr_t) &child->thread.fp_regs + offset); 652#ifdef CONFIG_64BIT
653 if (child->thread.vxrs)
654 tmp = *(__u32 *)
655 ((addr_t) child->thread.vxrs + 2*offset);
656 else
657#endif
658 tmp = *(__u32 *)
659 ((addr_t) &child->thread.fp_regs.fprs + offset);
620 660
621 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) { 661 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
622 /* 662 /*
@@ -722,15 +762,28 @@ static int __poke_user_compat(struct task_struct *child,
722 */ 762 */
723 return 0; 763 return 0;
724 764
725 } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { 765 } else if (addr == (addr_t) &dummy32->regs.fp_regs.fpc) {
726 /* 766 /*
727 * floating point regs. are stored in the thread structure 767 * floating point control reg. is in the thread structure
728 */ 768 */
729 if (addr == (addr_t) &dummy32->regs.fp_regs.fpc && 769 if (test_fp_ctl(tmp))
730 test_fp_ctl(tmp))
731 return -EINVAL; 770 return -EINVAL;
732 offset = addr - (addr_t) &dummy32->regs.fp_regs; 771 child->thread.fp_regs.fpc = data;
733 *(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp; 772
773 } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
774 /*
775 * floating point regs. are either in child->thread.fp_regs
776 * or the child->thread.vxrs array
777 */
778 offset = addr - (addr_t) &dummy32->regs.fp_regs.fprs;
779#ifdef CONFIG_64BIT
780 if (child->thread.vxrs)
781 *(__u32 *)((addr_t)
782 child->thread.vxrs + 2*offset) = tmp;
783 else
784#endif
785 *(__u32 *)((addr_t)
786 &child->thread.fp_regs.fprs + offset) = tmp;
734 787
735 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) { 788 } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
736 /* 789 /*
@@ -1038,12 +1091,6 @@ static int s390_tdb_set(struct task_struct *target,
1038 return 0; 1091 return 0;
1039} 1092}
1040 1093
1041static int s390_vxrs_active(struct task_struct *target,
1042 const struct user_regset *regset)
1043{
1044 return !!target->thread.vxrs;
1045}
1046
1047static int s390_vxrs_low_get(struct task_struct *target, 1094static int s390_vxrs_low_get(struct task_struct *target,
1048 const struct user_regset *regset, 1095 const struct user_regset *regset,
1049 unsigned int pos, unsigned int count, 1096 unsigned int pos, unsigned int count,
@@ -1052,6 +1099,8 @@ static int s390_vxrs_low_get(struct task_struct *target,
1052 __u64 vxrs[__NUM_VXRS_LOW]; 1099 __u64 vxrs[__NUM_VXRS_LOW];
1053 int i; 1100 int i;
1054 1101
1102 if (!MACHINE_HAS_VX)
1103 return -ENODEV;
1055 if (target->thread.vxrs) { 1104 if (target->thread.vxrs) {
1056 if (target == current) 1105 if (target == current)
1057 save_vx_regs(target->thread.vxrs); 1106 save_vx_regs(target->thread.vxrs);
@@ -1070,6 +1119,8 @@ static int s390_vxrs_low_set(struct task_struct *target,
1070 __u64 vxrs[__NUM_VXRS_LOW]; 1119 __u64 vxrs[__NUM_VXRS_LOW];
1071 int i, rc; 1120 int i, rc;
1072 1121
1122 if (!MACHINE_HAS_VX)
1123 return -ENODEV;
1073 if (!target->thread.vxrs) { 1124 if (!target->thread.vxrs) {
1074 rc = alloc_vector_registers(target); 1125 rc = alloc_vector_registers(target);
1075 if (rc) 1126 if (rc)
@@ -1095,6 +1146,8 @@ static int s390_vxrs_high_get(struct task_struct *target,
1095{ 1146{
1096 __vector128 vxrs[__NUM_VXRS_HIGH]; 1147 __vector128 vxrs[__NUM_VXRS_HIGH];
1097 1148
1149 if (!MACHINE_HAS_VX)
1150 return -ENODEV;
1098 if (target->thread.vxrs) { 1151 if (target->thread.vxrs) {
1099 if (target == current) 1152 if (target == current)
1100 save_vx_regs(target->thread.vxrs); 1153 save_vx_regs(target->thread.vxrs);
@@ -1112,6 +1165,8 @@ static int s390_vxrs_high_set(struct task_struct *target,
1112{ 1165{
1113 int rc; 1166 int rc;
1114 1167
1168 if (!MACHINE_HAS_VX)
1169 return -ENODEV;
1115 if (!target->thread.vxrs) { 1170 if (!target->thread.vxrs) {
1116 rc = alloc_vector_registers(target); 1171 rc = alloc_vector_registers(target);
1117 if (rc) 1172 if (rc)
@@ -1196,7 +1251,6 @@ static const struct user_regset s390_regsets[] = {
1196 .n = __NUM_VXRS_LOW, 1251 .n = __NUM_VXRS_LOW,
1197 .size = sizeof(__u64), 1252 .size = sizeof(__u64),
1198 .align = sizeof(__u64), 1253 .align = sizeof(__u64),
1199 .active = s390_vxrs_active,
1200 .get = s390_vxrs_low_get, 1254 .get = s390_vxrs_low_get,
1201 .set = s390_vxrs_low_set, 1255 .set = s390_vxrs_low_set,
1202 }, 1256 },
@@ -1205,7 +1259,6 @@ static const struct user_regset s390_regsets[] = {
1205 .n = __NUM_VXRS_HIGH, 1259 .n = __NUM_VXRS_HIGH,
1206 .size = sizeof(__vector128), 1260 .size = sizeof(__vector128),
1207 .align = sizeof(__vector128), 1261 .align = sizeof(__vector128),
1208 .active = s390_vxrs_active,
1209 .get = s390_vxrs_high_get, 1262 .get = s390_vxrs_high_get,
1210 .set = s390_vxrs_high_set, 1263 .set = s390_vxrs_high_set,
1211 }, 1264 },
@@ -1419,7 +1472,6 @@ static const struct user_regset s390_compat_regsets[] = {
1419 .n = __NUM_VXRS_LOW, 1472 .n = __NUM_VXRS_LOW,
1420 .size = sizeof(__u64), 1473 .size = sizeof(__u64),
1421 .align = sizeof(__u64), 1474 .align = sizeof(__u64),
1422 .active = s390_vxrs_active,
1423 .get = s390_vxrs_low_get, 1475 .get = s390_vxrs_low_get,
1424 .set = s390_vxrs_low_set, 1476 .set = s390_vxrs_low_set,
1425 }, 1477 },
@@ -1428,7 +1480,6 @@ static const struct user_regset s390_compat_regsets[] = {
1428 .n = __NUM_VXRS_HIGH, 1480 .n = __NUM_VXRS_HIGH,
1429 .size = sizeof(__vector128), 1481 .size = sizeof(__vector128),
1430 .align = sizeof(__vector128), 1482 .align = sizeof(__vector128),
1431 .active = s390_vxrs_active,
1432 .get = s390_vxrs_high_get, 1483 .get = s390_vxrs_high_get,
1433 .set = s390_vxrs_high_set, 1484 .set = s390_vxrs_high_set,
1434 }, 1485 },
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index e80d9ff9a56d..4e532c67832f 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -41,7 +41,6 @@
41#include <linux/ctype.h> 41#include <linux/ctype.h>
42#include <linux/reboot.h> 42#include <linux/reboot.h>
43#include <linux/topology.h> 43#include <linux/topology.h>
44#include <linux/ftrace.h>
45#include <linux/kexec.h> 44#include <linux/kexec.h>
46#include <linux/crash_dump.h> 45#include <linux/crash_dump.h>
47#include <linux/memory.h> 46#include <linux/memory.h>
@@ -356,7 +355,6 @@ static void __init setup_lowcore(void)
356 lc->steal_timer = S390_lowcore.steal_timer; 355 lc->steal_timer = S390_lowcore.steal_timer;
357 lc->last_update_timer = S390_lowcore.last_update_timer; 356 lc->last_update_timer = S390_lowcore.last_update_timer;
358 lc->last_update_clock = S390_lowcore.last_update_clock; 357 lc->last_update_clock = S390_lowcore.last_update_clock;
359 lc->ftrace_func = S390_lowcore.ftrace_func;
360 358
361 restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0); 359 restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
362 restart_stack += ASYNC_SIZE; 360 restart_stack += ASYNC_SIZE;
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 0c1a0ff0a558..6a2ac257d98f 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -371,7 +371,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
371 restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE; 371 restorer = (unsigned long) ka->sa.sa_restorer | PSW_ADDR_AMODE;
372 } else { 372 } else {
373 /* Signal frame without vector registers are short ! */ 373 /* Signal frame without vector registers are short ! */
374 __u16 __user *svc = (void *) frame + frame_size - 2; 374 __u16 __user *svc = (void __user *) frame + frame_size - 2;
375 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc)) 375 if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
376 return -EFAULT; 376 return -EFAULT;
377 restorer = (unsigned long) svc | PSW_ADDR_AMODE; 377 restorer = (unsigned long) svc | PSW_ADDR_AMODE;
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 6fd9e60101f1..0b499f5cbe19 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -236,7 +236,6 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
236 lc->percpu_offset = __per_cpu_offset[cpu]; 236 lc->percpu_offset = __per_cpu_offset[cpu];
237 lc->kernel_asce = S390_lowcore.kernel_asce; 237 lc->kernel_asce = S390_lowcore.kernel_asce;
238 lc->machine_flags = S390_lowcore.machine_flags; 238 lc->machine_flags = S390_lowcore.machine_flags;
239 lc->ftrace_func = S390_lowcore.ftrace_func;
240 lc->user_timer = lc->system_timer = lc->steal_timer = 0; 239 lc->user_timer = lc->system_timer = lc->steal_timer = 0;
241 __ctl_store(lc->cregs_save_area, 0, 15); 240 __ctl_store(lc->cregs_save_area, 0, 15);
242 save_access_regs((unsigned int *) lc->access_regs_save_area); 241 save_access_regs((unsigned int *) lc->access_regs_save_area);
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 9f7087fd58de..a2987243bc76 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -360,3 +360,5 @@ SYSCALL(sys_seccomp,sys_seccomp,compat_sys_seccomp)
360SYSCALL(sys_getrandom,sys_getrandom,compat_sys_getrandom) 360SYSCALL(sys_getrandom,sys_getrandom,compat_sys_getrandom)
361SYSCALL(sys_memfd_create,sys_memfd_create,compat_sys_memfd_create) /* 350 */ 361SYSCALL(sys_memfd_create,sys_memfd_create,compat_sys_memfd_create) /* 350 */
362SYSCALL(sys_bpf,sys_bpf,compat_sys_bpf) 362SYSCALL(sys_bpf,sys_bpf,compat_sys_bpf)
363SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_write,compat_sys_s390_pci_mmio_write)
364SYSCALL(sys_ni_syscall,sys_s390_pci_mmio_read,compat_sys_s390_pci_mmio_read)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 005d665fe4a5..20660dddb2d6 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -61,10 +61,11 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
61/* 61/*
62 * Scheduler clock - returns current time in nanosec units. 62 * Scheduler clock - returns current time in nanosec units.
63 */ 63 */
64unsigned long long notrace __kprobes sched_clock(void) 64unsigned long long notrace sched_clock(void)
65{ 65{
66 return tod_to_ns(get_tod_clock_monotonic()); 66 return tod_to_ns(get_tod_clock_monotonic());
67} 67}
68NOKPROBE_SYMBOL(sched_clock);
68 69
69/* 70/*
70 * Monotonic_clock - returns # of nanoseconds passed since time_init() 71 * Monotonic_clock - returns # of nanoseconds passed since time_init()
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 9ff5ecba26ab..f081cf1157c3 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -49,7 +49,8 @@ static inline void report_user_fault(struct pt_regs *regs, int signr)
49 return; 49 return;
50 if (!printk_ratelimit()) 50 if (!printk_ratelimit())
51 return; 51 return;
52 printk("User process fault: interruption code 0x%X ", regs->int_code); 52 printk("User process fault: interruption code %04x ilc:%d ",
53 regs->int_code & 0xffff, regs->int_code >> 17);
53 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); 54 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
54 printk("\n"); 55 printk("\n");
55 show_regs(regs); 56 show_regs(regs);
@@ -87,16 +88,16 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
87 } 88 }
88} 89}
89 90
90static void __kprobes do_trap(struct pt_regs *regs, int si_signo, int si_code, 91static void do_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
91 char *str)
92{ 92{
93 if (notify_die(DIE_TRAP, str, regs, 0, 93 if (notify_die(DIE_TRAP, str, regs, 0,
94 regs->int_code, si_signo) == NOTIFY_STOP) 94 regs->int_code, si_signo) == NOTIFY_STOP)
95 return; 95 return;
96 do_report_trap(regs, si_signo, si_code, str); 96 do_report_trap(regs, si_signo, si_code, str);
97} 97}
98NOKPROBE_SYMBOL(do_trap);
98 99
99void __kprobes do_per_trap(struct pt_regs *regs) 100void do_per_trap(struct pt_regs *regs)
100{ 101{
101 siginfo_t info; 102 siginfo_t info;
102 103
@@ -111,6 +112,7 @@ void __kprobes do_per_trap(struct pt_regs *regs)
111 (void __force __user *) current->thread.per_event.address; 112 (void __force __user *) current->thread.per_event.address;
112 force_sig_info(SIGTRAP, &info, current); 113 force_sig_info(SIGTRAP, &info, current);
113} 114}
115NOKPROBE_SYMBOL(do_per_trap);
114 116
115void default_trap_handler(struct pt_regs *regs) 117void default_trap_handler(struct pt_regs *regs)
116{ 118{
@@ -151,8 +153,6 @@ DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC,
151 "privileged operation") 153 "privileged operation")
152DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN, 154DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
153 "special operation exception") 155 "special operation exception")
154DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
155 "translation exception")
156 156
157#ifdef CONFIG_64BIT 157#ifdef CONFIG_64BIT
158DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN, 158DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN,
@@ -179,7 +179,13 @@ static inline void do_fp_trap(struct pt_regs *regs, int fpc)
179 do_trap(regs, SIGFPE, si_code, "floating point exception"); 179 do_trap(regs, SIGFPE, si_code, "floating point exception");
180} 180}
181 181
182void __kprobes illegal_op(struct pt_regs *regs) 182void translation_exception(struct pt_regs *regs)
183{
184 /* May never happen. */
185 die(regs, "Translation exception");
186}
187
188void illegal_op(struct pt_regs *regs)
183{ 189{
184 siginfo_t info; 190 siginfo_t info;
185 __u8 opcode[6]; 191 __u8 opcode[6];
@@ -252,7 +258,7 @@ void __kprobes illegal_op(struct pt_regs *regs)
252 if (signal) 258 if (signal)
253 do_trap(regs, signal, ILL_ILLOPC, "illegal operation"); 259 do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
254} 260}
255 261NOKPROBE_SYMBOL(illegal_op);
256 262
257#ifdef CONFIG_MATHEMU 263#ifdef CONFIG_MATHEMU
258void specification_exception(struct pt_regs *regs) 264void specification_exception(struct pt_regs *regs)
@@ -469,7 +475,7 @@ void space_switch_exception(struct pt_regs *regs)
469 do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); 475 do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
470} 476}
471 477
472void __kprobes kernel_stack_overflow(struct pt_regs * regs) 478void kernel_stack_overflow(struct pt_regs *regs)
473{ 479{
474 bust_spinlocks(1); 480 bust_spinlocks(1);
475 printk("Kernel stack overflow.\n"); 481 printk("Kernel stack overflow.\n");
@@ -477,6 +483,7 @@ void __kprobes kernel_stack_overflow(struct pt_regs * regs)
477 bust_spinlocks(0); 483 bust_spinlocks(0);
478 panic("Corrupt kernel stack, can't continue."); 484 panic("Corrupt kernel stack, can't continue.");
479} 485}
486NOKPROBE_SYMBOL(kernel_stack_overflow);
480 487
481void __init trap_init(void) 488void __init trap_init(void)
482{ 489{
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 55aade49b6d1..6b049ee75a56 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -271,7 +271,7 @@ static int kvm_s390_mem_control(struct kvm *kvm, struct kvm_device_attr *attr)
271 case KVM_S390_VM_MEM_CLR_CMMA: 271 case KVM_S390_VM_MEM_CLR_CMMA:
272 mutex_lock(&kvm->lock); 272 mutex_lock(&kvm->lock);
273 idx = srcu_read_lock(&kvm->srcu); 273 idx = srcu_read_lock(&kvm->srcu);
274 page_table_reset_pgste(kvm->arch.gmap->mm, 0, TASK_SIZE, false); 274 s390_reset_cmma(kvm->arch.gmap->mm);
275 srcu_read_unlock(&kvm->srcu, idx); 275 srcu_read_unlock(&kvm->srcu, idx);
276 mutex_unlock(&kvm->lock); 276 mutex_unlock(&kvm->lock);
277 ret = 0; 277 ret = 0;
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 72bb2dd8b9cd..f47cb0c6d906 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -156,21 +156,25 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
156 return 0; 156 return 0;
157} 157}
158 158
159static void __skey_check_enable(struct kvm_vcpu *vcpu) 159static int __skey_check_enable(struct kvm_vcpu *vcpu)
160{ 160{
161 int rc = 0;
161 if (!(vcpu->arch.sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE))) 162 if (!(vcpu->arch.sie_block->ictl & (ICTL_ISKE | ICTL_SSKE | ICTL_RRBE)))
162 return; 163 return rc;
163 164
164 s390_enable_skey(); 165 rc = s390_enable_skey();
165 trace_kvm_s390_skey_related_inst(vcpu); 166 trace_kvm_s390_skey_related_inst(vcpu);
166 vcpu->arch.sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE | ICTL_RRBE); 167 vcpu->arch.sie_block->ictl &= ~(ICTL_ISKE | ICTL_SSKE | ICTL_RRBE);
168 return rc;
167} 169}
168 170
169 171
170static int handle_skey(struct kvm_vcpu *vcpu) 172static int handle_skey(struct kvm_vcpu *vcpu)
171{ 173{
172 __skey_check_enable(vcpu); 174 int rc = __skey_check_enable(vcpu);
173 175
176 if (rc)
177 return rc;
174 vcpu->stat.instruction_storage_key++; 178 vcpu->stat.instruction_storage_key++;
175 179
176 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 180 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
@@ -683,7 +687,10 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
683 } 687 }
684 688
685 if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) { 689 if (vcpu->run->s.regs.gprs[reg1] & PFMF_SK) {
686 __skey_check_enable(vcpu); 690 int rc = __skey_check_enable(vcpu);
691
692 if (rc)
693 return rc;
687 if (set_guest_storage_key(current->mm, useraddr, 694 if (set_guest_storage_key(current->mm, useraddr,
688 vcpu->run->s.regs.gprs[reg1] & PFMF_KEY, 695 vcpu->run->s.regs.gprs[reg1] & PFMF_KEY,
689 vcpu->run->s.regs.gprs[reg1] & PFMF_NQ)) 696 vcpu->run->s.regs.gprs[reg1] & PFMF_NQ))
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index a2b81d6ce8a5..811937bb90be 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -261,8 +261,8 @@ static inline void report_user_fault(struct pt_regs *regs, long signr)
261 return; 261 return;
262 if (!printk_ratelimit()) 262 if (!printk_ratelimit())
263 return; 263 return;
264 printk(KERN_ALERT "User process fault: interruption code 0x%X ", 264 printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d",
265 regs->int_code); 265 regs->int_code & 0xffff, regs->int_code >> 17);
266 print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); 266 print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
267 printk(KERN_CONT "\n"); 267 printk(KERN_CONT "\n");
268 printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", 268 printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
@@ -548,7 +548,7 @@ out:
548 return fault; 548 return fault;
549} 549}
550 550
551void __kprobes do_protection_exception(struct pt_regs *regs) 551void do_protection_exception(struct pt_regs *regs)
552{ 552{
553 unsigned long trans_exc_code; 553 unsigned long trans_exc_code;
554 int fault; 554 int fault;
@@ -574,8 +574,9 @@ void __kprobes do_protection_exception(struct pt_regs *regs)
574 if (unlikely(fault)) 574 if (unlikely(fault))
575 do_fault_error(regs, fault); 575 do_fault_error(regs, fault);
576} 576}
577NOKPROBE_SYMBOL(do_protection_exception);
577 578
578void __kprobes do_dat_exception(struct pt_regs *regs) 579void do_dat_exception(struct pt_regs *regs)
579{ 580{
580 int access, fault; 581 int access, fault;
581 582
@@ -584,6 +585,7 @@ void __kprobes do_dat_exception(struct pt_regs *regs)
584 if (unlikely(fault)) 585 if (unlikely(fault))
585 do_fault_error(regs, fault); 586 do_fault_error(regs, fault);
586} 587}
588NOKPROBE_SYMBOL(do_dat_exception);
587 589
588#ifdef CONFIG_PFAULT 590#ifdef CONFIG_PFAULT
589/* 591/*
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 1b79ca67392f..71c7eff2c89f 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -18,6 +18,8 @@
18#include <linux/rcupdate.h> 18#include <linux/rcupdate.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/swapops.h> 20#include <linux/swapops.h>
21#include <linux/ksm.h>
22#include <linux/mman.h>
21 23
22#include <asm/pgtable.h> 24#include <asm/pgtable.h>
23#include <asm/pgalloc.h> 25#include <asm/pgalloc.h>
@@ -750,8 +752,7 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long gaddr, unsigned long len)
750 break; 752 break;
751 /* Walk the process page table, lock and get pte pointer */ 753 /* Walk the process page table, lock and get pte pointer */
752 ptep = get_locked_pte(gmap->mm, addr, &ptl); 754 ptep = get_locked_pte(gmap->mm, addr, &ptl);
753 if (unlikely(!ptep)) 755 VM_BUG_ON(!ptep);
754 continue;
755 /* Set notification bit in the pgste of the pte */ 756 /* Set notification bit in the pgste of the pte */
756 entry = *ptep; 757 entry = *ptep;
757 if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_PROTECT)) == 0) { 758 if ((pte_val(entry) & (_PAGE_INVALID | _PAGE_PROTECT)) == 0) {
@@ -761,7 +762,7 @@ int gmap_ipte_notify(struct gmap *gmap, unsigned long gaddr, unsigned long len)
761 gaddr += PAGE_SIZE; 762 gaddr += PAGE_SIZE;
762 len -= PAGE_SIZE; 763 len -= PAGE_SIZE;
763 } 764 }
764 spin_unlock(ptl); 765 pte_unmap_unlock(ptep, ptl);
765 } 766 }
766 up_read(&gmap->mm->mmap_sem); 767 up_read(&gmap->mm->mmap_sem);
767 return rc; 768 return rc;
@@ -834,99 +835,6 @@ static inline void page_table_free_pgste(unsigned long *table)
834 __free_page(page); 835 __free_page(page);
835} 836}
836 837
837static inline unsigned long page_table_reset_pte(struct mm_struct *mm, pmd_t *pmd,
838 unsigned long addr, unsigned long end, bool init_skey)
839{
840 pte_t *start_pte, *pte;
841 spinlock_t *ptl;
842 pgste_t pgste;
843
844 start_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
845 pte = start_pte;
846 do {
847 pgste = pgste_get_lock(pte);
848 pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK;
849 if (init_skey) {
850 unsigned long address;
851
852 pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT |
853 PGSTE_GR_BIT | PGSTE_GC_BIT);
854
855 /* skip invalid and not writable pages */
856 if (pte_val(*pte) & _PAGE_INVALID ||
857 !(pte_val(*pte) & _PAGE_WRITE)) {
858 pgste_set_unlock(pte, pgste);
859 continue;
860 }
861
862 address = pte_val(*pte) & PAGE_MASK;
863 page_set_storage_key(address, PAGE_DEFAULT_KEY, 1);
864 }
865 pgste_set_unlock(pte, pgste);
866 } while (pte++, addr += PAGE_SIZE, addr != end);
867 pte_unmap_unlock(start_pte, ptl);
868
869 return addr;
870}
871
872static inline unsigned long page_table_reset_pmd(struct mm_struct *mm, pud_t *pud,
873 unsigned long addr, unsigned long end, bool init_skey)
874{
875 unsigned long next;
876 pmd_t *pmd;
877
878 pmd = pmd_offset(pud, addr);
879 do {
880 next = pmd_addr_end(addr, end);
881 if (pmd_none_or_clear_bad(pmd))
882 continue;
883 next = page_table_reset_pte(mm, pmd, addr, next, init_skey);
884 } while (pmd++, addr = next, addr != end);
885
886 return addr;
887}
888
889static inline unsigned long page_table_reset_pud(struct mm_struct *mm, pgd_t *pgd,
890 unsigned long addr, unsigned long end, bool init_skey)
891{
892 unsigned long next;
893 pud_t *pud;
894
895 pud = pud_offset(pgd, addr);
896 do {
897 next = pud_addr_end(addr, end);
898 if (pud_none_or_clear_bad(pud))
899 continue;
900 next = page_table_reset_pmd(mm, pud, addr, next, init_skey);
901 } while (pud++, addr = next, addr != end);
902
903 return addr;
904}
905
906void page_table_reset_pgste(struct mm_struct *mm, unsigned long start,
907 unsigned long end, bool init_skey)
908{
909 unsigned long addr, next;
910 pgd_t *pgd;
911
912 down_write(&mm->mmap_sem);
913 if (init_skey && mm_use_skey(mm))
914 goto out_up;
915 addr = start;
916 pgd = pgd_offset(mm, addr);
917 do {
918 next = pgd_addr_end(addr, end);
919 if (pgd_none_or_clear_bad(pgd))
920 continue;
921 next = page_table_reset_pud(mm, pgd, addr, next, init_skey);
922 } while (pgd++, addr = next, addr != end);
923 if (init_skey)
924 current->mm->context.use_skey = 1;
925out_up:
926 up_write(&mm->mmap_sem);
927}
928EXPORT_SYMBOL(page_table_reset_pgste);
929
930int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, 838int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
931 unsigned long key, bool nq) 839 unsigned long key, bool nq)
932{ 840{
@@ -992,11 +900,6 @@ static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm)
992 return NULL; 900 return NULL;
993} 901}
994 902
995void page_table_reset_pgste(struct mm_struct *mm, unsigned long start,
996 unsigned long end, bool init_skey)
997{
998}
999
1000static inline void page_table_free_pgste(unsigned long *table) 903static inline void page_table_free_pgste(unsigned long *table)
1001{ 904{
1002} 905}
@@ -1347,13 +1250,89 @@ EXPORT_SYMBOL_GPL(s390_enable_sie);
1347 * Enable storage key handling from now on and initialize the storage 1250 * Enable storage key handling from now on and initialize the storage
1348 * keys with the default key. 1251 * keys with the default key.
1349 */ 1252 */
1350void s390_enable_skey(void) 1253static int __s390_enable_skey(pte_t *pte, unsigned long addr,
1254 unsigned long next, struct mm_walk *walk)
1351{ 1255{
1352 page_table_reset_pgste(current->mm, 0, TASK_SIZE, true); 1256 unsigned long ptev;
1257 pgste_t pgste;
1258
1259 pgste = pgste_get_lock(pte);
1260 /*
1261 * Remove all zero page mappings,
1262 * after establishing a policy to forbid zero page mappings
1263 * following faults for that page will get fresh anonymous pages
1264 */
1265 if (is_zero_pfn(pte_pfn(*pte))) {
1266 ptep_flush_direct(walk->mm, addr, pte);
1267 pte_val(*pte) = _PAGE_INVALID;
1268 }
1269 /* Clear storage key */
1270 pgste_val(pgste) &= ~(PGSTE_ACC_BITS | PGSTE_FP_BIT |
1271 PGSTE_GR_BIT | PGSTE_GC_BIT);
1272 ptev = pte_val(*pte);
1273 if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE))
1274 page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1);
1275 pgste_set_unlock(pte, pgste);
1276 return 0;
1277}
1278
1279int s390_enable_skey(void)
1280{
1281 struct mm_walk walk = { .pte_entry = __s390_enable_skey };
1282 struct mm_struct *mm = current->mm;
1283 struct vm_area_struct *vma;
1284 int rc = 0;
1285
1286 down_write(&mm->mmap_sem);
1287 if (mm_use_skey(mm))
1288 goto out_up;
1289
1290 mm->context.use_skey = 1;
1291 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1292 if (ksm_madvise(vma, vma->vm_start, vma->vm_end,
1293 MADV_UNMERGEABLE, &vma->vm_flags)) {
1294 mm->context.use_skey = 0;
1295 rc = -ENOMEM;
1296 goto out_up;
1297 }
1298 }
1299 mm->def_flags &= ~VM_MERGEABLE;
1300
1301 walk.mm = mm;
1302 walk_page_range(0, TASK_SIZE, &walk);
1303
1304out_up:
1305 up_write(&mm->mmap_sem);
1306 return rc;
1353} 1307}
1354EXPORT_SYMBOL_GPL(s390_enable_skey); 1308EXPORT_SYMBOL_GPL(s390_enable_skey);
1355 1309
1356/* 1310/*
1311 * Reset CMMA state, make all pages stable again.
1312 */
1313static int __s390_reset_cmma(pte_t *pte, unsigned long addr,
1314 unsigned long next, struct mm_walk *walk)
1315{
1316 pgste_t pgste;
1317
1318 pgste = pgste_get_lock(pte);
1319 pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK;
1320 pgste_set_unlock(pte, pgste);
1321 return 0;
1322}
1323
1324void s390_reset_cmma(struct mm_struct *mm)
1325{
1326 struct mm_walk walk = { .pte_entry = __s390_reset_cmma };
1327
1328 down_write(&mm->mmap_sem);
1329 walk.mm = mm;
1330 walk_page_range(0, TASK_SIZE, &walk);
1331 up_write(&mm->mmap_sem);
1332}
1333EXPORT_SYMBOL_GPL(s390_reset_cmma);
1334
1335/*
1357 * Test and reset if a guest page is dirty 1336 * Test and reset if a guest page is dirty
1358 */ 1337 */
1359bool gmap_test_and_clear_dirty(unsigned long address, struct gmap *gmap) 1338bool gmap_test_and_clear_dirty(unsigned long address, struct gmap *gmap)
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index a9e1dc4ae442..805d8b29193a 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -3,4 +3,4 @@
3# 3#
4 4
5obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_sysfs.o \ 5obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_sysfs.o \
6 pci_event.o pci_debug.o pci_insn.o 6 pci_event.o pci_debug.o pci_insn.o pci_mmio.o
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index d59c82569750..3290f11ae1d9 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -369,8 +369,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
369 369
370 if (type == PCI_CAP_ID_MSI && nvec > 1) 370 if (type == PCI_CAP_ID_MSI && nvec > 1)
371 return 1; 371 return 1;
372 msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); 372 msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
373 msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI);
374 373
375 /* Allocate adapter summary indicator bit */ 374 /* Allocate adapter summary indicator bit */
376 rc = -EIO; 375 rc = -EIO;
@@ -474,7 +473,8 @@ static void zpci_map_resources(struct zpci_dev *zdev)
474 len = pci_resource_len(pdev, i); 473 len = pci_resource_len(pdev, i);
475 if (!len) 474 if (!len)
476 continue; 475 continue;
477 pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); 476 pdev->resource[i].start =
477 (resource_size_t __force) pci_iomap(pdev, i, 0);
478 pdev->resource[i].end = pdev->resource[i].start + len - 1; 478 pdev->resource[i].end = pdev->resource[i].start + len - 1;
479 } 479 }
480} 480}
@@ -489,7 +489,8 @@ static void zpci_unmap_resources(struct zpci_dev *zdev)
489 len = pci_resource_len(pdev, i); 489 len = pci_resource_len(pdev, i);
490 if (!len) 490 if (!len)
491 continue; 491 continue;
492 pci_iounmap(pdev, (void *) pdev->resource[i].start); 492 pci_iounmap(pdev, (void __iomem __force *)
493 pdev->resource[i].start);
493 } 494 }
494} 495}
495 496
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index 6e22a247de9b..d6e411ed8b1f 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -62,6 +62,7 @@ static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
62 zdev->tlb_refresh = response->refresh; 62 zdev->tlb_refresh = response->refresh;
63 zdev->dma_mask = response->dasm; 63 zdev->dma_mask = response->dasm;
64 zdev->msi_addr = response->msia; 64 zdev->msi_addr = response->msia;
65 zdev->max_msi = response->noi;
65 zdev->fmb_update = response->mui; 66 zdev->fmb_update = response->mui;
66 67
67 switch (response->version) { 68 switch (response->version) {
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c
index eec598c5939f..3229a2e570df 100644
--- a/arch/s390/pci/pci_debug.c
+++ b/arch/s390/pci/pci_debug.c
@@ -158,10 +158,7 @@ int __init zpci_debug_init(void)
158 158
159void zpci_debug_exit(void) 159void zpci_debug_exit(void)
160{ 160{
161 if (pci_debug_msg_id) 161 debug_unregister(pci_debug_msg_id);
162 debug_unregister(pci_debug_msg_id); 162 debug_unregister(pci_debug_err_id);
163 if (pci_debug_err_id)
164 debug_unregister(pci_debug_err_id);
165
166 debugfs_remove(debugfs_root); 163 debugfs_remove(debugfs_root);
167} 164}
diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
new file mode 100644
index 000000000000..62c5ea6d8682
--- /dev/null
+++ b/arch/s390/pci/pci_mmio.c
@@ -0,0 +1,115 @@
1/*
2 * Access to PCI I/O memory from user space programs.
3 *
4 * Copyright IBM Corp. 2014
5 * Author(s): Alexey Ishchuk <aishchuk@linux.vnet.ibm.com>
6 */
7#include <linux/kernel.h>
8#include <linux/syscalls.h>
9#include <linux/init.h>
10#include <linux/mm.h>
11#include <linux/errno.h>
12#include <linux/pci.h>
13
14static long get_pfn(unsigned long user_addr, unsigned long access,
15 unsigned long *pfn)
16{
17 struct vm_area_struct *vma;
18 long ret;
19
20 down_read(&current->mm->mmap_sem);
21 ret = -EINVAL;
22 vma = find_vma(current->mm, user_addr);
23 if (!vma)
24 goto out;
25 ret = -EACCES;
26 if (!(vma->vm_flags & access))
27 goto out;
28 ret = follow_pfn(vma, user_addr, pfn);
29out:
30 up_read(&current->mm->mmap_sem);
31 return ret;
32}
33
34SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
35 const void __user *, user_buffer, size_t, length)
36{
37 u8 local_buf[64];
38 void __iomem *io_addr;
39 void *buf;
40 unsigned long pfn;
41 long ret;
42
43 if (!zpci_is_enabled())
44 return -ENODEV;
45
46 if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length)
47 return -EINVAL;
48 if (length > 64) {
49 buf = kmalloc(length, GFP_KERNEL);
50 if (!buf)
51 return -ENOMEM;
52 } else
53 buf = local_buf;
54
55 ret = get_pfn(mmio_addr, VM_WRITE, &pfn);
56 if (ret)
57 goto out;
58 io_addr = (void *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK));
59
60 ret = -EFAULT;
61 if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE)
62 goto out;
63
64 if (copy_from_user(buf, user_buffer, length))
65 goto out;
66
67 memcpy_toio(io_addr, buf, length);
68 ret = 0;
69out:
70 if (buf != local_buf)
71 kfree(buf);
72 return ret;
73}
74
75SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
76 void __user *, user_buffer, size_t, length)
77{
78 u8 local_buf[64];
79 void __iomem *io_addr;
80 void *buf;
81 unsigned long pfn;
82 long ret;
83
84 if (!zpci_is_enabled())
85 return -ENODEV;
86
87 if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length)
88 return -EINVAL;
89 if (length > 64) {
90 buf = kmalloc(length, GFP_KERNEL);
91 if (!buf)
92 return -ENOMEM;
93 } else
94 buf = local_buf;
95
96 ret = get_pfn(mmio_addr, VM_READ, &pfn);
97 if (ret)
98 goto out;
99 io_addr = (void *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK));
100
101 ret = -EFAULT;
102 if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE)
103 goto out;
104
105 memcpy_fromio(buf, io_addr, length);
106
107 if (copy_to_user(user_buffer, buf, length))
108 goto out;
109
110 ret = 0;
111out:
112 if (buf != local_buf)
113 kfree(buf);
114 return ret;
115}
diff --git a/arch/x86/include/asm/xen/cpuid.h b/arch/x86/include/asm/xen/cpuid.h
new file mode 100644
index 000000000000..0d809e9fc975
--- /dev/null
+++ b/arch/x86/include/asm/xen/cpuid.h
@@ -0,0 +1,91 @@
1/******************************************************************************
2 * arch-x86/cpuid.h
3 *
4 * CPUID interface to Xen.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Copyright (c) 2007 Citrix Systems, Inc.
25 *
26 * Authors:
27 * Keir Fraser <keir@xen.org>
28 */
29
30#ifndef __XEN_PUBLIC_ARCH_X86_CPUID_H__
31#define __XEN_PUBLIC_ARCH_X86_CPUID_H__
32
33/*
34 * For compatibility with other hypervisor interfaces, the Xen cpuid leaves
35 * can be found at the first otherwise unused 0x100 aligned boundary starting
36 * from 0x40000000.
37 *
38 * e.g If viridian extensions are enabled for an HVM domain, the Xen cpuid
39 * leaves will start at 0x40000100
40 */
41
42#define XEN_CPUID_FIRST_LEAF 0x40000000
43#define XEN_CPUID_LEAF(i) (XEN_CPUID_FIRST_LEAF + (i))
44
45/*
46 * Leaf 1 (0x40000x00)
47 * EAX: Largest Xen-information leaf. All leaves up to an including @EAX
48 * are supported by the Xen host.
49 * EBX-EDX: "XenVMMXenVMM" signature, allowing positive identification
50 * of a Xen host.
51 */
52#define XEN_CPUID_SIGNATURE_EBX 0x566e6558 /* "XenV" */
53#define XEN_CPUID_SIGNATURE_ECX 0x65584d4d /* "MMXe" */
54#define XEN_CPUID_SIGNATURE_EDX 0x4d4d566e /* "nVMM" */
55
56/*
57 * Leaf 2 (0x40000x01)
58 * EAX[31:16]: Xen major version.
59 * EAX[15: 0]: Xen minor version.
60 * EBX-EDX: Reserved (currently all zeroes).
61 */
62
63/*
64 * Leaf 3 (0x40000x02)
65 * EAX: Number of hypercall transfer pages. This register is always guaranteed
66 * to specify one hypercall page.
67 * EBX: Base address of Xen-specific MSRs.
68 * ECX: Features 1. Unused bits are set to zero.
69 * EDX: Features 2. Unused bits are set to zero.
70 */
71
72/* Does the host support MMU_PT_UPDATE_PRESERVE_AD for this guest? */
73#define _XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD 0
74#define XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD (1u<<0)
75
76/*
77 * Leaf 5 (0x40000x04)
78 * HVM-specific features
79 */
80
81/* EAX Features */
82/* Virtualized APIC registers */
83#define XEN_HVM_CPUID_APIC_ACCESS_VIRT (1u << 0)
84/* Virtualized x2APIC accesses */
85#define XEN_HVM_CPUID_X2APIC_VIRT (1u << 1)
86/* Memory mapped from other domains has valid IOMMU entries */
87#define XEN_HVM_CPUID_IOMMU_MAPPINGS (1u << 2)
88
89#define XEN_CPUID_MAX_NUM_LEAVES 4
90
91#endif /* __XEN_PUBLIC_ARCH_X86_CPUID_H__ */
diff --git a/arch/x86/include/asm/xen/page-coherent.h b/arch/x86/include/asm/xen/page-coherent.h
index 7f02fe4e2c7b..acd844c017d3 100644
--- a/arch/x86/include/asm/xen/page-coherent.h
+++ b/arch/x86/include/asm/xen/page-coherent.h
@@ -22,8 +22,8 @@ static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
22} 22}
23 23
24static inline void xen_dma_map_page(struct device *hwdev, struct page *page, 24static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
25 unsigned long offset, size_t size, enum dma_data_direction dir, 25 dma_addr_t dev_addr, unsigned long offset, size_t size,
26 struct dma_attrs *attrs) { } 26 enum dma_data_direction dir, struct dma_attrs *attrs) { }
27 27
28static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle, 28static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
29 size_t size, enum dma_data_direction dir, 29 size_t size, enum dma_data_direction dir,
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index c949923a5668..f58ef6c0613b 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -236,4 +236,11 @@ void make_lowmem_page_readwrite(void *vaddr);
236#define xen_remap(cookie, size) ioremap((cookie), (size)); 236#define xen_remap(cookie, size) ioremap((cookie), (size));
237#define xen_unmap(cookie) iounmap((cookie)) 237#define xen_unmap(cookie) iounmap((cookie))
238 238
239static inline bool xen_arch_need_swiotlb(struct device *dev,
240 unsigned long pfn,
241 unsigned long mfn)
242{
243 return false;
244}
245
239#endif /* _ASM_X86_XEN_PAGE_H */ 246#endif /* _ASM_X86_XEN_PAGE_H */
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 1819a91bbb9f..c489ef2c1a39 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -23,6 +23,8 @@
23#include <xen/features.h> 23#include <xen/features.h>
24#include <xen/events.h> 24#include <xen/events.h>
25#include <asm/xen/pci.h> 25#include <asm/xen/pci.h>
26#include <asm/xen/cpuid.h>
27#include <asm/apic.h>
26#include <asm/i8259.h> 28#include <asm/i8259.h>
27 29
28static int xen_pcifront_enable_irq(struct pci_dev *dev) 30static int xen_pcifront_enable_irq(struct pci_dev *dev)
@@ -423,6 +425,28 @@ int __init pci_xen_init(void)
423 return 0; 425 return 0;
424} 426}
425 427
428#ifdef CONFIG_PCI_MSI
429void __init xen_msi_init(void)
430{
431 if (!disable_apic) {
432 /*
433 * If hardware supports (x2)APIC virtualization (as indicated
434 * by hypervisor's leaf 4) then we don't need to use pirqs/
435 * event channels for MSI handling and instead use regular
436 * APIC processing
437 */
438 uint32_t eax = cpuid_eax(xen_cpuid_base() + 4);
439
440 if (((eax & XEN_HVM_CPUID_X2APIC_VIRT) && x2apic_mode) ||
441 ((eax & XEN_HVM_CPUID_APIC_ACCESS_VIRT) && cpu_has_apic))
442 return;
443 }
444
445 x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
446 x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
447}
448#endif
449
426int __init pci_xen_hvm_init(void) 450int __init pci_xen_hvm_init(void)
427{ 451{
428 if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs)) 452 if (!xen_have_vector_callback || !xen_feature(XENFEAT_hvm_pirqs))
@@ -437,8 +461,11 @@ int __init pci_xen_hvm_init(void)
437#endif 461#endif
438 462
439#ifdef CONFIG_PCI_MSI 463#ifdef CONFIG_PCI_MSI
440 x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs; 464 /*
441 x86_msi.teardown_msi_irq = xen_teardown_msi_irq; 465 * We need to wait until after x2apic is initialized
466 * before we can set MSI IRQ ops.
467 */
468 x86_platform.apic_post_init = xen_msi_init;
442#endif 469#endif
443 return 0; 470 return 0;
444} 471}