aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig100
-rw-r--r--arch/arm/Kconfig.debug2
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-shmobile.S53
-rw-r--r--arch/arm/common/Kconfig4
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/clkdev.c179
-rw-r--r--arch/arm/common/dmabounce.c16
-rw-r--r--arch/arm/common/gic.c69
-rw-r--r--arch/arm/common/it8152.c1
-rw-r--r--arch/arm/common/timer-sp.c (renamed from arch/arm/plat-versatile/timer-sp.c)8
-rw-r--r--arch/arm/include/asm/assembler.h35
-rw-r--r--arch/arm/include/asm/cache.h2
-rw-r--r--arch/arm/include/asm/clkdev.h22
-rw-r--r--arch/arm/include/asm/dma-mapping.h93
-rw-r--r--arch/arm/include/asm/domain.h31
-rw-r--r--arch/arm/include/asm/elf.h2
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S44
-rw-r--r--arch/arm/include/asm/futex.h9
-rw-r--r--arch/arm/include/asm/hardirq.h18
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-gic.S75
-rw-r--r--arch/arm/include/asm/hardware/gic.h7
-rw-r--r--arch/arm/include/asm/hardware/it8152.h1
-rw-r--r--arch/arm/include/asm/hardware/timer-sp.h (renamed from arch/arm/plat-versatile/include/plat/timer-sp.h)0
-rw-r--r--arch/arm/include/asm/highmem.h3
-rw-r--r--arch/arm/include/asm/io.h13
-rw-r--r--arch/arm/include/asm/kexec.h18
-rw-r--r--arch/arm/include/asm/localtimer.h12
-rw-r--r--arch/arm/include/asm/mach/arch.h9
-rw-r--r--arch/arm/include/asm/mach/irq.h8
-rw-r--r--arch/arm/include/asm/mach/time.h1
-rw-r--r--arch/arm/include/asm/module.h15
-rw-r--r--arch/arm/include/asm/page.h6
-rw-r--r--arch/arm/include/asm/pgalloc.h50
-rw-r--r--arch/arm/include/asm/pgtable.h315
-rw-r--r--arch/arm/include/asm/sched_clock.h118
-rw-r--r--arch/arm/include/asm/sizes.h6
-rw-r--r--arch/arm/include/asm/smp.h17
-rw-r--r--arch/arm/include/asm/smp_mpidr.h17
-rw-r--r--arch/arm/include/asm/smp_twd.h1
-rw-r--r--arch/arm/include/asm/system.h8
-rw-r--r--arch/arm/include/asm/traps.h2
-rw-r--r--arch/arm/include/asm/uaccess.h16
-rw-r--r--arch/arm/kernel/Makefile5
-rw-r--r--arch/arm/kernel/entry-armv.S52
-rw-r--r--arch/arm/kernel/entry-common.S6
-rw-r--r--arch/arm/kernel/fiq.c10
-rw-r--r--arch/arm/kernel/head.S50
-rw-r--r--arch/arm/kernel/irq.c30
-rw-r--r--arch/arm/kernel/machine_kexec.c30
-rw-r--r--arch/arm/kernel/module.c109
-rw-r--r--arch/arm/kernel/sched_clock.c69
-rw-r--r--arch/arm/kernel/setup.c37
-rw-r--r--arch/arm/kernel/smp.c446
-rw-r--r--arch/arm/kernel/smp_tlb.c139
-rw-r--r--arch/arm/kernel/smp_twd.c17
-rw-r--r--arch/arm/kernel/swp_emulate.c267
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c26
-rw-r--r--arch/arm/kernel/vmlinux.lds.S1
-rw-r--r--arch/arm/lib/getuser.S13
-rw-r--r--arch/arm/lib/putuser.S29
-rw-r--r--arch/arm/lib/uaccess.S83
-rw-r--r--arch/arm/mach-at91/Makefile2
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c4
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c4
-rw-r--r--arch/arm/mach-at91/board-pcontrol-g20.c98
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c82
-rw-r--r--arch/arm/mach-at91/clock.c2
-rw-r--r--arch/arm/mach-at91/include/mach/at91_mci.h2
-rw-r--r--arch/arm/mach-at91/include/mach/stamp9g20.h7
-rw-r--r--arch/arm/mach-bcmring/clock.c3
-rw-r--r--arch/arm/mach-bcmring/core.c16
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig1
-rw-r--r--arch/arm/mach-cns3xxx/core.c7
-rw-r--r--arch/arm/mach-cns3xxx/core.h1
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/entry-macro.S66
-rw-r--r--arch/arm/mach-davinci/clock.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/io.h4
-rw-r--r--arch/arm/mach-davinci/time.c7
-rw-r--r--arch/arm/mach-ep93xx/clock.c2
-rw-r--r--arch/arm/mach-imx/clock-imx1.c3
-rw-r--r--arch/arm/mach-imx/clock-imx21.c2
-rw-r--r--arch/arm/mach-imx/clock-imx25.c3
-rw-r--r--arch/arm/mach-imx/clock-imx27.c2
-rw-r--r--arch/arm/mach-integrator/Kconfig1
-rw-r--r--arch/arm/mach-integrator/core.c3
-rw-r--r--arch/arm/mach-integrator/impd1.c3
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c4
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c5
-rw-r--r--arch/arm/mach-iop13xx/include/mach/io.h4
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h6
-rw-r--r--arch/arm/mach-iop32x/include/mach/io.h4
-rw-r--r--arch/arm/mach-iop33x/include/mach/io.h4
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/io.h4
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c2
-rw-r--r--arch/arm/mach-ixp4xx/common.c35
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h4
-rw-r--r--arch/arm/mach-kirkwood/include/mach/io.h4
-rw-r--r--arch/arm/mach-ks8695/Kconfig1
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h8
-rw-r--r--arch/arm/mach-lpc32xx/clock.c3
-rw-r--r--arch/arm/mach-lpc32xx/timer.c5
-rw-r--r--arch/arm/mach-mmp/clock.h2
-rw-r--r--arch/arm/mach-mmp/time.c39
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c7
-rw-r--r--arch/arm/mach-msm/include/mach/smp.h4
-rw-r--r--arch/arm/mach-msm/timer.c5
-rw-r--r--arch/arm/mach-mx3/clock-imx31.c2
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c3
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c2
-rw-r--r--arch/arm/mach-mxc91231/clock.c2
-rw-r--r--arch/arm/mach-netx/time.c5
-rw-r--r--arch/arm/mach-nomadik/clock.c2
-rw-r--r--arch/arm/mach-ns9xxx/time-ns9360.c6
-rw-r--r--arch/arm/mach-nuc93x/clock.h2
-rw-r--r--arch/arm/mach-omap1/clock.c2
-rw-r--r--arch/arm/mach-omap1/time.c6
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c2
-rw-r--r--arch/arm/mach-omap2/include/mach/entry-macro.S93
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h1
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c14
-rw-r--r--arch/arm/mach-omap2/omap-smp.c68
-rw-r--r--arch/arm/mach-omap2/omap4-common.c11
-rw-r--r--arch/arm/mach-omap2/timer-gp.c5
-rw-r--r--arch/arm/mach-orion5x/include/mach/io.h4
-rw-r--r--arch/arm/mach-pnx4008/clock.c3
-rw-r--r--arch/arm/mach-pxa/Kconfig2
-rw-r--r--arch/arm/mach-pxa/clock.c3
-rw-r--r--arch/arm/mach-pxa/clock.h2
-rw-r--r--arch/arm/mach-pxa/sleep.S4
-rw-r--r--arch/arm/mach-pxa/time.c35
-rw-r--r--arch/arm/mach-realview/core.c18
-rw-r--r--arch/arm/mach-realview/core.h1
-rw-r--r--arch/arm/mach-realview/hotplug.c44
-rw-r--r--arch/arm/mach-realview/include/mach/entry-macro.S65
-rw-r--r--arch/arm/mach-realview/include/mach/smp.h5
-rw-r--r--arch/arm/mach-realview/platsmp.c116
-rw-r--r--arch/arm/mach-realview/realview_eb.c14
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c11
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c10
-rw-r--r--arch/arm/mach-realview/realview_pba8.c6
-rw-r--r--arch/arm/mach-realview/realview_pbx.c13
-rw-r--r--arch/arm/mach-s3c2412/Kconfig9
-rw-r--r--arch/arm/mach-s3c2412/Makefile3
-rw-r--r--arch/arm/mach-s3c2416/Kconfig1
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c6
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c6
-rw-r--r--arch/arm/mach-s5pv310/cpu.c6
-rw-r--r--arch/arm/mach-s5pv310/hotplug.c44
-rw-r--r--arch/arm/mach-s5pv310/include/mach/smp.h7
-rw-r--r--arch/arm/mach-s5pv310/platsmp.c68
-rw-r--r--arch/arm/mach-s5pv310/time.c6
-rw-r--r--arch/arm/mach-sa1100/Kconfig10
-rw-r--r--arch/arm/mach-sa1100/Makefile3
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c51
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1110.c57
-rw-r--r--arch/arm/mach-sa1100/generic.c64
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h8
-rw-r--r--arch/arm/mach-sa1100/include/mach/nanoengine.h52
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c119
-rw-r--r--arch/arm/mach-sa1100/pci-nanoengine.c284
-rw-r--r--arch/arm/mach-sa1100/simpad.c7
-rw-r--r--arch/arm/mach-sa1100/time.c36
-rw-r--r--arch/arm/mach-shmobile/Kconfig6
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c1
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro.S30
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-ap4evb.txt87
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot.h20
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot_macros.h65
-rw-r--r--arch/arm/mach-tcc8k/clock.c3
-rw-r--r--arch/arm/mach-tcc8k/time.c5
-rw-r--r--arch/arm/mach-tegra/clock.c2
-rw-r--r--arch/arm/mach-tegra/clock.h2
-rw-r--r--arch/arm/mach-tegra/hotplug.c44
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S66
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h12
-rw-r--r--arch/arm/mach-tegra/irq.c4
-rw-r--r--arch/arm/mach-tegra/platsmp.c35
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c3
-rw-r--r--arch/arm/mach-tegra/timer.c31
-rw-r--r--arch/arm/mach-u300/clock.c2
-rw-r--r--arch/arm/mach-u300/timer.c22
-rw-r--r--arch/arm/mach-ux500/clock.c3
-rw-r--r--arch/arm/mach-ux500/cpu.c4
-rw-r--r--arch/arm/mach-ux500/headsmp.S1
-rw-r--r--arch/arm/mach-ux500/hotplug.c18
-rw-r--r--arch/arm/mach-ux500/include/mach/entry-macro.S68
-rw-r--r--arch/arm/mach-ux500/include/mach/smp.h5
-rw-r--r--arch/arm/mach-ux500/platsmp.c75
-rw-r--r--arch/arm/mach-versatile/Kconfig1
-rw-r--r--arch/arm/mach-versatile/core.c15
-rw-r--r--arch/arm/mach-vexpress/Makefile1
-rw-r--r--arch/arm/mach-vexpress/core.h2
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c12
-rw-r--r--arch/arm/mach-vexpress/hotplug.c128
-rw-r--r--arch/arm/mach-vexpress/include/mach/entry-macro.S62
-rw-r--r--arch/arm/mach-vexpress/include/mach/smp.h5
-rw-r--r--arch/arm/mach-vexpress/platsmp.c76
-rw-r--r--arch/arm/mach-vexpress/v2m.c8
-rw-r--r--arch/arm/mach-w90x900/clock.h2
-rw-r--r--arch/arm/mach-w90x900/time.c5
-rw-r--r--arch/arm/mm/Kconfig35
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c37
-rw-r--r--arch/arm/mm/cache-xsc3l2.c57
-rw-r--r--arch/arm/mm/dma-mapping.c35
-rw-r--r--arch/arm/mm/fault-armv.c2
-rw-r--r--arch/arm/mm/fault.c2
-rw-r--r--arch/arm/mm/flush.c7
-rw-r--r--arch/arm/mm/highmem.c87
-rw-r--r--arch/arm/mm/idmap.c67
-rw-r--r--arch/arm/mm/ioremap.c8
-rw-r--r--arch/arm/mm/mm.h2
-rw-r--r--arch/arm/mm/mmu.c68
-rw-r--r--arch/arm/mm/pgd.c37
-rw-r--r--arch/arm/mm/proc-macros.S37
-rw-r--r--arch/arm/mm/proc-v7.S27
-rw-r--r--arch/arm/mm/proc-xscale.S4
-rw-r--r--arch/arm/plat-iop/time.c27
-rw-r--r--arch/arm/plat-mxc/epit.c5
-rw-r--r--arch/arm/plat-mxc/time.c5
-rw-r--r--arch/arm/plat-nomadik/Kconfig1
-rw-r--r--arch/arm/plat-nomadik/timer.c80
-rw-r--r--arch/arm/plat-omap/Kconfig4
-rw-r--r--arch/arm/plat-omap/counter_32k.c47
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h2
-rw-r--r--arch/arm/plat-omap/include/plat/io.h4
-rw-r--r--arch/arm/plat-omap/include/plat/memory.h8
-rw-r--r--arch/arm/plat-omap/include/plat/smp.h5
-rw-r--r--arch/arm/plat-orion/time.c50
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig2
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h2
-rw-r--r--arch/arm/plat-spear/time.c6
-rw-r--r--arch/arm/plat-stmp3xxx/clock.c2
-rw-r--r--arch/arm/plat-stmp3xxx/timer.c5
-rw-r--r--arch/arm/plat-versatile/Makefile6
-rw-r--r--arch/arm/plat-versatile/include/plat/sched_clock.h6
-rw-r--r--arch/arm/plat-versatile/sched-clock.c50
-rw-r--r--arch/arm/vfp/vfpmodule.c24
-rw-r--r--arch/mips/Kconfig38
-rw-r--r--arch/mips/alchemy/common/platform.c2
-rw-r--r--arch/mips/alchemy/devboards/prom.c5
-rw-r--r--arch/mips/ar7/clock.c9
-rw-r--r--arch/mips/ar7/time.c3
-rw-r--r--arch/mips/bcm47xx/setup.c153
-rw-r--r--arch/mips/include/asm/cpu.h4
-rw-r--r--arch/mips/include/asm/elf.h8
-rw-r--r--arch/mips/include/asm/io.h12
-rw-r--r--arch/mips/include/asm/mach-ar7/ar7.h3
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/nvram.h7
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c4
-rw-r--r--arch/mips/jz4740/platform.c2
-rw-r--r--arch/mips/jz4740/prom.c2
-rw-r--r--arch/mips/kernel/cevt-r4k.c2
-rw-r--r--arch/mips/kernel/cpu-probe.c7
-rw-r--r--arch/mips/kernel/linux32.c13
-rw-r--r--arch/mips/kernel/process.c1
-rw-r--r--arch/mips/kernel/prom.c2
-rw-r--r--arch/mips/kernel/smp-mt.c2
-rw-r--r--arch/mips/kernel/traps.c44
-rw-r--r--arch/mips/kernel/vpe.c14
-rw-r--r--arch/mips/lib/memset.S4
-rw-r--r--arch/mips/loongson/common/env.c4
-rw-r--r--arch/mips/math-emu/cp1emu.c116
-rw-r--r--arch/mips/mm/dma-default.c4
-rw-r--r--arch/mips/mm/sc-mips.c4
-rw-r--r--arch/mips/pmc-sierra/yosemite/py-console.c12
-rw-r--r--arch/mips/sibyte/swarm/setup.c8
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/time.c10
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c1
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/boards/mach-highlander/setup.c2
-rw-r--r--arch/sh/boards/mach-se/7206/irq.c2
-rw-r--r--arch/sh/include/asm/clkdev.h38
-rw-r--r--arch/sh/kernel/Makefile2
-rw-r--r--arch/sh/kernel/clkdev.c171
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c2
-rw-r--r--arch/sh/kernel/cpu/clock.c16
-rw-r--r--arch/sh/kernel/cpu/sh2a/clock-sh7201.c2
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7366.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7723.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c2
-rw-r--r--arch/tile/include/asm/signal.h2
-rw-r--r--arch/tile/kernel/compat_signal.c6
-rw-r--r--arch/tile/kernel/intvec_32.S24
-rw-r--r--arch/tile/kernel/process.c8
-rw-r--r--arch/tile/kernel/signal.c10
-rw-r--r--arch/x86/boot/compressed/misc.c2
-rw-r--r--arch/x86/include/asm/e820.h3
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kernel/Makefile1
-rw-r--r--arch/x86/kernel/apic/apic.c8
-rw-r--r--arch/x86/kernel/apic/io_apic.c4
-rw-r--r--arch/x86/kernel/apic/probe_64.c7
-rw-r--r--arch/x86/kernel/head_32.S16
-rw-r--r--arch/x86/kernel/hpet.c26
-rw-r--r--arch/x86/kernel/microcode_intel.c16
-rw-r--r--arch/x86/kernel/resource.c48
-rw-r--r--arch/x86/kernel/setup.c18
-rw-r--r--arch/x86/kernel/xsave.c3
-rw-r--r--arch/x86/kvm/i8259.c2
-rw-r--r--arch/x86/kvm/mmu.c3
-rw-r--r--arch/x86/kvm/svm.c4
-rw-r--r--arch/x86/kvm/vmx.c5
-rw-r--r--arch/x86/kvm/x86.c11
-rw-r--r--arch/x86/kvm/x86.h5
-rw-r--r--arch/x86/lguest/boot.c16
-rw-r--r--arch/x86/lguest/i386_head.S105
-rw-r--r--arch/x86/oprofile/op_model_amd.c24
-rw-r--r--arch/x86/pci/i386.c18
-rw-r--r--arch/x86/vdso/Makefile4
327 files changed, 4330 insertions, 3377 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fac58916ade..a3fb23be87f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
2 bool 2 bool
3 default y 3 default y
4 select HAVE_AOUT 4 select HAVE_AOUT
5 select HAVE_DMA_API_DEBUG
5 select HAVE_IDE 6 select HAVE_IDE
6 select HAVE_MEMBLOCK 7 select HAVE_MEMBLOCK
7 select RTC_LIB 8 select RTC_LIB
@@ -24,6 +25,7 @@ config ARM
24 select PERF_USE_VMALLOC 25 select PERF_USE_VMALLOC
25 select HAVE_REGS_AND_STACK_ACCESS_API 26 select HAVE_REGS_AND_STACK_ACCESS_API
26 select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7)) 27 select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
28 select HAVE_C_RECORDMCOUNT
27 help 29 help
28 The ARM series is a line of low-power-consumption RISC chip designs 30 The ARM series is a line of low-power-consumption RISC chip designs
29 licensed by ARM Ltd and targeted at embedded applications and 31 licensed by ARM Ltd and targeted at embedded applications and
@@ -35,9 +37,15 @@ config ARM
35config HAVE_PWM 37config HAVE_PWM
36 bool 38 bool
37 39
40config MIGHT_HAVE_PCI
41 bool
42
38config SYS_SUPPORTS_APM_EMULATION 43config SYS_SUPPORTS_APM_EMULATION
39 bool 44 bool
40 45
46config HAVE_SCHED_CLOCK
47 bool
48
41config GENERIC_GPIO 49config GENERIC_GPIO
42 bool 50 bool
43 51
@@ -222,7 +230,7 @@ config ARCH_INTEGRATOR
222 bool "ARM Ltd. Integrator family" 230 bool "ARM Ltd. Integrator family"
223 select ARM_AMBA 231 select ARM_AMBA
224 select ARCH_HAS_CPUFREQ 232 select ARCH_HAS_CPUFREQ
225 select COMMON_CLKDEV 233 select CLKDEV_LOOKUP
226 select ICST 234 select ICST
227 select GENERIC_CLOCKEVENTS 235 select GENERIC_CLOCKEVENTS
228 select PLAT_VERSATILE 236 select PLAT_VERSATILE
@@ -232,7 +240,8 @@ config ARCH_INTEGRATOR
232config ARCH_REALVIEW 240config ARCH_REALVIEW
233 bool "ARM Ltd. RealView family" 241 bool "ARM Ltd. RealView family"
234 select ARM_AMBA 242 select ARM_AMBA
235 select COMMON_CLKDEV 243 select CLKDEV_LOOKUP
244 select HAVE_SCHED_CLOCK
236 select ICST 245 select ICST
237 select GENERIC_CLOCKEVENTS 246 select GENERIC_CLOCKEVENTS
238 select ARCH_WANT_OPTIONAL_GPIOLIB 247 select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -246,7 +255,8 @@ config ARCH_VERSATILE
246 bool "ARM Ltd. Versatile family" 255 bool "ARM Ltd. Versatile family"
247 select ARM_AMBA 256 select ARM_AMBA
248 select ARM_VIC 257 select ARM_VIC
249 select COMMON_CLKDEV 258 select CLKDEV_LOOKUP
259 select HAVE_SCHED_CLOCK
250 select ICST 260 select ICST
251 select GENERIC_CLOCKEVENTS 261 select GENERIC_CLOCKEVENTS
252 select ARCH_WANT_OPTIONAL_GPIOLIB 262 select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -260,9 +270,10 @@ config ARCH_VEXPRESS
260 select ARCH_WANT_OPTIONAL_GPIOLIB 270 select ARCH_WANT_OPTIONAL_GPIOLIB
261 select ARM_AMBA 271 select ARM_AMBA
262 select ARM_TIMER_SP804 272 select ARM_TIMER_SP804
263 select COMMON_CLKDEV 273 select CLKDEV_LOOKUP
264 select GENERIC_CLOCKEVENTS 274 select GENERIC_CLOCKEVENTS
265 select HAVE_CLK 275 select HAVE_CLK
276 select HAVE_SCHED_CLOCK
266 select ICST 277 select ICST
267 select PLAT_VERSATILE 278 select PLAT_VERSATILE
268 help 279 help
@@ -281,7 +292,7 @@ config ARCH_BCMRING
281 depends on MMU 292 depends on MMU
282 select CPU_V6 293 select CPU_V6
283 select ARM_AMBA 294 select ARM_AMBA
284 select COMMON_CLKDEV 295 select CLKDEV_LOOKUP
285 select GENERIC_CLOCKEVENTS 296 select GENERIC_CLOCKEVENTS
286 select ARCH_WANT_OPTIONAL_GPIOLIB 297 select ARCH_WANT_OPTIONAL_GPIOLIB
287 help 298 help
@@ -299,6 +310,7 @@ config ARCH_CNS3XXX
299 select CPU_V6 310 select CPU_V6
300 select GENERIC_CLOCKEVENTS 311 select GENERIC_CLOCKEVENTS
301 select ARM_GIC 312 select ARM_GIC
313 select MIGHT_HAVE_PCI
302 select PCI_DOMAINS if PCI 314 select PCI_DOMAINS if PCI
303 help 315 help
304 Support for Cavium Networks CNS3XXX platform. 316 Support for Cavium Networks CNS3XXX platform.
@@ -328,7 +340,7 @@ config ARCH_EP93XX
328 select CPU_ARM920T 340 select CPU_ARM920T
329 select ARM_AMBA 341 select ARM_AMBA
330 select ARM_VIC 342 select ARM_VIC
331 select COMMON_CLKDEV 343 select CLKDEV_LOOKUP
332 select ARCH_REQUIRE_GPIOLIB 344 select ARCH_REQUIRE_GPIOLIB
333 select ARCH_HAS_HOLES_MEMORYMODEL 345 select ARCH_HAS_HOLES_MEMORYMODEL
334 select ARCH_USES_GETTIMEOFFSET 346 select ARCH_USES_GETTIMEOFFSET
@@ -348,7 +360,7 @@ config ARCH_MXC
348 bool "Freescale MXC/iMX-based" 360 bool "Freescale MXC/iMX-based"
349 select GENERIC_CLOCKEVENTS 361 select GENERIC_CLOCKEVENTS
350 select ARCH_REQUIRE_GPIOLIB 362 select ARCH_REQUIRE_GPIOLIB
351 select COMMON_CLKDEV 363 select CLKDEV_LOOKUP
352 help 364 help
353 Support for Freescale MXC/iMX-based family of processors 365 Support for Freescale MXC/iMX-based family of processors
354 366
@@ -363,7 +375,7 @@ config ARCH_MXS
363config ARCH_STMP3XXX 375config ARCH_STMP3XXX
364 bool "Freescale STMP3xxx" 376 bool "Freescale STMP3xxx"
365 select CPU_ARM926T 377 select CPU_ARM926T
366 select COMMON_CLKDEV 378 select CLKDEV_LOOKUP
367 select ARCH_REQUIRE_GPIOLIB 379 select ARCH_REQUIRE_GPIOLIB
368 select GENERIC_CLOCKEVENTS 380 select GENERIC_CLOCKEVENTS
369 select USB_ARCH_HAS_EHCI 381 select USB_ARCH_HAS_EHCI
@@ -442,6 +454,8 @@ config ARCH_IXP4XX
442 select CPU_XSCALE 454 select CPU_XSCALE
443 select GENERIC_GPIO 455 select GENERIC_GPIO
444 select GENERIC_CLOCKEVENTS 456 select GENERIC_CLOCKEVENTS
457 select HAVE_SCHED_CLOCK
458 select MIGHT_HAVE_PCI
445 select DMABOUNCE if PCI 459 select DMABOUNCE if PCI
446 help 460 help
447 Support for Intel's IXP4XX (XScale) family of processors. 461 Support for Intel's IXP4XX (XScale) family of processors.
@@ -481,7 +495,7 @@ config ARCH_LPC32XX
481 select HAVE_IDE 495 select HAVE_IDE
482 select ARM_AMBA 496 select ARM_AMBA
483 select USB_ARCH_HAS_OHCI 497 select USB_ARCH_HAS_OHCI
484 select COMMON_CLKDEV 498 select CLKDEV_LOOKUP
485 select GENERIC_TIME 499 select GENERIC_TIME
486 select GENERIC_CLOCKEVENTS 500 select GENERIC_CLOCKEVENTS
487 help 501 help
@@ -515,8 +529,9 @@ config ARCH_MMP
515 bool "Marvell PXA168/910/MMP2" 529 bool "Marvell PXA168/910/MMP2"
516 depends on MMU 530 depends on MMU
517 select ARCH_REQUIRE_GPIOLIB 531 select ARCH_REQUIRE_GPIOLIB
518 select COMMON_CLKDEV 532 select CLKDEV_LOOKUP
519 select GENERIC_CLOCKEVENTS 533 select GENERIC_CLOCKEVENTS
534 select HAVE_SCHED_CLOCK
520 select TICK_ONESHOT 535 select TICK_ONESHOT
521 select PLAT_PXA 536 select PLAT_PXA
522 select SPARSE_IRQ 537 select SPARSE_IRQ
@@ -548,7 +563,7 @@ config ARCH_W90X900
548 bool "Nuvoton W90X900 CPU" 563 bool "Nuvoton W90X900 CPU"
549 select CPU_ARM926T 564 select CPU_ARM926T
550 select ARCH_REQUIRE_GPIOLIB 565 select ARCH_REQUIRE_GPIOLIB
551 select COMMON_CLKDEV 566 select CLKDEV_LOOKUP
552 select GENERIC_CLOCKEVENTS 567 select GENERIC_CLOCKEVENTS
553 help 568 help
554 Support for Nuvoton (Winbond logic dept.) ARM9 processor, 569 Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -562,18 +577,19 @@ config ARCH_W90X900
562config ARCH_NUC93X 577config ARCH_NUC93X
563 bool "Nuvoton NUC93X CPU" 578 bool "Nuvoton NUC93X CPU"
564 select CPU_ARM926T 579 select CPU_ARM926T
565 select COMMON_CLKDEV 580 select CLKDEV_LOOKUP
566 help 581 help
567 Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a 582 Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
568 low-power and high performance MPEG-4/JPEG multimedia controller chip. 583 low-power and high performance MPEG-4/JPEG multimedia controller chip.
569 584
570config ARCH_TEGRA 585config ARCH_TEGRA
571 bool "NVIDIA Tegra" 586 bool "NVIDIA Tegra"
587 select CLKDEV_LOOKUP
572 select GENERIC_TIME 588 select GENERIC_TIME
573 select GENERIC_CLOCKEVENTS 589 select GENERIC_CLOCKEVENTS
574 select GENERIC_GPIO 590 select GENERIC_GPIO
575 select HAVE_CLK 591 select HAVE_CLK
576 select COMMON_CLKDEV 592 select HAVE_SCHED_CLOCK
577 select ARCH_HAS_BARRIERS if CACHE_L2X0 593 select ARCH_HAS_BARRIERS if CACHE_L2X0
578 select ARCH_HAS_CPUFREQ 594 select ARCH_HAS_CPUFREQ
579 help 595 help
@@ -583,7 +599,7 @@ config ARCH_TEGRA
583config ARCH_PNX4008 599config ARCH_PNX4008
584 bool "Philips Nexperia PNX4008 Mobile" 600 bool "Philips Nexperia PNX4008 Mobile"
585 select CPU_ARM926T 601 select CPU_ARM926T
586 select COMMON_CLKDEV 602 select CLKDEV_LOOKUP
587 select ARCH_USES_GETTIMEOFFSET 603 select ARCH_USES_GETTIMEOFFSET
588 help 604 help
589 This enables support for Philips PNX4008 mobile platform. 605 This enables support for Philips PNX4008 mobile platform.
@@ -593,9 +609,10 @@ config ARCH_PXA
593 depends on MMU 609 depends on MMU
594 select ARCH_MTD_XIP 610 select ARCH_MTD_XIP
595 select ARCH_HAS_CPUFREQ 611 select ARCH_HAS_CPUFREQ
596 select COMMON_CLKDEV 612 select CLKDEV_LOOKUP
597 select ARCH_REQUIRE_GPIOLIB 613 select ARCH_REQUIRE_GPIOLIB
598 select GENERIC_CLOCKEVENTS 614 select GENERIC_CLOCKEVENTS
615 select HAVE_SCHED_CLOCK
599 select TICK_ONESHOT 616 select TICK_ONESHOT
600 select PLAT_PXA 617 select PLAT_PXA
601 select SPARSE_IRQ 618 select SPARSE_IRQ
@@ -644,6 +661,7 @@ config ARCH_SA1100
644 select CPU_FREQ 661 select CPU_FREQ
645 select GENERIC_CLOCKEVENTS 662 select GENERIC_CLOCKEVENTS
646 select HAVE_CLK 663 select HAVE_CLK
664 select HAVE_SCHED_CLOCK
647 select TICK_ONESHOT 665 select TICK_ONESHOT
648 select ARCH_REQUIRE_GPIOLIB 666 select ARCH_REQUIRE_GPIOLIB
649 help 667 help
@@ -770,7 +788,7 @@ config ARCH_TCC_926
770 bool "Telechips TCC ARM926-based systems" 788 bool "Telechips TCC ARM926-based systems"
771 select CPU_ARM926T 789 select CPU_ARM926T
772 select HAVE_CLK 790 select HAVE_CLK
773 select COMMON_CLKDEV 791 select CLKDEV_LOOKUP
774 select GENERIC_CLOCKEVENTS 792 select GENERIC_CLOCKEVENTS
775 help 793 help
776 Support for Telechips TCC ARM926-based systems. 794 Support for Telechips TCC ARM926-based systems.
@@ -790,11 +808,12 @@ config ARCH_U300
790 bool "ST-Ericsson U300 Series" 808 bool "ST-Ericsson U300 Series"
791 depends on MMU 809 depends on MMU
792 select CPU_ARM926T 810 select CPU_ARM926T
811 select HAVE_SCHED_CLOCK
793 select HAVE_TCM 812 select HAVE_TCM
794 select ARM_AMBA 813 select ARM_AMBA
795 select ARM_VIC 814 select ARM_VIC
796 select GENERIC_CLOCKEVENTS 815 select GENERIC_CLOCKEVENTS
797 select COMMON_CLKDEV 816 select CLKDEV_LOOKUP
798 select GENERIC_GPIO 817 select GENERIC_GPIO
799 help 818 help
800 Support for ST-Ericsson U300 series mobile platforms. 819 Support for ST-Ericsson U300 series mobile platforms.
@@ -804,7 +823,7 @@ config ARCH_U8500
804 select CPU_V7 823 select CPU_V7
805 select ARM_AMBA 824 select ARM_AMBA
806 select GENERIC_CLOCKEVENTS 825 select GENERIC_CLOCKEVENTS
807 select COMMON_CLKDEV 826 select CLKDEV_LOOKUP
808 select ARCH_REQUIRE_GPIOLIB 827 select ARCH_REQUIRE_GPIOLIB
809 select ARCH_HAS_CPUFREQ 828 select ARCH_HAS_CPUFREQ
810 help 829 help
@@ -815,7 +834,7 @@ config ARCH_NOMADIK
815 select ARM_AMBA 834 select ARM_AMBA
816 select ARM_VIC 835 select ARM_VIC
817 select CPU_ARM926T 836 select CPU_ARM926T
818 select COMMON_CLKDEV 837 select CLKDEV_LOOKUP
819 select GENERIC_CLOCKEVENTS 838 select GENERIC_CLOCKEVENTS
820 select ARCH_REQUIRE_GPIOLIB 839 select ARCH_REQUIRE_GPIOLIB
821 help 840 help
@@ -827,7 +846,7 @@ config ARCH_DAVINCI
827 select ARCH_REQUIRE_GPIOLIB 846 select ARCH_REQUIRE_GPIOLIB
828 select ZONE_DMA 847 select ZONE_DMA
829 select HAVE_IDE 848 select HAVE_IDE
830 select COMMON_CLKDEV 849 select CLKDEV_LOOKUP
831 select GENERIC_ALLOCATOR 850 select GENERIC_ALLOCATOR
832 select ARCH_HAS_HOLES_MEMORYMODEL 851 select ARCH_HAS_HOLES_MEMORYMODEL
833 help 852 help
@@ -839,6 +858,7 @@ config ARCH_OMAP
839 select ARCH_REQUIRE_GPIOLIB 858 select ARCH_REQUIRE_GPIOLIB
840 select ARCH_HAS_CPUFREQ 859 select ARCH_HAS_CPUFREQ
841 select GENERIC_CLOCKEVENTS 860 select GENERIC_CLOCKEVENTS
861 select HAVE_SCHED_CLOCK
842 select ARCH_HAS_HOLES_MEMORYMODEL 862 select ARCH_HAS_HOLES_MEMORYMODEL
843 help 863 help
844 Support for TI's OMAP platform (OMAP1/2/3/4). 864 Support for TI's OMAP platform (OMAP1/2/3/4).
@@ -847,7 +867,7 @@ config PLAT_SPEAR
847 bool "ST SPEAr" 867 bool "ST SPEAr"
848 select ARM_AMBA 868 select ARM_AMBA
849 select ARCH_REQUIRE_GPIOLIB 869 select ARCH_REQUIRE_GPIOLIB
850 select COMMON_CLKDEV 870 select CLKDEV_LOOKUP
851 select GENERIC_CLOCKEVENTS 871 select GENERIC_CLOCKEVENTS
852 select HAVE_CLK 872 select HAVE_CLK
853 help 873 help
@@ -994,9 +1014,11 @@ config ARCH_ACORN
994config PLAT_IOP 1014config PLAT_IOP
995 bool 1015 bool
996 select GENERIC_CLOCKEVENTS 1016 select GENERIC_CLOCKEVENTS
1017 select HAVE_SCHED_CLOCK
997 1018
998config PLAT_ORION 1019config PLAT_ORION
999 bool 1020 bool
1021 select HAVE_SCHED_CLOCK
1000 1022
1001config PLAT_PXA 1023config PLAT_PXA
1002 bool 1024 bool
@@ -1029,6 +1051,11 @@ config CPU_HAS_PMU
1029 default y 1051 default y
1030 bool 1052 bool
1031 1053
1054config MULTI_IRQ_HANDLER
1055 bool
1056 help
1057 Allow each machine to specify it's own IRQ handler at run time.
1058
1032if !MMU 1059if !MMU
1033source "arch/arm/Kconfig-nommu" 1060source "arch/arm/Kconfig-nommu"
1034endif 1061endif
@@ -1176,7 +1203,7 @@ config ISA_DMA_API
1176 bool 1203 bool
1177 1204
1178config PCI 1205config PCI
1179 bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX 1206 bool "PCI support" if MIGHT_HAVE_PCI
1180 help 1207 help
1181 Find out whether you have a PCI motherboard. PCI is the name of a 1208 Find out whether you have a PCI motherboard. PCI is the name of a
1182 bus system, i.e. the way the CPU talks to the other stuff inside 1209 bus system, i.e. the way the CPU talks to the other stuff inside
@@ -1187,6 +1214,12 @@ config PCI_DOMAINS
1187 bool 1214 bool
1188 depends on PCI 1215 depends on PCI
1189 1216
1217config PCI_NANOENGINE
1218 bool "BSE nanoEngine PCI support"
1219 depends on SA1100_NANOENGINE
1220 help
1221 Enable PCI on the BSE nanoEngine board.
1222
1190config PCI_SYSCALL 1223config PCI_SYSCALL
1191 def_bool PCI 1224 def_bool PCI
1192 1225
@@ -1242,7 +1275,7 @@ config SMP
1242config SMP_ON_UP 1275config SMP_ON_UP
1243 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)" 1276 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
1244 depends on EXPERIMENTAL 1277 depends on EXPERIMENTAL
1245 depends on SMP && !XIP && !THUMB2_KERNEL 1278 depends on SMP && !XIP
1246 default y 1279 default y
1247 help 1280 help
1248 SMP kernels contain instructions which fail on non-SMP processors. 1281 SMP kernels contain instructions which fail on non-SMP processors.
@@ -1261,6 +1294,7 @@ config HAVE_ARM_SCU
1261config HAVE_ARM_TWD 1294config HAVE_ARM_TWD
1262 bool 1295 bool
1263 depends on SMP 1296 depends on SMP
1297 select TICK_ONESHOT
1264 help 1298 help
1265 This options enables support for the ARM timer and watchdog unit 1299 This options enables support for the ARM timer and watchdog unit
1266 1300
@@ -1324,7 +1358,7 @@ config HZ
1324 default 100 1358 default 100
1325 1359
1326config THUMB2_KERNEL 1360config THUMB2_KERNEL
1327 bool "Compile the kernel in Thumb-2 mode" 1361 bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
1328 depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL 1362 depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
1329 select AEABI 1363 select AEABI
1330 select ARM_ASM_UNIFIED 1364 select ARM_ASM_UNIFIED
@@ -1538,6 +1572,7 @@ config SECCOMP
1538 1572
1539config CC_STACKPROTECTOR 1573config CC_STACKPROTECTOR
1540 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" 1574 bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
1575 depends on EXPERIMENTAL
1541 help 1576 help
1542 This option turns on the -fstack-protector GCC feature. This 1577 This option turns on the -fstack-protector GCC feature. This
1543 feature puts, at the beginning of functions, a canary value on 1578 feature puts, at the beginning of functions, a canary value on
@@ -1664,6 +1699,19 @@ config ATAGS_PROC
1664 Should the atags used to boot the kernel be exported in an "atags" 1699 Should the atags used to boot the kernel be exported in an "atags"
1665 file in procfs. Useful with kexec. 1700 file in procfs. Useful with kexec.
1666 1701
1702config CRASH_DUMP
1703 bool "Build kdump crash kernel (EXPERIMENTAL)"
1704 depends on EXPERIMENTAL
1705 help
1706 Generate crash dump after being started by kexec. This should
1707 be normally only set in special crash dump kernels which are
1708 loaded in the main kernel with kexec-tools into a specially
1709 reserved region and then later executed after a crash by
1710 kdump/kexec. The crash dump kernel must be compiled to a
1711 memory address not used by the main kernel
1712
1713 For more details see Documentation/kdump/kdump.txt
1714
1667config AUTO_ZRELADDR 1715config AUTO_ZRELADDR
1668 bool "Auto calculation of the decompressed kernel image address" 1716 bool "Auto calculation of the decompressed kernel image address"
1669 depends on !ZBOOT_ROM && !ARCH_U300 1717 depends on !ZBOOT_ROM && !ARCH_U300
@@ -1721,7 +1769,7 @@ config CPU_FREQ_S3C
1721 Internal configuration node for common cpufreq on Samsung SoC 1769 Internal configuration node for common cpufreq on Samsung SoC
1722 1770
1723config CPU_FREQ_S3C24XX 1771config CPU_FREQ_S3C24XX
1724 bool "CPUfreq driver for Samsung S3C24XX series CPUs" 1772 bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
1725 depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL 1773 depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
1726 select CPU_FREQ_S3C 1774 select CPU_FREQ_S3C
1727 help 1775 help
@@ -1733,7 +1781,7 @@ config CPU_FREQ_S3C24XX
1733 If in doubt, say N. 1781 If in doubt, say N.
1734 1782
1735config CPU_FREQ_S3C24XX_PLL 1783config CPU_FREQ_S3C24XX_PLL
1736 bool "Support CPUfreq changing of PLL frequency" 1784 bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
1737 depends on CPU_FREQ_S3C24XX && EXPERIMENTAL 1785 depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
1738 help 1786 help
1739 Compile in support for changing the PLL frequency from the 1787 Compile in support for changing the PLL frequency from the
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index eac62085f5b..494224a9b45 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -31,7 +31,7 @@ config FRAME_POINTER
31 reported is severely limited. 31 reported is severely limited.
32 32
33config ARM_UNWIND 33config ARM_UNWIND
34 bool "Enable stack unwinding support" 34 bool "Enable stack unwinding support (EXPERIMENTAL)"
35 depends on AEABI && EXPERIMENTAL 35 depends on AEABI && EXPERIMENTAL
36 default y 36 default y
37 help 37 help
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 65a7c1c588a..0a8f748e506 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -45,6 +45,10 @@ else
45endif 45endif
46endif 46endif
47 47
48ifeq ($(CONFIG_ARCH_SHMOBILE),y)
49OBJS += head-shmobile.o
50endif
51
48# 52#
49# We now have a PIC decompressor implementation. Decompressors running 53# We now have a PIC decompressor implementation. Decompressors running
50# from RAM should not define ZTEXTADDR. Decompressors running directly 54# from RAM should not define ZTEXTADDR. Decompressors running directly
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
new file mode 100644
index 00000000000..30973b76e6a
--- /dev/null
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -0,0 +1,53 @@
1/*
2 * The head-file for SH-Mobile ARM platforms
3 *
4 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
5 * Simon Horman <horms@verge.net.au>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#ifdef CONFIG_ZBOOT_ROM
22
23 .section ".start", "ax"
24
25 /* load board-specific initialization code */
26#include <mach/zboot.h>
27
28 b 1f
29__atags:@ tag #1
30 .long 12 @ tag->hdr.size = tag_size(tag_core);
31 .long 0x54410001 @ tag->hdr.tag = ATAG_CORE;
32 .long 0 @ tag->u.core.flags = 0;
33 .long 0 @ tag->u.core.pagesize = 0;
34 .long 0 @ tag->u.core.rootdev = 0;
35 @ tag #2
36 .long 8 @ tag->hdr.size = tag_size(tag_mem32);
37 .long 0x54410002 @ tag->hdr.tag = ATAG_MEM;
38 .long CONFIG_MEMORY_SIZE @ tag->u.mem.size = CONFIG_MEMORY_SIZE;
39 .long CONFIG_MEMORY_START @ @ tag->u.mem.start = CONFIG_MEMORY_START;
40 @ tag #3
41 .long 0 @ tag->hdr.size = 0
42 .long 0 @ tag->hdr.tag = ATAG_NONE;
431:
44
45 /* Set board ID necessary for boot */
46 ldr r7, 1f @ Set machine type register
47 adr r8, __atags @ Set atag register
48 b 2f
49
501 : .long MACH_TYPE
512 :
52
53#endif /* CONFIG_ZBOOT_ROM */
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 0a34c818692..778655f0257 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -37,7 +37,3 @@ config SHARP_PARAM
37 37
38config SHARP_SCOOP 38config SHARP_SCOOP
39 bool 39 bool
40
41config COMMON_CLKDEV
42 bool
43 select HAVE_CLK
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e6e8664a941..e7521bca2c3 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ARCH_IXP2000) += uengine.o
17obj-$(CONFIG_ARCH_IXP23XX) += uengine.o 17obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
18obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o 18obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
19obj-$(CONFIG_COMMON_CLKDEV) += clkdev.o 19obj-$(CONFIG_COMMON_CLKDEV) += clkdev.o
20obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c
deleted file mode 100644
index e2b2bb66e09..00000000000
--- a/arch/arm/common/clkdev.c
+++ /dev/null
@@ -1,179 +0,0 @@
1/*
2 * arch/arm/common/clkdev.c
3 *
4 * Copyright (C) 2008 Russell King.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Helper for the clk API to assist looking up a struct clk.
11 */
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/device.h>
15#include <linux/list.h>
16#include <linux/errno.h>
17#include <linux/err.h>
18#include <linux/string.h>
19#include <linux/mutex.h>
20#include <linux/clk.h>
21#include <linux/slab.h>
22
23#include <asm/clkdev.h>
24#include <mach/clkdev.h>
25
26static LIST_HEAD(clocks);
27static DEFINE_MUTEX(clocks_mutex);
28
29/*
30 * Find the correct struct clk for the device and connection ID.
31 * We do slightly fuzzy matching here:
32 * An entry with a NULL ID is assumed to be a wildcard.
33 * If an entry has a device ID, it must match
34 * If an entry has a connection ID, it must match
35 * Then we take the most specific entry - with the following
36 * order of precedence: dev+con > dev only > con only.
37 */
38static struct clk *clk_find(const char *dev_id, const char *con_id)
39{
40 struct clk_lookup *p;
41 struct clk *clk = NULL;
42 int match, best = 0;
43
44 list_for_each_entry(p, &clocks, node) {
45 match = 0;
46 if (p->dev_id) {
47 if (!dev_id || strcmp(p->dev_id, dev_id))
48 continue;
49 match += 2;
50 }
51 if (p->con_id) {
52 if (!con_id || strcmp(p->con_id, con_id))
53 continue;
54 match += 1;
55 }
56
57 if (match > best) {
58 clk = p->clk;
59 if (match != 3)
60 best = match;
61 else
62 break;
63 }
64 }
65 return clk;
66}
67
68struct clk *clk_get_sys(const char *dev_id, const char *con_id)
69{
70 struct clk *clk;
71
72 mutex_lock(&clocks_mutex);
73 clk = clk_find(dev_id, con_id);
74 if (clk && !__clk_get(clk))
75 clk = NULL;
76 mutex_unlock(&clocks_mutex);
77
78 return clk ? clk : ERR_PTR(-ENOENT);
79}
80EXPORT_SYMBOL(clk_get_sys);
81
82struct clk *clk_get(struct device *dev, const char *con_id)
83{
84 const char *dev_id = dev ? dev_name(dev) : NULL;
85
86 return clk_get_sys(dev_id, con_id);
87}
88EXPORT_SYMBOL(clk_get);
89
90void clk_put(struct clk *clk)
91{
92 __clk_put(clk);
93}
94EXPORT_SYMBOL(clk_put);
95
96void clkdev_add(struct clk_lookup *cl)
97{
98 mutex_lock(&clocks_mutex);
99 list_add_tail(&cl->node, &clocks);
100 mutex_unlock(&clocks_mutex);
101}
102EXPORT_SYMBOL(clkdev_add);
103
104void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
105{
106 mutex_lock(&clocks_mutex);
107 while (num--) {
108 list_add_tail(&cl->node, &clocks);
109 cl++;
110 }
111 mutex_unlock(&clocks_mutex);
112}
113
114#define MAX_DEV_ID 20
115#define MAX_CON_ID 16
116
117struct clk_lookup_alloc {
118 struct clk_lookup cl;
119 char dev_id[MAX_DEV_ID];
120 char con_id[MAX_CON_ID];
121};
122
123struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
124 const char *dev_fmt, ...)
125{
126 struct clk_lookup_alloc *cla;
127
128 cla = kzalloc(sizeof(*cla), GFP_KERNEL);
129 if (!cla)
130 return NULL;
131
132 cla->cl.clk = clk;
133 if (con_id) {
134 strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
135 cla->cl.con_id = cla->con_id;
136 }
137
138 if (dev_fmt) {
139 va_list ap;
140
141 va_start(ap, dev_fmt);
142 vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
143 cla->cl.dev_id = cla->dev_id;
144 va_end(ap);
145 }
146
147 return &cla->cl;
148}
149EXPORT_SYMBOL(clkdev_alloc);
150
151int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
152 struct device *dev)
153{
154 struct clk *r = clk_get(dev, id);
155 struct clk_lookup *l;
156
157 if (IS_ERR(r))
158 return PTR_ERR(r);
159
160 l = clkdev_alloc(r, alias, alias_dev_name);
161 clk_put(r);
162 if (!l)
163 return -ENODEV;
164 clkdev_add(l);
165 return 0;
166}
167EXPORT_SYMBOL(clk_add_alias);
168
169/*
170 * clkdev_drop - remove a clock dynamically allocated
171 */
172void clkdev_drop(struct clk_lookup *cl)
173{
174 mutex_lock(&clocks_mutex);
175 list_del(&cl->node);
176 mutex_unlock(&clocks_mutex);
177 kfree(cl);
178}
179EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index cc0a932bbea..e5681636626 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -328,7 +328,7 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
328 * substitute the safe buffer for the unsafe one. 328 * substitute the safe buffer for the unsafe one.
329 * (basically move the buffer from an unsafe area to a safe one) 329 * (basically move the buffer from an unsafe area to a safe one)
330 */ 330 */
331dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, 331dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
332 enum dma_data_direction dir) 332 enum dma_data_direction dir)
333{ 333{
334 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 334 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -338,7 +338,7 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
338 338
339 return map_single(dev, ptr, size, dir); 339 return map_single(dev, ptr, size, dir);
340} 340}
341EXPORT_SYMBOL(dma_map_single); 341EXPORT_SYMBOL(__dma_map_single);
342 342
343/* 343/*
344 * see if a mapped address was really a "safe" buffer and if so, copy 344 * see if a mapped address was really a "safe" buffer and if so, copy
@@ -346,7 +346,7 @@ EXPORT_SYMBOL(dma_map_single);
346 * the safe buffer. (basically return things back to the way they 346 * the safe buffer. (basically return things back to the way they
347 * should be) 347 * should be)
348 */ 348 */
349void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 349void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
350 enum dma_data_direction dir) 350 enum dma_data_direction dir)
351{ 351{
352 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 352 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -354,9 +354,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
354 354
355 unmap_single(dev, dma_addr, size, dir); 355 unmap_single(dev, dma_addr, size, dir);
356} 356}
357EXPORT_SYMBOL(dma_unmap_single); 357EXPORT_SYMBOL(__dma_unmap_single);
358 358
359dma_addr_t dma_map_page(struct device *dev, struct page *page, 359dma_addr_t __dma_map_page(struct device *dev, struct page *page,
360 unsigned long offset, size_t size, enum dma_data_direction dir) 360 unsigned long offset, size_t size, enum dma_data_direction dir)
361{ 361{
362 dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n", 362 dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
@@ -372,7 +372,7 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
372 372
373 return map_single(dev, page_address(page) + offset, size, dir); 373 return map_single(dev, page_address(page) + offset, size, dir);
374} 374}
375EXPORT_SYMBOL(dma_map_page); 375EXPORT_SYMBOL(__dma_map_page);
376 376
377/* 377/*
378 * see if a mapped address was really a "safe" buffer and if so, copy 378 * see if a mapped address was really a "safe" buffer and if so, copy
@@ -380,7 +380,7 @@ EXPORT_SYMBOL(dma_map_page);
380 * the safe buffer. (basically return things back to the way they 380 * the safe buffer. (basically return things back to the way they
381 * should be) 381 * should be)
382 */ 382 */
383void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, 383void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
384 enum dma_data_direction dir) 384 enum dma_data_direction dir)
385{ 385{
386 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 386 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -388,7 +388,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
388 388
389 unmap_single(dev, dma_addr, size, dir); 389 unmap_single(dev, dma_addr, size, dir);
390} 390}
391EXPORT_SYMBOL(dma_unmap_page); 391EXPORT_SYMBOL(__dma_unmap_page);
392 392
393int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, 393int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
394 unsigned long off, size_t sz, enum dma_data_direction dir) 394 unsigned long off, size_t sz, enum dma_data_direction dir)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index e6388dcd8cf..0b89ef00133 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -35,6 +35,9 @@
35 35
36static DEFINE_SPINLOCK(irq_controller_lock); 36static DEFINE_SPINLOCK(irq_controller_lock);
37 37
38/* Address of GIC 0 CPU interface */
39void __iomem *gic_cpu_base_addr __read_mostly;
40
38struct gic_chip_data { 41struct gic_chip_data {
39 unsigned int irq_offset; 42 unsigned int irq_offset;
40 void __iomem *dist_base; 43 void __iomem *dist_base;
@@ -45,7 +48,7 @@ struct gic_chip_data {
45#define MAX_GIC_NR 1 48#define MAX_GIC_NR 1
46#endif 49#endif
47 50
48static struct gic_chip_data gic_data[MAX_GIC_NR]; 51static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
49 52
50static inline void __iomem *gic_dist_base(unsigned int irq) 53static inline void __iomem *gic_dist_base(unsigned int irq)
51{ 54{
@@ -213,21 +216,16 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
213 set_irq_chained_handler(irq, gic_handle_cascade_irq); 216 set_irq_chained_handler(irq, gic_handle_cascade_irq);
214} 217}
215 218
216void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, 219static void __init gic_dist_init(struct gic_chip_data *gic,
217 unsigned int irq_start) 220 unsigned int irq_start)
218{ 221{
219 unsigned int gic_irqs, irq_limit, i; 222 unsigned int gic_irqs, irq_limit, i;
223 void __iomem *base = gic->dist_base;
220 u32 cpumask = 1 << smp_processor_id(); 224 u32 cpumask = 1 << smp_processor_id();
221 225
222 if (gic_nr >= MAX_GIC_NR)
223 BUG();
224
225 cpumask |= cpumask << 8; 226 cpumask |= cpumask << 8;
226 cpumask |= cpumask << 16; 227 cpumask |= cpumask << 16;
227 228
228 gic_data[gic_nr].dist_base = base;
229 gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;
230
231 writel(0, base + GIC_DIST_CTRL); 229 writel(0, base + GIC_DIST_CTRL);
232 230
233 /* 231 /*
@@ -267,7 +265,7 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
267 /* 265 /*
268 * Limit number of interrupts registered to the platform maximum 266 * Limit number of interrupts registered to the platform maximum
269 */ 267 */
270 irq_limit = gic_data[gic_nr].irq_offset + gic_irqs; 268 irq_limit = gic->irq_offset + gic_irqs;
271 if (WARN_ON(irq_limit > NR_IRQS)) 269 if (WARN_ON(irq_limit > NR_IRQS))
272 irq_limit = NR_IRQS; 270 irq_limit = NR_IRQS;
273 271
@@ -276,7 +274,7 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
276 */ 274 */
277 for (i = irq_start; i < irq_limit; i++) { 275 for (i = irq_start; i < irq_limit; i++) {
278 set_irq_chip(i, &gic_chip); 276 set_irq_chip(i, &gic_chip);
279 set_irq_chip_data(i, &gic_data[gic_nr]); 277 set_irq_chip_data(i, gic);
280 set_irq_handler(i, handle_level_irq); 278 set_irq_handler(i, handle_level_irq);
281 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 279 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
282 } 280 }
@@ -284,19 +282,12 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
284 writel(1, base + GIC_DIST_CTRL); 282 writel(1, base + GIC_DIST_CTRL);
285} 283}
286 284
287void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) 285static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
288{ 286{
289 void __iomem *dist_base; 287 void __iomem *dist_base = gic->dist_base;
288 void __iomem *base = gic->cpu_base;
290 int i; 289 int i;
291 290
292 if (gic_nr >= MAX_GIC_NR)
293 BUG();
294
295 dist_base = gic_data[gic_nr].dist_base;
296 BUG_ON(!dist_base);
297
298 gic_data[gic_nr].cpu_base = base;
299
300 /* 291 /*
301 * Deal with the banked PPI and SGI interrupts - disable all 292 * Deal with the banked PPI and SGI interrupts - disable all
302 * PPI interrupts, ensure all SGI interrupts are enabled. 293 * PPI interrupts, ensure all SGI interrupts are enabled.
@@ -314,6 +305,42 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
314 writel(1, base + GIC_CPU_CTRL); 305 writel(1, base + GIC_CPU_CTRL);
315} 306}
316 307
308void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
309 void __iomem *dist_base, void __iomem *cpu_base)
310{
311 struct gic_chip_data *gic;
312
313 BUG_ON(gic_nr >= MAX_GIC_NR);
314
315 gic = &gic_data[gic_nr];
316 gic->dist_base = dist_base;
317 gic->cpu_base = cpu_base;
318 gic->irq_offset = (irq_start - 1) & ~31;
319
320 if (gic_nr == 0)
321 gic_cpu_base_addr = cpu_base;
322
323 gic_dist_init(gic, irq_start);
324 gic_cpu_init(gic);
325}
326
327void __cpuinit gic_secondary_init(unsigned int gic_nr)
328{
329 BUG_ON(gic_nr >= MAX_GIC_NR);
330
331 gic_cpu_init(&gic_data[gic_nr]);
332}
333
334void __cpuinit gic_enable_ppi(unsigned int irq)
335{
336 unsigned long flags;
337
338 local_irq_save(flags);
339 irq_to_desc(irq)->status |= IRQ_NOPROBE;
340 gic_unmask_irq(irq);
341 local_irq_restore(flags);
342}
343
317#ifdef CONFIG_SMP 344#ifdef CONFIG_SMP
318void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) 345void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
319{ 346{
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index 1bec96e8519..42ff90b46df 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -352,3 +352,4 @@ struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
352 return pci_scan_bus(nr, &it8152_ops, sys); 352 return pci_scan_bus(nr, &it8152_ops, sys);
353} 353}
354 354
355EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/common/timer-sp.c
index fb0d1c29971..6ef3342153b 100644
--- a/arch/arm/plat-versatile/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/plat-versatile/timer-sp.c 2 * linux/arch/arm/common/timer-sp.c
3 * 3 *
4 * Copyright (C) 1999 - 2003 ARM Limited 4 * Copyright (C) 1999 - 2003 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd 5 * Copyright (C) 2000 Deep Blue Solutions Ltd
@@ -26,8 +26,6 @@
26 26
27#include <asm/hardware/arm_timer.h> 27#include <asm/hardware/arm_timer.h>
28 28
29#include <plat/timer-sp.h>
30
31/* 29/*
32 * These timers are currently always setup to be clocked at 1MHz. 30 * These timers are currently always setup to be clocked at 1MHz.
33 */ 31 */
@@ -46,7 +44,6 @@ static struct clocksource clocksource_sp804 = {
46 .rating = 200, 44 .rating = 200,
47 .read = sp804_read, 45 .read = sp804_read,
48 .mask = CLOCKSOURCE_MASK(32), 46 .mask = CLOCKSOURCE_MASK(32),
49 .shift = 20,
50 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 47 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
51}; 48};
52 49
@@ -63,8 +60,7 @@ void __init sp804_clocksource_init(void __iomem *base)
63 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, 60 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
64 clksrc_base + TIMER_CTRL); 61 clksrc_base + TIMER_CTRL);
65 62
66 cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift); 63 clocksource_register_khz(cs, TIMER_FREQ_KHZ);
67 clocksource_register(cs);
68} 64}
69 65
70 66
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 749bb662240..bc2d2d75f70 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -18,6 +18,7 @@
18#endif 18#endif
19 19
20#include <asm/ptrace.h> 20#include <asm/ptrace.h>
21#include <asm/domain.h>
21 22
22/* 23/*
23 * Endian independent macros for shifting bytes within registers. 24 * Endian independent macros for shifting bytes within registers.
@@ -157,16 +158,24 @@
157#ifdef CONFIG_SMP 158#ifdef CONFIG_SMP
158#define ALT_SMP(instr...) \ 159#define ALT_SMP(instr...) \
1599998: instr 1609998: instr
161/*
162 * Note: if you get assembler errors from ALT_UP() when building with
163 * CONFIG_THUMB2_KERNEL, you almost certainly need to use
164 * ALT_SMP( W(instr) ... )
165 */
160#define ALT_UP(instr...) \ 166#define ALT_UP(instr...) \
161 .pushsection ".alt.smp.init", "a" ;\ 167 .pushsection ".alt.smp.init", "a" ;\
162 .long 9998b ;\ 168 .long 9998b ;\
163 instr ;\ 1699997: instr ;\
170 .if . - 9997b != 4 ;\
171 .error "ALT_UP() content must assemble to exactly 4 bytes";\
172 .endif ;\
164 .popsection 173 .popsection
165#define ALT_UP_B(label) \ 174#define ALT_UP_B(label) \
166 .equ up_b_offset, label - 9998b ;\ 175 .equ up_b_offset, label - 9998b ;\
167 .pushsection ".alt.smp.init", "a" ;\ 176 .pushsection ".alt.smp.init", "a" ;\
168 .long 9998b ;\ 177 .long 9998b ;\
169 b . + up_b_offset ;\ 178 W(b) . + up_b_offset ;\
170 .popsection 179 .popsection
171#else 180#else
172#define ALT_SMP(instr...) 181#define ALT_SMP(instr...)
@@ -177,16 +186,24 @@
177/* 186/*
178 * SMP data memory barrier 187 * SMP data memory barrier
179 */ 188 */
180 .macro smp_dmb 189 .macro smp_dmb mode
181#ifdef CONFIG_SMP 190#ifdef CONFIG_SMP
182#if __LINUX_ARM_ARCH__ >= 7 191#if __LINUX_ARM_ARCH__ >= 7
192 .ifeqs "\mode","arm"
183 ALT_SMP(dmb) 193 ALT_SMP(dmb)
194 .else
195 ALT_SMP(W(dmb))
196 .endif
184#elif __LINUX_ARM_ARCH__ == 6 197#elif __LINUX_ARM_ARCH__ == 6
185 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb 198 ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
186#else 199#else
187#error Incompatible SMP platform 200#error Incompatible SMP platform
188#endif 201#endif
202 .ifeqs "\mode","arm"
189 ALT_UP(nop) 203 ALT_UP(nop)
204 .else
205 ALT_UP(W(nop))
206 .endif
190#endif 207#endif
191 .endm 208 .endm
192 209
@@ -206,12 +223,12 @@
206 */ 223 */
207#ifdef CONFIG_THUMB2_KERNEL 224#ifdef CONFIG_THUMB2_KERNEL
208 225
209 .macro usraccoff, instr, reg, ptr, inc, off, cond, abort 226 .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T()
2109999: 2279999:
211 .if \inc == 1 228 .if \inc == 1
212 \instr\cond\()bt \reg, [\ptr, #\off] 229 \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
213 .elseif \inc == 4 230 .elseif \inc == 4
214 \instr\cond\()t \reg, [\ptr, #\off] 231 \instr\cond\()\t\().w \reg, [\ptr, #\off]
215 .else 232 .else
216 .error "Unsupported inc macro argument" 233 .error "Unsupported inc macro argument"
217 .endif 234 .endif
@@ -246,13 +263,13 @@
246 263
247#else /* !CONFIG_THUMB2_KERNEL */ 264#else /* !CONFIG_THUMB2_KERNEL */
248 265
249 .macro usracc, instr, reg, ptr, inc, cond, rept, abort 266 .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T()
250 .rept \rept 267 .rept \rept
2519999: 2689999:
252 .if \inc == 1 269 .if \inc == 1
253 \instr\cond\()bt \reg, [\ptr], #\inc 270 \instr\cond\()b\()\t \reg, [\ptr], #\inc
254 .elseif \inc == 4 271 .elseif \inc == 4
255 \instr\cond\()t \reg, [\ptr], #\inc 272 \instr\cond\()\t \reg, [\ptr], #\inc
256 .else 273 .else
257 .error "Unsupported inc macro argument" 274 .error "Unsupported inc macro argument"
258 .endif 275 .endif
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 9d6122096fb..75fe66bc02b 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -23,4 +23,6 @@
23#define ARCH_SLAB_MINALIGN 8 23#define ARCH_SLAB_MINALIGN 8
24#endif 24#endif
25 25
26#define __read_mostly __attribute__((__section__(".data..read_mostly")))
27
26#endif 28#endif
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
index b56c1389b6f..765d3322236 100644
--- a/arch/arm/include/asm/clkdev.h
+++ b/arch/arm/include/asm/clkdev.h
@@ -12,23 +12,13 @@
12#ifndef __ASM_CLKDEV_H 12#ifndef __ASM_CLKDEV_H
13#define __ASM_CLKDEV_H 13#define __ASM_CLKDEV_H
14 14
15struct clk; 15#include <linux/slab.h>
16struct device;
17 16
18struct clk_lookup { 17#include <mach/clkdev.h>
19 struct list_head node;
20 const char *dev_id;
21 const char *con_id;
22 struct clk *clk;
23};
24 18
25struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 19static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
26 const char *dev_fmt, ...); 20{
27 21 return kzalloc(size, GFP_KERNEL);
28void clkdev_add(struct clk_lookup *cl); 22}
29void clkdev_drop(struct clk_lookup *cl);
30
31void clkdev_add_table(struct clk_lookup *, size_t);
32int clk_add_alias(const char *, const char *, char *, struct device *);
33 23
34#endif 24#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index c568da7dcae..4fff837363e 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,24 +5,29 @@
5 5
6#include <linux/mm_types.h> 6#include <linux/mm_types.h>
7#include <linux/scatterlist.h> 7#include <linux/scatterlist.h>
8#include <linux/dma-debug.h>
8 9
9#include <asm-generic/dma-coherent.h> 10#include <asm-generic/dma-coherent.h>
10#include <asm/memory.h> 11#include <asm/memory.h>
11 12
13#ifdef __arch_page_to_dma
14#error Please update to __arch_pfn_to_dma
15#endif
16
12/* 17/*
13 * page_to_dma/dma_to_virt/virt_to_dma are architecture private functions 18 * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
14 * used internally by the DMA-mapping API to provide DMA addresses. They 19 * functions used internally by the DMA-mapping API to provide DMA
15 * must not be used by drivers. 20 * addresses. They must not be used by drivers.
16 */ 21 */
17#ifndef __arch_page_to_dma 22#ifndef __arch_pfn_to_dma
18static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) 23static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
19{ 24{
20 return (dma_addr_t)__pfn_to_bus(page_to_pfn(page)); 25 return (dma_addr_t)__pfn_to_bus(pfn);
21} 26}
22 27
23static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) 28static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
24{ 29{
25 return pfn_to_page(__bus_to_pfn(addr)); 30 return __bus_to_pfn(addr);
26} 31}
27 32
28static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) 33static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
@@ -35,14 +40,14 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
35 return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); 40 return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
36} 41}
37#else 42#else
38static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) 43static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
39{ 44{
40 return __arch_page_to_dma(dev, page); 45 return __arch_pfn_to_dma(dev, pfn);
41} 46}
42 47
43static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) 48static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
44{ 49{
45 return __arch_dma_to_page(dev, addr); 50 return __arch_dma_to_pfn(dev, addr);
46} 51}
47 52
48static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) 53static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
@@ -293,13 +298,13 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
293/* 298/*
294 * The DMA API, implemented by dmabounce.c. See below for descriptions. 299 * The DMA API, implemented by dmabounce.c. See below for descriptions.
295 */ 300 */
296extern dma_addr_t dma_map_single(struct device *, void *, size_t, 301extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
297 enum dma_data_direction); 302 enum dma_data_direction);
298extern void dma_unmap_single(struct device *, dma_addr_t, size_t, 303extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
299 enum dma_data_direction); 304 enum dma_data_direction);
300extern dma_addr_t dma_map_page(struct device *, struct page *, 305extern dma_addr_t __dma_map_page(struct device *, struct page *,
301 unsigned long, size_t, enum dma_data_direction); 306 unsigned long, size_t, enum dma_data_direction);
302extern void dma_unmap_page(struct device *, dma_addr_t, size_t, 307extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
303 enum dma_data_direction); 308 enum dma_data_direction);
304 309
305/* 310/*
@@ -323,6 +328,34 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
323} 328}
324 329
325 330
331static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
332 size_t size, enum dma_data_direction dir)
333{
334 __dma_single_cpu_to_dev(cpu_addr, size, dir);
335 return virt_to_dma(dev, cpu_addr);
336}
337
338static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
339 unsigned long offset, size_t size, enum dma_data_direction dir)
340{
341 __dma_page_cpu_to_dev(page, offset, size, dir);
342 return pfn_to_dma(dev, page_to_pfn(page)) + offset;
343}
344
345static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
346 size_t size, enum dma_data_direction dir)
347{
348 __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
349}
350
351static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
352 size_t size, enum dma_data_direction dir)
353{
354 __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
355 handle & ~PAGE_MASK, size, dir);
356}
357#endif /* CONFIG_DMABOUNCE */
358
326/** 359/**
327 * dma_map_single - map a single buffer for streaming DMA 360 * dma_map_single - map a single buffer for streaming DMA
328 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 361 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -340,11 +373,16 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
340static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, 373static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
341 size_t size, enum dma_data_direction dir) 374 size_t size, enum dma_data_direction dir)
342{ 375{
376 dma_addr_t addr;
377
343 BUG_ON(!valid_dma_direction(dir)); 378 BUG_ON(!valid_dma_direction(dir));
344 379
345 __dma_single_cpu_to_dev(cpu_addr, size, dir); 380 addr = __dma_map_single(dev, cpu_addr, size, dir);
381 debug_dma_map_page(dev, virt_to_page(cpu_addr),
382 (unsigned long)cpu_addr & ~PAGE_MASK, size,
383 dir, addr, true);
346 384
347 return virt_to_dma(dev, cpu_addr); 385 return addr;
348} 386}
349 387
350/** 388/**
@@ -364,11 +402,14 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
364static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, 402static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
365 unsigned long offset, size_t size, enum dma_data_direction dir) 403 unsigned long offset, size_t size, enum dma_data_direction dir)
366{ 404{
405 dma_addr_t addr;
406
367 BUG_ON(!valid_dma_direction(dir)); 407 BUG_ON(!valid_dma_direction(dir));
368 408
369 __dma_page_cpu_to_dev(page, offset, size, dir); 409 addr = __dma_map_page(dev, page, offset, size, dir);
410 debug_dma_map_page(dev, page, offset, size, dir, addr, false);
370 411
371 return page_to_dma(dev, page) + offset; 412 return addr;
372} 413}
373 414
374/** 415/**
@@ -388,7 +429,8 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
388static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, 429static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
389 size_t size, enum dma_data_direction dir) 430 size_t size, enum dma_data_direction dir)
390{ 431{
391 __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); 432 debug_dma_unmap_page(dev, handle, size, dir, true);
433 __dma_unmap_single(dev, handle, size, dir);
392} 434}
393 435
394/** 436/**
@@ -408,10 +450,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
408static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, 450static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
409 size_t size, enum dma_data_direction dir) 451 size_t size, enum dma_data_direction dir)
410{ 452{
411 __dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK, 453 debug_dma_unmap_page(dev, handle, size, dir, false);
412 size, dir); 454 __dma_unmap_page(dev, handle, size, dir);
413} 455}
414#endif /* CONFIG_DMABOUNCE */
415 456
416/** 457/**
417 * dma_sync_single_range_for_cpu 458 * dma_sync_single_range_for_cpu
@@ -437,6 +478,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
437{ 478{
438 BUG_ON(!valid_dma_direction(dir)); 479 BUG_ON(!valid_dma_direction(dir));
439 480
481 debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
482
440 if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) 483 if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
441 return; 484 return;
442 485
@@ -449,6 +492,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
449{ 492{
450 BUG_ON(!valid_dma_direction(dir)); 493 BUG_ON(!valid_dma_direction(dir));
451 494
495 debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
496
452 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) 497 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
453 return; 498 return;
454 499
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index cc7ef408071..af18ceaacf5 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -45,13 +45,17 @@
45 */ 45 */
46#define DOMAIN_NOACCESS 0 46#define DOMAIN_NOACCESS 0
47#define DOMAIN_CLIENT 1 47#define DOMAIN_CLIENT 1
48#ifdef CONFIG_CPU_USE_DOMAINS
48#define DOMAIN_MANAGER 3 49#define DOMAIN_MANAGER 3
50#else
51#define DOMAIN_MANAGER 1
52#endif
49 53
50#define domain_val(dom,type) ((type) << (2*(dom))) 54#define domain_val(dom,type) ((type) << (2*(dom)))
51 55
52#ifndef __ASSEMBLY__ 56#ifndef __ASSEMBLY__
53 57
54#ifdef CONFIG_MMU 58#ifdef CONFIG_CPU_USE_DOMAINS
55#define set_domain(x) \ 59#define set_domain(x) \
56 do { \ 60 do { \
57 __asm__ __volatile__( \ 61 __asm__ __volatile__( \
@@ -74,5 +78,28 @@
74#define modify_domain(dom,type) do { } while (0) 78#define modify_domain(dom,type) do { } while (0)
75#endif 79#endif
76 80
81/*
82 * Generate the T (user) versions of the LDR/STR and related
83 * instructions (inline assembly)
84 */
85#ifdef CONFIG_CPU_USE_DOMAINS
86#define T(instr) #instr "t"
87#else
88#define T(instr) #instr
77#endif 89#endif
78#endif /* !__ASSEMBLY__ */ 90
91#else /* __ASSEMBLY__ */
92
93/*
94 * Generate the T (user) versions of the LDR/STR and related
95 * instructions
96 */
97#ifdef CONFIG_CPU_USE_DOMAINS
98#define T(instr) instr ## t
99#else
100#define T(instr) instr
101#endif
102
103#endif /* __ASSEMBLY__ */
104
105#endif /* !__ASM_PROC_DOMAIN_H */
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 8bb66bca2e3..c3cd8755e64 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -99,6 +99,8 @@ struct elf32_hdr;
99extern int elf_check_arch(const struct elf32_hdr *); 99extern int elf_check_arch(const struct elf32_hdr *);
100#define elf_check_arch elf_check_arch 100#define elf_check_arch elf_check_arch
101 101
102#define vmcore_elf64_check_arch(x) (0)
103
102extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int); 104extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
103#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk) 105#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
104 106
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
new file mode 100644
index 00000000000..ec0bbf79c71
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -0,0 +1,44 @@
1/*
2 * Interrupt handling. Preserves r7, r8, r9
3 */
4 .macro arch_irq_handler_default
5 get_irqnr_preamble r5, lr
61: get_irqnr_and_base r0, r6, r5, lr
7 movne r1, sp
8 @
9 @ routine called with r0 = irq number, r1 = struct pt_regs *
10 @
11 adrne lr, BSYM(1b)
12 bne asm_do_IRQ
13
14#ifdef CONFIG_SMP
15 /*
16 * XXX
17 *
18 * this macro assumes that irqstat (r6) and base (r5) are
19 * preserved from get_irqnr_and_base above
20 */
21 ALT_SMP(test_for_ipi r0, r6, r5, lr)
22 ALT_UP_B(9997f)
23 movne r1, sp
24 adrne lr, BSYM(1b)
25 bne do_IPI
26
27#ifdef CONFIG_LOCAL_TIMERS
28 test_for_ltirq r0, r6, r5, lr
29 movne r0, sp
30 adrne lr, BSYM(1b)
31 bne do_local_timer
32#endif
33#endif
349997:
35 .endm
36
37 .macro arch_irq_handler, symbol_name
38 .align 5
39 .global \symbol_name
40\symbol_name:
41 mov r4, lr
42 arch_irq_handler_default
43 mov pc, r4
44 .endm
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 540a044153a..b33fe7065b3 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -13,12 +13,13 @@
13#include <linux/preempt.h> 13#include <linux/preempt.h>
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <asm/errno.h> 15#include <asm/errno.h>
16#include <asm/domain.h>
16 17
17#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ 18#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
18 __asm__ __volatile__( \ 19 __asm__ __volatile__( \
19 "1: ldrt %1, [%2]\n" \ 20 "1: " T(ldr) " %1, [%2]\n" \
20 " " insn "\n" \ 21 " " insn "\n" \
21 "2: strt %0, [%2]\n" \ 22 "2: " T(str) " %0, [%2]\n" \
22 " mov %0, #0\n" \ 23 " mov %0, #0\n" \
23 "3:\n" \ 24 "3:\n" \
24 " .pushsection __ex_table,\"a\"\n" \ 25 " .pushsection __ex_table,\"a\"\n" \
@@ -97,10 +98,10 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
97 pagefault_disable(); /* implies preempt_disable() */ 98 pagefault_disable(); /* implies preempt_disable() */
98 99
99 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" 100 __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
100 "1: ldrt %0, [%3]\n" 101 "1: " T(ldr) " %0, [%3]\n"
101 " teq %0, %1\n" 102 " teq %0, %1\n"
102 " it eq @ explicit IT needed for the 2b label\n" 103 " it eq @ explicit IT needed for the 2b label\n"
103 "2: streqt %2, [%3]\n" 104 "2: " T(streq) " %2, [%3]\n"
104 "3:\n" 105 "3:\n"
105 " .pushsection __ex_table,\"a\"\n" 106 " .pushsection __ex_table,\"a\"\n"
106 " .align 3\n" 107 " .align 3\n"
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 6d7485aff95..89ad1805e57 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,13 +5,31 @@
5#include <linux/threads.h> 5#include <linux/threads.h>
6#include <asm/irq.h> 6#include <asm/irq.h>
7 7
8#define NR_IPI 5
9
8typedef struct { 10typedef struct {
9 unsigned int __softirq_pending; 11 unsigned int __softirq_pending;
12#ifdef CONFIG_LOCAL_TIMERS
10 unsigned int local_timer_irqs; 13 unsigned int local_timer_irqs;
14#endif
15#ifdef CONFIG_SMP
16 unsigned int ipi_irqs[NR_IPI];
17#endif
11} ____cacheline_aligned irq_cpustat_t; 18} ____cacheline_aligned irq_cpustat_t;
12 19
13#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 20#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
14 21
22#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++
23#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member)
24
25#ifdef CONFIG_SMP
26u64 smp_irq_stat_cpu(unsigned int cpu);
27#else
28#define smp_irq_stat_cpu(cpu) 0
29#endif
30
31#define arch_irq_stat_cpu smp_irq_stat_cpu
32
15#if NR_IRQS > 512 33#if NR_IRQS > 512
16#define HARDIRQ_BITS 10 34#define HARDIRQ_BITS 10
17#elif NR_IRQS > 256 35#elif NR_IRQS > 256
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
new file mode 100644
index 00000000000..c115b82fe80
--- /dev/null
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -0,0 +1,75 @@
1/*
2 * arch/arm/include/asm/hardware/entry-macro-gic.S
3 *
4 * Low-level IRQ helper macros for GIC
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#include <asm/hardware/gic.h>
12
13#ifndef HAVE_GET_IRQNR_PREAMBLE
14 .macro get_irqnr_preamble, base, tmp
15 ldr \base, =gic_cpu_base_addr
16 ldr \base, [\base]
17 .endm
18#endif
19
20/*
21 * The interrupt numbering scheme is defined in the
22 * interrupt controller spec. To wit:
23 *
24 * Interrupts 0-15 are IPI
25 * 16-28 are reserved
26 * 29-31 are local. We allow 30 to be used for the watchdog.
27 * 32-1020 are global
28 * 1021-1022 are reserved
29 * 1023 is "spurious" (no interrupt)
30 *
31 * For now, we ignore all local interrupts so only return an interrupt if it's
32 * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
33 *
34 * A simple read from the controller will tell us the number of the highest
35 * priority enabled interrupt. We then just need to check whether it is in the
36 * valid range for an IRQ (30-1020 inclusive).
37 */
38
39 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
40
41 ldr \irqstat, [\base, #GIC_CPU_INTACK]
42 /* bits 12-10 = src CPU, 9-0 = int # */
43
44 ldr \tmp, =1021
45 bic \irqnr, \irqstat, #0x1c00
46 cmp \irqnr, #29
47 cmpcc \irqnr, \irqnr
48 cmpne \irqnr, \tmp
49 cmpcs \irqnr, \irqnr
50 .endm
51
52/* We assume that irqstat (the raw value of the IRQ acknowledge
53 * register) is preserved from the macro above.
54 * If there is an IPI, we immediately signal end of interrupt on the
55 * controller, since this requires the original irqstat value which
56 * we won't easily be able to recreate later.
57 */
58
59 .macro test_for_ipi, irqnr, irqstat, base, tmp
60 bic \irqnr, \irqstat, #0x1c00
61 cmp \irqnr, #16
62 strcc \irqstat, [\base, #GIC_CPU_EOI]
63 cmpcs \irqnr, \irqnr
64 .endm
65
66/* As above, this assumes that irqstat and base are preserved.. */
67
68 .macro test_for_ltirq, irqnr, irqstat, base, tmp
69 bic \irqnr, \irqstat, #0x1c00
70 mov \tmp, #0
71 cmp \irqnr, #29
72 moveq \tmp, #1
73 streq \irqstat, [\base, #GIC_CPU_EOI]
74 cmp \tmp, #0
75 .endm
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 7f34333bb54..84557d32100 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -33,10 +33,13 @@
33#define GIC_DIST_SOFTINT 0xf00 33#define GIC_DIST_SOFTINT 0xf00
34 34
35#ifndef __ASSEMBLY__ 35#ifndef __ASSEMBLY__
36void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); 36extern void __iomem *gic_cpu_base_addr;
37void gic_cpu_init(unsigned int gic_nr, void __iomem *base); 37
38void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
39void gic_secondary_init(unsigned int);
38void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); 40void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
39void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); 41void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
42void gic_enable_ppi(unsigned int);
40#endif 43#endif
41 44
42#endif 45#endif
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h
index 21fa272301f..b2f95c72287 100644
--- a/arch/arm/include/asm/hardware/it8152.h
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -76,6 +76,7 @@ extern unsigned long it8152_base_address;
76 IT8152_PD_IRQ(0) Audio controller (ACR) 76 IT8152_PD_IRQ(0) Audio controller (ACR)
77 */ 77 */
78#define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) 78#define IT8152_IRQ(x) (IRQ_BOARD_START + (x))
79#define IT8152_LAST_IRQ (IRQ_BOARD_START + 40)
79 80
80/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ 81/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
81#define IT8152_LD_IRQ_COUNT 9 82#define IT8152_LD_IRQ_COUNT 9
diff --git a/arch/arm/plat-versatile/include/plat/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 21e75e30d49..21e75e30d49 100644
--- a/arch/arm/plat-versatile/include/plat/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 1fc684e70ab..7080e2c8fa6 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -25,9 +25,6 @@ extern void *kmap_high(struct page *page);
25extern void *kmap_high_get(struct page *page); 25extern void *kmap_high_get(struct page *page);
26extern void kunmap_high(struct page *page); 26extern void kunmap_high(struct page *page);
27 27
28extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
29extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
30
31/* 28/*
32 * The following functions are already defined by <linux/highmem.h> 29 * The following functions are already defined by <linux/highmem.h>
33 * when CONFIG_HIGHMEM is not set. 30 * when CONFIG_HIGHMEM is not set.
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 815efa2d4e0..20e0f7c9e03 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -241,18 +241,15 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
241 * 241 *
242 */ 242 */
243#ifndef __arch_ioremap 243#ifndef __arch_ioremap
244#define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) 244#define __arch_ioremap __arm_ioremap
245#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) 245#define __arch_iounmap __iounmap
246#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED) 246#endif
247#define ioremap_wc(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_WC) 247
248#define iounmap(cookie) __iounmap(cookie)
249#else
250#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) 248#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
251#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) 249#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
252#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED) 250#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
253#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC) 251#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC)
254#define iounmap(cookie) __arch_iounmap(cookie) 252#define iounmap __arch_iounmap
255#endif
256 253
257/* 254/*
258 * io{read,write}{8,16,32} macros 255 * io{read,write}{8,16,32} macros
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index 8ec9ef5c3c7..c0094d8edae 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -33,10 +33,20 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
33 if (oldregs) { 33 if (oldregs) {
34 memcpy(newregs, oldregs, sizeof(*newregs)); 34 memcpy(newregs, oldregs, sizeof(*newregs));
35 } else { 35 } else {
36 __asm__ __volatile__ ("stmia %0, {r0 - r15}" 36 __asm__ __volatile__ (
37 : : "r" (&newregs->ARM_r0)); 37 "stmia %[regs_base], {r0-r12}\n\t"
38 __asm__ __volatile__ ("mrs %0, cpsr" 38 "mov %[_ARM_sp], sp\n\t"
39 : "=r" (newregs->ARM_cpsr)); 39 "str lr, %[_ARM_lr]\n\t"
40 "adr %[_ARM_pc], 1f\n\t"
41 "mrs %[_ARM_cpsr], cpsr\n\t"
42 "1:"
43 : [_ARM_pc] "=r" (newregs->ARM_pc),
44 [_ARM_cpsr] "=r" (newregs->ARM_cpsr),
45 [_ARM_sp] "=r" (newregs->ARM_sp),
46 [_ARM_lr] "=o" (newregs->ARM_lr)
47 : [regs_base] "r" (&newregs->ARM_r0)
48 : "memory"
49 );
40 } 50 }
41} 51}
42 52
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 50c7e7cfd67..6bc63ab498c 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -30,7 +30,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
30#include "smp_twd.h" 30#include "smp_twd.h"
31 31
32#define local_timer_ack() twd_timer_ack() 32#define local_timer_ack() twd_timer_ack()
33#define local_timer_stop() twd_timer_stop()
34 33
35#else 34#else
36 35
@@ -40,11 +39,6 @@ asmlinkage void do_local_timer(struct pt_regs *);
40 */ 39 */
41int local_timer_ack(void); 40int local_timer_ack(void);
42 41
43/*
44 * Stop a local timer interrupt.
45 */
46void local_timer_stop(void);
47
48#endif 42#endif
49 43
50/* 44/*
@@ -52,12 +46,6 @@ void local_timer_stop(void);
52 */ 46 */
53void local_timer_setup(struct clock_event_device *); 47void local_timer_setup(struct clock_event_device *);
54 48
55#else
56
57static inline void local_timer_stop(void)
58{
59}
60
61#endif 49#endif
62 50
63#endif 51#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index d97a964207f..3a0893a76a3 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -37,12 +37,21 @@ struct machine_desc {
37 struct meminfo *); 37 struct meminfo *);
38 void (*reserve)(void);/* reserve mem blocks */ 38 void (*reserve)(void);/* reserve mem blocks */
39 void (*map_io)(void);/* IO mapping function */ 39 void (*map_io)(void);/* IO mapping function */
40 void (*init_early)(void);
40 void (*init_irq)(void); 41 void (*init_irq)(void);
41 struct sys_timer *timer; /* system tick timer */ 42 struct sys_timer *timer; /* system tick timer */
42 void (*init_machine)(void); 43 void (*init_machine)(void);
44#ifdef CONFIG_MULTI_IRQ_HANDLER
45 void (*handle_irq)(struct pt_regs *);
46#endif
43}; 47};
44 48
45/* 49/*
50 * Current machine - only accessible during boot.
51 */
52extern struct machine_desc *machine_desc;
53
54/*
46 * Set of macros to define architecture features. This is built into 55 * Set of macros to define architecture features. This is built into
47 * a table by the linker. 56 * a table by the linker.
48 */ 57 */
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
index ce3eee9fe26..22ac140edd9 100644
--- a/arch/arm/include/asm/mach/irq.h
+++ b/arch/arm/include/asm/mach/irq.h
@@ -17,10 +17,12 @@ struct seq_file;
17/* 17/*
18 * This is internal. Do not use it. 18 * This is internal. Do not use it.
19 */ 19 */
20extern unsigned int arch_nr_irqs;
21extern void (*init_arch_irq)(void);
22extern void init_FIQ(void); 20extern void init_FIQ(void);
23extern int show_fiq_list(struct seq_file *, void *); 21extern int show_fiq_list(struct seq_file *, int);
22
23#ifdef CONFIG_MULTI_IRQ_HANDLER
24extern void (*handle_arch_irq)(struct pt_regs *);
25#endif
24 26
25/* 27/*
26 * This is for easy migration, but should be changed in the source 28 * This is for easy migration, but should be changed in the source
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index 35d408f6dcc..883f6be5117 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -43,7 +43,6 @@ struct sys_timer {
43#endif 43#endif
44}; 44};
45 45
46extern struct sys_timer *system_timer;
47extern void timer_tick(void); 46extern void timer_tick(void);
48 47
49#endif 48#endif
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index cbb0bc295d2..12c8e680cbf 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -8,11 +8,6 @@
8struct unwind_table; 8struct unwind_table;
9 9
10#ifdef CONFIG_ARM_UNWIND 10#ifdef CONFIG_ARM_UNWIND
11struct arm_unwind_mapping {
12 Elf_Shdr *unw_sec;
13 Elf_Shdr *sec_text;
14 struct unwind_table *unwind;
15};
16enum { 11enum {
17 ARM_SEC_INIT, 12 ARM_SEC_INIT,
18 ARM_SEC_DEVINIT, 13 ARM_SEC_DEVINIT,
@@ -21,13 +16,13 @@ enum {
21 ARM_SEC_DEVEXIT, 16 ARM_SEC_DEVEXIT,
22 ARM_SEC_MAX, 17 ARM_SEC_MAX,
23}; 18};
19#endif
20
24struct mod_arch_specific { 21struct mod_arch_specific {
25 struct arm_unwind_mapping map[ARM_SEC_MAX]; 22#ifdef CONFIG_ARM_UNWIND
26}; 23 struct unwind_table *unwind[ARM_SEC_MAX];
27#else
28struct mod_arch_specific {
29};
30#endif 24#endif
25};
31 26
32/* 27/*
33 * Include the ARM architecture version. 28 * Include the ARM architecture version.
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index a485ac3c869..f51a69595f6 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -151,13 +151,15 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
151#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) 151#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
152extern void copy_page(void *to, const void *from); 152extern void copy_page(void *to, const void *from);
153 153
154typedef unsigned long pteval_t;
155
154#undef STRICT_MM_TYPECHECKS 156#undef STRICT_MM_TYPECHECKS
155 157
156#ifdef STRICT_MM_TYPECHECKS 158#ifdef STRICT_MM_TYPECHECKS
157/* 159/*
158 * These are used to make use of C type-checking.. 160 * These are used to make use of C type-checking..
159 */ 161 */
160typedef struct { unsigned long pte; } pte_t; 162typedef struct { pteval_t pte; } pte_t;
161typedef struct { unsigned long pmd; } pmd_t; 163typedef struct { unsigned long pmd; } pmd_t;
162typedef struct { unsigned long pgd[2]; } pgd_t; 164typedef struct { unsigned long pgd[2]; } pgd_t;
163typedef struct { unsigned long pgprot; } pgprot_t; 165typedef struct { unsigned long pgprot; } pgprot_t;
@@ -175,7 +177,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
175/* 177/*
176 * .. while these make it easier on the compiler 178 * .. while these make it easier on the compiler
177 */ 179 */
178typedef unsigned long pte_t; 180typedef pteval_t pte_t;
179typedef unsigned long pmd_t; 181typedef unsigned long pmd_t;
180typedef unsigned long pgd_t[2]; 182typedef unsigned long pgd_t[2];
181typedef unsigned long pgprot_t; 183typedef unsigned long pgprot_t;
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index b12cc98bbe0..9763be04f77 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -30,14 +30,16 @@
30#define pmd_free(mm, pmd) do { } while (0) 30#define pmd_free(mm, pmd) do { } while (0)
31#define pgd_populate(mm,pmd,pte) BUG() 31#define pgd_populate(mm,pmd,pte) BUG()
32 32
33extern pgd_t *get_pgd_slow(struct mm_struct *mm); 33extern pgd_t *pgd_alloc(struct mm_struct *mm);
34extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd); 34extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
35
36#define pgd_alloc(mm) get_pgd_slow(mm)
37#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
38 35
39#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO) 36#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
40 37
38static inline void clean_pte_table(pte_t *pte)
39{
40 clean_dcache_area(pte + PTE_HWTABLE_PTRS, PTE_HWTABLE_SIZE);
41}
42
41/* 43/*
42 * Allocate one PTE table. 44 * Allocate one PTE table.
43 * 45 *
@@ -45,14 +47,14 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
45 * into one table thus: 47 * into one table thus:
46 * 48 *
47 * +------------+ 49 * +------------+
48 * | h/w pt 0 |
49 * +------------+
50 * | h/w pt 1 |
51 * +------------+
52 * | Linux pt 0 | 50 * | Linux pt 0 |
53 * +------------+ 51 * +------------+
54 * | Linux pt 1 | 52 * | Linux pt 1 |
55 * +------------+ 53 * +------------+
54 * | h/w pt 0 |
55 * +------------+
56 * | h/w pt 1 |
57 * +------------+
56 */ 58 */
57static inline pte_t * 59static inline pte_t *
58pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) 60pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
@@ -60,10 +62,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
60 pte_t *pte; 62 pte_t *pte;
61 63
62 pte = (pte_t *)__get_free_page(PGALLOC_GFP); 64 pte = (pte_t *)__get_free_page(PGALLOC_GFP);
63 if (pte) { 65 if (pte)
64 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); 66 clean_pte_table(pte);
65 pte += PTRS_PER_PTE;
66 }
67 67
68 return pte; 68 return pte;
69} 69}
@@ -79,10 +79,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
79 pte = alloc_pages(PGALLOC_GFP, 0); 79 pte = alloc_pages(PGALLOC_GFP, 0);
80#endif 80#endif
81 if (pte) { 81 if (pte) {
82 if (!PageHighMem(pte)) { 82 if (!PageHighMem(pte))
83 void *page = page_address(pte); 83 clean_pte_table(page_address(pte));
84 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
85 }
86 pgtable_page_ctor(pte); 84 pgtable_page_ctor(pte);
87 } 85 }
88 86
@@ -94,10 +92,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
94 */ 92 */
95static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 93static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
96{ 94{
97 if (pte) { 95 if (pte)
98 pte -= PTRS_PER_PTE;
99 free_page((unsigned long)pte); 96 free_page((unsigned long)pte);
100 }
101} 97}
102 98
103static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 99static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
@@ -106,8 +102,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
106 __free_page(pte); 102 __free_page(pte);
107} 103}
108 104
109static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval) 105static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
106 unsigned long prot)
110{ 107{
108 unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
111 pmdp[0] = __pmd(pmdval); 109 pmdp[0] = __pmd(pmdval);
112 pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); 110 pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
113 flush_pmd_entry(pmdp); 111 flush_pmd_entry(pmdp);
@@ -122,20 +120,16 @@ static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
122static inline void 120static inline void
123pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) 121pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
124{ 122{
125 unsigned long pte_ptr = (unsigned long)ptep;
126
127 /* 123 /*
128 * The pmd must be loaded with the physical 124 * The pmd must be loaded with the physical address of the PTE table
129 * address of the PTE table
130 */ 125 */
131 pte_ptr -= PTRS_PER_PTE * sizeof(void *); 126 __pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE);
132 __pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
133} 127}
134 128
135static inline void 129static inline void
136pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) 130pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
137{ 131{
138 __pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE); 132 __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE);
139} 133}
140#define pmd_pgtable(pmd) pmd_page(pmd) 134#define pmd_pgtable(pmd) pmd_page(pmd)
141 135
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 53d1d5deb11..ebcb6432f45 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -10,6 +10,7 @@
10#ifndef _ASMARM_PGTABLE_H 10#ifndef _ASMARM_PGTABLE_H
11#define _ASMARM_PGTABLE_H 11#define _ASMARM_PGTABLE_H
12 12
13#include <linux/const.h>
13#include <asm-generic/4level-fixup.h> 14#include <asm-generic/4level-fixup.h>
14#include <asm/proc-fns.h> 15#include <asm/proc-fns.h>
15 16
@@ -54,7 +55,7 @@
54 * Therefore, we tweak the implementation slightly - we tell Linux that we 55 * Therefore, we tweak the implementation slightly - we tell Linux that we
55 * have 2048 entries in the first level, each of which is 8 bytes (iow, two 56 * have 2048 entries in the first level, each of which is 8 bytes (iow, two
56 * hardware pointers to the second level.) The second level contains two 57 * hardware pointers to the second level.) The second level contains two
57 * hardware PTE tables arranged contiguously, followed by Linux versions 58 * hardware PTE tables arranged contiguously, preceded by Linux versions
58 * which contain the state information Linux needs. We, therefore, end up 59 * which contain the state information Linux needs. We, therefore, end up
59 * with 512 entries in the "PTE" level. 60 * with 512 entries in the "PTE" level.
60 * 61 *
@@ -62,15 +63,15 @@
62 * 63 *
63 * pgd pte 64 * pgd pte
64 * | | 65 * | |
65 * +--------+ +0 66 * +--------+
66 * | |-----> +------------+ +0 67 * | | +------------+ +0
68 * +- - - - + | Linux pt 0 |
69 * | | +------------+ +1024
70 * +--------+ +0 | Linux pt 1 |
71 * | |-----> +------------+ +2048
67 * +- - - - + +4 | h/w pt 0 | 72 * +- - - - + +4 | h/w pt 0 |
68 * | |-----> +------------+ +1024 73 * | |-----> +------------+ +3072
69 * +--------+ +8 | h/w pt 1 | 74 * +--------+ +8 | h/w pt 1 |
70 * | | +------------+ +2048
71 * +- - - - + | Linux pt 0 |
72 * | | +------------+ +3072
73 * +--------+ | Linux pt 1 |
74 * | | +------------+ +4096 75 * | | +------------+ +4096
75 * 76 *
76 * See L_PTE_xxx below for definitions of bits in the "Linux pt", and 77 * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
@@ -102,6 +103,10 @@
102#define PTRS_PER_PMD 1 103#define PTRS_PER_PMD 1
103#define PTRS_PER_PGD 2048 104#define PTRS_PER_PGD 2048
104 105
106#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
107#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
108#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
109
105/* 110/*
106 * PMD_SHIFT determines the size of the area a second-level page table can map 111 * PMD_SHIFT determines the size of the area a second-level page table can map
107 * PGDIR_SHIFT determines what a third-level page table entry can map 112 * PGDIR_SHIFT determines what a third-level page table entry can map
@@ -112,13 +117,13 @@
112#define LIBRARY_TEXT_START 0x0c000000 117#define LIBRARY_TEXT_START 0x0c000000
113 118
114#ifndef __ASSEMBLY__ 119#ifndef __ASSEMBLY__
115extern void __pte_error(const char *file, int line, unsigned long val); 120extern void __pte_error(const char *file, int line, pte_t);
116extern void __pmd_error(const char *file, int line, unsigned long val); 121extern void __pmd_error(const char *file, int line, pmd_t);
117extern void __pgd_error(const char *file, int line, unsigned long val); 122extern void __pgd_error(const char *file, int line, pgd_t);
118 123
119#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) 124#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
120#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) 125#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
121#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) 126#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
122#endif /* !__ASSEMBLY__ */ 127#endif /* !__ASSEMBLY__ */
123 128
124#define PMD_SIZE (1UL << PMD_SHIFT) 129#define PMD_SIZE (1UL << PMD_SHIFT)
@@ -133,8 +138,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
133 */ 138 */
134#define FIRST_USER_ADDRESS PAGE_SIZE 139#define FIRST_USER_ADDRESS PAGE_SIZE
135 140
136#define FIRST_USER_PGD_NR 1 141#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
137#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
138 142
139/* 143/*
140 * section address mask and size definitions. 144 * section address mask and size definitions.
@@ -161,30 +165,30 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
161 * The PTE table pointer refers to the hardware entries; the "Linux" 165 * The PTE table pointer refers to the hardware entries; the "Linux"
162 * entries are stored 1024 bytes below. 166 * entries are stored 1024 bytes below.
163 */ 167 */
164#define L_PTE_PRESENT (1 << 0) 168#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
165#define L_PTE_YOUNG (1 << 1) 169#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
166#define L_PTE_FILE (1 << 2) /* only when !PRESENT */ 170#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
167#define L_PTE_DIRTY (1 << 6) 171#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
168#define L_PTE_WRITE (1 << 7) 172#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
169#define L_PTE_USER (1 << 8) 173#define L_PTE_USER (_AT(pteval_t, 1) << 8)
170#define L_PTE_EXEC (1 << 9) 174#define L_PTE_XN (_AT(pteval_t, 1) << 9)
171#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */ 175#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
172 176
173/* 177/*
174 * These are the memory types, defined to be compatible with 178 * These are the memory types, defined to be compatible with
175 * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB 179 * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
176 */ 180 */
177#define L_PTE_MT_UNCACHED (0x00 << 2) /* 0000 */ 181#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
178#define L_PTE_MT_BUFFERABLE (0x01 << 2) /* 0001 */ 182#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
179#define L_PTE_MT_WRITETHROUGH (0x02 << 2) /* 0010 */ 183#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
180#define L_PTE_MT_WRITEBACK (0x03 << 2) /* 0011 */ 184#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
181#define L_PTE_MT_MINICACHE (0x06 << 2) /* 0110 (sa1100, xscale) */ 185#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
182#define L_PTE_MT_WRITEALLOC (0x07 << 2) /* 0111 */ 186#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
183#define L_PTE_MT_DEV_SHARED (0x04 << 2) /* 0100 */ 187#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
184#define L_PTE_MT_DEV_NONSHARED (0x0c << 2) /* 1100 */ 188#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
185#define L_PTE_MT_DEV_WC (0x09 << 2) /* 1001 */ 189#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
186#define L_PTE_MT_DEV_CACHED (0x0b << 2) /* 1011 */ 190#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
187#define L_PTE_MT_MASK (0x0f << 2) 191#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
188 192
189#ifndef __ASSEMBLY__ 193#ifndef __ASSEMBLY__
190 194
@@ -201,23 +205,44 @@ extern pgprot_t pgprot_kernel;
201 205
202#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) 206#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
203 207
204#define PAGE_NONE pgprot_user 208#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
205#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE) 209#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
206#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC) 210#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
207#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER) 211#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
208#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC) 212#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
209#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER) 213#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
210#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC) 214#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
211#define PAGE_KERNEL pgprot_kernel 215#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
212#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_kernel, L_PTE_EXEC) 216#define PAGE_KERNEL_EXEC pgprot_kernel
213 217
214#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT) 218#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
215#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE) 219#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
216#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC) 220#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
217#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER) 221#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
218#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC) 222#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
219#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER) 223#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
220#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC) 224#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
225
226#define __pgprot_modify(prot,mask,bits) \
227 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
228
229#define pgprot_noncached(prot) \
230 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
231
232#define pgprot_writecombine(prot) \
233 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
234
235#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
236#define pgprot_dmacoherent(prot) \
237 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
238#define __HAVE_PHYS_MEM_ACCESS_PROT
239struct file;
240extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
241 unsigned long size, pgprot_t vma_prot);
242#else
243#define pgprot_dmacoherent(prot) \
244 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
245#endif
221 246
222#endif /* __ASSEMBLY__ */ 247#endif /* __ASSEMBLY__ */
223 248
@@ -255,26 +280,84 @@ extern pgprot_t pgprot_kernel;
255extern struct page *empty_zero_page; 280extern struct page *empty_zero_page;
256#define ZERO_PAGE(vaddr) (empty_zero_page) 281#define ZERO_PAGE(vaddr) (empty_zero_page)
257 282
258#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
259#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
260 283
261#define pte_none(pte) (!pte_val(pte)) 284extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
262#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) 285
263#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) 286/* to find an entry in a page-table-directory */
264#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) 287#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
288
289#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
290
291/* to find an entry in a kernel page-table-directory */
292#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
293
294/*
295 * The "pgd_xxx()" functions here are trivial for a folded two-level
296 * setup: the pgd is never bad, and a pmd always exists (as it's folded
297 * into the pgd entry)
298 */
299#define pgd_none(pgd) (0)
300#define pgd_bad(pgd) (0)
301#define pgd_present(pgd) (1)
302#define pgd_clear(pgdp) do { } while (0)
303#define set_pgd(pgd,pgdp) do { } while (0)
304
305
306/* Find an entry in the second-level page table.. */
307#define pmd_offset(dir, addr) ((pmd_t *)(dir))
308
309#define pmd_none(pmd) (!pmd_val(pmd))
310#define pmd_present(pmd) (pmd_val(pmd))
311#define pmd_bad(pmd) (pmd_val(pmd) & 2)
312
313#define copy_pmd(pmdpd,pmdps) \
314 do { \
315 pmdpd[0] = pmdps[0]; \
316 pmdpd[1] = pmdps[1]; \
317 flush_pmd_entry(pmdpd); \
318 } while (0)
319
320#define pmd_clear(pmdp) \
321 do { \
322 pmdp[0] = __pmd(0); \
323 pmdp[1] = __pmd(0); \
324 clean_pmd_entry(pmdp); \
325 } while (0)
326
327static inline pte_t *pmd_page_vaddr(pmd_t pmd)
328{
329 return __va(pmd_val(pmd) & PAGE_MASK);
330}
331
332#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
333
334/* we don't need complex calculations here as the pmd is folded into the pgd */
335#define pmd_addr_end(addr,end) (end)
265 336
266#define pte_offset_map(dir,addr) (__pte_map(dir) + __pte_index(addr))
267#define pte_unmap(pte) __pte_unmap(pte)
268 337
269#ifndef CONFIG_HIGHPTE 338#ifndef CONFIG_HIGHPTE
270#define __pte_map(dir) pmd_page_vaddr(*(dir)) 339#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
271#define __pte_unmap(pte) do { } while (0) 340#define __pte_unmap(pte) do { } while (0)
272#else 341#else
273#define __pte_map(dir) ((pte_t *)kmap_atomic(pmd_page(*(dir))) + PTRS_PER_PTE) 342#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd)))
274#define __pte_unmap(pte) kunmap_atomic((pte - PTRS_PER_PTE)) 343#define __pte_unmap(pte) kunmap_atomic(pte)
275#endif 344#endif
276 345
346#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
347
348#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
349
350#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
351#define pte_unmap(pte) __pte_unmap(pte)
352
353#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
354#define pfn_pte(pfn,prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
355
356#define pte_page(pte) pfn_to_page(pte_pfn(pte))
357#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
358
277#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) 359#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
360#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
278 361
279#if __LINUX_ARM_ARCH__ < 6 362#if __LINUX_ARM_ARCH__ < 6
280static inline void __sync_icache_dcache(pte_t pteval) 363static inline void __sync_icache_dcache(pte_t pteval)
@@ -295,15 +378,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
295 } 378 }
296} 379}
297 380
298/* 381#define pte_none(pte) (!pte_val(pte))
299 * The following only work if pte_present() is true.
300 * Undefined behaviour if not..
301 */
302#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) 382#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
303#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) 383#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
304#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) 384#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
305#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) 385#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
306#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) 386#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
307#define pte_special(pte) (0) 387#define pte_special(pte) (0)
308 388
309#define pte_present_user(pte) \ 389#define pte_present_user(pte) \
@@ -313,8 +393,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
313#define PTE_BIT_FUNC(fn,op) \ 393#define PTE_BIT_FUNC(fn,op) \
314static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 394static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
315 395
316PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE); 396PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
317PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE); 397PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY);
318PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); 398PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
319PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); 399PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
320PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); 400PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
@@ -322,101 +402,13 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
322 402
323static inline pte_t pte_mkspecial(pte_t pte) { return pte; } 403static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
324 404
325#define __pgprot_modify(prot,mask,bits) \
326 __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
327
328/*
329 * Mark the prot value as uncacheable and unbufferable.
330 */
331#define pgprot_noncached(prot) \
332 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
333#define pgprot_writecombine(prot) \
334 __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
335#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
336#define pgprot_dmacoherent(prot) \
337 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
338#define __HAVE_PHYS_MEM_ACCESS_PROT
339struct file;
340extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
341 unsigned long size, pgprot_t vma_prot);
342#else
343#define pgprot_dmacoherent(prot) \
344 __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
345#endif
346
347#define pmd_none(pmd) (!pmd_val(pmd))
348#define pmd_present(pmd) (pmd_val(pmd))
349#define pmd_bad(pmd) (pmd_val(pmd) & 2)
350
351#define copy_pmd(pmdpd,pmdps) \
352 do { \
353 pmdpd[0] = pmdps[0]; \
354 pmdpd[1] = pmdps[1]; \
355 flush_pmd_entry(pmdpd); \
356 } while (0)
357
358#define pmd_clear(pmdp) \
359 do { \
360 pmdp[0] = __pmd(0); \
361 pmdp[1] = __pmd(0); \
362 clean_pmd_entry(pmdp); \
363 } while (0)
364
365static inline pte_t *pmd_page_vaddr(pmd_t pmd)
366{
367 unsigned long ptr;
368
369 ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
370 ptr += PTRS_PER_PTE * sizeof(void *);
371
372 return __va(ptr);
373}
374
375#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
376
377/* we don't need complex calculations here as the pmd is folded into the pgd */
378#define pmd_addr_end(addr,end) (end)
379
380/*
381 * Conversion functions: convert a page and protection to a page entry,
382 * and a page entry and page directory to the page they refer to.
383 */
384#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
385
386/*
387 * The "pgd_xxx()" functions here are trivial for a folded two-level
388 * setup: the pgd is never bad, and a pmd always exists (as it's folded
389 * into the pgd entry)
390 */
391#define pgd_none(pgd) (0)
392#define pgd_bad(pgd) (0)
393#define pgd_present(pgd) (1)
394#define pgd_clear(pgdp) do { } while (0)
395#define set_pgd(pgd,pgdp) do { } while (0)
396
397/* to find an entry in a page-table-directory */
398#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
399
400#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
401
402/* to find an entry in a kernel page-table-directory */
403#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
404
405/* Find an entry in the second-level page table.. */
406#define pmd_offset(dir, addr) ((pmd_t *)(dir))
407
408/* Find an entry in the third-level page table.. */
409#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
410
411static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 405static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
412{ 406{
413 const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER; 407 const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
414 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 408 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
415 return pte; 409 return pte;
416} 410}
417 411
418extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
419
420/* 412/*
421 * Encode and decode a swap entry. Swap entries are stored in the Linux 413 * Encode and decode a swap entry. Swap entries are stored in the Linux
422 * page tables as follows: 414 * page tables as follows:
@@ -481,6 +473,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
481 473
482#define pgtable_cache_init() do { } while (0) 474#define pgtable_cache_init() do { } while (0)
483 475
476void identity_mapping_add(pgd_t *, unsigned long, unsigned long);
477void identity_mapping_del(pgd_t *, unsigned long, unsigned long);
478
484#endif /* !__ASSEMBLY__ */ 479#endif /* !__ASSEMBLY__ */
485 480
486#endif /* CONFIG_MMU */ 481#endif /* CONFIG_MMU */
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
new file mode 100644
index 00000000000..a84628be1a7
--- /dev/null
+++ b/arch/arm/include/asm/sched_clock.h
@@ -0,0 +1,118 @@
1/*
2 * sched_clock.h: support for extending counters to full 64-bit ns counter
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 as
6 * published by the Free Software Foundation.
7 */
8#ifndef ASM_SCHED_CLOCK
9#define ASM_SCHED_CLOCK
10
11#include <linux/kernel.h>
12#include <linux/types.h>
13
14struct clock_data {
15 u64 epoch_ns;
16 u32 epoch_cyc;
17 u32 epoch_cyc_copy;
18 u32 mult;
19 u32 shift;
20};
21
22#define DEFINE_CLOCK_DATA(name) struct clock_data name
23
24static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
25{
26 return (cyc * mult) >> shift;
27}
28
29/*
30 * Atomically update the sched_clock epoch. Your update callback will
31 * be called from a timer before the counter wraps - read the current
32 * counter value, and call this function to safely move the epochs
33 * forward. Only use this from the update callback.
34 */
35static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask)
36{
37 unsigned long flags;
38 u64 ns = cd->epoch_ns +
39 cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift);
40
41 /*
42 * Write epoch_cyc and epoch_ns in a way that the update is
43 * detectable in cyc_to_fixed_sched_clock().
44 */
45 raw_local_irq_save(flags);
46 cd->epoch_cyc = cyc;
47 smp_wmb();
48 cd->epoch_ns = ns;
49 smp_wmb();
50 cd->epoch_cyc_copy = cyc;
51 raw_local_irq_restore(flags);
52}
53
54/*
55 * If your clock rate is known at compile time, using this will allow
56 * you to optimize the mult/shift loads away. This is paired with
57 * init_fixed_sched_clock() to ensure that your mult/shift are correct.
58 */
59static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd,
60 u32 cyc, u32 mask, u32 mult, u32 shift)
61{
62 u64 epoch_ns;
63 u32 epoch_cyc;
64
65 /*
66 * Load the epoch_cyc and epoch_ns atomically. We do this by
67 * ensuring that we always write epoch_cyc, epoch_ns and
68 * epoch_cyc_copy in strict order, and read them in strict order.
69 * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
70 * the middle of an update, and we should repeat the load.
71 */
72 do {
73 epoch_cyc = cd->epoch_cyc;
74 smp_rmb();
75 epoch_ns = cd->epoch_ns;
76 smp_rmb();
77 } while (epoch_cyc != cd->epoch_cyc_copy);
78
79 return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift);
80}
81
82/*
83 * Otherwise, you need to use this, which will obtain the mult/shift
84 * from the clock_data structure. Use init_sched_clock() with this.
85 */
86static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd,
87 u32 cyc, u32 mask)
88{
89 return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift);
90}
91
92/*
93 * Initialize the clock data - calculate the appropriate multiplier
94 * and shift. Also setup a timer to ensure that the epoch is refreshed
95 * at the appropriate time interval, which will call your update
96 * handler.
97 */
98void init_sched_clock(struct clock_data *, void (*)(void),
99 unsigned int, unsigned long);
100
101/*
102 * Use this initialization function rather than init_sched_clock() if
103 * you're using cyc_to_fixed_sched_clock, which will warn if your
104 * constants are incorrect.
105 */
106static inline void init_fixed_sched_clock(struct clock_data *cd,
107 void (*update)(void), unsigned int bits, unsigned long rate,
108 u32 mult, u32 shift)
109{
110 init_sched_clock(cd, update, bits, rate);
111 if (cd->mult != mult || cd->shift != shift) {
112 pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n"
113 "sched_clock: fix multiply/shift to avoid scheduler hiccups\n",
114 mult, shift, cd->mult, cd->shift);
115 }
116}
117
118#endif
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
index 4fc1565e4f9..316bb2b2be3 100644
--- a/arch/arm/include/asm/sizes.h
+++ b/arch/arm/include/asm/sizes.h
@@ -13,9 +13,6 @@
13 * along with this program; if not, write to the Free Software 13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */ 15 */
16/* DO NOT EDIT!! - this file automatically generated
17 * from .s file by awk -f s2h.awk
18 */
19/* Size definitions 16/* Size definitions
20 * Copyright (C) ARM Limited 1998. All rights reserved. 17 * Copyright (C) ARM Limited 1998. All rights reserved.
21 */ 18 */
@@ -25,6 +22,9 @@
25 22
26/* handy sizes */ 23/* handy sizes */
27#define SZ_16 0x00000010 24#define SZ_16 0x00000010
25#define SZ_32 0x00000020
26#define SZ_64 0x00000040
27#define SZ_128 0x00000080
28#define SZ_256 0x00000100 28#define SZ_256 0x00000100
29#define SZ_512 0x00000200 29#define SZ_512 0x00000200
30 30
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 3d05190797c..96ed521f240 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -33,27 +33,23 @@ struct seq_file;
33/* 33/*
34 * generate IPI list text 34 * generate IPI list text
35 */ 35 */
36extern void show_ipi_list(struct seq_file *p); 36extern void show_ipi_list(struct seq_file *, int);
37 37
38/* 38/*
39 * Called from assembly code, this handles an IPI. 39 * Called from assembly code, this handles an IPI.
40 */ 40 */
41asmlinkage void do_IPI(struct pt_regs *regs); 41asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
42 42
43/* 43/*
44 * Setup the set of possible CPUs (via set_cpu_possible) 44 * Setup the set of possible CPUs (via set_cpu_possible)
45 */ 45 */
46extern void smp_init_cpus(void); 46extern void smp_init_cpus(void);
47 47
48/*
49 * Move global data into per-processor storage.
50 */
51extern void smp_store_cpu_info(unsigned int cpuid);
52 48
53/* 49/*
54 * Raise an IPI cross call on CPUs in callmap. 50 * Raise an IPI cross call on CPUs in callmap.
55 */ 51 */
56extern void smp_cross_call(const struct cpumask *mask); 52extern void smp_cross_call(const struct cpumask *mask, int ipi);
57 53
58/* 54/*
59 * Boot a secondary CPU, and assign it the specified idle task. 55 * Boot a secondary CPU, and assign it the specified idle task.
@@ -73,6 +69,11 @@ asmlinkage void secondary_start_kernel(void);
73extern void platform_secondary_init(unsigned int cpu); 69extern void platform_secondary_init(unsigned int cpu);
74 70
75/* 71/*
72 * Initialize cpu_possible map, and enable coherency
73 */
74extern void platform_smp_prepare_cpus(unsigned int);
75
76/*
76 * Initial data for bringing up a secondary CPU. 77 * Initial data for bringing up a secondary CPU.
77 */ 78 */
78struct secondary_data { 79struct secondary_data {
@@ -97,6 +98,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
97/* 98/*
98 * show local interrupt info 99 * show local interrupt info
99 */ 100 */
100extern void show_local_irqs(struct seq_file *); 101extern void show_local_irqs(struct seq_file *, int);
101 102
102#endif /* ifndef __ASM_ARM_SMP_H */ 103#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/smp_mpidr.h b/arch/arm/include/asm/smp_mpidr.h
deleted file mode 100644
index 6a9307d6490..00000000000
--- a/arch/arm/include/asm/smp_mpidr.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#ifndef ASMARM_SMP_MIDR_H
2#define ASMARM_SMP_MIDR_H
3
4#define hard_smp_processor_id() \
5 ({ \
6 unsigned int cpunum; \
7 __asm__("\n" \
8 "1: mrc p15, 0, %0, c0, c0, 5\n" \
9 " .pushsection \".alt.smp.init\", \"a\"\n"\
10 " .long 1b\n" \
11 " mov %0, #0\n" \
12 " .popsection" \
13 : "=r" (cpunum)); \
14 cpunum &= 0x0F; \
15 })
16
17#endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index 634f357be6b..fed9981fba0 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -22,7 +22,6 @@ struct clock_event_device;
22 22
23extern void __iomem *twd_base; 23extern void __iomem *twd_base;
24 24
25void twd_timer_stop(void);
26int twd_timer_ack(void); 25int twd_timer_ack(void);
27void twd_timer_setup(struct clock_event_device *); 26void twd_timer_setup(struct clock_event_device *);
28 27
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index ec4327a4653..97f6d60297d 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -124,6 +124,13 @@ extern unsigned int user_debug;
124#define vectors_high() (0) 124#define vectors_high() (0)
125#endif 125#endif
126 126
127#if __LINUX_ARM_ARCH__ >= 7 || \
128 (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
129#define sev() __asm__ __volatile__ ("sev" : : : "memory")
130#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
131#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
132#endif
133
127#if __LINUX_ARM_ARCH__ >= 7 134#if __LINUX_ARM_ARCH__ >= 7
128#define isb() __asm__ __volatile__ ("isb" : : : "memory") 135#define isb() __asm__ __volatile__ ("isb" : : : "memory")
129#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") 136#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
@@ -155,6 +162,7 @@ extern unsigned int user_debug;
155#define rmb() dmb() 162#define rmb() dmb()
156#define wmb() mb() 163#define wmb() mb()
157#else 164#else
165#include <asm/memory.h>
158#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) 166#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
159#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) 167#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
160#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) 168#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index 124475afb00..1b960d5ef6a 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -46,4 +46,6 @@ static inline int in_exception_text(unsigned long ptr)
46extern void __init early_trap_init(void); 46extern void __init early_trap_init(void);
47extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); 47extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
48 48
49extern void *vectors_page;
50
49#endif 51#endif
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 33e4a48fe10..b293616a1a1 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -227,7 +227,7 @@ do { \
227 227
228#define __get_user_asm_byte(x,addr,err) \ 228#define __get_user_asm_byte(x,addr,err) \
229 __asm__ __volatile__( \ 229 __asm__ __volatile__( \
230 "1: ldrbt %1,[%2]\n" \ 230 "1: " T(ldrb) " %1,[%2],#0\n" \
231 "2:\n" \ 231 "2:\n" \
232 " .pushsection .fixup,\"ax\"\n" \ 232 " .pushsection .fixup,\"ax\"\n" \
233 " .align 2\n" \ 233 " .align 2\n" \
@@ -263,7 +263,7 @@ do { \
263 263
264#define __get_user_asm_word(x,addr,err) \ 264#define __get_user_asm_word(x,addr,err) \
265 __asm__ __volatile__( \ 265 __asm__ __volatile__( \
266 "1: ldrt %1,[%2]\n" \ 266 "1: " T(ldr) " %1,[%2],#0\n" \
267 "2:\n" \ 267 "2:\n" \
268 " .pushsection .fixup,\"ax\"\n" \ 268 " .pushsection .fixup,\"ax\"\n" \
269 " .align 2\n" \ 269 " .align 2\n" \
@@ -308,7 +308,7 @@ do { \
308 308
309#define __put_user_asm_byte(x,__pu_addr,err) \ 309#define __put_user_asm_byte(x,__pu_addr,err) \
310 __asm__ __volatile__( \ 310 __asm__ __volatile__( \
311 "1: strbt %1,[%2]\n" \ 311 "1: " T(strb) " %1,[%2],#0\n" \
312 "2:\n" \ 312 "2:\n" \
313 " .pushsection .fixup,\"ax\"\n" \ 313 " .pushsection .fixup,\"ax\"\n" \
314 " .align 2\n" \ 314 " .align 2\n" \
@@ -341,7 +341,7 @@ do { \
341 341
342#define __put_user_asm_word(x,__pu_addr,err) \ 342#define __put_user_asm_word(x,__pu_addr,err) \
343 __asm__ __volatile__( \ 343 __asm__ __volatile__( \
344 "1: strt %1,[%2]\n" \ 344 "1: " T(str) " %1,[%2],#0\n" \
345 "2:\n" \ 345 "2:\n" \
346 " .pushsection .fixup,\"ax\"\n" \ 346 " .pushsection .fixup,\"ax\"\n" \
347 " .align 2\n" \ 347 " .align 2\n" \
@@ -366,10 +366,10 @@ do { \
366 366
367#define __put_user_asm_dword(x,__pu_addr,err) \ 367#define __put_user_asm_dword(x,__pu_addr,err) \
368 __asm__ __volatile__( \ 368 __asm__ __volatile__( \
369 ARM( "1: strt " __reg_oper1 ", [%1], #4\n" ) \ 369 ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \
370 ARM( "2: strt " __reg_oper0 ", [%1]\n" ) \ 370 ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \
371 THUMB( "1: strt " __reg_oper1 ", [%1]\n" ) \ 371 THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \
372 THUMB( "2: strt " __reg_oper0 ", [%1, #4]\n" ) \ 372 THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \
373 "3:\n" \ 373 "3:\n" \
374 " .pushsection .fixup,\"ax\"\n" \ 374 " .pushsection .fixup,\"ax\"\n" \
375 " .align 2\n" \ 375 " .align 2\n" \
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index c73abe4b7e7..185ee822c93 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,7 +29,8 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
29obj-$(CONFIG_ARTHUR) += arthur.o 29obj-$(CONFIG_ARTHUR) += arthur.o
30obj-$(CONFIG_ISA_DMA) += dma-isa.o 30obj-$(CONFIG_ISA_DMA) += dma-isa.o
31obj-$(CONFIG_PCI) += bios32.o isa.o 31obj-$(CONFIG_PCI) += bios32.o isa.o
32obj-$(CONFIG_SMP) += smp.o 32obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
33obj-$(CONFIG_SMP) += smp.o smp_tlb.o
33obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 34obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
34obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 35obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
35obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 36obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
@@ -43,6 +44,8 @@ obj-$(CONFIG_KGDB) += kgdb.o
43obj-$(CONFIG_ARM_UNWIND) += unwind.o 44obj-$(CONFIG_ARM_UNWIND) += unwind.o
44obj-$(CONFIG_HAVE_TCM) += tcm.o 45obj-$(CONFIG_HAVE_TCM) += tcm.o
45obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 46obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
47obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
48CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
46obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 49obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
47 50
48obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o 51obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 36199ffc4cc..2b46fea36c9 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -25,42 +25,22 @@
25#include <asm/tls.h> 25#include <asm/tls.h>
26 26
27#include "entry-header.S" 27#include "entry-header.S"
28#include <asm/entry-macro-multi.S>
28 29
29/* 30/*
30 * Interrupt handling. Preserves r7, r8, r9 31 * Interrupt handling. Preserves r7, r8, r9
31 */ 32 */
32 .macro irq_handler 33 .macro irq_handler
33 get_irqnr_preamble r5, lr 34#ifdef CONFIG_MULTI_IRQ_HANDLER
341: get_irqnr_and_base r0, r6, r5, lr 35 ldr r5, =handle_arch_irq
35 movne r1, sp 36 mov r0, sp
36 @ 37 ldr r5, [r5]
37 @ routine called with r0 = irq number, r1 = struct pt_regs * 38 adr lr, BSYM(9997f)
38 @ 39 teq r5, #0
39 adrne lr, BSYM(1b) 40 movne pc, r5
40 bne asm_do_IRQ
41
42#ifdef CONFIG_SMP
43 /*
44 * XXX
45 *
46 * this macro assumes that irqstat (r6) and base (r5) are
47 * preserved from get_irqnr_and_base above
48 */
49 ALT_SMP(test_for_ipi r0, r6, r5, lr)
50 ALT_UP_B(9997f)
51 movne r0, sp
52 adrne lr, BSYM(1b)
53 bne do_IPI
54
55#ifdef CONFIG_LOCAL_TIMERS
56 test_for_ltirq r0, r6, r5, lr
57 movne r0, sp
58 adrne lr, BSYM(1b)
59 bne do_local_timer
60#endif 41#endif
42 arch_irq_handler_default
619997: 439997:
62#endif
63
64 .endm 44 .endm
65 45
66#ifdef CONFIG_KPROBES 46#ifdef CONFIG_KPROBES
@@ -739,7 +719,7 @@ ENTRY(__switch_to)
739 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack 719 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
740 THUMB( str sp, [ip], #4 ) 720 THUMB( str sp, [ip], #4 )
741 THUMB( str lr, [ip], #4 ) 721 THUMB( str lr, [ip], #4 )
742#ifdef CONFIG_MMU 722#ifdef CONFIG_CPU_USE_DOMAINS
743 ldr r6, [r2, #TI_CPU_DOMAIN] 723 ldr r6, [r2, #TI_CPU_DOMAIN]
744#endif 724#endif
745 set_tls r3, r4, r5 725 set_tls r3, r4, r5
@@ -748,7 +728,7 @@ ENTRY(__switch_to)
748 ldr r8, =__stack_chk_guard 728 ldr r8, =__stack_chk_guard
749 ldr r7, [r7, #TSK_STACK_CANARY] 729 ldr r7, [r7, #TSK_STACK_CANARY]
750#endif 730#endif
751#ifdef CONFIG_MMU 731#ifdef CONFIG_CPU_USE_DOMAINS
752 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 732 mcr p15, 0, r6, c3, c0, 0 @ Set domain register
753#endif 733#endif
754 mov r5, r0 734 mov r5, r0
@@ -846,7 +826,7 @@ __kuser_helper_start:
846 */ 826 */
847 827
848__kuser_memory_barrier: @ 0xffff0fa0 828__kuser_memory_barrier: @ 0xffff0fa0
849 smp_dmb 829 smp_dmb arm
850 usr_ret lr 830 usr_ret lr
851 831
852 .align 5 832 .align 5
@@ -963,7 +943,7 @@ kuser_cmpxchg_fixup:
963 943
964#else 944#else
965 945
966 smp_dmb 946 smp_dmb arm
9671: ldrex r3, [r2] 9471: ldrex r3, [r2]
968 subs r3, r3, r0 948 subs r3, r3, r0
969 strexeq r3, r1, [r2] 949 strexeq r3, r1, [r2]
@@ -1249,3 +1229,9 @@ cr_alignment:
1249 .space 4 1229 .space 4
1250cr_no_alignment: 1230cr_no_alignment:
1251 .space 4 1231 .space 4
1232
1233#ifdef CONFIG_MULTI_IRQ_HANDLER
1234 .globl handle_arch_irq
1235handle_arch_irq:
1236 .space 4
1237#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index aae802ee12f..1e7b04a40a3 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -29,6 +29,9 @@ ret_fast_syscall:
29 ldr r1, [tsk, #TI_FLAGS] 29 ldr r1, [tsk, #TI_FLAGS]
30 tst r1, #_TIF_WORK_MASK 30 tst r1, #_TIF_WORK_MASK
31 bne fast_work_pending 31 bne fast_work_pending
32#if defined(CONFIG_IRQSOFF_TRACER)
33 asm_trace_hardirqs_on
34#endif
32 35
33 /* perform architecture specific actions before user return */ 36 /* perform architecture specific actions before user return */
34 arch_ret_to_user r1, lr 37 arch_ret_to_user r1, lr
@@ -65,6 +68,9 @@ ret_slow_syscall:
65 tst r1, #_TIF_WORK_MASK 68 tst r1, #_TIF_WORK_MASK
66 bne work_pending 69 bne work_pending
67no_work_pending: 70no_work_pending:
71#if defined(CONFIG_IRQSOFF_TRACER)
72 asm_trace_hardirqs_on
73#endif
68 /* perform architecture specific actions before user return */ 74 /* perform architecture specific actions before user return */
69 arch_ret_to_user r1, lr 75 arch_ret_to_user r1, lr
70 76
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 6ff7919613d..e72dc34eea1 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -45,6 +45,7 @@
45#include <asm/fiq.h> 45#include <asm/fiq.h>
46#include <asm/irq.h> 46#include <asm/irq.h>
47#include <asm/system.h> 47#include <asm/system.h>
48#include <asm/traps.h>
48 49
49static unsigned long no_fiq_insn; 50static unsigned long no_fiq_insn;
50 51
@@ -67,17 +68,22 @@ static struct fiq_handler default_owner = {
67 68
68static struct fiq_handler *current_fiq = &default_owner; 69static struct fiq_handler *current_fiq = &default_owner;
69 70
70int show_fiq_list(struct seq_file *p, void *v) 71int show_fiq_list(struct seq_file *p, int prec)
71{ 72{
72 if (current_fiq != &default_owner) 73 if (current_fiq != &default_owner)
73 seq_printf(p, "FIQ: %s\n", current_fiq->name); 74 seq_printf(p, "%*s: %s\n", prec, "FIQ",
75 current_fiq->name);
74 76
75 return 0; 77 return 0;
76} 78}
77 79
78void set_fiq_handler(void *start, unsigned int length) 80void set_fiq_handler(void *start, unsigned int length)
79{ 81{
82#if defined(CONFIG_CPU_USE_DOMAINS)
80 memcpy((void *)0xffff001c, start, length); 83 memcpy((void *)0xffff001c, start, length);
84#else
85 memcpy(vectors_page + 0x1c, start, length);
86#endif
81 flush_icache_range(0xffff001c, 0xffff001c + length); 87 flush_icache_range(0xffff001c, 0xffff001c + length);
82 if (!vectors_high()) 88 if (!vectors_high())
83 flush_icache_range(0x1c, 0x1c + length); 89 flush_icache_range(0x1c, 0x1c + length);
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 6bd82d25683..f17d9a09e8f 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -91,6 +91,11 @@ ENTRY(stext)
91 movs r8, r5 @ invalid machine (r5=0)? 91 movs r8, r5 @ invalid machine (r5=0)?
92 THUMB( it eq ) @ force fixup-able long branch encoding 92 THUMB( it eq ) @ force fixup-able long branch encoding
93 beq __error_a @ yes, error 'a' 93 beq __error_a @ yes, error 'a'
94
95 /*
96 * r1 = machine no, r2 = atags,
97 * r8 = machinfo, r9 = cpuid, r10 = procinfo
98 */
94 bl __vet_atags 99 bl __vet_atags
95#ifdef CONFIG_SMP_ON_UP 100#ifdef CONFIG_SMP_ON_UP
96 bl __fixup_smp 101 bl __fixup_smp
@@ -387,19 +392,19 @@ ENDPROC(__turn_mmu_on)
387 392
388#ifdef CONFIG_SMP_ON_UP 393#ifdef CONFIG_SMP_ON_UP
389__fixup_smp: 394__fixup_smp:
390 mov r7, #0x00070000 395 mov r4, #0x00070000
391 orr r6, r7, #0xff000000 @ mask 0xff070000 396 orr r3, r4, #0xff000000 @ mask 0xff070000
392 orr r7, r7, #0x41000000 @ val 0x41070000 397 orr r4, r4, #0x41000000 @ val 0x41070000
393 and r0, r9, r6 398 and r0, r9, r3
394 teq r0, r7 @ ARM CPU and ARMv6/v7? 399 teq r0, r4 @ ARM CPU and ARMv6/v7?
395 bne __fixup_smp_on_up @ no, assume UP 400 bne __fixup_smp_on_up @ no, assume UP
396 401
397 orr r6, r6, #0x0000ff00 402 orr r3, r3, #0x0000ff00
398 orr r6, r6, #0x000000f0 @ mask 0xff07fff0 403 orr r3, r3, #0x000000f0 @ mask 0xff07fff0
399 orr r7, r7, #0x0000b000 404 orr r4, r4, #0x0000b000
400 orr r7, r7, #0x00000020 @ val 0x4107b020 405 orr r4, r4, #0x00000020 @ val 0x4107b020
401 and r0, r9, r6 406 and r0, r9, r3
402 teq r0, r7 @ ARM 11MPCore? 407 teq r0, r4 @ ARM 11MPCore?
403 moveq pc, lr @ yes, assume SMP 408 moveq pc, lr @ yes, assume SMP
404 409
405 mrc p15, 0, r0, c0, c0, 5 @ read MPIDR 410 mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
@@ -408,15 +413,22 @@ __fixup_smp:
408 413
409__fixup_smp_on_up: 414__fixup_smp_on_up:
410 adr r0, 1f 415 adr r0, 1f
411 ldmia r0, {r3, r6, r7} 416 ldmia r0, {r3 - r5}
412 sub r3, r0, r3 417 sub r3, r0, r3
413 add r6, r6, r3 418 add r4, r4, r3
414 add r7, r7, r3 419 add r5, r5, r3
4152: cmp r6, r7 4202: cmp r4, r5
416 ldmia r6!, {r0, r4} 421 movhs pc, lr
417 strlo r4, [r0, r3] 422 ldmia r4!, {r0, r6}
418 blo 2b 423 ARM( str r6, [r0, r3] )
419 mov pc, lr 424 THUMB( add r0, r0, r3 )
425#ifdef __ARMEB__
426 THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
427#endif
428 THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
429 THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
430 THUMB( strh r6, [r0] )
431 b 2b
420ENDPROC(__fixup_smp) 432ENDPROC(__fixup_smp)
421 433
422 .align 434 .align
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 6d616333340..8135438b881 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -38,6 +38,7 @@
38#include <linux/ftrace.h> 38#include <linux/ftrace.h>
39 39
40#include <asm/system.h> 40#include <asm/system.h>
41#include <asm/mach/arch.h>
41#include <asm/mach/irq.h> 42#include <asm/mach/irq.h>
42#include <asm/mach/time.h> 43#include <asm/mach/time.h>
43 44
@@ -48,8 +49,6 @@
48#define irq_finish(irq) do { } while (0) 49#define irq_finish(irq) do { } while (0)
49#endif 50#endif
50 51
51unsigned int arch_nr_irqs;
52void (*init_arch_irq)(void) __initdata = NULL;
53unsigned long irq_err_count; 52unsigned long irq_err_count;
54 53
55int show_interrupts(struct seq_file *p, void *v) 54int show_interrupts(struct seq_file *p, void *v)
@@ -58,11 +57,20 @@ int show_interrupts(struct seq_file *p, void *v)
58 struct irq_desc *desc; 57 struct irq_desc *desc;
59 struct irqaction * action; 58 struct irqaction * action;
60 unsigned long flags; 59 unsigned long flags;
60 int prec, n;
61
62 for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
63 n *= 10;
64
65#ifdef CONFIG_SMP
66 if (prec < 4)
67 prec = 4;
68#endif
61 69
62 if (i == 0) { 70 if (i == 0) {
63 char cpuname[12]; 71 char cpuname[12];
64 72
65 seq_printf(p, " "); 73 seq_printf(p, "%*s ", prec, "");
66 for_each_present_cpu(cpu) { 74 for_each_present_cpu(cpu) {
67 sprintf(cpuname, "CPU%d", cpu); 75 sprintf(cpuname, "CPU%d", cpu);
68 seq_printf(p, " %10s", cpuname); 76 seq_printf(p, " %10s", cpuname);
@@ -77,7 +85,7 @@ int show_interrupts(struct seq_file *p, void *v)
77 if (!action) 85 if (!action)
78 goto unlock; 86 goto unlock;
79 87
80 seq_printf(p, "%3d: ", i); 88 seq_printf(p, "%*d: ", prec, i);
81 for_each_present_cpu(cpu) 89 for_each_present_cpu(cpu)
82 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); 90 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
83 seq_printf(p, " %10s", desc->chip->name ? : "-"); 91 seq_printf(p, " %10s", desc->chip->name ? : "-");
@@ -90,13 +98,15 @@ unlock:
90 raw_spin_unlock_irqrestore(&desc->lock, flags); 98 raw_spin_unlock_irqrestore(&desc->lock, flags);
91 } else if (i == nr_irqs) { 99 } else if (i == nr_irqs) {
92#ifdef CONFIG_FIQ 100#ifdef CONFIG_FIQ
93 show_fiq_list(p, v); 101 show_fiq_list(p, prec);
94#endif 102#endif
95#ifdef CONFIG_SMP 103#ifdef CONFIG_SMP
96 show_ipi_list(p); 104 show_ipi_list(p, prec);
97 show_local_irqs(p); 105#endif
106#ifdef CONFIG_LOCAL_TIMERS
107 show_local_irqs(p, prec);
98#endif 108#endif
99 seq_printf(p, "Err: %10lu\n", irq_err_count); 109 seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
100 } 110 }
101 return 0; 111 return 0;
102} 112}
@@ -156,13 +166,13 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
156 166
157void __init init_IRQ(void) 167void __init init_IRQ(void)
158{ 168{
159 init_arch_irq(); 169 machine_desc->init_irq();
160} 170}
161 171
162#ifdef CONFIG_SPARSE_IRQ 172#ifdef CONFIG_SPARSE_IRQ
163int __init arch_probe_nr_irqs(void) 173int __init arch_probe_nr_irqs(void)
164{ 174{
165 nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS; 175 nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
166 return nr_irqs; 176 return nr_irqs;
167} 177}
168#endif 178#endif
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 3a8fd5140d7..30ead135ff5 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -23,6 +23,8 @@ extern unsigned long kexec_indirection_page;
23extern unsigned long kexec_mach_type; 23extern unsigned long kexec_mach_type;
24extern unsigned long kexec_boot_atags; 24extern unsigned long kexec_boot_atags;
25 25
26static atomic_t waiting_for_crash_ipi;
27
26/* 28/*
27 * Provide a dummy crash_notes definition while crash dump arrives to arm. 29 * Provide a dummy crash_notes definition while crash dump arrives to arm.
28 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. 30 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -37,9 +39,37 @@ void machine_kexec_cleanup(struct kimage *image)
37{ 39{
38} 40}
39 41
42void machine_crash_nonpanic_core(void *unused)
43{
44 struct pt_regs regs;
45
46 crash_setup_regs(&regs, NULL);
47 printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
48 smp_processor_id());
49 crash_save_cpu(&regs, smp_processor_id());
50 flush_cache_all();
51
52 atomic_dec(&waiting_for_crash_ipi);
53 while (1)
54 cpu_relax();
55}
56
40void machine_crash_shutdown(struct pt_regs *regs) 57void machine_crash_shutdown(struct pt_regs *regs)
41{ 58{
59 unsigned long msecs;
60
42 local_irq_disable(); 61 local_irq_disable();
62
63 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
64 smp_call_function(machine_crash_nonpanic_core, NULL, false);
65 msecs = 1000; /* Wait at most a second for the other cpus to stop */
66 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
67 mdelay(1);
68 msecs--;
69 }
70 if (atomic_read(&waiting_for_crash_ipi) > 0)
71 printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
72
43 crash_save_cpu(regs, smp_processor_id()); 73 crash_save_cpu(regs, smp_processor_id());
44 74
45 printk(KERN_INFO "Loading crashdump kernel...\n"); 75 printk(KERN_INFO "Loading crashdump kernel...\n");
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index d9bd786ce23..0c1bb68ff4a 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -67,35 +67,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
67 char *secstrings, 67 char *secstrings,
68 struct module *mod) 68 struct module *mod)
69{ 69{
70#ifdef CONFIG_ARM_UNWIND
71 Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
72 struct arm_unwind_mapping *maps = mod->arch.map;
73
74 for (s = sechdrs; s < sechdrs_end; s++) {
75 char const *secname = secstrings + s->sh_name;
76
77 if (strcmp(".ARM.exidx.init.text", secname) == 0)
78 maps[ARM_SEC_INIT].unw_sec = s;
79 else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
80 maps[ARM_SEC_DEVINIT].unw_sec = s;
81 else if (strcmp(".ARM.exidx", secname) == 0)
82 maps[ARM_SEC_CORE].unw_sec = s;
83 else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
84 maps[ARM_SEC_EXIT].unw_sec = s;
85 else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
86 maps[ARM_SEC_DEVEXIT].unw_sec = s;
87 else if (strcmp(".init.text", secname) == 0)
88 maps[ARM_SEC_INIT].sec_text = s;
89 else if (strcmp(".devinit.text", secname) == 0)
90 maps[ARM_SEC_DEVINIT].sec_text = s;
91 else if (strcmp(".text", secname) == 0)
92 maps[ARM_SEC_CORE].sec_text = s;
93 else if (strcmp(".exit.text", secname) == 0)
94 maps[ARM_SEC_EXIT].sec_text = s;
95 else if (strcmp(".devexit.text", secname) == 0)
96 maps[ARM_SEC_DEVEXIT].sec_text = s;
97 }
98#endif
99 return 0; 70 return 0;
100} 71}
101 72
@@ -300,41 +271,69 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
300 return -ENOEXEC; 271 return -ENOEXEC;
301} 272}
302 273
303#ifdef CONFIG_ARM_UNWIND 274struct mod_unwind_map {
304static void register_unwind_tables(struct module *mod) 275 const Elf_Shdr *unw_sec;
276 const Elf_Shdr *txt_sec;
277};
278
279int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
280 struct module *mod)
305{ 281{
282#ifdef CONFIG_ARM_UNWIND
283 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
284 const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
285 struct mod_unwind_map maps[ARM_SEC_MAX];
306 int i; 286 int i;
307 for (i = 0; i < ARM_SEC_MAX; ++i) { 287
308 struct arm_unwind_mapping *map = &mod->arch.map[i]; 288 memset(maps, 0, sizeof(maps));
309 if (map->unw_sec && map->sec_text) 289
310 map->unwind = unwind_table_add(map->unw_sec->sh_addr, 290 for (s = sechdrs; s < sechdrs_end; s++) {
311 map->unw_sec->sh_size, 291 const char *secname = secstrs + s->sh_name;
312 map->sec_text->sh_addr, 292
313 map->sec_text->sh_size); 293 if (!(s->sh_flags & SHF_ALLOC))
294 continue;
295
296 if (strcmp(".ARM.exidx.init.text", secname) == 0)
297 maps[ARM_SEC_INIT].unw_sec = s;
298 else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
299 maps[ARM_SEC_DEVINIT].unw_sec = s;
300 else if (strcmp(".ARM.exidx", secname) == 0)
301 maps[ARM_SEC_CORE].unw_sec = s;
302 else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
303 maps[ARM_SEC_EXIT].unw_sec = s;
304 else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
305 maps[ARM_SEC_DEVEXIT].unw_sec = s;
306 else if (strcmp(".init.text", secname) == 0)
307 maps[ARM_SEC_INIT].txt_sec = s;
308 else if (strcmp(".devinit.text", secname) == 0)
309 maps[ARM_SEC_DEVINIT].txt_sec = s;
310 else if (strcmp(".text", secname) == 0)
311 maps[ARM_SEC_CORE].txt_sec = s;
312 else if (strcmp(".exit.text", secname) == 0)
313 maps[ARM_SEC_EXIT].txt_sec = s;
314 else if (strcmp(".devexit.text", secname) == 0)
315 maps[ARM_SEC_DEVEXIT].txt_sec = s;
314 } 316 }
315}
316 317
317static void unregister_unwind_tables(struct module *mod) 318 for (i = 0; i < ARM_SEC_MAX; i++)
318{ 319 if (maps[i].unw_sec && maps[i].txt_sec)
319 int i = ARM_SEC_MAX; 320 mod->arch.unwind[i] =
320 while (--i >= 0) 321 unwind_table_add(maps[i].unw_sec->sh_addr,
321 unwind_table_del(mod->arch.map[i].unwind); 322 maps[i].unw_sec->sh_size,
322} 323 maps[i].txt_sec->sh_addr,
323#else 324 maps[i].txt_sec->sh_size);
324static inline void register_unwind_tables(struct module *mod) { }
325static inline void unregister_unwind_tables(struct module *mod) { }
326#endif 325#endif
327
328int
329module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
330 struct module *module)
331{
332 register_unwind_tables(module);
333 return 0; 326 return 0;
334} 327}
335 328
336void 329void
337module_arch_cleanup(struct module *mod) 330module_arch_cleanup(struct module *mod)
338{ 331{
339 unregister_unwind_tables(mod); 332#ifdef CONFIG_ARM_UNWIND
333 int i;
334
335 for (i = 0; i < ARM_SEC_MAX; i++)
336 if (mod->arch.unwind[i])
337 unwind_table_del(mod->arch.unwind[i]);
338#endif
340} 339}
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
new file mode 100644
index 00000000000..2cdcc9287c7
--- /dev/null
+++ b/arch/arm/kernel/sched_clock.c
@@ -0,0 +1,69 @@
1/*
2 * sched_clock.c: support for extending counters to full 64-bit ns counter
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 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/clocksource.h>
9#include <linux/init.h>
10#include <linux/jiffies.h>
11#include <linux/kernel.h>
12#include <linux/sched.h>
13#include <linux/timer.h>
14
15#include <asm/sched_clock.h>
16
17static void sched_clock_poll(unsigned long wrap_ticks);
18static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
19static void (*sched_clock_update_fn)(void);
20
21static void sched_clock_poll(unsigned long wrap_ticks)
22{
23 mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
24 sched_clock_update_fn();
25}
26
27void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
28 unsigned int clock_bits, unsigned long rate)
29{
30 unsigned long r, w;
31 u64 res, wrap;
32 char r_unit;
33
34 sched_clock_update_fn = update;
35
36 /* calculate the mult/shift to convert counter ticks to ns. */
37 clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 60);
38
39 r = rate;
40 if (r >= 4000000) {
41 r /= 1000000;
42 r_unit = 'M';
43 } else {
44 r /= 1000;
45 r_unit = 'k';
46 }
47
48 /* calculate how many ns until we wrap */
49 wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift);
50 do_div(wrap, NSEC_PER_MSEC);
51 w = wrap;
52
53 /* calculate the ns resolution of this counter */
54 res = cyc_to_ns(1ULL, cd->mult, cd->shift);
55 pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
56 clock_bits, r, r_unit, res, w);
57
58 /*
59 * Start the timer to keep sched_clock() properly updated and
60 * sets the initial epoch.
61 */
62 sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
63 sched_clock_poll(sched_clock_timer.data);
64
65 /*
66 * Ensure that sched_clock() starts off at 0ns
67 */
68 cd->epoch_ns = 0;
69}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 336f14e0e5c..3455ad33de4 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -75,9 +75,9 @@ extern void reboot_setup(char *str);
75 75
76unsigned int processor_id; 76unsigned int processor_id;
77EXPORT_SYMBOL(processor_id); 77EXPORT_SYMBOL(processor_id);
78unsigned int __machine_arch_type; 78unsigned int __machine_arch_type __read_mostly;
79EXPORT_SYMBOL(__machine_arch_type); 79EXPORT_SYMBOL(__machine_arch_type);
80unsigned int cacheid; 80unsigned int cacheid __read_mostly;
81EXPORT_SYMBOL(cacheid); 81EXPORT_SYMBOL(cacheid);
82 82
83unsigned int __atags_pointer __initdata; 83unsigned int __atags_pointer __initdata;
@@ -91,24 +91,24 @@ EXPORT_SYMBOL(system_serial_low);
91unsigned int system_serial_high; 91unsigned int system_serial_high;
92EXPORT_SYMBOL(system_serial_high); 92EXPORT_SYMBOL(system_serial_high);
93 93
94unsigned int elf_hwcap; 94unsigned int elf_hwcap __read_mostly;
95EXPORT_SYMBOL(elf_hwcap); 95EXPORT_SYMBOL(elf_hwcap);
96 96
97 97
98#ifdef MULTI_CPU 98#ifdef MULTI_CPU
99struct processor processor; 99struct processor processor __read_mostly;
100#endif 100#endif
101#ifdef MULTI_TLB 101#ifdef MULTI_TLB
102struct cpu_tlb_fns cpu_tlb; 102struct cpu_tlb_fns cpu_tlb __read_mostly;
103#endif 103#endif
104#ifdef MULTI_USER 104#ifdef MULTI_USER
105struct cpu_user_fns cpu_user; 105struct cpu_user_fns cpu_user __read_mostly;
106#endif 106#endif
107#ifdef MULTI_CACHE 107#ifdef MULTI_CACHE
108struct cpu_cache_fns cpu_cache; 108struct cpu_cache_fns cpu_cache __read_mostly;
109#endif 109#endif
110#ifdef CONFIG_OUTER_CACHE 110#ifdef CONFIG_OUTER_CACHE
111struct outer_cache_fns outer_cache; 111struct outer_cache_fns outer_cache __read_mostly;
112EXPORT_SYMBOL(outer_cache); 112EXPORT_SYMBOL(outer_cache);
113#endif 113#endif
114 114
@@ -126,6 +126,7 @@ EXPORT_SYMBOL(elf_platform);
126static const char *cpu_name; 126static const char *cpu_name;
127static const char *machine_name; 127static const char *machine_name;
128static char __initdata cmd_line[COMMAND_LINE_SIZE]; 128static char __initdata cmd_line[COMMAND_LINE_SIZE];
129struct machine_desc *machine_desc __initdata;
129 130
130static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; 131static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
131static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; 132static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -708,13 +709,11 @@ static struct init_tags {
708 { 0, ATAG_NONE } 709 { 0, ATAG_NONE }
709}; 710};
710 711
711static void (*init_machine)(void) __initdata;
712
713static int __init customize_machine(void) 712static int __init customize_machine(void)
714{ 713{
715 /* customizes platform devices, or adds new ones */ 714 /* customizes platform devices, or adds new ones */
716 if (init_machine) 715 if (machine_desc->init_machine)
717 init_machine(); 716 machine_desc->init_machine();
718 return 0; 717 return 0;
719} 718}
720arch_initcall(customize_machine); 719arch_initcall(customize_machine);
@@ -809,6 +808,7 @@ void __init setup_arch(char **cmdline_p)
809 808
810 setup_processor(); 809 setup_processor();
811 mdesc = setup_machine(machine_arch_type); 810 mdesc = setup_machine(machine_arch_type);
811 machine_desc = mdesc;
812 machine_name = mdesc->name; 812 machine_name = mdesc->name;
813 813
814 if (mdesc->soft_reboot) 814 if (mdesc->soft_reboot)
@@ -868,13 +868,9 @@ void __init setup_arch(char **cmdline_p)
868 cpu_init(); 868 cpu_init();
869 tcm_init(); 869 tcm_init();
870 870
871 /* 871#ifdef CONFIG_MULTI_IRQ_HANDLER
872 * Set up various architecture-specific pointers 872 handle_arch_irq = mdesc->handle_irq;
873 */ 873#endif
874 arch_nr_irqs = mdesc->nr_irqs;
875 init_arch_irq = mdesc->init_irq;
876 system_timer = mdesc->timer;
877 init_machine = mdesc->init_machine;
878 874
879#ifdef CONFIG_VT 875#ifdef CONFIG_VT
880#if defined(CONFIG_VGA_CONSOLE) 876#if defined(CONFIG_VGA_CONSOLE)
@@ -884,6 +880,9 @@ void __init setup_arch(char **cmdline_p)
884#endif 880#endif
885#endif 881#endif
886 early_trap_init(); 882 early_trap_init();
883
884 if (mdesc->init_early)
885 mdesc->init_early();
887} 886}
888 887
889 888
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index bbca89872c1..4539ebcb089 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -25,6 +25,7 @@
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/percpu.h> 26#include <linux/percpu.h>
27#include <linux/clockchips.h> 27#include <linux/clockchips.h>
28#include <linux/completion.h>
28 29
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/cacheflush.h> 31#include <asm/cacheflush.h>
@@ -38,7 +39,6 @@
38#include <asm/tlbflush.h> 39#include <asm/tlbflush.h>
39#include <asm/ptrace.h> 40#include <asm/ptrace.h>
40#include <asm/localtimer.h> 41#include <asm/localtimer.h>
41#include <asm/smp_plat.h>
42 42
43/* 43/*
44 * as from 2.5, kernels no longer have an init_tasks structure 44 * as from 2.5, kernels no longer have an init_tasks structure
@@ -47,64 +47,14 @@
47 */ 47 */
48struct secondary_data secondary_data; 48struct secondary_data secondary_data;
49 49
50/*
51 * structures for inter-processor calls
52 * - A collection of single bit ipi messages.
53 */
54struct ipi_data {
55 spinlock_t lock;
56 unsigned long ipi_count;
57 unsigned long bits;
58};
59
60static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
61 .lock = SPIN_LOCK_UNLOCKED,
62};
63
64enum ipi_msg_type { 50enum ipi_msg_type {
65 IPI_TIMER, 51 IPI_TIMER = 2,
66 IPI_RESCHEDULE, 52 IPI_RESCHEDULE,
67 IPI_CALL_FUNC, 53 IPI_CALL_FUNC,
68 IPI_CALL_FUNC_SINGLE, 54 IPI_CALL_FUNC_SINGLE,
69 IPI_CPU_STOP, 55 IPI_CPU_STOP,
70}; 56};
71 57
72static inline void identity_mapping_add(pgd_t *pgd, unsigned long start,
73 unsigned long end)
74{
75 unsigned long addr, prot;
76 pmd_t *pmd;
77
78 prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
79 if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
80 prot |= PMD_BIT4;
81
82 for (addr = start & PGDIR_MASK; addr < end;) {
83 pmd = pmd_offset(pgd + pgd_index(addr), addr);
84 pmd[0] = __pmd(addr | prot);
85 addr += SECTION_SIZE;
86 pmd[1] = __pmd(addr | prot);
87 addr += SECTION_SIZE;
88 flush_pmd_entry(pmd);
89 outer_clean_range(__pa(pmd), __pa(pmd + 1));
90 }
91}
92
93static inline void identity_mapping_del(pgd_t *pgd, unsigned long start,
94 unsigned long end)
95{
96 unsigned long addr;
97 pmd_t *pmd;
98
99 for (addr = start & PGDIR_MASK; addr < end; addr += PGDIR_SIZE) {
100 pmd = pmd_offset(pgd + pgd_index(addr), addr);
101 pmd[0] = __pmd(0);
102 pmd[1] = __pmd(0);
103 clean_pmd_entry(pmd);
104 outer_clean_range(__pa(pmd), __pa(pmd + 1));
105 }
106}
107
108int __cpuinit __cpu_up(unsigned int cpu) 58int __cpuinit __cpu_up(unsigned int cpu)
109{ 59{
110 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); 60 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
@@ -178,8 +128,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
178 barrier(); 128 barrier();
179 } 129 }
180 130
181 if (!cpu_online(cpu)) 131 if (!cpu_online(cpu)) {
132 pr_crit("CPU%u: failed to come online\n", cpu);
182 ret = -EIO; 133 ret = -EIO;
134 }
135 } else {
136 pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
183 } 137 }
184 138
185 secondary_data.stack = NULL; 139 secondary_data.stack = NULL;
@@ -195,18 +149,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
195 149
196 pgd_free(&init_mm, pgd); 150 pgd_free(&init_mm, pgd);
197 151
198 if (ret) {
199 printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
200
201 /*
202 * FIXME: We need to clean up the new idle thread. --rmk
203 */
204 }
205
206 return ret; 152 return ret;
207} 153}
208 154
209#ifdef CONFIG_HOTPLUG_CPU 155#ifdef CONFIG_HOTPLUG_CPU
156static void percpu_timer_stop(void);
157
210/* 158/*
211 * __cpu_disable runs on the processor to be shutdown. 159 * __cpu_disable runs on the processor to be shutdown.
212 */ 160 */
@@ -234,7 +182,7 @@ int __cpu_disable(void)
234 /* 182 /*
235 * Stop the local timer for this CPU. 183 * Stop the local timer for this CPU.
236 */ 184 */
237 local_timer_stop(); 185 percpu_timer_stop();
238 186
239 /* 187 /*
240 * Flush user cache and TLB mappings, and then remove this CPU 188 * Flush user cache and TLB mappings, and then remove this CPU
@@ -253,12 +201,20 @@ int __cpu_disable(void)
253 return 0; 201 return 0;
254} 202}
255 203
204static DECLARE_COMPLETION(cpu_died);
205
256/* 206/*
257 * called on the thread which is asking for a CPU to be shutdown - 207 * called on the thread which is asking for a CPU to be shutdown -
258 * waits until shutdown has completed, or it is timed out. 208 * waits until shutdown has completed, or it is timed out.
259 */ 209 */
260void __cpu_die(unsigned int cpu) 210void __cpu_die(unsigned int cpu)
261{ 211{
212 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
213 pr_err("CPU%u: cpu didn't die\n", cpu);
214 return;
215 }
216 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
217
262 if (!platform_cpu_kill(cpu)) 218 if (!platform_cpu_kill(cpu))
263 printk("CPU%u: unable to kill\n", cpu); 219 printk("CPU%u: unable to kill\n", cpu);
264} 220}
@@ -275,12 +231,17 @@ void __ref cpu_die(void)
275{ 231{
276 unsigned int cpu = smp_processor_id(); 232 unsigned int cpu = smp_processor_id();
277 233
278 local_irq_disable();
279 idle_task_exit(); 234 idle_task_exit();
280 235
236 local_irq_disable();
237 mb();
238
239 /* Tell __cpu_die() that this CPU is now safe to dispose of */
240 complete(&cpu_died);
241
281 /* 242 /*
282 * actual CPU shutdown procedure is at least platform (if not 243 * actual CPU shutdown procedure is at least platform (if not
283 * CPU) specific 244 * CPU) specific.
284 */ 245 */
285 platform_cpu_die(cpu); 246 platform_cpu_die(cpu);
286 247
@@ -290,6 +251,7 @@ void __ref cpu_die(void)
290 * to be repeated to undo the effects of taking the CPU offline. 251 * to be repeated to undo the effects of taking the CPU offline.
291 */ 252 */
292 __asm__("mov sp, %0\n" 253 __asm__("mov sp, %0\n"
254 " mov fp, #0\n"
293 " b secondary_start_kernel" 255 " b secondary_start_kernel"
294 : 256 :
295 : "r" (task_stack_page(current) + THREAD_SIZE - 8)); 257 : "r" (task_stack_page(current) + THREAD_SIZE - 8));
@@ -297,6 +259,17 @@ void __ref cpu_die(void)
297#endif /* CONFIG_HOTPLUG_CPU */ 259#endif /* CONFIG_HOTPLUG_CPU */
298 260
299/* 261/*
262 * Called by both boot and secondaries to move global data into
263 * per-processor storage.
264 */
265static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
266{
267 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
268
269 cpu_info->loops_per_jiffy = loops_per_jiffy;
270}
271
272/*
300 * This is the secondary CPU boot entry. We're using this CPUs 273 * This is the secondary CPU boot entry. We're using this CPUs
301 * idle thread stack, but a set of temporary page tables. 274 * idle thread stack, but a set of temporary page tables.
302 */ 275 */
@@ -311,7 +284,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
311 * All kernel threads share the same mm context; grab a 284 * All kernel threads share the same mm context; grab a
312 * reference and switch to it. 285 * reference and switch to it.
313 */ 286 */
314 atomic_inc(&mm->mm_users);
315 atomic_inc(&mm->mm_count); 287 atomic_inc(&mm->mm_count);
316 current->active_mm = mm; 288 current->active_mm = mm;
317 cpumask_set_cpu(cpu, mm_cpumask(mm)); 289 cpumask_set_cpu(cpu, mm_cpumask(mm));
@@ -321,6 +293,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
321 293
322 cpu_init(); 294 cpu_init();
323 preempt_disable(); 295 preempt_disable();
296 trace_hardirqs_off();
324 297
325 /* 298 /*
326 * Give the platform a chance to do its own initialisation. 299 * Give the platform a chance to do its own initialisation.
@@ -354,17 +327,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
354 cpu_idle(); 327 cpu_idle();
355} 328}
356 329
357/*
358 * Called by both boot and secondaries to move global data into
359 * per-processor storage.
360 */
361void __cpuinit smp_store_cpu_info(unsigned int cpuid)
362{
363 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
364
365 cpu_info->loops_per_jiffy = loops_per_jiffy;
366}
367
368void __init smp_cpus_done(unsigned int max_cpus) 330void __init smp_cpus_done(unsigned int max_cpus)
369{ 331{
370 int cpu; 332 int cpu;
@@ -387,61 +349,80 @@ void __init smp_prepare_boot_cpu(void)
387 per_cpu(cpu_data, cpu).idle = current; 349 per_cpu(cpu_data, cpu).idle = current;
388} 350}
389 351
390static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) 352void __init smp_prepare_cpus(unsigned int max_cpus)
391{ 353{
392 unsigned long flags; 354 unsigned int ncores = num_possible_cpus();
393 unsigned int cpu;
394 355
395 local_irq_save(flags); 356 smp_store_cpu_info(smp_processor_id());
396
397 for_each_cpu(cpu, mask) {
398 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
399
400 spin_lock(&ipi->lock);
401 ipi->bits |= 1 << msg;
402 spin_unlock(&ipi->lock);
403 }
404 357
405 /* 358 /*
406 * Call the platform specific cross-CPU call function. 359 * are we trying to boot more cores than exist?
407 */ 360 */
408 smp_cross_call(mask); 361 if (max_cpus > ncores)
362 max_cpus = ncores;
363
364 if (max_cpus > 1) {
365 /*
366 * Enable the local timer or broadcast device for the
367 * boot CPU, but only if we have more than one CPU.
368 */
369 percpu_timer_setup();
409 370
410 local_irq_restore(flags); 371 /*
372 * Initialise the SCU if there are more than one CPU
373 * and let them know where to start.
374 */
375 platform_smp_prepare_cpus(max_cpus);
376 }
411} 377}
412 378
413void arch_send_call_function_ipi_mask(const struct cpumask *mask) 379void arch_send_call_function_ipi_mask(const struct cpumask *mask)
414{ 380{
415 send_ipi_message(mask, IPI_CALL_FUNC); 381 smp_cross_call(mask, IPI_CALL_FUNC);
416} 382}
417 383
418void arch_send_call_function_single_ipi(int cpu) 384void arch_send_call_function_single_ipi(int cpu)
419{ 385{
420 send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); 386 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
421} 387}
422 388
423void show_ipi_list(struct seq_file *p) 389static const char *ipi_types[NR_IPI] = {
390#define S(x,s) [x - IPI_TIMER] = s
391 S(IPI_TIMER, "Timer broadcast interrupts"),
392 S(IPI_RESCHEDULE, "Rescheduling interrupts"),
393 S(IPI_CALL_FUNC, "Function call interrupts"),
394 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
395 S(IPI_CPU_STOP, "CPU stop interrupts"),
396};
397
398void show_ipi_list(struct seq_file *p, int prec)
424{ 399{
425 unsigned int cpu; 400 unsigned int cpu, i;
426 401
427 seq_puts(p, "IPI:"); 402 for (i = 0; i < NR_IPI; i++) {
403 seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
428 404
429 for_each_present_cpu(cpu) 405 for_each_present_cpu(cpu)
430 seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count); 406 seq_printf(p, "%10u ",
407 __get_irq_stat(cpu, ipi_irqs[i]));
431 408
432 seq_putc(p, '\n'); 409 seq_printf(p, " %s\n", ipi_types[i]);
410 }
433} 411}
434 412
435void show_local_irqs(struct seq_file *p) 413u64 smp_irq_stat_cpu(unsigned int cpu)
436{ 414{
437 unsigned int cpu; 415 u64 sum = 0;
416 int i;
438 417
439 seq_printf(p, "LOC: "); 418 for (i = 0; i < NR_IPI; i++)
419 sum += __get_irq_stat(cpu, ipi_irqs[i]);
440 420
441 for_each_present_cpu(cpu) 421#ifdef CONFIG_LOCAL_TIMERS
442 seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs); 422 sum += __get_irq_stat(cpu, local_timer_irqs);
423#endif
443 424
444 seq_putc(p, '\n'); 425 return sum;
445} 426}
446 427
447/* 428/*
@@ -464,18 +445,30 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
464 int cpu = smp_processor_id(); 445 int cpu = smp_processor_id();
465 446
466 if (local_timer_ack()) { 447 if (local_timer_ack()) {
467 irq_stat[cpu].local_timer_irqs++; 448 __inc_irq_stat(cpu, local_timer_irqs);
468 ipi_timer(); 449 ipi_timer();
469 } 450 }
470 451
471 set_irq_regs(old_regs); 452 set_irq_regs(old_regs);
472} 453}
454
455void show_local_irqs(struct seq_file *p, int prec)
456{
457 unsigned int cpu;
458
459 seq_printf(p, "%*s: ", prec, "LOC");
460
461 for_each_present_cpu(cpu)
462 seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
463
464 seq_printf(p, " Local timer interrupts\n");
465}
473#endif 466#endif
474 467
475#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 468#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
476static void smp_timer_broadcast(const struct cpumask *mask) 469static void smp_timer_broadcast(const struct cpumask *mask)
477{ 470{
478 send_ipi_message(mask, IPI_TIMER); 471 smp_cross_call(mask, IPI_TIMER);
479} 472}
480#else 473#else
481#define smp_timer_broadcast NULL 474#define smp_timer_broadcast NULL
@@ -512,6 +505,21 @@ void __cpuinit percpu_timer_setup(void)
512 local_timer_setup(evt); 505 local_timer_setup(evt);
513} 506}
514 507
508#ifdef CONFIG_HOTPLUG_CPU
509/*
510 * The generic clock events code purposely does not stop the local timer
511 * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
512 * manually here.
513 */
514static void percpu_timer_stop(void)
515{
516 unsigned int cpu = smp_processor_id();
517 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
518
519 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
520}
521#endif
522
515static DEFINE_SPINLOCK(stop_lock); 523static DEFINE_SPINLOCK(stop_lock);
516 524
517/* 525/*
@@ -538,216 +546,76 @@ static void ipi_cpu_stop(unsigned int cpu)
538 546
539/* 547/*
540 * Main handler for inter-processor interrupts 548 * Main handler for inter-processor interrupts
541 *
542 * For ARM, the ipimask now only identifies a single
543 * category of IPI (Bit 1 IPIs have been replaced by a
544 * different mechanism):
545 *
546 * Bit 0 - Inter-processor function call
547 */ 549 */
548asmlinkage void __exception_irq_entry do_IPI(struct pt_regs *regs) 550asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
549{ 551{
550 unsigned int cpu = smp_processor_id(); 552 unsigned int cpu = smp_processor_id();
551 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
552 struct pt_regs *old_regs = set_irq_regs(regs); 553 struct pt_regs *old_regs = set_irq_regs(regs);
553 554
554 ipi->ipi_count++; 555 if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
555 556 __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
556 for (;;) {
557 unsigned long msgs;
558
559 spin_lock(&ipi->lock);
560 msgs = ipi->bits;
561 ipi->bits = 0;
562 spin_unlock(&ipi->lock);
563 557
564 if (!msgs) 558 switch (ipinr) {
565 break; 559 case IPI_TIMER:
566 560 ipi_timer();
567 do { 561 break;
568 unsigned nextmsg;
569
570 nextmsg = msgs & -msgs;
571 msgs &= ~nextmsg;
572 nextmsg = ffz(~nextmsg);
573
574 switch (nextmsg) {
575 case IPI_TIMER:
576 ipi_timer();
577 break;
578 562
579 case IPI_RESCHEDULE: 563 case IPI_RESCHEDULE:
580 /* 564 /*
581 * nothing more to do - eveything is 565 * nothing more to do - eveything is
582 * done on the interrupt return path 566 * done on the interrupt return path
583 */ 567 */
584 break; 568 break;
585 569
586 case IPI_CALL_FUNC: 570 case IPI_CALL_FUNC:
587 generic_smp_call_function_interrupt(); 571 generic_smp_call_function_interrupt();
588 break; 572 break;
589 573
590 case IPI_CALL_FUNC_SINGLE: 574 case IPI_CALL_FUNC_SINGLE:
591 generic_smp_call_function_single_interrupt(); 575 generic_smp_call_function_single_interrupt();
592 break; 576 break;
593 577
594 case IPI_CPU_STOP: 578 case IPI_CPU_STOP:
595 ipi_cpu_stop(cpu); 579 ipi_cpu_stop(cpu);
596 break; 580 break;
597 581
598 default: 582 default:
599 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", 583 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
600 cpu, nextmsg); 584 cpu, ipinr);
601 break; 585 break;
602 }
603 } while (msgs);
604 } 586 }
605
606 set_irq_regs(old_regs); 587 set_irq_regs(old_regs);
607} 588}
608 589
609void smp_send_reschedule(int cpu) 590void smp_send_reschedule(int cpu)
610{ 591{
611 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); 592 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
612} 593}
613 594
614void smp_send_stop(void) 595void smp_send_stop(void)
615{ 596{
616 cpumask_t mask = cpu_online_map; 597 unsigned long timeout;
617 cpu_clear(smp_processor_id(), mask);
618 if (!cpus_empty(mask))
619 send_ipi_message(&mask, IPI_CPU_STOP);
620}
621 598
622/* 599 if (num_online_cpus() > 1) {
623 * not supported here 600 cpumask_t mask = cpu_online_map;
624 */ 601 cpu_clear(smp_processor_id(), mask);
625int setup_profiling_timer(unsigned int multiplier)
626{
627 return -EINVAL;
628}
629 602
630static void 603 smp_cross_call(&mask, IPI_CPU_STOP);
631on_each_cpu_mask(void (*func)(void *), void *info, int wait, 604 }
632 const struct cpumask *mask)
633{
634 preempt_disable();
635 605
636 smp_call_function_many(mask, func, info, wait); 606 /* Wait up to one second for other CPUs to stop */
637 if (cpumask_test_cpu(smp_processor_id(), mask)) 607 timeout = USEC_PER_SEC;
638 func(info); 608 while (num_online_cpus() > 1 && timeout--)
609 udelay(1);
639 610
640 preempt_enable(); 611 if (num_online_cpus() > 1)
612 pr_warning("SMP: failed to stop secondary CPUs\n");
641} 613}
642 614
643/**********************************************************************/
644
645/* 615/*
646 * TLB operations 616 * not supported here
647 */ 617 */
648struct tlb_args { 618int setup_profiling_timer(unsigned int multiplier)
649 struct vm_area_struct *ta_vma;
650 unsigned long ta_start;
651 unsigned long ta_end;
652};
653
654static inline void ipi_flush_tlb_all(void *ignored)
655{
656 local_flush_tlb_all();
657}
658
659static inline void ipi_flush_tlb_mm(void *arg)
660{
661 struct mm_struct *mm = (struct mm_struct *)arg;
662
663 local_flush_tlb_mm(mm);
664}
665
666static inline void ipi_flush_tlb_page(void *arg)
667{
668 struct tlb_args *ta = (struct tlb_args *)arg;
669
670 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
671}
672
673static inline void ipi_flush_tlb_kernel_page(void *arg)
674{
675 struct tlb_args *ta = (struct tlb_args *)arg;
676
677 local_flush_tlb_kernel_page(ta->ta_start);
678}
679
680static inline void ipi_flush_tlb_range(void *arg)
681{
682 struct tlb_args *ta = (struct tlb_args *)arg;
683
684 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
685}
686
687static inline void ipi_flush_tlb_kernel_range(void *arg)
688{
689 struct tlb_args *ta = (struct tlb_args *)arg;
690
691 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
692}
693
694void flush_tlb_all(void)
695{
696 if (tlb_ops_need_broadcast())
697 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
698 else
699 local_flush_tlb_all();
700}
701
702void flush_tlb_mm(struct mm_struct *mm)
703{
704 if (tlb_ops_need_broadcast())
705 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
706 else
707 local_flush_tlb_mm(mm);
708}
709
710void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
711{
712 if (tlb_ops_need_broadcast()) {
713 struct tlb_args ta;
714 ta.ta_vma = vma;
715 ta.ta_start = uaddr;
716 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
717 } else
718 local_flush_tlb_page(vma, uaddr);
719}
720
721void flush_tlb_kernel_page(unsigned long kaddr)
722{
723 if (tlb_ops_need_broadcast()) {
724 struct tlb_args ta;
725 ta.ta_start = kaddr;
726 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
727 } else
728 local_flush_tlb_kernel_page(kaddr);
729}
730
731void flush_tlb_range(struct vm_area_struct *vma,
732 unsigned long start, unsigned long end)
733{
734 if (tlb_ops_need_broadcast()) {
735 struct tlb_args ta;
736 ta.ta_vma = vma;
737 ta.ta_start = start;
738 ta.ta_end = end;
739 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
740 } else
741 local_flush_tlb_range(vma, start, end);
742}
743
744void flush_tlb_kernel_range(unsigned long start, unsigned long end)
745{ 619{
746 if (tlb_ops_need_broadcast()) { 620 return -EINVAL;
747 struct tlb_args ta;
748 ta.ta_start = start;
749 ta.ta_end = end;
750 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
751 } else
752 local_flush_tlb_kernel_range(start, end);
753} 621}
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
new file mode 100644
index 00000000000..7dcb35285be
--- /dev/null
+++ b/arch/arm/kernel/smp_tlb.c
@@ -0,0 +1,139 @@
1/*
2 * linux/arch/arm/kernel/smp_tlb.c
3 *
4 * Copyright (C) 2002 ARM Limited, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/preempt.h>
11#include <linux/smp.h>
12
13#include <asm/smp_plat.h>
14#include <asm/tlbflush.h>
15
16static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
17 const struct cpumask *mask)
18{
19 preempt_disable();
20
21 smp_call_function_many(mask, func, info, wait);
22 if (cpumask_test_cpu(smp_processor_id(), mask))
23 func(info);
24
25 preempt_enable();
26}
27
28/**********************************************************************/
29
30/*
31 * TLB operations
32 */
33struct tlb_args {
34 struct vm_area_struct *ta_vma;
35 unsigned long ta_start;
36 unsigned long ta_end;
37};
38
39static inline void ipi_flush_tlb_all(void *ignored)
40{
41 local_flush_tlb_all();
42}
43
44static inline void ipi_flush_tlb_mm(void *arg)
45{
46 struct mm_struct *mm = (struct mm_struct *)arg;
47
48 local_flush_tlb_mm(mm);
49}
50
51static inline void ipi_flush_tlb_page(void *arg)
52{
53 struct tlb_args *ta = (struct tlb_args *)arg;
54
55 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
56}
57
58static inline void ipi_flush_tlb_kernel_page(void *arg)
59{
60 struct tlb_args *ta = (struct tlb_args *)arg;
61
62 local_flush_tlb_kernel_page(ta->ta_start);
63}
64
65static inline void ipi_flush_tlb_range(void *arg)
66{
67 struct tlb_args *ta = (struct tlb_args *)arg;
68
69 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
70}
71
72static inline void ipi_flush_tlb_kernel_range(void *arg)
73{
74 struct tlb_args *ta = (struct tlb_args *)arg;
75
76 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
77}
78
79void flush_tlb_all(void)
80{
81 if (tlb_ops_need_broadcast())
82 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
83 else
84 local_flush_tlb_all();
85}
86
87void flush_tlb_mm(struct mm_struct *mm)
88{
89 if (tlb_ops_need_broadcast())
90 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
91 else
92 local_flush_tlb_mm(mm);
93}
94
95void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
96{
97 if (tlb_ops_need_broadcast()) {
98 struct tlb_args ta;
99 ta.ta_vma = vma;
100 ta.ta_start = uaddr;
101 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
102 } else
103 local_flush_tlb_page(vma, uaddr);
104}
105
106void flush_tlb_kernel_page(unsigned long kaddr)
107{
108 if (tlb_ops_need_broadcast()) {
109 struct tlb_args ta;
110 ta.ta_start = kaddr;
111 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
112 } else
113 local_flush_tlb_kernel_page(kaddr);
114}
115
116void flush_tlb_range(struct vm_area_struct *vma,
117 unsigned long start, unsigned long end)
118{
119 if (tlb_ops_need_broadcast()) {
120 struct tlb_args ta;
121 ta.ta_vma = vma;
122 ta.ta_start = start;
123 ta.ta_end = end;
124 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
125 } else
126 local_flush_tlb_range(vma, start, end);
127}
128
129void flush_tlb_kernel_range(unsigned long start, unsigned long end)
130{
131 if (tlb_ops_need_broadcast()) {
132 struct tlb_args ta;
133 ta.ta_start = start;
134 ta.ta_end = end;
135 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
136 } else
137 local_flush_tlb_kernel_range(start, end);
138}
139
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 35882fbf37f..dd790745b3e 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -127,8 +127,6 @@ static void __cpuinit twd_calibrate_rate(void)
127 */ 127 */
128void __cpuinit twd_timer_setup(struct clock_event_device *clk) 128void __cpuinit twd_timer_setup(struct clock_event_device *clk)
129{ 129{
130 unsigned long flags;
131
132 twd_calibrate_rate(); 130 twd_calibrate_rate();
133 131
134 clk->name = "local_timer"; 132 clk->name = "local_timer";
@@ -143,20 +141,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
143 clk->min_delta_ns = clockevent_delta2ns(0xf, clk); 141 clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
144 142
145 /* Make sure our local interrupt controller has this enabled */ 143 /* Make sure our local interrupt controller has this enabled */
146 local_irq_save(flags); 144 gic_enable_ppi(clk->irq);
147 irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
148 get_irq_chip(clk->irq)->unmask(clk->irq);
149 local_irq_restore(flags);
150 145
151 clockevents_register_device(clk); 146 clockevents_register_device(clk);
152} 147}
153
154#ifdef CONFIG_HOTPLUG_CPU
155/*
156 * take a local timer down
157 */
158void twd_timer_stop(void)
159{
160 __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
161}
162#endif
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
new file mode 100644
index 00000000000..7a576092291
--- /dev/null
+++ b/arch/arm/kernel/swp_emulate.c
@@ -0,0 +1,267 @@
1/*
2 * linux/arch/arm/kernel/swp_emulate.c
3 *
4 * Copyright (C) 2009 ARM Limited
5 * __user_* functions adapted from include/asm/uaccess.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Implements emulation of the SWP/SWPB instructions using load-exclusive and
12 * store-exclusive for processors that have them disabled (or future ones that
13 * might not implement them).
14 *
15 * Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
16 * Where: Rt = destination
17 * Rt2 = source
18 * Rn = address
19 */
20
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/proc_fs.h>
24#include <linux/sched.h>
25#include <linux/syscalls.h>
26#include <linux/perf_event.h>
27
28#include <asm/traps.h>
29#include <asm/uaccess.h>
30
31/*
32 * Error-checking SWP macros implemented using ldrex{b}/strex{b}
33 */
34#define __user_swpX_asm(data, addr, res, temp, B) \
35 __asm__ __volatile__( \
36 " mov %2, %1\n" \
37 "0: ldrex"B" %1, [%3]\n" \
38 "1: strex"B" %0, %2, [%3]\n" \
39 " cmp %0, #0\n" \
40 " movne %0, %4\n" \
41 "2:\n" \
42 " .section .fixup,\"ax\"\n" \
43 " .align 2\n" \
44 "3: mov %0, %5\n" \
45 " b 2b\n" \
46 " .previous\n" \
47 " .section __ex_table,\"a\"\n" \
48 " .align 3\n" \
49 " .long 0b, 3b\n" \
50 " .long 1b, 3b\n" \
51 " .previous" \
52 : "=&r" (res), "+r" (data), "=&r" (temp) \
53 : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
54 : "cc", "memory")
55
56#define __user_swp_asm(data, addr, res, temp) \
57 __user_swpX_asm(data, addr, res, temp, "")
58#define __user_swpb_asm(data, addr, res, temp) \
59 __user_swpX_asm(data, addr, res, temp, "b")
60
61/*
62 * Macros/defines for extracting register numbers from instruction.
63 */
64#define EXTRACT_REG_NUM(instruction, offset) \
65 (((instruction) & (0xf << (offset))) >> (offset))
66#define RN_OFFSET 16
67#define RT_OFFSET 12
68#define RT2_OFFSET 0
69/*
70 * Bit 22 of the instruction encoding distinguishes between
71 * the SWP and SWPB variants (bit set means SWPB).
72 */
73#define TYPE_SWPB (1 << 22)
74
75static unsigned long swpcounter;
76static unsigned long swpbcounter;
77static unsigned long abtcounter;
78static pid_t previous_pid;
79
80#ifdef CONFIG_PROC_FS
81static int proc_read_status(char *page, char **start, off_t off, int count,
82 int *eof, void *data)
83{
84 char *p = page;
85 int len;
86
87 p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
88 p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
89 p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
90 if (previous_pid != 0)
91 p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
92
93 len = (p - page) - off;
94 if (len < 0)
95 len = 0;
96
97 *eof = (len <= count) ? 1 : 0;
98 *start = page + off;
99
100 return len;
101}
102#endif
103
104/*
105 * Set up process info to signal segmentation fault - called on access error.
106 */
107static void set_segfault(struct pt_regs *regs, unsigned long addr)
108{
109 siginfo_t info;
110
111 if (find_vma(current->mm, addr) == NULL)
112 info.si_code = SEGV_MAPERR;
113 else
114 info.si_code = SEGV_ACCERR;
115
116 info.si_signo = SIGSEGV;
117 info.si_errno = 0;
118 info.si_addr = (void *) instruction_pointer(regs);
119
120 pr_debug("SWP{B} emulation: access caused memory abort!\n");
121 arm_notify_die("Illegal memory access", regs, &info, 0, 0);
122
123 abtcounter++;
124}
125
126static int emulate_swpX(unsigned int address, unsigned int *data,
127 unsigned int type)
128{
129 unsigned int res = 0;
130
131 if ((type != TYPE_SWPB) && (address & 0x3)) {
132 /* SWP to unaligned address not permitted */
133 pr_debug("SWP instruction on unaligned pointer!\n");
134 return -EFAULT;
135 }
136
137 while (1) {
138 unsigned long temp;
139
140 /*
141 * Barrier required between accessing protected resource and
142 * releasing a lock for it. Legacy code might not have done
143 * this, and we cannot determine that this is not the case
144 * being emulated, so insert always.
145 */
146 smp_mb();
147
148 if (type == TYPE_SWPB)
149 __user_swpb_asm(*data, address, res, temp);
150 else
151 __user_swp_asm(*data, address, res, temp);
152
153 if (likely(res != -EAGAIN) || signal_pending(current))
154 break;
155
156 cond_resched();
157 }
158
159 if (res == 0) {
160 /*
161 * Barrier also required between aquiring a lock for a
162 * protected resource and accessing the resource. Inserted for
163 * same reason as above.
164 */
165 smp_mb();
166
167 if (type == TYPE_SWPB)
168 swpbcounter++;
169 else
170 swpcounter++;
171 }
172
173 return res;
174}
175
176/*
177 * swp_handler logs the id of calling process, dissects the instruction, sanity
178 * checks the memory location, calls emulate_swpX for the actual operation and
179 * deals with fixup/error handling before returning
180 */
181static int swp_handler(struct pt_regs *regs, unsigned int instr)
182{
183 unsigned int address, destreg, data, type;
184 unsigned int res = 0;
185
186 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, regs->ARM_pc);
187
188 if (current->pid != previous_pid) {
189 pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
190 current->comm, (unsigned long)current->pid);
191 previous_pid = current->pid;
192 }
193
194 address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
195 data = regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
196 destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
197
198 type = instr & TYPE_SWPB;
199
200 pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n",
201 EXTRACT_REG_NUM(instr, RN_OFFSET), address,
202 destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
203
204 /* Check access in reasonable access range for both SWP and SWPB */
205 if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
206 pr_debug("SWP{B} emulation: access to %p not allowed!\n",
207 (void *)address);
208 res = -EFAULT;
209 } else {
210 res = emulate_swpX(address, &data, type);
211 }
212
213 if (res == 0) {
214 /*
215 * On successful emulation, revert the adjustment to the PC
216 * made in kernel/traps.c in order to resume execution at the
217 * instruction following the SWP{B}.
218 */
219 regs->ARM_pc += 4;
220 regs->uregs[destreg] = data;
221 } else if (res == -EFAULT) {
222 /*
223 * Memory errors do not mean emulation failed.
224 * Set up signal info to return SEGV, then return OK
225 */
226 set_segfault(regs, address);
227 }
228
229 return 0;
230}
231
232/*
233 * Only emulate SWP/SWPB executed in ARM state/User mode.
234 * The kernel must be SWP free and SWP{B} does not exist in Thumb/ThumbEE.
235 */
236static struct undef_hook swp_hook = {
237 .instr_mask = 0x0fb00ff0,
238 .instr_val = 0x01000090,
239 .cpsr_mask = MODE_MASK | PSR_T_BIT | PSR_J_BIT,
240 .cpsr_val = USR_MODE,
241 .fn = swp_handler
242};
243
244/*
245 * Register handler and create status file in /proc/cpu
246 * Invoked as late_initcall, since not needed before init spawned.
247 */
248static int __init swp_emulation_init(void)
249{
250#ifdef CONFIG_PROC_FS
251 struct proc_dir_entry *res;
252
253 res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
254
255 if (!res)
256 return -ENOMEM;
257
258 res->read_proc = proc_read_status;
259#endif /* CONFIG_PROC_FS */
260
261 printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
262 register_undef_hook(&swp_hook);
263
264 return 0;
265}
266
267late_initcall(swp_emulation_init);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 38c261f9951..f1e2eb19a67 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -30,12 +30,13 @@
30#include <asm/leds.h> 30#include <asm/leds.h>
31#include <asm/thread_info.h> 31#include <asm/thread_info.h>
32#include <asm/stacktrace.h> 32#include <asm/stacktrace.h>
33#include <asm/mach/arch.h>
33#include <asm/mach/time.h> 34#include <asm/mach/time.h>
34 35
35/* 36/*
36 * Our system timer. 37 * Our system timer.
37 */ 38 */
38struct sys_timer *system_timer; 39static struct sys_timer *system_timer;
39 40
40#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 41#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
41/* this needs a better home */ 42/* this needs a better home */
@@ -160,6 +161,7 @@ device_initcall(timer_init_sysfs);
160 161
161void __init time_init(void) 162void __init time_init(void)
162{ 163{
164 system_timer = machine_desc->timer;
163 system_timer->init(); 165 system_timer->init();
164} 166}
165 167
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 446aee97436..ee57640ba2b 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -37,6 +37,8 @@
37 37
38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; 38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
39 39
40void *vectors_page;
41
40#ifdef CONFIG_DEBUG_USER 42#ifdef CONFIG_DEBUG_USER
41unsigned int user_debug; 43unsigned int user_debug;
42 44
@@ -708,19 +710,19 @@ void __readwrite_bug(const char *fn)
708} 710}
709EXPORT_SYMBOL(__readwrite_bug); 711EXPORT_SYMBOL(__readwrite_bug);
710 712
711void __pte_error(const char *file, int line, unsigned long val) 713void __pte_error(const char *file, int line, pte_t pte)
712{ 714{
713 printk("%s:%d: bad pte %08lx.\n", file, line, val); 715 printk("%s:%d: bad pte %08lx.\n", file, line, pte_val(pte));
714} 716}
715 717
716void __pmd_error(const char *file, int line, unsigned long val) 718void __pmd_error(const char *file, int line, pmd_t pmd)
717{ 719{
718 printk("%s:%d: bad pmd %08lx.\n", file, line, val); 720 printk("%s:%d: bad pmd %08lx.\n", file, line, pmd_val(pmd));
719} 721}
720 722
721void __pgd_error(const char *file, int line, unsigned long val) 723void __pgd_error(const char *file, int line, pgd_t pgd)
722{ 724{
723 printk("%s:%d: bad pgd %08lx.\n", file, line, val); 725 printk("%s:%d: bad pgd %08lx.\n", file, line, pgd_val(pgd));
724} 726}
725 727
726asmlinkage void __div0(void) 728asmlinkage void __div0(void)
@@ -756,7 +758,11 @@ static void __init kuser_get_tls_init(unsigned long vectors)
756 758
757void __init early_trap_init(void) 759void __init early_trap_init(void)
758{ 760{
761#if defined(CONFIG_CPU_USE_DOMAINS)
759 unsigned long vectors = CONFIG_VECTORS_BASE; 762 unsigned long vectors = CONFIG_VECTORS_BASE;
763#else
764 unsigned long vectors = (unsigned long)vectors_page;
765#endif
760 extern char __stubs_start[], __stubs_end[]; 766 extern char __stubs_start[], __stubs_end[];
761 extern char __vectors_start[], __vectors_end[]; 767 extern char __vectors_start[], __vectors_end[];
762 extern char __kuser_helper_start[], __kuser_helper_end[]; 768 extern char __kuser_helper_start[], __kuser_helper_end[];
@@ -780,10 +786,10 @@ void __init early_trap_init(void)
780 * Copy signal return handlers into the vector page, and 786 * Copy signal return handlers into the vector page, and
781 * set sigreturn to be a pointer to these. 787 * set sigreturn to be a pointer to these.
782 */ 788 */
783 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, 789 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
784 sizeof(sigreturn_codes)); 790 sigreturn_codes, sizeof(sigreturn_codes));
785 memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, 791 memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
786 sizeof(syscall_restart_code)); 792 syscall_restart_code, sizeof(syscall_restart_code));
787 793
788 flush_icache_range(vectors, vectors + PAGE_SIZE); 794 flush_icache_range(vectors, vectors + PAGE_SIZE);
789 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 795 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 897c1a8f169..86b66f3f203 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -168,6 +168,7 @@ SECTIONS
168 168
169 NOSAVE_DATA 169 NOSAVE_DATA
170 CACHELINE_ALIGNED_DATA(32) 170 CACHELINE_ALIGNED_DATA(32)
171 READ_MOSTLY_DATA(32)
171 172
172 /* 173 /*
173 * The exception fixup table (might need resorting at runtime) 174 * The exception fixup table (might need resorting at runtime)
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index b1631a7dbe7..1b049cd7a49 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -28,20 +28,21 @@
28 */ 28 */
29#include <linux/linkage.h> 29#include <linux/linkage.h>
30#include <asm/errno.h> 30#include <asm/errno.h>
31#include <asm/domain.h>
31 32
32ENTRY(__get_user_1) 33ENTRY(__get_user_1)
331: ldrbt r2, [r0] 341: T(ldrb) r2, [r0]
34 mov r0, #0 35 mov r0, #0
35 mov pc, lr 36 mov pc, lr
36ENDPROC(__get_user_1) 37ENDPROC(__get_user_1)
37 38
38ENTRY(__get_user_2) 39ENTRY(__get_user_2)
39#ifdef CONFIG_THUMB2_KERNEL 40#ifdef CONFIG_THUMB2_KERNEL
402: ldrbt r2, [r0] 412: T(ldrb) r2, [r0]
413: ldrbt r3, [r0, #1] 423: T(ldrb) r3, [r0, #1]
42#else 43#else
432: ldrbt r2, [r0], #1 442: T(ldrb) r2, [r0], #1
443: ldrbt r3, [r0] 453: T(ldrb) r3, [r0]
45#endif 46#endif
46#ifndef __ARMEB__ 47#ifndef __ARMEB__
47 orr r2, r2, r3, lsl #8 48 orr r2, r2, r3, lsl #8
@@ -53,7 +54,7 @@ ENTRY(__get_user_2)
53ENDPROC(__get_user_2) 54ENDPROC(__get_user_2)
54 55
55ENTRY(__get_user_4) 56ENTRY(__get_user_4)
564: ldrt r2, [r0] 574: T(ldr) r2, [r0]
57 mov r0, #0 58 mov r0, #0
58 mov pc, lr 59 mov pc, lr
59ENDPROC(__get_user_4) 60ENDPROC(__get_user_4)
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 5a01a23c6c0..c023fc11e86 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -28,9 +28,10 @@
28 */ 28 */
29#include <linux/linkage.h> 29#include <linux/linkage.h>
30#include <asm/errno.h> 30#include <asm/errno.h>
31#include <asm/domain.h>
31 32
32ENTRY(__put_user_1) 33ENTRY(__put_user_1)
331: strbt r2, [r0] 341: T(strb) r2, [r0]
34 mov r0, #0 35 mov r0, #0
35 mov pc, lr 36 mov pc, lr
36ENDPROC(__put_user_1) 37ENDPROC(__put_user_1)
@@ -39,19 +40,19 @@ ENTRY(__put_user_2)
39 mov ip, r2, lsr #8 40 mov ip, r2, lsr #8
40#ifdef CONFIG_THUMB2_KERNEL 41#ifdef CONFIG_THUMB2_KERNEL
41#ifndef __ARMEB__ 42#ifndef __ARMEB__
422: strbt r2, [r0] 432: T(strb) r2, [r0]
433: strbt ip, [r0, #1] 443: T(strb) ip, [r0, #1]
44#else 45#else
452: strbt ip, [r0] 462: T(strb) ip, [r0]
463: strbt r2, [r0, #1] 473: T(strb) r2, [r0, #1]
47#endif 48#endif
48#else /* !CONFIG_THUMB2_KERNEL */ 49#else /* !CONFIG_THUMB2_KERNEL */
49#ifndef __ARMEB__ 50#ifndef __ARMEB__
502: strbt r2, [r0], #1 512: T(strb) r2, [r0], #1
513: strbt ip, [r0] 523: T(strb) ip, [r0]
52#else 53#else
532: strbt ip, [r0], #1 542: T(strb) ip, [r0], #1
543: strbt r2, [r0] 553: T(strb) r2, [r0]
55#endif 56#endif
56#endif /* CONFIG_THUMB2_KERNEL */ 57#endif /* CONFIG_THUMB2_KERNEL */
57 mov r0, #0 58 mov r0, #0
@@ -59,18 +60,18 @@ ENTRY(__put_user_2)
59ENDPROC(__put_user_2) 60ENDPROC(__put_user_2)
60 61
61ENTRY(__put_user_4) 62ENTRY(__put_user_4)
624: strt r2, [r0] 634: T(str) r2, [r0]
63 mov r0, #0 64 mov r0, #0
64 mov pc, lr 65 mov pc, lr
65ENDPROC(__put_user_4) 66ENDPROC(__put_user_4)
66 67
67ENTRY(__put_user_8) 68ENTRY(__put_user_8)
68#ifdef CONFIG_THUMB2_KERNEL 69#ifdef CONFIG_THUMB2_KERNEL
695: strt r2, [r0] 705: T(str) r2, [r0]
706: strt r3, [r0, #4] 716: T(str) r3, [r0, #4]
71#else 72#else
725: strt r2, [r0], #4 735: T(str) r2, [r0], #4
736: strt r3, [r0] 746: T(str) r3, [r0]
74#endif 75#endif
75 mov r0, #0 76 mov r0, #0
76 mov pc, lr 77 mov pc, lr
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index fee9f6f88ad..d0ece2aeb70 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -14,6 +14,7 @@
14#include <linux/linkage.h> 14#include <linux/linkage.h>
15#include <asm/assembler.h> 15#include <asm/assembler.h>
16#include <asm/errno.h> 16#include <asm/errno.h>
17#include <asm/domain.h>
17 18
18 .text 19 .text
19 20
@@ -31,11 +32,11 @@
31 rsb ip, ip, #4 32 rsb ip, ip, #4
32 cmp ip, #2 33 cmp ip, #2
33 ldrb r3, [r1], #1 34 ldrb r3, [r1], #1
34USER( strbt r3, [r0], #1) @ May fault 35USER( T(strb) r3, [r0], #1) @ May fault
35 ldrgeb r3, [r1], #1 36 ldrgeb r3, [r1], #1
36USER( strgebt r3, [r0], #1) @ May fault 37USER( T(strgeb) r3, [r0], #1) @ May fault
37 ldrgtb r3, [r1], #1 38 ldrgtb r3, [r1], #1
38USER( strgtbt r3, [r0], #1) @ May fault 39USER( T(strgtb) r3, [r0], #1) @ May fault
39 sub r2, r2, ip 40 sub r2, r2, ip
40 b .Lc2u_dest_aligned 41 b .Lc2u_dest_aligned
41 42
@@ -58,7 +59,7 @@ ENTRY(__copy_to_user)
58 addmi ip, r2, #4 59 addmi ip, r2, #4
59 bmi .Lc2u_0nowords 60 bmi .Lc2u_0nowords
60 ldr r3, [r1], #4 61 ldr r3, [r1], #4
61USER( strt r3, [r0], #4) @ May fault 62USER( T(str) r3, [r0], #4) @ May fault
62 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction 63 mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
63 rsb ip, ip, #0 64 rsb ip, ip, #0
64 movs ip, ip, lsr #32 - PAGE_SHIFT 65 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -87,18 +88,18 @@ USER( strt r3, [r0], #4) @ May fault
87 stmneia r0!, {r3 - r4} @ Shouldnt fault 88 stmneia r0!, {r3 - r4} @ Shouldnt fault
88 tst ip, #4 89 tst ip, #4
89 ldrne r3, [r1], #4 90 ldrne r3, [r1], #4
90 strnet r3, [r0], #4 @ Shouldnt fault 91 T(strne) r3, [r0], #4 @ Shouldnt fault
91 ands ip, ip, #3 92 ands ip, ip, #3
92 beq .Lc2u_0fupi 93 beq .Lc2u_0fupi
93.Lc2u_0nowords: teq ip, #0 94.Lc2u_0nowords: teq ip, #0
94 beq .Lc2u_finished 95 beq .Lc2u_finished
95.Lc2u_nowords: cmp ip, #2 96.Lc2u_nowords: cmp ip, #2
96 ldrb r3, [r1], #1 97 ldrb r3, [r1], #1
97USER( strbt r3, [r0], #1) @ May fault 98USER( T(strb) r3, [r0], #1) @ May fault
98 ldrgeb r3, [r1], #1 99 ldrgeb r3, [r1], #1
99USER( strgebt r3, [r0], #1) @ May fault 100USER( T(strgeb) r3, [r0], #1) @ May fault
100 ldrgtb r3, [r1], #1 101 ldrgtb r3, [r1], #1
101USER( strgtbt r3, [r0], #1) @ May fault 102USER( T(strgtb) r3, [r0], #1) @ May fault
102 b .Lc2u_finished 103 b .Lc2u_finished
103 104
104.Lc2u_not_enough: 105.Lc2u_not_enough:
@@ -119,7 +120,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
119 mov r3, r7, pull #8 120 mov r3, r7, pull #8
120 ldr r7, [r1], #4 121 ldr r7, [r1], #4
121 orr r3, r3, r7, push #24 122 orr r3, r3, r7, push #24
122USER( strt r3, [r0], #4) @ May fault 123USER( T(str) r3, [r0], #4) @ May fault
123 mov ip, r0, lsl #32 - PAGE_SHIFT 124 mov ip, r0, lsl #32 - PAGE_SHIFT
124 rsb ip, ip, #0 125 rsb ip, ip, #0
125 movs ip, ip, lsr #32 - PAGE_SHIFT 126 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -154,18 +155,18 @@ USER( strt r3, [r0], #4) @ May fault
154 movne r3, r7, pull #8 155 movne r3, r7, pull #8
155 ldrne r7, [r1], #4 156 ldrne r7, [r1], #4
156 orrne r3, r3, r7, push #24 157 orrne r3, r3, r7, push #24
157 strnet r3, [r0], #4 @ Shouldnt fault 158 T(strne) r3, [r0], #4 @ Shouldnt fault
158 ands ip, ip, #3 159 ands ip, ip, #3
159 beq .Lc2u_1fupi 160 beq .Lc2u_1fupi
160.Lc2u_1nowords: mov r3, r7, get_byte_1 161.Lc2u_1nowords: mov r3, r7, get_byte_1
161 teq ip, #0 162 teq ip, #0
162 beq .Lc2u_finished 163 beq .Lc2u_finished
163 cmp ip, #2 164 cmp ip, #2
164USER( strbt r3, [r0], #1) @ May fault 165USER( T(strb) r3, [r0], #1) @ May fault
165 movge r3, r7, get_byte_2 166 movge r3, r7, get_byte_2
166USER( strgebt r3, [r0], #1) @ May fault 167USER( T(strgeb) r3, [r0], #1) @ May fault
167 movgt r3, r7, get_byte_3 168 movgt r3, r7, get_byte_3
168USER( strgtbt r3, [r0], #1) @ May fault 169USER( T(strgtb) r3, [r0], #1) @ May fault
169 b .Lc2u_finished 170 b .Lc2u_finished
170 171
171.Lc2u_2fupi: subs r2, r2, #4 172.Lc2u_2fupi: subs r2, r2, #4
@@ -174,7 +175,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
174 mov r3, r7, pull #16 175 mov r3, r7, pull #16
175 ldr r7, [r1], #4 176 ldr r7, [r1], #4
176 orr r3, r3, r7, push #16 177 orr r3, r3, r7, push #16
177USER( strt r3, [r0], #4) @ May fault 178USER( T(str) r3, [r0], #4) @ May fault
178 mov ip, r0, lsl #32 - PAGE_SHIFT 179 mov ip, r0, lsl #32 - PAGE_SHIFT
179 rsb ip, ip, #0 180 rsb ip, ip, #0
180 movs ip, ip, lsr #32 - PAGE_SHIFT 181 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -209,18 +210,18 @@ USER( strt r3, [r0], #4) @ May fault
209 movne r3, r7, pull #16 210 movne r3, r7, pull #16
210 ldrne r7, [r1], #4 211 ldrne r7, [r1], #4
211 orrne r3, r3, r7, push #16 212 orrne r3, r3, r7, push #16
212 strnet r3, [r0], #4 @ Shouldnt fault 213 T(strne) r3, [r0], #4 @ Shouldnt fault
213 ands ip, ip, #3 214 ands ip, ip, #3
214 beq .Lc2u_2fupi 215 beq .Lc2u_2fupi
215.Lc2u_2nowords: mov r3, r7, get_byte_2 216.Lc2u_2nowords: mov r3, r7, get_byte_2
216 teq ip, #0 217 teq ip, #0
217 beq .Lc2u_finished 218 beq .Lc2u_finished
218 cmp ip, #2 219 cmp ip, #2
219USER( strbt r3, [r0], #1) @ May fault 220USER( T(strb) r3, [r0], #1) @ May fault
220 movge r3, r7, get_byte_3 221 movge r3, r7, get_byte_3
221USER( strgebt r3, [r0], #1) @ May fault 222USER( T(strgeb) r3, [r0], #1) @ May fault
222 ldrgtb r3, [r1], #0 223 ldrgtb r3, [r1], #0
223USER( strgtbt r3, [r0], #1) @ May fault 224USER( T(strgtb) r3, [r0], #1) @ May fault
224 b .Lc2u_finished 225 b .Lc2u_finished
225 226
226.Lc2u_3fupi: subs r2, r2, #4 227.Lc2u_3fupi: subs r2, r2, #4
@@ -229,7 +230,7 @@ USER( strgtbt r3, [r0], #1) @ May fault
229 mov r3, r7, pull #24 230 mov r3, r7, pull #24
230 ldr r7, [r1], #4 231 ldr r7, [r1], #4
231 orr r3, r3, r7, push #8 232 orr r3, r3, r7, push #8
232USER( strt r3, [r0], #4) @ May fault 233USER( T(str) r3, [r0], #4) @ May fault
233 mov ip, r0, lsl #32 - PAGE_SHIFT 234 mov ip, r0, lsl #32 - PAGE_SHIFT
234 rsb ip, ip, #0 235 rsb ip, ip, #0
235 movs ip, ip, lsr #32 - PAGE_SHIFT 236 movs ip, ip, lsr #32 - PAGE_SHIFT
@@ -264,18 +265,18 @@ USER( strt r3, [r0], #4) @ May fault
264 movne r3, r7, pull #24 265 movne r3, r7, pull #24
265 ldrne r7, [r1], #4 266 ldrne r7, [r1], #4
266 orrne r3, r3, r7, push #8 267 orrne r3, r3, r7, push #8
267 strnet r3, [r0], #4 @ Shouldnt fault 268 T(strne) r3, [r0], #4 @ Shouldnt fault
268 ands ip, ip, #3 269 ands ip, ip, #3
269 beq .Lc2u_3fupi 270 beq .Lc2u_3fupi
270.Lc2u_3nowords: mov r3, r7, get_byte_3 271.Lc2u_3nowords: mov r3, r7, get_byte_3
271 teq ip, #0 272 teq ip, #0
272 beq .Lc2u_finished 273 beq .Lc2u_finished
273 cmp ip, #2 274 cmp ip, #2
274USER( strbt r3, [r0], #1) @ May fault 275USER( T(strb) r3, [r0], #1) @ May fault
275 ldrgeb r3, [r1], #1 276 ldrgeb r3, [r1], #1
276USER( strgebt r3, [r0], #1) @ May fault 277USER( T(strgeb) r3, [r0], #1) @ May fault
277 ldrgtb r3, [r1], #0 278 ldrgtb r3, [r1], #0
278USER( strgtbt r3, [r0], #1) @ May fault 279USER( T(strgtb) r3, [r0], #1) @ May fault
279 b .Lc2u_finished 280 b .Lc2u_finished
280ENDPROC(__copy_to_user) 281ENDPROC(__copy_to_user)
281 282
@@ -294,11 +295,11 @@ ENDPROC(__copy_to_user)
294.Lcfu_dest_not_aligned: 295.Lcfu_dest_not_aligned:
295 rsb ip, ip, #4 296 rsb ip, ip, #4
296 cmp ip, #2 297 cmp ip, #2
297USER( ldrbt r3, [r1], #1) @ May fault 298USER( T(ldrb) r3, [r1], #1) @ May fault
298 strb r3, [r0], #1 299 strb r3, [r0], #1
299USER( ldrgebt r3, [r1], #1) @ May fault 300USER( T(ldrgeb) r3, [r1], #1) @ May fault
300 strgeb r3, [r0], #1 301 strgeb r3, [r0], #1
301USER( ldrgtbt r3, [r1], #1) @ May fault 302USER( T(ldrgtb) r3, [r1], #1) @ May fault
302 strgtb r3, [r0], #1 303 strgtb r3, [r0], #1
303 sub r2, r2, ip 304 sub r2, r2, ip
304 b .Lcfu_dest_aligned 305 b .Lcfu_dest_aligned
@@ -321,7 +322,7 @@ ENTRY(__copy_from_user)
321.Lcfu_0fupi: subs r2, r2, #4 322.Lcfu_0fupi: subs r2, r2, #4
322 addmi ip, r2, #4 323 addmi ip, r2, #4
323 bmi .Lcfu_0nowords 324 bmi .Lcfu_0nowords
324USER( ldrt r3, [r1], #4) 325USER( T(ldr) r3, [r1], #4)
325 str r3, [r0], #4 326 str r3, [r0], #4
326 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction 327 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
327 rsb ip, ip, #0 328 rsb ip, ip, #0
@@ -350,18 +351,18 @@ USER( ldrt r3, [r1], #4)
350 ldmneia r1!, {r3 - r4} @ Shouldnt fault 351 ldmneia r1!, {r3 - r4} @ Shouldnt fault
351 stmneia r0!, {r3 - r4} 352 stmneia r0!, {r3 - r4}
352 tst ip, #4 353 tst ip, #4
353 ldrnet r3, [r1], #4 @ Shouldnt fault 354 T(ldrne) r3, [r1], #4 @ Shouldnt fault
354 strne r3, [r0], #4 355 strne r3, [r0], #4
355 ands ip, ip, #3 356 ands ip, ip, #3
356 beq .Lcfu_0fupi 357 beq .Lcfu_0fupi
357.Lcfu_0nowords: teq ip, #0 358.Lcfu_0nowords: teq ip, #0
358 beq .Lcfu_finished 359 beq .Lcfu_finished
359.Lcfu_nowords: cmp ip, #2 360.Lcfu_nowords: cmp ip, #2
360USER( ldrbt r3, [r1], #1) @ May fault 361USER( T(ldrb) r3, [r1], #1) @ May fault
361 strb r3, [r0], #1 362 strb r3, [r0], #1
362USER( ldrgebt r3, [r1], #1) @ May fault 363USER( T(ldrgeb) r3, [r1], #1) @ May fault
363 strgeb r3, [r0], #1 364 strgeb r3, [r0], #1
364USER( ldrgtbt r3, [r1], #1) @ May fault 365USER( T(ldrgtb) r3, [r1], #1) @ May fault
365 strgtb r3, [r0], #1 366 strgtb r3, [r0], #1
366 b .Lcfu_finished 367 b .Lcfu_finished
367 368
@@ -374,7 +375,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
374 375
375.Lcfu_src_not_aligned: 376.Lcfu_src_not_aligned:
376 bic r1, r1, #3 377 bic r1, r1, #3
377USER( ldrt r7, [r1], #4) @ May fault 378USER( T(ldr) r7, [r1], #4) @ May fault
378 cmp ip, #2 379 cmp ip, #2
379 bgt .Lcfu_3fupi 380 bgt .Lcfu_3fupi
380 beq .Lcfu_2fupi 381 beq .Lcfu_2fupi
@@ -382,7 +383,7 @@ USER( ldrt r7, [r1], #4) @ May fault
382 addmi ip, r2, #4 383 addmi ip, r2, #4
383 bmi .Lcfu_1nowords 384 bmi .Lcfu_1nowords
384 mov r3, r7, pull #8 385 mov r3, r7, pull #8
385USER( ldrt r7, [r1], #4) @ May fault 386USER( T(ldr) r7, [r1], #4) @ May fault
386 orr r3, r3, r7, push #24 387 orr r3, r3, r7, push #24
387 str r3, [r0], #4 388 str r3, [r0], #4
388 mov ip, r1, lsl #32 - PAGE_SHIFT 389 mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -417,7 +418,7 @@ USER( ldrt r7, [r1], #4) @ May fault
417 stmneia r0!, {r3 - r4} 418 stmneia r0!, {r3 - r4}
418 tst ip, #4 419 tst ip, #4
419 movne r3, r7, pull #8 420 movne r3, r7, pull #8
420USER( ldrnet r7, [r1], #4) @ May fault 421USER( T(ldrne) r7, [r1], #4) @ May fault
421 orrne r3, r3, r7, push #24 422 orrne r3, r3, r7, push #24
422 strne r3, [r0], #4 423 strne r3, [r0], #4
423 ands ip, ip, #3 424 ands ip, ip, #3
@@ -437,7 +438,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
437 addmi ip, r2, #4 438 addmi ip, r2, #4
438 bmi .Lcfu_2nowords 439 bmi .Lcfu_2nowords
439 mov r3, r7, pull #16 440 mov r3, r7, pull #16
440USER( ldrt r7, [r1], #4) @ May fault 441USER( T(ldr) r7, [r1], #4) @ May fault
441 orr r3, r3, r7, push #16 442 orr r3, r3, r7, push #16
442 str r3, [r0], #4 443 str r3, [r0], #4
443 mov ip, r1, lsl #32 - PAGE_SHIFT 444 mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -473,7 +474,7 @@ USER( ldrt r7, [r1], #4) @ May fault
473 stmneia r0!, {r3 - r4} 474 stmneia r0!, {r3 - r4}
474 tst ip, #4 475 tst ip, #4
475 movne r3, r7, pull #16 476 movne r3, r7, pull #16
476USER( ldrnet r7, [r1], #4) @ May fault 477USER( T(ldrne) r7, [r1], #4) @ May fault
477 orrne r3, r3, r7, push #16 478 orrne r3, r3, r7, push #16
478 strne r3, [r0], #4 479 strne r3, [r0], #4
479 ands ip, ip, #3 480 ands ip, ip, #3
@@ -485,7 +486,7 @@ USER( ldrnet r7, [r1], #4) @ May fault
485 strb r3, [r0], #1 486 strb r3, [r0], #1
486 movge r3, r7, get_byte_3 487 movge r3, r7, get_byte_3
487 strgeb r3, [r0], #1 488 strgeb r3, [r0], #1
488USER( ldrgtbt r3, [r1], #0) @ May fault 489USER( T(ldrgtb) r3, [r1], #0) @ May fault
489 strgtb r3, [r0], #1 490 strgtb r3, [r0], #1
490 b .Lcfu_finished 491 b .Lcfu_finished
491 492
@@ -493,7 +494,7 @@ USER( ldrgtbt r3, [r1], #0) @ May fault
493 addmi ip, r2, #4 494 addmi ip, r2, #4
494 bmi .Lcfu_3nowords 495 bmi .Lcfu_3nowords
495 mov r3, r7, pull #24 496 mov r3, r7, pull #24
496USER( ldrt r7, [r1], #4) @ May fault 497USER( T(ldr) r7, [r1], #4) @ May fault
497 orr r3, r3, r7, push #8 498 orr r3, r3, r7, push #8
498 str r3, [r0], #4 499 str r3, [r0], #4
499 mov ip, r1, lsl #32 - PAGE_SHIFT 500 mov ip, r1, lsl #32 - PAGE_SHIFT
@@ -528,7 +529,7 @@ USER( ldrt r7, [r1], #4) @ May fault
528 stmneia r0!, {r3 - r4} 529 stmneia r0!, {r3 - r4}
529 tst ip, #4 530 tst ip, #4
530 movne r3, r7, pull #24 531 movne r3, r7, pull #24
531USER( ldrnet r7, [r1], #4) @ May fault 532USER( T(ldrne) r7, [r1], #4) @ May fault
532 orrne r3, r3, r7, push #8 533 orrne r3, r3, r7, push #8
533 strne r3, [r0], #4 534 strne r3, [r0], #4
534 ands ip, ip, #3 535 ands ip, ip, #3
@@ -538,9 +539,9 @@ USER( ldrnet r7, [r1], #4) @ May fault
538 beq .Lcfu_finished 539 beq .Lcfu_finished
539 cmp ip, #2 540 cmp ip, #2
540 strb r3, [r0], #1 541 strb r3, [r0], #1
541USER( ldrgebt r3, [r1], #1) @ May fault 542USER( T(ldrgeb) r3, [r1], #1) @ May fault
542 strgeb r3, [r0], #1 543 strgeb r3, [r0], #1
543USER( ldrgtbt r3, [r1], #1) @ May fault 544USER( T(ldrgtb) r3, [r1], #1) @ May fault
544 strgtb r3, [r0], #1 545 strgtb r3, [r0], #1
545 b .Lcfu_finished 546 b .Lcfu_finished
546ENDPROC(__copy_from_user) 547ENDPROC(__copy_from_user)
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 62d686f0b42..d13add71f72 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
65obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o 65obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
66obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o 66obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
67obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o 67obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
68obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o 68obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o
69 69
70# AT91SAM9260/AT91SAM9G20 board-specific support 70# AT91SAM9260/AT91SAM9G20 board-specific support
71obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o 71obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 2500f41d8d2..1dd69c85dfe 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -101,7 +101,6 @@ static struct clocksource clk32k = {
101 .rating = 150, 101 .rating = 150,
102 .read = read_clk32k, 102 .read = read_clk32k,
103 .mask = CLOCKSOURCE_MASK(20), 103 .mask = CLOCKSOURCE_MASK(20),
104 .shift = 10,
105 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 104 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
106}; 105};
107 106
@@ -201,8 +200,7 @@ void __init at91rm9200_timer_init(void)
201 clockevents_register_device(&clkevt); 200 clockevents_register_device(&clkevt);
202 201
203 /* register clocksource */ 202 /* register clocksource */
204 clk32k.mult = clocksource_hz2mult(AT91_SLOW_CLOCK, clk32k.shift); 203 clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
205 clocksource_register(&clk32k);
206} 204}
207 205
208struct sys_timer at91rm9200_timer = { 206struct sys_timer at91rm9200_timer = {
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 608a63240b6..4ba85499fa9 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -51,7 +51,6 @@ static struct clocksource pit_clk = {
51 .name = "pit", 51 .name = "pit",
52 .rating = 175, 52 .rating = 175,
53 .read = read_pit_clk, 53 .read = read_pit_clk,
54 .shift = 20,
55 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 54 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
56}; 55};
57 56
@@ -163,10 +162,9 @@ static void __init at91sam926x_pit_init(void)
163 * Register clocksource. The high order bits of PIV are unused, 162 * Register clocksource. The high order bits of PIV are unused,
164 * so this isn't a 32-bit counter unless we get clockevent irqs. 163 * so this isn't a 32-bit counter unless we get clockevent irqs.
165 */ 164 */
166 pit_clk.mult = clocksource_hz2mult(pit_rate, pit_clk.shift);
167 bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */; 165 bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */;
168 pit_clk.mask = CLOCKSOURCE_MASK(bits); 166 pit_clk.mask = CLOCKSOURCE_MASK(bits);
169 clocksource_register(&pit_clk); 167 clocksource_register_hz(&pit_clk, pit_rate);
170 168
171 /* Set up irq handler */ 169 /* Set up irq handler */
172 setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq); 170 setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq);
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
index bba5a560e02..feb65787c30 100644
--- a/arch/arm/mach-at91/board-pcontrol-g20.c
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -31,6 +31,7 @@
31 31
32#include <mach/board.h> 32#include <mach/board.h>
33#include <mach/at91sam9_smc.h> 33#include <mach/at91sam9_smc.h>
34#include <mach/stamp9g20.h>
34 35
35#include "sam9_smc.h" 36#include "sam9_smc.h"
36#include "generic.h" 37#include "generic.h"
@@ -38,11 +39,7 @@
38 39
39static void __init pcontrol_g20_map_io(void) 40static void __init pcontrol_g20_map_io(void)
40{ 41{
41 /* Initialize processor: 18.432 MHz crystal */ 42 stamp9g20_map_io();
42 at91sam9260_initialize(18432000);
43
44 /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */
45 at91_register_uart(0, 0, 0);
46 43
47 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ 44 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */
48 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS 45 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
@@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void)
54 51
55 /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ 52 /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */
56 at91_register_uart(AT91SAM9260_ID_US4, 3, 0); 53 at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
57
58 /* set serial console to ttyS0 (ie, DBGU) */
59 at91_set_serial_console(0);
60} 54}
61 55
62 56
@@ -66,38 +60,6 @@ static void __init init_irq(void)
66} 60}
67 61
68 62
69/*
70 * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB
71 */
72static struct atmel_nand_data __initdata nand_data = {
73 .ale = 21,
74 .cle = 22,
75 .rdy_pin = AT91_PIN_PC13,
76 .enable_pin = AT91_PIN_PC14,
77};
78
79/*
80 * Bus timings; unit = 7.57ns
81 */
82static struct sam9_smc_config __initdata nand_smc_config = {
83 .ncs_read_setup = 0,
84 .nrd_setup = 2,
85 .ncs_write_setup = 0,
86 .nwe_setup = 2,
87
88 .ncs_read_pulse = 4,
89 .nrd_pulse = 4,
90 .ncs_write_pulse = 4,
91 .nwe_pulse = 4,
92
93 .read_cycle = 7,
94 .write_cycle = 7,
95
96 .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
97 | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
98 .tdf_cycles = 3,
99};
100
101static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { 63static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
102 .ncs_read_setup = 16, 64 .ncs_read_setup = 16,
103 .nrd_setup = 18, 65 .nrd_setup = 18,
@@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
138 .tdf_cycles = 1, 100 .tdf_cycles = 1,
139} }; 101} };
140 102
141static void __init add_device_nand(void)
142{
143 /* configure chip-select 3 (NAND) */
144 sam9_smc_configure(3, &nand_smc_config);
145 at91_add_device_nand(&nand_data);
146}
147
148
149static void __init add_device_pcontrol(void) 103static void __init add_device_pcontrol(void)
150{ 104{
151 /* configure chip-select 4 (IO compatible to 8051 X4 ) */ 105 /* configure chip-select 4 (IO compatible to 8051 X4 ) */
@@ -156,23 +110,6 @@ static void __init add_device_pcontrol(void)
156 110
157 111
158/* 112/*
159 * MCI (SD/MMC)
160 * det_pin, wp_pin and vcc_pin are not connected
161 */
162#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
163static struct mci_platform_data __initdata mmc_data = {
164 .slot[0] = {
165 .bus_width = 4,
166 },
167};
168#else
169static struct at91_mmc_data __initdata mmc_data = {
170 .wire4 = 1,
171};
172#endif
173
174
175/*
176 * USB Host port 113 * USB Host port
177 */ 114 */
178static struct at91_usbh_data __initdata usbh_data = { 115static struct at91_usbh_data __initdata usbh_data = {
@@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = {
265}; 202};
266 203
267 204
268/*
269 * Dallas 1-Wire DS2431
270 */
271static struct w1_gpio_platform_data w1_gpio_pdata = {
272 .pin = AT91_PIN_PA29,
273 .is_open_drain = 1,
274};
275
276static struct platform_device w1_device = {
277 .name = "w1-gpio",
278 .id = -1,
279 .dev.platform_data = &w1_gpio_pdata,
280};
281
282static void add_wire1(void)
283{
284 at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
285 at91_set_multi_drive(w1_gpio_pdata.pin, 1);
286 platform_device_register(&w1_device);
287}
288
289
290static void __init pcontrol_g20_board_init(void) 205static void __init pcontrol_g20_board_init(void)
291{ 206{
292 at91_add_device_serial(); 207 stamp9g20_board_init();
293 add_device_nand();
294#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
295 at91_add_device_mci(0, &mmc_data);
296#else
297 at91_add_device_mmc(0, &mmc_data);
298#endif
299 at91_add_device_usbh(&usbh_data); 208 at91_add_device_usbh(&usbh_data);
300 at91_add_device_eth(&macb_data); 209 at91_add_device_eth(&macb_data);
301 at91_add_device_i2c(pcontrol_g20_i2c_devices, 210 at91_add_device_i2c(pcontrol_g20_i2c_devices,
302 ARRAY_SIZE(pcontrol_g20_i2c_devices)); 211 ARRAY_SIZE(pcontrol_g20_i2c_devices));
303 add_wire1();
304 add_device_pcontrol(); 212 add_device_pcontrol();
305 at91_add_device_spi(pcontrol_g20_spi_devices, 213 at91_add_device_spi(pcontrol_g20_spi_devices,
306 ARRAY_SIZE(pcontrol_g20_spi_devices)); 214 ARRAY_SIZE(pcontrol_g20_spi_devices));
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index 5206eef4a67..f8902b11896 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -32,7 +32,7 @@
32#include "generic.h" 32#include "generic.h"
33 33
34 34
35static void __init portuxg20_map_io(void) 35void __init stamp9g20_map_io(void)
36{ 36{
37 /* Initialize processor: 18.432 MHz crystal */ 37 /* Initialize processor: 18.432 MHz crystal */
38 at91sam9260_initialize(18432000); 38 at91sam9260_initialize(18432000);
@@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void)
40 /* DGBU on ttyS0. (Rx & Tx only) */ 40 /* DGBU on ttyS0. (Rx & Tx only) */
41 at91_register_uart(0, 0, 0); 41 at91_register_uart(0, 0, 0);
42 42
43 /* set serial console to ttyS0 (ie, DBGU) */
44 at91_set_serial_console(0);
45}
46
47static void __init stamp9g20evb_map_io(void)
48{
49 stamp9g20_map_io();
50
51 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
52 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
53 | ATMEL_UART_DTR | ATMEL_UART_DSR
54 | ATMEL_UART_DCD | ATMEL_UART_RI);
55}
56
57static void __init portuxg20_map_io(void)
58{
59 stamp9g20_map_io();
60
43 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ 61 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
44 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS 62 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
45 | ATMEL_UART_DTR | ATMEL_UART_DSR 63 | ATMEL_UART_DTR | ATMEL_UART_DSR
@@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void)
56 74
57 /* USART5 on ttyS6. (Rx, Tx only) */ 75 /* USART5 on ttyS6. (Rx, Tx only) */
58 at91_register_uart(AT91SAM9260_ID_US5, 6, 0); 76 at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
59
60 /* set serial console to ttyS0 (ie, DBGU) */
61 at91_set_serial_console(0);
62}
63
64static void __init stamp9g20_map_io(void)
65{
66 /* Initialize processor: 18.432 MHz crystal */
67 at91sam9260_initialize(18432000);
68
69 /* DGBU on ttyS0. (Rx & Tx only) */
70 at91_register_uart(0, 0, 0);
71
72 /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
73 at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
74 | ATMEL_UART_DTR | ATMEL_UART_DSR
75 | ATMEL_UART_DCD | ATMEL_UART_RI);
76
77 /* set serial console to ttyS0 (ie, DBGU) */
78 at91_set_serial_console(0);
79} 77}
80 78
81static void __init init_irq(void) 79static void __init init_irq(void)
@@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = {
156 .pullup_pin = 0, /* pull-up driven by UDC */ 154 .pullup_pin = 0, /* pull-up driven by UDC */
157}; 155};
158 156
159static struct at91_udc_data __initdata stamp9g20_udc_data = { 157static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
160 .vbus_pin = AT91_PIN_PA22, 158 .vbus_pin = AT91_PIN_PA22,
161 .pullup_pin = 0, /* pull-up driven by UDC */ 159 .pullup_pin = 0, /* pull-up driven by UDC */
162}; 160};
@@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = {
190 } 188 }
191}; 189};
192 190
193static struct gpio_led stamp9g20_leds[] = { 191static struct gpio_led stamp9g20evb_leds[] = {
194 { 192 {
195 .name = "D8", 193 .name = "D8",
196 .gpio = AT91_PIN_PB18, 194 .gpio = AT91_PIN_PB18,
@@ -250,7 +248,7 @@ void add_w1(void)
250} 248}
251 249
252 250
253static void __init generic_board_init(void) 251void __init stamp9g20_board_init(void)
254{ 252{
255 /* Serial */ 253 /* Serial */
256 at91_add_device_serial(); 254 at91_add_device_serial();
@@ -262,34 +260,40 @@ static void __init generic_board_init(void)
262#else 260#else
263 at91_add_device_mmc(0, &mmc_data); 261 at91_add_device_mmc(0, &mmc_data);
264#endif 262#endif
265 /* USB Host */
266 at91_add_device_usbh(&usbh_data);
267 /* Ethernet */
268 at91_add_device_eth(&macb_data);
269 /* I2C */
270 at91_add_device_i2c(NULL, 0);
271 /* W1 */ 263 /* W1 */
272 add_w1(); 264 add_w1();
273} 265}
274 266
275static void __init portuxg20_board_init(void) 267static void __init portuxg20_board_init(void)
276{ 268{
277 generic_board_init(); 269 stamp9g20_board_init();
278 /* SPI */ 270 /* USB Host */
279 at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); 271 at91_add_device_usbh(&usbh_data);
280 /* USB Device */ 272 /* USB Device */
281 at91_add_device_udc(&portuxg20_udc_data); 273 at91_add_device_udc(&portuxg20_udc_data);
274 /* Ethernet */
275 at91_add_device_eth(&macb_data);
276 /* I2C */
277 at91_add_device_i2c(NULL, 0);
278 /* SPI */
279 at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
282 /* LEDs */ 280 /* LEDs */
283 at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); 281 at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
284} 282}
285 283
286static void __init stamp9g20_board_init(void) 284static void __init stamp9g20evb_board_init(void)
287{ 285{
288 generic_board_init(); 286 stamp9g20_board_init();
287 /* USB Host */
288 at91_add_device_usbh(&usbh_data);
289 /* USB Device */ 289 /* USB Device */
290 at91_add_device_udc(&stamp9g20_udc_data); 290 at91_add_device_udc(&stamp9g20evb_udc_data);
291 /* Ethernet */
292 at91_add_device_eth(&macb_data);
293 /* I2C */
294 at91_add_device_i2c(NULL, 0);
291 /* LEDs */ 295 /* LEDs */
292 at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds)); 296 at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds));
293} 297}
294 298
295MACHINE_START(PORTUXG20, "taskit PortuxG20") 299MACHINE_START(PORTUXG20, "taskit PortuxG20")
@@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20")
305 /* Maintainer: taskit GmbH */ 309 /* Maintainer: taskit GmbH */
306 .boot_params = AT91_SDRAM_BASE + 0x100, 310 .boot_params = AT91_SDRAM_BASE + 0x100,
307 .timer = &at91sam926x_timer, 311 .timer = &at91sam926x_timer,
308 .map_io = stamp9g20_map_io, 312 .map_io = stamp9g20evb_map_io,
309 .init_irq = init_irq, 313 .init_irq = init_irq,
310 .init_machine = stamp9g20_board_init, 314 .init_machine = stamp9g20evb_board_init,
311MACHINE_END 315MACHINE_END
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 7525cee3983..9113da6845f 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
658 /* Now set uhpck values */ 658 /* Now set uhpck values */
659 uhpck.parent = &utmi_clk; 659 uhpck.parent = &utmi_clk;
660 uhpck.pmc_mask = AT91SAM926x_PMC_UHP; 660 uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
661 uhpck.rate_hz = utmi_clk.parent->rate_hz; 661 uhpck.rate_hz = utmi_clk.rate_hz;
662 uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); 662 uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
663} 663}
664 664
diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h
index 57f8ee15494..27ac6f550fe 100644
--- a/arch/arm/mach-at91/include/mach/at91_mci.h
+++ b/arch/arm/mach-at91/include/mach/at91_mci.h
@@ -74,6 +74,8 @@
74#define AT91_MCI_TRTYP_BLOCK (0 << 19) 74#define AT91_MCI_TRTYP_BLOCK (0 << 19)
75#define AT91_MCI_TRTYP_MULTIPLE (1 << 19) 75#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
76#define AT91_MCI_TRTYP_STREAM (2 << 19) 76#define AT91_MCI_TRTYP_STREAM (2 << 19)
77#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19)
78#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19)
77 79
78#define AT91_MCI_BLKR 0x18 /* Block Register */ 80#define AT91_MCI_BLKR 0x18 /* Block Register */
79#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ 81#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h
new file mode 100644
index 00000000000..6120f9c46d5
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/stamp9g20.h
@@ -0,0 +1,7 @@
1#ifndef __MACH_STAMP9G20_H
2#define __MACH_STAMP9G20_H
3
4void stamp9g20_map_io(void);
5void stamp9g20_board_init(void);
6
7#endif
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c
index 14bafc38f2d..ad237a42d26 100644
--- a/arch/arm/mach-bcmring/clock.c
+++ b/arch/arm/mach-bcmring/clock.c
@@ -21,13 +21,12 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/clkdev.h>
24#include <mach/csp/hw_cfg.h> 25#include <mach/csp/hw_cfg.h>
25#include <mach/csp/chipcHw_def.h> 26#include <mach/csp/chipcHw_def.h>
26#include <mach/csp/chipcHw_reg.h> 27#include <mach/csp/chipcHw_reg.h>
27#include <mach/csp/chipcHw_inline.h> 28#include <mach/csp/chipcHw_inline.h>
28 29
29#include <asm/clkdev.h>
30
31#include "clock.h" 30#include "clock.h"
32 31
33#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) 32#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index d3f959e92b2..8fc2035759f 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -30,10 +30,10 @@
30#include <linux/amba/bus.h> 30#include <linux/amba/bus.h>
31#include <linux/clocksource.h> 31#include <linux/clocksource.h>
32#include <linux/clockchips.h> 32#include <linux/clockchips.h>
33#include <linux/clkdev.h>
33 34
34#include <mach/csp/mm_addr.h> 35#include <mach/csp/mm_addr.h>
35#include <mach/hardware.h> 36#include <mach/hardware.h>
36#include <asm/clkdev.h>
37#include <linux/io.h> 37#include <linux/io.h>
38#include <asm/irq.h> 38#include <asm/irq.h>
39#include <asm/hardware/arm_timer.h> 39#include <asm/hardware/arm_timer.h>
@@ -294,7 +294,6 @@ static struct clocksource clocksource_bcmring_timer1 = {
294 .rating = 200, 294 .rating = 200,
295 .read = bcmring_get_cycles_timer1, 295 .read = bcmring_get_cycles_timer1,
296 .mask = CLOCKSOURCE_MASK(32), 296 .mask = CLOCKSOURCE_MASK(32),
297 .shift = 20,
298 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 297 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
299}; 298};
300 299
@@ -303,7 +302,6 @@ static struct clocksource clocksource_bcmring_timer3 = {
303 .rating = 100, 302 .rating = 100,
304 .read = bcmring_get_cycles_timer3, 303 .read = bcmring_get_cycles_timer3,
305 .mask = CLOCKSOURCE_MASK(32), 304 .mask = CLOCKSOURCE_MASK(32),
306 .shift = 20,
307 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 305 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
308}; 306};
309 307
@@ -316,10 +314,8 @@ static int __init bcmring_clocksource_init(void)
316 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, 314 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
317 TIMER1_VA_BASE + TIMER_CTRL); 315 TIMER1_VA_BASE + TIMER_CTRL);
318 316
319 clocksource_bcmring_timer1.mult = 317 clocksource_register_khz(&clocksource_bcmring_timer1,
320 clocksource_khz2mult(TIMER1_FREQUENCY_MHZ * 1000, 318 TIMER1_FREQUENCY_MHZ * 1000);
321 clocksource_bcmring_timer1.shift);
322 clocksource_register(&clocksource_bcmring_timer1);
323 319
324 /* setup timer3 as free-running clocksource */ 320 /* setup timer3 as free-running clocksource */
325 writel(0, TIMER3_VA_BASE + TIMER_CTRL); 321 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
@@ -328,10 +324,8 @@ static int __init bcmring_clocksource_init(void)
328 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, 324 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
329 TIMER3_VA_BASE + TIMER_CTRL); 325 TIMER3_VA_BASE + TIMER_CTRL);
330 326
331 clocksource_bcmring_timer3.mult = 327 clocksource_register_khz(&clocksource_bcmring_timer3,
332 clocksource_khz2mult(TIMER3_FREQUENCY_KHZ, 328 TIMER3_FREQUENCY_KHZ);
333 clocksource_bcmring_timer3.shift);
334 clocksource_register(&clocksource_bcmring_timer3);
335 329
336 return 0; 330 return 0;
337} 331}
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
index 9ebfcc46feb..29b13f249aa 100644
--- a/arch/arm/mach-cns3xxx/Kconfig
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -3,6 +3,7 @@ menu "CNS3XXX platform type"
3 3
4config MACH_CNS3420VB 4config MACH_CNS3420VB
5 bool "Support for CNS3420 Validation Board" 5 bool "Support for CNS3420 Validation Board"
6 select MIGHT_HAVE_PCI
6 help 7 help
7 Include support for the Cavium Networks CNS3420 MPCore Platform 8 Include support for the Cavium Networks CNS3420 MPCore Platform
8 Baseboard. 9 Baseboard.
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
index 9ca4d581016..da30078a80c 100644
--- a/arch/arm/mach-cns3xxx/core.c
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -69,13 +69,10 @@ void __init cns3xxx_map_io(void)
69} 69}
70 70
71/* used by entry-macro.S */ 71/* used by entry-macro.S */
72void __iomem *gic_cpu_base_addr;
73
74void __init cns3xxx_init_irq(void) 72void __init cns3xxx_init_irq(void)
75{ 73{
76 gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT); 74 gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
77 gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29); 75 __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
78 gic_cpu_init(0, gic_cpu_base_addr);
79} 76}
80 77
81void cns3xxx_power_off(void) 78void cns3xxx_power_off(void)
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
index 73898a7835d..ffeb3a8b73b 100644
--- a/arch/arm/mach-cns3xxx/core.h
+++ b/arch/arm/mach-cns3xxx/core.h
@@ -11,7 +11,6 @@
11#ifndef __CNS3XXX_CORE_H 11#ifndef __CNS3XXX_CORE_H
12#define __CNS3XXX_CORE_H 12#define __CNS3XXX_CORE_H
13 13
14extern void __iomem *gic_cpu_base_addr;
15extern struct sys_timer cns3xxx_timer; 14extern struct sys_timer cns3xxx_timer;
16 15
17void __init cns3xxx_map_io(void); 16void __init cns3xxx_map_io(void);
diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
index 5e1c5545680..6bd83ed90af 100644
--- a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
+++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
@@ -9,74 +9,10 @@
9 */ 9 */
10 10
11#include <mach/hardware.h> 11#include <mach/hardware.h>
12#include <asm/hardware/gic.h> 12#include <asm/hardware/entry-macro-gic.S>
13 13
14 .macro disable_fiq 14 .macro disable_fiq
15 .endm 15 .endm
16 16
17 .macro get_irqnr_preamble, base, tmp
18 ldr \base, =gic_cpu_base_addr
19 ldr \base, [\base]
20 .endm
21
22 .macro arch_ret_to_user, tmp1, tmp2 17 .macro arch_ret_to_user, tmp1, tmp2
23 .endm 18 .endm
24
25 /*
26 * The interrupt numbering scheme is defined in the
27 * interrupt controller spec. To wit:
28 *
29 * Interrupts 0-15 are IPI
30 * 16-28 are reserved
31 * 29-31 are local. We allow 30 to be used for the watchdog.
32 * 32-1020 are global
33 * 1021-1022 are reserved
34 * 1023 is "spurious" (no interrupt)
35 *
36 * For now, we ignore all local interrupts so only return an interrupt if it's
37 * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
38 *
39 * A simple read from the controller will tell us the number of the highest
40 * priority enabled interrupt. We then just need to check whether it is in the
41 * valid range for an IRQ (30-1020 inclusive).
42 */
43
44 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
45
46 ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
47
48 ldr \tmp, =1021
49
50 bic \irqnr, \irqstat, #0x1c00
51
52 cmp \irqnr, #29
53 cmpcc \irqnr, \irqnr
54 cmpne \irqnr, \tmp
55 cmpcs \irqnr, \irqnr
56
57 .endm
58
59 /* We assume that irqstat (the raw value of the IRQ acknowledge
60 * register) is preserved from the macro above.
61 * If there is an IPI, we immediately signal end of interrupt on the
62 * controller, since this requires the original irqstat value which
63 * we won't easily be able to recreate later.
64 */
65
66 .macro test_for_ipi, irqnr, irqstat, base, tmp
67 bic \irqnr, \irqstat, #0x1c00
68 cmp \irqnr, #16
69 strcc \irqstat, [\base, #GIC_CPU_EOI]
70 cmpcs \irqnr, \irqnr
71 .endm
72
73 /* As above, this assumes that irqstat and base are preserved.. */
74
75 .macro test_for_ltirq, irqnr, irqstat, base, tmp
76 bic \irqnr, \irqstat, #0x1c00
77 mov \tmp, #0
78 cmp \irqnr, #29
79 moveq \tmp, #1
80 streq \irqstat, [\base, #GIC_CPU_EOI]
81 cmp \tmp, #0
82 .endm
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index 11099980b58..0dd22031ec6 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -68,7 +68,7 @@
68#ifndef __ASSEMBLER__ 68#ifndef __ASSEMBLER__
69 69
70#include <linux/list.h> 70#include <linux/list.h>
71#include <asm/clkdev.h> 71#include <linux/clkdev.h>
72 72
73#define PLLSTAT_GOSTAT BIT(0) 73#define PLLSTAT_GOSTAT BIT(0)
74#define PLLCMD_GOSET BIT(0) 74#define PLLCMD_GOSET BIT(0)
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
index 62b0a90309a..d1b954955c1 100644
--- a/arch/arm/mach-davinci/include/mach/io.h
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -22,8 +22,8 @@
22#define __mem_isa(a) (a) 22#define __mem_isa(a) (a)
23 23
24#ifndef __ASSEMBLER__ 24#ifndef __ASSEMBLER__
25#define __arch_ioremap(p, s, t) davinci_ioremap(p, s, t) 25#define __arch_ioremap davinci_ioremap
26#define __arch_iounmap(v) davinci_iounmap(v) 26#define __arch_iounmap davinci_iounmap
27 27
28void __iomem *davinci_ioremap(unsigned long phys, size_t size, 28void __iomem *davinci_ioremap(unsigned long phys, size_t size,
29 unsigned int type); 29 unsigned int type);
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 5d1eea02663..e1969ce904d 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -286,7 +286,6 @@ static struct clocksource clocksource_davinci = {
286 .rating = 300, 286 .rating = 300,
287 .read = read_dummy, 287 .read = read_dummy,
288 .mask = CLOCKSOURCE_MASK(32), 288 .mask = CLOCKSOURCE_MASK(32),
289 .shift = 24,
290 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 289 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
291}; 290};
292 291
@@ -400,10 +399,8 @@ static void __init davinci_timer_init(void)
400 /* setup clocksource */ 399 /* setup clocksource */
401 clocksource_davinci.read = read_cycles; 400 clocksource_davinci.read = read_cycles;
402 clocksource_davinci.name = id_to_name[clocksource_id]; 401 clocksource_davinci.name = id_to_name[clocksource_id];
403 clocksource_davinci.mult = 402 if (clocksource_register_hz(&clocksource_davinci,
404 clocksource_khz2mult(davinci_clock_tick_rate/1000, 403 davinci_clock_tick_rate))
405 clocksource_davinci.shift);
406 if (clocksource_register(&clocksource_davinci))
407 printk(err, clocksource_davinci.name); 404 printk(err, clocksource_davinci.name);
408 405
409 /* setup clockevent */ 406 /* setup clockevent */
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index ef06c66a6f1..ca4de710509 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -19,10 +19,10 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/clkdev.h>
22 23
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24 25
25#include <asm/clkdev.h>
26#include <asm/div64.h> 26#include <asm/div64.h>
27 27
28 28
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
index daca30b2d5b..3938a563b28 100644
--- a/arch/arm/mach-imx/clock-imx1.c
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -22,8 +22,7 @@
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/io.h> 24#include <linux/io.h>
25 25#include <linux/clkdev.h>
26#include <asm/clkdev.h>
27 26
28#include <mach/clock.h> 27#include <mach/clock.h>
29#include <mach/hardware.h> 28#include <mach/hardware.h>
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
index c63a4f5ffcb..bf30a8c7ce6 100644
--- a/arch/arm/mach-imx/clock-imx21.c
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -21,11 +21,11 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/clkdev.h>
24 25
25#include <mach/clock.h> 26#include <mach/clock.h>
26#include <mach/hardware.h> 27#include <mach/hardware.h>
27#include <mach/common.h> 28#include <mach/common.h>
28#include <asm/clkdev.h>
29#include <asm/div64.h> 29#include <asm/div64.h>
30 30
31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off))) 31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
index 21ef34c501e..daa0165b677 100644
--- a/arch/arm/mach-imx/clock-imx25.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -21,8 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/clkdev.h>
25#include <asm/clkdev.h>
26 25
27#include <mach/clock.h> 26#include <mach/clock.h>
28#include <mach/hardware.h> 27#include <mach/hardware.h>
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
index f32f3b8e8ba..583f2515c1d 100644
--- a/arch/arm/mach-imx/clock-imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -21,8 +21,8 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/clkdev.h>
24 25
25#include <asm/clkdev.h>
26#include <asm/div64.h> 26#include <asm/div64.h>
27 27
28#include <mach/clock.h> 28#include <mach/clock.h>
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index 27db275b367..769b0f10c83 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -4,6 +4,7 @@ menu "Integrator Options"
4 4
5config ARCH_INTEGRATOR_AP 5config ARCH_INTEGRATOR_AP
6 bool "Support Integrator/AP and Integrator/PP2 platforms" 6 bool "Support Integrator/AP and Integrator/PP2 platforms"
7 select MIGHT_HAVE_PCI
7 help 8 help
8 Include support for the ARM(R) Integrator/AP and 9 Include support for the ARM(R) Integrator/AP and
9 Integrator/PP2 platforms. 10 Integrator/PP2 platforms.
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 8f4fb6d638f..b8e884b450d 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -21,9 +21,8 @@
21#include <linux/amba/bus.h> 21#include <linux/amba/bus.h>
22#include <linux/amba/serial.h> 22#include <linux/amba/serial.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clkdev.h>
24 25
25#include <asm/clkdev.h>
26#include <mach/clkdev.h>
27#include <mach/hardware.h> 26#include <mach/hardware.h>
28#include <mach/platform.h> 27#include <mach/platform.h>
29#include <asm/irq.h> 28#include <asm/irq.h>
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index fd684bf205e..5db574f8ae3 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -22,9 +22,8 @@
22#include <linux/amba/clcd.h> 22#include <linux/amba/clcd.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/clkdev.h>
25 26
26#include <asm/clkdev.h>
27#include <mach/clkdev.h>
28#include <asm/hardware/icst.h> 27#include <asm/hardware/icst.h>
29#include <mach/lm.h> 28#include <mach/lm.h>
30#include <mach/impd1.h> 29#include <mach/impd1.h>
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 548208f1117..2774df8021d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -372,7 +372,6 @@ static struct clocksource clocksource_timersp = {
372 .rating = 200, 372 .rating = 200,
373 .read = timersp_read, 373 .read = timersp_read,
374 .mask = CLOCKSOURCE_MASK(16), 374 .mask = CLOCKSOURCE_MASK(16),
375 .shift = 16,
376 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 375 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
377}; 376};
378 377
@@ -390,8 +389,7 @@ static void integrator_clocksource_init(u32 khz)
390 writel(ctrl, base + TIMER_CTRL); 389 writel(ctrl, base + TIMER_CTRL);
391 writel(0xffff, base + TIMER_LOAD); 390 writel(0xffff, base + TIMER_LOAD);
392 391
393 cs->mult = clocksource_khz2mult(khz, cs->shift); 392 clocksource_register_khz(cs, khz);
394 clocksource_register(cs);
395} 393}
396 394
397static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; 395static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 6258c90d020..85e48a5f77b 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -21,9 +21,8 @@
21#include <linux/amba/mmci.h> 21#include <linux/amba/mmci.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/gfp.h> 23#include <linux/gfp.h>
24#include <linux/clkdev.h>
24 25
25#include <asm/clkdev.h>
26#include <mach/clkdev.h>
27#include <mach/hardware.h> 26#include <mach/hardware.h>
28#include <mach/platform.h> 27#include <mach/platform.h>
29#include <asm/irq.h> 28#include <asm/irq.h>
@@ -41,7 +40,7 @@
41#include <asm/mach/map.h> 40#include <asm/mach/map.h>
42#include <asm/mach/time.h> 41#include <asm/mach/time.h>
43 42
44#include <plat/timer-sp.h> 43#include <asm/hardware/timer-sp.h>
45 44
46#include "common.h" 45#include "common.h"
47 46
diff --git a/arch/arm/mach-iop13xx/include/mach/io.h b/arch/arm/mach-iop13xx/include/mach/io.h
index a6e0f9e6ddc..dffb234bb96 100644
--- a/arch/arm/mach-iop13xx/include/mach/io.h
+++ b/arch/arm/mach-iop13xx/include/mach/io.h
@@ -35,7 +35,7 @@ extern u32 iop13xx_atux_mem_base;
35extern size_t iop13xx_atue_mem_size; 35extern size_t iop13xx_atue_mem_size;
36extern size_t iop13xx_atux_mem_size; 36extern size_t iop13xx_atux_mem_size;
37 37
38#define __arch_ioremap(a, s, f) __iop13xx_ioremap(a, s, f) 38#define __arch_ioremap __iop13xx_ioremap
39#define __arch_iounmap(a) __iop13xx_iounmap(a) 39#define __arch_iounmap __iop13xx_iounmap
40 40
41#endif 41#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index 7415e433865..3ad45531886 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -58,13 +58,13 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
58 __dma; \ 58 __dma; \
59 }) 59 })
60 60
61#define __arch_page_to_dma(dev, page) \ 61#define __arch_pfn_to_dma(dev, pfn) \
62 ({ \ 62 ({ \
63 /* __is_lbus_virt() can never be true for RAM pages */ \ 63 /* __is_lbus_virt() can never be true for RAM pages */ \
64 (dma_addr_t)page_to_phys(page); \ 64 (dma_addr_t)__pfn_to_phys(pfn); \
65 }) 65 })
66 66
67#define __arch_dma_to_page(dev, addr) phys_to_page(addr) 67#define __arch_dma_to_pfn(dev, addr) __phys_to_pfn(addr)
68 68
69#endif /* CONFIG_ARCH_IOP13XX */ 69#endif /* CONFIG_ARCH_IOP13XX */
70#endif /* !ASSEMBLY */ 70#endif /* !ASSEMBLY */
diff --git a/arch/arm/mach-iop32x/include/mach/io.h b/arch/arm/mach-iop32x/include/mach/io.h
index 339e5854728..059c783ce0b 100644
--- a/arch/arm/mach-iop32x/include/mach/io.h
+++ b/arch/arm/mach-iop32x/include/mach/io.h
@@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
21#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p)) 21#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
22#define __mem_pci(a) (a) 22#define __mem_pci(a) (a)
23 23
24#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f) 24#define __arch_ioremap __iop3xx_ioremap
25#define __arch_iounmap(a) __iop3xx_iounmap(a) 25#define __arch_iounmap __iop3xx_iounmap
26 26
27#endif 27#endif
diff --git a/arch/arm/mach-iop33x/include/mach/io.h b/arch/arm/mach-iop33x/include/mach/io.h
index e99a7ed6d05..39e893e97c2 100644
--- a/arch/arm/mach-iop33x/include/mach/io.h
+++ b/arch/arm/mach-iop33x/include/mach/io.h
@@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
21#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p)) 21#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
22#define __mem_pci(a) (a) 22#define __mem_pci(a) (a)
23 23
24#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f) 24#define __arch_ioremap __iop3xx_ioremap
25#define __arch_iounmap(a) __iop3xx_iounmap(a) 25#define __arch_iounmap __iop3xx_iounmap
26 26
27#endif 27#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/io.h b/arch/arm/mach-ixp23xx/include/mach/io.h
index fd9ef8e519f..a1749d0fd89 100644
--- a/arch/arm/mach-ixp23xx/include/mach/io.h
+++ b/arch/arm/mach-ixp23xx/include/mach/io.h
@@ -45,8 +45,8 @@ ixp23xx_iounmap(void __iomem *addr)
45 __iounmap(addr); 45 __iounmap(addr);
46} 46}
47 47
48#define __arch_ioremap(a,s,f) ixp23xx_ioremap(a,s,f) 48#define __arch_ioremap ixp23xx_ioremap
49#define __arch_iounmap(a) ixp23xx_iounmap(a) 49#define __arch_iounmap ixp23xx_iounmap
50 50
51 51
52#endif 52#endif
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 24498a932ba..a54b3db8036 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
513 513
514EXPORT_SYMBOL(ixp4xx_pci_read); 514EXPORT_SYMBOL(ixp4xx_pci_read);
515EXPORT_SYMBOL(ixp4xx_pci_write); 515EXPORT_SYMBOL(ixp4xx_pci_write);
516 516EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 0bce09799d1..4dbfcbb9163 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -35,6 +35,7 @@
35#include <asm/pgtable.h> 35#include <asm/pgtable.h>
36#include <asm/page.h> 36#include <asm/page.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/sched_clock.h>
38 39
39#include <asm/mach/map.h> 40#include <asm/mach/map.h>
40#include <asm/mach/irq.h> 41#include <asm/mach/irq.h>
@@ -399,6 +400,23 @@ void __init ixp4xx_sys_init(void)
399} 400}
400 401
401/* 402/*
403 * sched_clock()
404 */
405static DEFINE_CLOCK_DATA(cd);
406
407unsigned long long notrace sched_clock(void)
408{
409 u32 cyc = *IXP4XX_OSTS;
410 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
411}
412
413static void notrace ixp4xx_update_sched_clock(void)
414{
415 u32 cyc = *IXP4XX_OSTS;
416 update_sched_clock(&cd, cyc, (u32)~0);
417}
418
419/*
402 * clocksource 420 * clocksource
403 */ 421 */
404static cycle_t ixp4xx_get_cycles(struct clocksource *cs) 422static cycle_t ixp4xx_get_cycles(struct clocksource *cs)
@@ -411,7 +429,6 @@ static struct clocksource clocksource_ixp4xx = {
411 .rating = 200, 429 .rating = 200,
412 .read = ixp4xx_get_cycles, 430 .read = ixp4xx_get_cycles,
413 .mask = CLOCKSOURCE_MASK(32), 431 .mask = CLOCKSOURCE_MASK(32),
414 .shift = 20,
415 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 432 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
416}; 433};
417 434
@@ -419,21 +436,9 @@ unsigned long ixp4xx_timer_freq = FREQ;
419EXPORT_SYMBOL(ixp4xx_timer_freq); 436EXPORT_SYMBOL(ixp4xx_timer_freq);
420static void __init ixp4xx_clocksource_init(void) 437static void __init ixp4xx_clocksource_init(void)
421{ 438{
422 clocksource_ixp4xx.mult = 439 init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq);
423 clocksource_hz2mult(ixp4xx_timer_freq,
424 clocksource_ixp4xx.shift);
425 clocksource_register(&clocksource_ixp4xx);
426}
427
428/*
429 * sched_clock()
430 */
431unsigned long long sched_clock(void)
432{
433 cycle_t cyc = ixp4xx_get_cycles(NULL);
434 struct clocksource *cs = &clocksource_ixp4xx;
435 440
436 return clocksource_cyc2ns(cyc, cs->mult, cs->shift); 441 clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq);
437} 442}
438 443
439/* 444/*
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
index de274a1f19d..57b5410c31f 100644
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -74,8 +74,8 @@ static inline void __indirect_iounmap(void __iomem *addr)
74 __iounmap(addr); 74 __iounmap(addr);
75} 75}
76 76
77#define __arch_ioremap(a, s, f) __indirect_ioremap(a, s, f) 77#define __arch_ioremap __indirect_ioremap
78#define __arch_iounmap(a) __indirect_iounmap(a) 78#define __arch_iounmap __indirect_iounmap
79 79
80#define writeb(v, p) __indirect_writeb(v, p) 80#define writeb(v, p) __indirect_writeb(v, p)
81#define writew(v, p) __indirect_writew(v, p) 81#define writew(v, p) __indirect_writew(v, p)
diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h
index 44e8be04f25..1aaddc364f2 100644
--- a/arch/arm/mach-kirkwood/include/mach/io.h
+++ b/arch/arm/mach-kirkwood/include/mach/io.h
@@ -42,8 +42,8 @@ __arch_iounmap(void __iomem *addr)
42 __iounmap(addr); 42 __iounmap(addr);
43} 43}
44 44
45#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m) 45#define __arch_ioremap __arch_ioremap
46#define __arch_iounmap(a) __arch_iounmap(a) 46#define __arch_iounmap __arch_iounmap
47#define __io(a) __io(a) 47#define __io(a) __io(a)
48#define __mem_pci(a) (a) 48#define __mem_pci(a) (a)
49 49
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
index fe0c82e30b2..f5c39a8c2b0 100644
--- a/arch/arm/mach-ks8695/Kconfig
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -4,6 +4,7 @@ menu "Kendin/Micrel KS8695 Implementations"
4 4
5config MACH_KS8695 5config MACH_KS8695
6 bool "KS8695 development board" 6 bool "KS8695 development board"
7 select MIGHT_HAVE_PCI
7 help 8 help
8 Say 'Y' here if you want your kernel to run on the original 9 Say 'Y' here if you want your kernel to run on the original
9 Kendin-Micrel KS8695 development board. 10 Kendin-Micrel KS8695 development board.
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index ffa19aae6e0..bace9a681ad 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -35,17 +35,17 @@ extern struct bus_type platform_bus_type;
35 __phys_to_virt(x) : __bus_to_virt(x)); }) 35 __phys_to_virt(x) : __bus_to_virt(x)); })
36#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \ 36#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
37 (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); }) 37 (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
38#define __arch_page_to_dma(dev, x) \ 38#define __arch_pfn_to_dma(dev, pfn) \
39 ({ dma_addr_t __dma = page_to_phys(page); \ 39 ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
40 if (!is_lbus_device(dev)) \ 40 if (!is_lbus_device(dev)) \
41 __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \ 41 __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
42 __dma; }) 42 __dma; })
43 43
44#define __arch_dma_to_page(dev, x) \ 44#define __arch_dma_to_pfn(dev, x) \
45 ({ dma_addr_t __dma = x; \ 45 ({ dma_addr_t __dma = x; \
46 if (!is_lbus_device(dev)) \ 46 if (!is_lbus_device(dev)) \
47 __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \ 47 __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \
48 phys_to_page(__dma); \ 48 __phys_to_pfn(__dma); \
49 }) 49 })
50 50
51#endif 51#endif
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index 32d63796430..da0e6498110 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -90,10 +90,9 @@
90#include <linux/clk.h> 90#include <linux/clk.h>
91#include <linux/amba/bus.h> 91#include <linux/amba/bus.h>
92#include <linux/amba/clcd.h> 92#include <linux/amba/clcd.h>
93#include <linux/clkdev.h>
93 94
94#include <mach/hardware.h> 95#include <mach/hardware.h>
95#include <asm/clkdev.h>
96#include <mach/clkdev.h>
97#include <mach/platform.h> 96#include <mach/platform.h>
98#include "clock.h" 97#include "clock.h"
99#include "common.h" 98#include "common.h"
diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c
index 630dd4a74b2..6162ac308c2 100644
--- a/arch/arm/mach-lpc32xx/timer.c
+++ b/arch/arm/mach-lpc32xx/timer.c
@@ -38,7 +38,6 @@ static cycle_t lpc32xx_clksrc_read(struct clocksource *cs)
38 38
39static struct clocksource lpc32xx_clksrc = { 39static struct clocksource lpc32xx_clksrc = {
40 .name = "lpc32xx_clksrc", 40 .name = "lpc32xx_clksrc",
41 .shift = 24,
42 .rating = 300, 41 .rating = 300,
43 .read = lpc32xx_clksrc_read, 42 .read = lpc32xx_clksrc_read,
44 .mask = CLOCKSOURCE_MASK(32), 43 .mask = CLOCKSOURCE_MASK(32),
@@ -171,9 +170,7 @@ static void __init lpc32xx_timer_init(void)
171 __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); 170 __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
172 __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN, 171 __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
173 LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); 172 LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
174 lpc32xx_clksrc.mult = clocksource_hz2mult(clkrate, 173 clocksource_register_hz(&lpc32xx_clksrc, clkrate);
175 lpc32xx_clksrc.shift);
176 clocksource_register(&lpc32xx_clksrc);
177} 174}
178 175
179struct sys_timer lpc32xx_timer = { 176struct sys_timer lpc32xx_timer = {
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
index 016ae94691c..9b027d7491f 100644
--- a/arch/arm/mach-mmp/clock.h
+++ b/arch/arm/mach-mmp/clock.h
@@ -6,7 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#include <asm/clkdev.h> 9#include <linux/clkdev.h>
10 10
11struct clkops { 11struct clkops {
12 void (*enable)(struct clk *); 12 void (*enable)(struct clk *);
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 66528193f93..aeb9ae23e6c 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -26,8 +26,8 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/irq.h> 27#include <linux/irq.h>
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/cnt32_to_63.h>
30 29
30#include <asm/sched_clock.h>
31#include <mach/addr-map.h> 31#include <mach/addr-map.h>
32#include <mach/regs-timers.h> 32#include <mach/regs-timers.h>
33#include <mach/regs-apbc.h> 33#include <mach/regs-apbc.h>
@@ -42,23 +42,7 @@
42#define MAX_DELTA (0xfffffffe) 42#define MAX_DELTA (0xfffffffe)
43#define MIN_DELTA (16) 43#define MIN_DELTA (16)
44 44
45#define TCR2NS_SCALE_FACTOR 10 45static DEFINE_CLOCK_DATA(cd);
46
47static unsigned long tcr2ns_scale;
48
49static void __init set_tcr2ns_scale(unsigned long tcr_rate)
50{
51 unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR;
52 do_div(v, tcr_rate);
53 tcr2ns_scale = v;
54 /*
55 * We want an even value to automatically clear the top bit
56 * returned by cnt32_to_63() without an additional run time
57 * instruction. So if the LSB is 1 then round it up.
58 */
59 if (tcr2ns_scale & 1)
60 tcr2ns_scale++;
61}
62 46
63/* 47/*
64 * FIXME: the timer needs some delay to stablize the counter capture 48 * FIXME: the timer needs some delay to stablize the counter capture
@@ -75,10 +59,16 @@ static inline uint32_t timer_read(void)
75 return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); 59 return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0));
76} 60}
77 61
78unsigned long long sched_clock(void) 62unsigned long long notrace sched_clock(void)
79{ 63{
80 unsigned long long v = cnt32_to_63(timer_read()); 64 u32 cyc = timer_read();
81 return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR; 65 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
66}
67
68static void notrace mmp_update_sched_clock(void)
69{
70 u32 cyc = timer_read();
71 update_sched_clock(&cd, cyc, (u32)~0);
82} 72}
83 73
84static irqreturn_t timer_interrupt(int irq, void *dev_id) 74static irqreturn_t timer_interrupt(int irq, void *dev_id)
@@ -146,7 +136,6 @@ static cycle_t clksrc_read(struct clocksource *cs)
146 136
147static struct clocksource cksrc = { 137static struct clocksource cksrc = {
148 .name = "clocksource", 138 .name = "clocksource",
149 .shift = 20,
150 .rating = 200, 139 .rating = 200,
151 .read = clksrc_read, 140 .read = clksrc_read,
152 .mask = CLOCKSOURCE_MASK(32), 141 .mask = CLOCKSOURCE_MASK(32),
@@ -186,17 +175,15 @@ void __init timer_init(int irq)
186{ 175{
187 timer_config(); 176 timer_config();
188 177
189 set_tcr2ns_scale(CLOCK_TICK_RATE); 178 init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE);
190 179
191 ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); 180 ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift);
192 ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); 181 ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt);
193 ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt); 182 ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt);
194 ckevt.cpumask = cpumask_of(0); 183 ckevt.cpumask = cpumask_of(0);
195 184
196 cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift);
197
198 setup_irq(irq, &timer_irq); 185 setup_irq(irq, &timer_irq);
199 186
200 clocksource_register(&cksrc); 187 clocksource_register_hz(&cksrc, CLOCK_TICK_RATE);
201 clockevents_register_device(&ckevt); 188 clockevents_register_device(&ckevt);
202} 189}
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 7486a681cc7..9b5eb2b4ae1 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -28,8 +28,6 @@
28#include <mach/board.h> 28#include <mach/board.h>
29#include <mach/msm_iomap.h> 29#include <mach/msm_iomap.h>
30 30
31void __iomem *gic_cpu_base_addr;
32
33unsigned long clk_get_max_axi_khz(void) 31unsigned long clk_get_max_axi_khz(void)
34{ 32{
35 return 0; 33 return 0;
@@ -44,9 +42,8 @@ static void __init msm8x60_init_irq(void)
44{ 42{
45 unsigned int i; 43 unsigned int i;
46 44
47 gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START); 45 gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
48 gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE; 46 (void *)MSM_QGIC_CPU_BASE);
49 gic_cpu_init(0, MSM_QGIC_CPU_BASE);
50 47
51 /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ 48 /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
52 writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); 49 writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
diff --git a/arch/arm/mach-msm/include/mach/smp.h b/arch/arm/mach-msm/include/mach/smp.h
index 3ff7bf5e679..a95f7b9efe3 100644
--- a/arch/arm/mach-msm/include/mach/smp.h
+++ b/arch/arm/mach-msm/include/mach/smp.h
@@ -31,9 +31,9 @@
31 31
32#include <asm/hardware/gic.h> 32#include <asm/hardware/gic.h>
33 33
34static inline void smp_cross_call(const struct cpumask *mask) 34static inline void smp_cross_call(const struct cpumask *mask, int ipi)
35{ 35{
36 gic_raise_softirq(mask, 1); 36 gic_raise_softirq(mask, ipi);
37} 37}
38 38
39#endif 39#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 950100f19d0..595be7fea31 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -137,7 +137,6 @@ static struct msm_clock msm_clocks[] = {
137 .rating = 200, 137 .rating = 200,
138 .read = msm_gpt_read, 138 .read = msm_gpt_read,
139 .mask = CLOCKSOURCE_MASK(32), 139 .mask = CLOCKSOURCE_MASK(32),
140 .shift = 17,
141 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 140 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
142 }, 141 },
143 .irq = { 142 .irq = {
@@ -164,7 +163,6 @@ static struct msm_clock msm_clocks[] = {
164 .rating = 300, 163 .rating = 300,
165 .read = msm_dgt_read, 164 .read = msm_dgt_read,
166 .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), 165 .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
167 .shift = 24 - MSM_DGT_SHIFT,
168 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 166 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
169 }, 167 },
170 .irq = { 168 .irq = {
@@ -205,8 +203,7 @@ static void __init msm_timer_init(void)
205 ce->min_delta_ns = clockevent_delta2ns(4, ce); 203 ce->min_delta_ns = clockevent_delta2ns(4, ce);
206 ce->cpumask = cpumask_of(0); 204 ce->cpumask = cpumask_of(0);
207 205
208 cs->mult = clocksource_hz2mult(clock->freq, cs->shift); 206 res = clocksource_register_hz(cs, clock->freq);
209 res = clocksource_register(cs);
210 if (res) 207 if (res)
211 printk(KERN_ERR "msm_timer_init: clocksource_register " 208 printk(KERN_ERR "msm_timer_init: clocksource_register "
212 "failed for %s\n", cs->name); 209 "failed for %s\n", cs->name);
diff --git a/arch/arm/mach-mx3/clock-imx31.c b/arch/arm/mach-mx3/clock-imx31.c
index 4193cf5a263..d423cac8cab 100644
--- a/arch/arm/mach-mx3/clock-imx31.c
+++ b/arch/arm/mach-mx3/clock-imx31.c
@@ -23,8 +23,8 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/clkdev.h>
26 27
27#include <asm/clkdev.h>
28#include <asm/div64.h> 28#include <asm/div64.h>
29 29
30#include <mach/clock.h> 30#include <mach/clock.h>
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 22259d95583..448a038cd1e 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -21,8 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/clkdev.h>
25#include <asm/clkdev.h>
26 25
27#include <mach/clock.h> 26#include <mach/clock.h>
28#include <mach/hardware.h> 27#include <mach/hardware.h>
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index b21bc47d482..785e1a33618 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -14,8 +14,8 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/clkdev.h>
17 18
18#include <asm/clkdev.h>
19#include <asm/div64.h> 19#include <asm/div64.h>
20 20
21#include <mach/hardware.h> 21#include <mach/hardware.h>
diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c
index 5c85075d8a5..9fab505f1eb 100644
--- a/arch/arm/mach-mxc91231/clock.c
+++ b/arch/arm/mach-mxc91231/clock.c
@@ -2,12 +2,12 @@
2#include <linux/kernel.h> 2#include <linux/kernel.h>
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/io.h> 4#include <linux/io.h>
5#include <linux/clkdev.h>
5 6
6#include <mach/clock.h> 7#include <mach/clock.h>
7#include <mach/hardware.h> 8#include <mach/hardware.h>
8#include <mach/common.h> 9#include <mach/common.h>
9 10
10#include <asm/clkdev.h>
11#include <asm/bug.h> 11#include <asm/bug.h>
12#include <asm/div64.h> 12#include <asm/div64.h>
13 13
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 82801dbf057..f12f22d09b6 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -114,7 +114,6 @@ static struct clocksource clocksource_netx = {
114 .rating = 200, 114 .rating = 200,
115 .read = netx_get_cycles, 115 .read = netx_get_cycles,
116 .mask = CLOCKSOURCE_MASK(32), 116 .mask = CLOCKSOURCE_MASK(32),
117 .shift = 20,
118 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 117 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
119}; 118};
120 119
@@ -151,9 +150,7 @@ static void __init netx_timer_init(void)
151 writel(NETX_GPIO_COUNTER_CTRL_RUN, 150 writel(NETX_GPIO_COUNTER_CTRL_RUN,
152 NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE)); 151 NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
153 152
154 clocksource_netx.mult = 153 clocksource_register_hz(&clocksource_netx, CLOCK_TICK_RATE);
155 clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift);
156 clocksource_register(&clocksource_netx);
157 154
158 netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 155 netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
159 netx_clockevent.shift); 156 netx_clockevent.shift);
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
index 89f793adf77..48a59f24e10 100644
--- a/arch/arm/mach-nomadik/clock.c
+++ b/arch/arm/mach-nomadik/clock.c
@@ -7,7 +7,7 @@
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/clk.h> 9#include <linux/clk.h>
10#include <asm/clkdev.h> 10#include <linux/clkdev.h>
11#include "clock.h" 11#include "clock.h"
12 12
13/* 13/*
diff --git a/arch/arm/mach-ns9xxx/time-ns9360.c b/arch/arm/mach-ns9xxx/time-ns9360.c
index 77281260358..9ca32f55728 100644
--- a/arch/arm/mach-ns9xxx/time-ns9360.c
+++ b/arch/arm/mach-ns9xxx/time-ns9360.c
@@ -35,7 +35,6 @@ static struct clocksource ns9360_clocksource = {
35 .rating = 300, 35 .rating = 300,
36 .read = ns9360_clocksource_read, 36 .read = ns9360_clocksource_read,
37 .mask = CLOCKSOURCE_MASK(32), 37 .mask = CLOCKSOURCE_MASK(32),
38 .shift = 20,
39 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 38 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
40}; 39};
41 40
@@ -148,10 +147,7 @@ static void __init ns9360_timer_init(void)
148 147
149 __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE)); 148 __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
150 149
151 ns9360_clocksource.mult = clocksource_hz2mult(ns9360_cpuclock(), 150 clocksource_register_hz(&ns9360_clocksource, ns9360_cpuclock());
152 ns9360_clocksource.shift);
153
154 clocksource_register(&ns9360_clocksource);
155 151
156 latch = SH_DIV(ns9360_cpuclock(), HZ, 0); 152 latch = SH_DIV(ns9360_cpuclock(), HZ, 0);
157 153
diff --git a/arch/arm/mach-nuc93x/clock.h b/arch/arm/mach-nuc93x/clock.h
index 18e51be4816..4de1f1da9dc 100644
--- a/arch/arm/mach-nuc93x/clock.h
+++ b/arch/arm/mach-nuc93x/clock.h
@@ -10,7 +10,7 @@
10 * the Free Software Foundation; either version 2 of the License. 10 * the Free Software Foundation; either version 2 of the License.
11 */ 11 */
12 12
13#include <asm/clkdev.h> 13#include <linux/clkdev.h>
14 14
15void nuc93x_clk_enable(struct clk *clk, int enable); 15void nuc93x_clk_enable(struct clk *clk, int enable);
16void clks_register(struct clk_lookup *clks, size_t num); 16void clks_register(struct clk_lookup *clks, size_t num);
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index b8c7fb9d792..84ef70476b5 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -17,9 +17,9 @@
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/clk.h> 18#include <linux/clk.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/clkdev.h>
20 21
21#include <asm/mach-types.h> 22#include <asm/mach-types.h>
22#include <asm/clkdev.h>
23 23
24#include <plat/cpu.h> 24#include <plat/cpu.h>
25#include <plat/usb.h> 25#include <plat/usb.h>
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 1be6a214d88..abb34ff2041 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -208,7 +208,6 @@ static struct clocksource clocksource_mpu = {
208 .rating = 300, 208 .rating = 300,
209 .read = mpu_read, 209 .read = mpu_read,
210 .mask = CLOCKSOURCE_MASK(32), 210 .mask = CLOCKSOURCE_MASK(32),
211 .shift = 24,
212 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 211 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
213}; 212};
214 213
@@ -217,13 +216,10 @@ static void __init omap_init_clocksource(unsigned long rate)
217 static char err[] __initdata = KERN_ERR 216 static char err[] __initdata = KERN_ERR
218 "%s: can't register clocksource!\n"; 217 "%s: can't register clocksource!\n";
219 218
220 clocksource_mpu.mult
221 = clocksource_khz2mult(rate/1000, clocksource_mpu.shift);
222
223 setup_irq(INT_TIMER2, &omap_mpu_timer2_irq); 219 setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
224 omap_mpu_timer_start(1, ~0, 1); 220 omap_mpu_timer_start(1, ~0, 1);
225 221
226 if (clocksource_register(&clocksource_mpu)) 222 if (clocksource_register_hz(&clocksource_mpu, rate))
227 printk(err, clocksource_mpu.name); 223 printk(err, clocksource_mpu.name);
228} 224}
229 225
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index ed8d330522f..ebb888f5936 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -26,10 +26,10 @@
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/clkdev.h>
29 30
30#include <plat/cpu.h> 31#include <plat/cpu.h>
31#include <plat/clock.h> 32#include <plat/clock.h>
32#include <asm/clkdev.h>
33 33
34#include "clock.h" 34#include "clock.h"
35#include "prm.h" 35#include "prm.h"
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S
index 06e64e1fc28..d54c4f89a8b 100644
--- a/arch/arm/mach-omap2/include/mach/entry-macro.S
+++ b/arch/arm/mach-omap2/include/mach/entry-macro.S
@@ -105,6 +105,35 @@ omap_irq_base: .word 0
1059999: 1059999:
106 .endm 106 .endm
107 107
108#ifdef CONFIG_SMP
109 /* We assume that irqstat (the raw value of the IRQ acknowledge
110 * register) is preserved from the macro above.
111 * If there is an IPI, we immediately signal end of interrupt
112 * on the controller, since this requires the original irqstat
113 * value which we won't easily be able to recreate later.
114 */
115
116 .macro test_for_ipi, irqnr, irqstat, base, tmp
117 bic \irqnr, \irqstat, #0x1c00
118 cmp \irqnr, #16
119 it cc
120 strcc \irqstat, [\base, #GIC_CPU_EOI]
121 it cs
122 cmpcs \irqnr, \irqnr
123 .endm
124
125 /* As above, this assumes that irqstat and base are preserved */
126
127 .macro test_for_ltirq, irqnr, irqstat, base, tmp
128 bic \irqnr, \irqstat, #0x1c00
129 mov \tmp, #0
130 cmp \irqnr, #29
131 itt eq
132 moveq \tmp, #1
133 streq \irqstat, [\base, #GIC_CPU_EOI]
134 cmp \tmp, #0
135 .endm
136#endif /* CONFIG_SMP */
108 137
109#else /* MULTI_OMAP2 */ 138#else /* MULTI_OMAP2 */
110 139
@@ -141,74 +170,16 @@ omap_irq_base: .word 0
141 170
142 171
143#ifdef CONFIG_ARCH_OMAP4 172#ifdef CONFIG_ARCH_OMAP4
173#define HAVE_GET_IRQNR_PREAMBLE
174#include <asm/hardware/entry-macro-gic.S>
144 175
145 .macro get_irqnr_preamble, base, tmp 176 .macro get_irqnr_preamble, base, tmp
146 ldr \base, =OMAP4_IRQ_BASE 177 ldr \base, =OMAP4_IRQ_BASE
147 .endm 178 .endm
148 179
149 /*
150 * The interrupt numbering scheme is defined in the
151 * interrupt controller spec. To wit:
152 *
153 * Interrupts 0-15 are IPI
154 * 16-28 are reserved
155 * 29-31 are local. We allow 30 to be used for the watchdog.
156 * 32-1020 are global
157 * 1021-1022 are reserved
158 * 1023 is "spurious" (no interrupt)
159 *
160 * For now, we ignore all local interrupts so only return an
161 * interrupt if it's between 30 and 1020. The test_for_ipi
162 * routine below will pick up on IPIs.
163 * A simple read from the controller will tell us the number
164 * of the highest priority enabled interrupt.
165 * We then just need to check whether it is in the
166 * valid range for an IRQ (30-1020 inclusive).
167 */
168 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
169 ldr \irqstat, [\base, #GIC_CPU_INTACK]
170
171 ldr \tmp, =1021
172
173 bic \irqnr, \irqstat, #0x1c00
174
175 cmp \irqnr, #29
176 cmpcc \irqnr, \irqnr
177 cmpne \irqnr, \tmp
178 cmpcs \irqnr, \irqnr
179 .endm
180#endif 180#endif
181#endif /* MULTI_OMAP2 */
182
183#ifdef CONFIG_SMP
184 /* We assume that irqstat (the raw value of the IRQ acknowledge
185 * register) is preserved from the macro above.
186 * If there is an IPI, we immediately signal end of interrupt
187 * on the controller, since this requires the original irqstat
188 * value which we won't easily be able to recreate later.
189 */
190 181
191 .macro test_for_ipi, irqnr, irqstat, base, tmp 182#endif /* MULTI_OMAP2 */
192 bic \irqnr, \irqstat, #0x1c00
193 cmp \irqnr, #16
194 it cc
195 strcc \irqstat, [\base, #GIC_CPU_EOI]
196 it cs
197 cmpcs \irqnr, \irqnr
198 .endm
199
200 /* As above, this assumes that irqstat and base are preserved */
201
202 .macro test_for_ltirq, irqnr, irqstat, base, tmp
203 bic \irqnr, \irqstat, #0x1c00
204 mov \tmp, #0
205 cmp \irqnr, #29
206 itt eq
207 moveq \tmp, #1
208 streq \irqstat, [\base, #GIC_CPU_EOI]
209 cmp \tmp, #0
210 .endm
211#endif /* CONFIG_SMP */
212 183
213 .macro irq_prio_table 184 .macro irq_prio_table
214 .endm 185 .endm
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index 2744dfee1ff..5b0270b2893 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -24,7 +24,6 @@
24extern void __iomem *l2cache_base; 24extern void __iomem *l2cache_base;
25#endif 25#endif
26 26
27extern void __iomem *gic_cpu_base_addr;
28extern void __iomem *gic_dist_base_addr; 27extern void __iomem *gic_dist_base_addr;
29 28
30extern void __init gic_init_irq(void); 29extern void __init gic_init_irq(void);
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index 6cee456ca54..4976b9393e4 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -17,16 +17,13 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/completion.h>
21 20
22#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
23#include <mach/omap4-common.h> 22#include <mach/omap4-common.h>
24 23
25static DECLARE_COMPLETION(cpu_killed);
26
27int platform_cpu_kill(unsigned int cpu) 24int platform_cpu_kill(unsigned int cpu)
28{ 25{
29 return wait_for_completion_timeout(&cpu_killed, 5000); 26 return 1;
30} 27}
31 28
32/* 29/*
@@ -35,15 +32,6 @@ int platform_cpu_kill(unsigned int cpu)
35 */ 32 */
36void platform_cpu_die(unsigned int cpu) 33void platform_cpu_die(unsigned int cpu)
37{ 34{
38 unsigned int this_cpu = hard_smp_processor_id();
39
40 if (cpu != this_cpu) {
41 pr_crit("platform_cpu_die running on %u, should be %u\n",
42 this_cpu, cpu);
43 BUG();
44 }
45 pr_notice("CPU%u: shutdown\n", cpu);
46 complete(&cpu_killed);
47 flush_cache_all(); 35 flush_cache_all();
48 dsb(); 36 dsb();
49 37
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 9e9f70e18e3..b66cfe8bc46 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -21,7 +21,6 @@
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/localtimer.h>
25#include <asm/smp_scu.h> 24#include <asm/smp_scu.h>
26#include <mach/hardware.h> 25#include <mach/hardware.h>
27#include <mach/omap4-common.h> 26#include <mach/omap4-common.h>
@@ -29,28 +28,16 @@
29/* SCU base address */ 28/* SCU base address */
30static void __iomem *scu_base; 29static void __iomem *scu_base;
31 30
32/*
33 * Use SCU config register to count number of cores
34 */
35static inline unsigned int get_core_count(void)
36{
37 if (scu_base)
38 return scu_get_core_count(scu_base);
39 return 1;
40}
41
42static DEFINE_SPINLOCK(boot_lock); 31static DEFINE_SPINLOCK(boot_lock);
43 32
44void __cpuinit platform_secondary_init(unsigned int cpu) 33void __cpuinit platform_secondary_init(unsigned int cpu)
45{ 34{
46 trace_hardirqs_off();
47
48 /* 35 /*
49 * If any interrupts are already enabled for the primary 36 * If any interrupts are already enabled for the primary
50 * core (e.g. timer irq), then they will not have been enabled 37 * core (e.g. timer irq), then they will not have been enabled
51 * for us: do so 38 * for us: do so
52 */ 39 */
53 gic_cpu_init(0, gic_cpu_base_addr); 40 gic_secondary_init(0);
54 41
55 /* 42 /*
56 * Synchronise with the boot thread. 43 * Synchronise with the boot thread.
@@ -76,7 +63,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
76 omap_modify_auxcoreboot0(0x200, 0xfffffdff); 63 omap_modify_auxcoreboot0(0x200, 0xfffffdff);
77 flush_cache_all(); 64 flush_cache_all();
78 smp_wmb(); 65 smp_wmb();
79 smp_cross_call(cpumask_of(cpu)); 66 smp_cross_call(cpumask_of(cpu), 1);
80 67
81 /* 68 /*
82 * Now the secondary core is starting up let it run its 69 * Now the secondary core is starting up let it run its
@@ -118,25 +105,9 @@ void __init smp_init_cpus(void)
118 scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256); 105 scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
119 BUG_ON(!scu_base); 106 BUG_ON(!scu_base);
120 107
121 ncores = get_core_count(); 108 ncores = scu_get_core_count(scu_base);
122
123 for (i = 0; i < ncores; i++)
124 set_cpu_possible(i, true);
125}
126
127void __init smp_prepare_cpus(unsigned int max_cpus)
128{
129 unsigned int ncores = get_core_count();
130 unsigned int cpu = smp_processor_id();
131 int i;
132 109
133 /* sanity check */ 110 /* sanity check */
134 if (ncores == 0) {
135 printk(KERN_ERR
136 "OMAP4: strange core count of 0? Default to 1\n");
137 ncores = 1;
138 }
139
140 if (ncores > NR_CPUS) { 111 if (ncores > NR_CPUS) {
141 printk(KERN_WARNING 112 printk(KERN_WARNING
142 "OMAP4: no. of cores (%d) greater than configured " 113 "OMAP4: no. of cores (%d) greater than configured "
@@ -144,13 +115,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
144 ncores, NR_CPUS); 115 ncores, NR_CPUS);
145 ncores = NR_CPUS; 116 ncores = NR_CPUS;
146 } 117 }
147 smp_store_cpu_info(cpu);
148 118
149 /* 119 for (i = 0; i < ncores; i++)
150 * are we trying to boot more cores than exist? 120 set_cpu_possible(i, true);
151 */ 121}
152 if (max_cpus > ncores) 122
153 max_cpus = ncores; 123void __init platform_smp_prepare_cpus(unsigned int max_cpus)
124{
125 int i;
154 126
155 /* 127 /*
156 * Initialise the present map, which describes the set of CPUs 128 * Initialise the present map, which describes the set of CPUs
@@ -159,18 +131,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
159 for (i = 0; i < max_cpus; i++) 131 for (i = 0; i < max_cpus; i++)
160 set_cpu_present(i, true); 132 set_cpu_present(i, true);
161 133
162 if (max_cpus > 1) { 134 /*
163 /* 135 * Initialise the SCU and wake up the secondary core using
164 * Enable the local timer or broadcast device for the 136 * wakeup_secondary().
165 * boot CPU, but only if we have more than one CPU. 137 */
166 */ 138 scu_enable(scu_base);
167 percpu_timer_setup(); 139 wakeup_secondary();
168
169 /*
170 * Initialise the SCU and wake up the secondary core using
171 * wakeup_secondary().
172 */
173 scu_enable(scu_base);
174 wakeup_secondary();
175 }
176} 140}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 2f895553e6a..666e852988d 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -26,21 +26,22 @@
26void __iomem *l2cache_base; 26void __iomem *l2cache_base;
27#endif 27#endif
28 28
29void __iomem *gic_cpu_base_addr;
30void __iomem *gic_dist_base_addr; 29void __iomem *gic_dist_base_addr;
31 30
32 31
33void __init gic_init_irq(void) 32void __init gic_init_irq(void)
34{ 33{
34 void __iomem *gic_cpu_base;
35
35 /* Static mapping, never released */ 36 /* Static mapping, never released */
36 gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K); 37 gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
37 BUG_ON(!gic_dist_base_addr); 38 BUG_ON(!gic_dist_base_addr);
38 gic_dist_init(0, gic_dist_base_addr, 29);
39 39
40 /* Static mapping, never released */ 40 /* Static mapping, never released */
41 gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); 41 gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
42 BUG_ON(!gic_cpu_base_addr); 42 BUG_ON(!gic_cpu_base);
43 gic_cpu_init(0, gic_cpu_base_addr); 43
44 gic_init(0, 29, gic_dist_base_addr, gic_cpu_base);
44} 45}
45 46
46#ifdef CONFIG_CACHE_L2X0 47#ifdef CONFIG_CACHE_L2X0
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index e13c29eecf2..a7816dbdc6b 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -195,7 +195,6 @@ static struct clocksource clocksource_gpt = {
195 .rating = 300, 195 .rating = 300,
196 .read = clocksource_read_cycles, 196 .read = clocksource_read_cycles,
197 .mask = CLOCKSOURCE_MASK(32), 197 .mask = CLOCKSOURCE_MASK(32),
198 .shift = 24,
199 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 198 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
200}; 199};
201 200
@@ -220,9 +219,7 @@ static void __init omap2_gp_clocksource_init(void)
220 219
221 omap_dm_timer_set_load_start(gpt, 1, 0); 220 omap_dm_timer_set_load_start(gpt, 1, 0);
222 221
223 clocksource_gpt.mult = 222 if (clocksource_register_hz(&clocksource_gpt, tick_rate))
224 clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift);
225 if (clocksource_register(&clocksource_gpt))
226 printk(err2, clocksource_gpt.name); 223 printk(err2, clocksource_gpt.name);
227} 224}
228#endif 225#endif
diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h
index c47b033bd99..c5196101a23 100644
--- a/arch/arm/mach-orion5x/include/mach/io.h
+++ b/arch/arm/mach-orion5x/include/mach/io.h
@@ -38,8 +38,8 @@ __arch_iounmap(void __iomem *addr)
38 __iounmap(addr); 38 __iounmap(addr);
39} 39}
40 40
41#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m) 41#define __arch_ioremap __arch_ioremap
42#define __arch_iounmap(a) __arch_iounmap(a) 42#define __arch_iounmap __arch_iounmap
43#define __io(a) __typesafe_io(a) 43#define __io(a) __typesafe_io(a)
44#define __mem_pci(a) (a) 44#define __mem_pci(a) (a)
45 45
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
index 9d1975fa4d9..a4a3819c96c 100644
--- a/arch/arm/mach-pnx4008/clock.c
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -21,8 +21,7 @@
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24#include <linux/clkdev.h>
25#include <asm/clkdev.h>
26 25
27#include <mach/hardware.h> 26#include <mach/hardware.h>
28#include <mach/clock.h> 27#include <mach/clock.h>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 1df6db6a136..2fc9f94cdd2 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -98,6 +98,7 @@ config MACH_ARMCORE
98 select PXA27x 98 select PXA27x
99 select IWMMXT 99 select IWMMXT
100 select PXA25x 100 select PXA25x
101 select MIGHT_HAVE_PCI
101 102
102config MACH_EM_X270 103config MACH_EM_X270
103 bool "CompuLab EM-x270 platform" 104 bool "CompuLab EM-x270 platform"
@@ -544,6 +545,7 @@ config MACH_ICONTROL
544config ARCH_PXA_ESERIES 545config ARCH_PXA_ESERIES
545 bool "PXA based Toshiba e-series PDAs" 546 bool "PXA based Toshiba e-series PDAs"
546 select PXA25x 547 select PXA25x
548 select FB_W100
547 549
548config MACH_E330 550config MACH_E330
549 bool "Toshiba e330" 551 bool "Toshiba e330"
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 8184fe2d71c..d5152220ce9 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -6,8 +6,7 @@
6#include <linux/clk.h> 6#include <linux/clk.h>
7#include <linux/spinlock.h> 7#include <linux/spinlock.h>
8#include <linux/delay.h> 8#include <linux/delay.h>
9 9#include <linux/clkdev.h>
10#include <asm/clkdev.h>
11 10
12#include "clock.h" 11#include "clock.h"
13 12
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index 6e949944f2e..f9f349a21b5 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -1,5 +1,5 @@
1#include <linux/clkdev.h>
1#include <linux/sysdev.h> 2#include <linux/sysdev.h>
2#include <asm/clkdev.h>
3 3
4struct clkops { 4struct clkops {
5 void (*enable)(struct clk *); 5 void (*enable)(struct clk *);
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 2f5b08aeb52..c551da86baf 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -353,8 +353,8 @@ resume_turn_on_mmu:
353 353
354 @ Let us ensure we jump to resume_after_mmu only when the mcr above 354 @ Let us ensure we jump to resume_after_mmu only when the mcr above
355 @ actually took effect. They call it the "cpwait" operation. 355 @ actually took effect. They call it the "cpwait" operation.
356 mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15 356 mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
357 sub pc, r2, r1, lsr #32 @ jump to virtual addr 357 sub pc, r2, r0, lsr #32 @ jump to virtual addr
358 nop 358 nop
359 nop 359 nop
360 nop 360 nop
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 293e40aeaf2..e7f64d9b4f2 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -17,11 +17,11 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/clockchips.h> 18#include <linux/clockchips.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/cnt32_to_63.h>
21 20
22#include <asm/div64.h> 21#include <asm/div64.h>
23#include <asm/mach/irq.h> 22#include <asm/mach/irq.h>
24#include <asm/mach/time.h> 23#include <asm/mach/time.h>
24#include <asm/sched_clock.h>
25#include <mach/regs-ost.h> 25#include <mach/regs-ost.h>
26 26
27/* 27/*
@@ -32,29 +32,18 @@
32 * long as there is always less than 582 seconds between successive 32 * long as there is always less than 582 seconds between successive
33 * calls to sched_clock() which should always be the case in practice. 33 * calls to sched_clock() which should always be the case in practice.
34 */ 34 */
35static DEFINE_CLOCK_DATA(cd);
35 36
36#define OSCR2NS_SCALE_FACTOR 10 37unsigned long long notrace sched_clock(void)
37
38static unsigned long oscr2ns_scale;
39
40static void __init set_oscr2ns_scale(unsigned long oscr_rate)
41{ 38{
42 unsigned long long v = 1000000000ULL << OSCR2NS_SCALE_FACTOR; 39 u32 cyc = OSCR;
43 do_div(v, oscr_rate); 40 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
44 oscr2ns_scale = v;
45 /*
46 * We want an even value to automatically clear the top bit
47 * returned by cnt32_to_63() without an additional run time
48 * instruction. So if the LSB is 1 then round it up.
49 */
50 if (oscr2ns_scale & 1)
51 oscr2ns_scale++;
52} 41}
53 42
54unsigned long long sched_clock(void) 43static void notrace pxa_update_sched_clock(void)
55{ 44{
56 unsigned long long v = cnt32_to_63(OSCR); 45 u32 cyc = OSCR;
57 return (v * oscr2ns_scale) >> OSCR2NS_SCALE_FACTOR; 46 update_sched_clock(&cd, cyc, (u32)~0);
58} 47}
59 48
60 49
@@ -127,7 +116,6 @@ static struct clocksource cksrc_pxa_oscr0 = {
127 .rating = 200, 116 .rating = 200,
128 .read = pxa_read_oscr, 117 .read = pxa_read_oscr,
129 .mask = CLOCKSOURCE_MASK(32), 118 .mask = CLOCKSOURCE_MASK(32),
130 .shift = 20,
131 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 119 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
132}; 120};
133 121
@@ -145,7 +133,7 @@ static void __init pxa_timer_init(void)
145 OIER = 0; 133 OIER = 0;
146 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; 134 OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
147 135
148 set_oscr2ns_scale(clock_tick_rate); 136 init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
149 137
150 ckevt_pxa_osmr0.mult = 138 ckevt_pxa_osmr0.mult =
151 div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); 139 div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
@@ -155,12 +143,9 @@ static void __init pxa_timer_init(void)
155 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1; 143 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
156 ckevt_pxa_osmr0.cpumask = cpumask_of(0); 144 ckevt_pxa_osmr0.cpumask = cpumask_of(0);
157 145
158 cksrc_pxa_oscr0.mult =
159 clocksource_hz2mult(clock_tick_rate, cksrc_pxa_oscr0.shift);
160
161 setup_irq(IRQ_OST0, &pxa_ost0_irq); 146 setup_irq(IRQ_OST0, &pxa_ost0_irq);
162 147
163 clocksource_register(&cksrc_pxa_oscr0); 148 clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate);
164 clockevents_register_device(&ckevt_pxa_osmr0); 149 clockevents_register_device(&ckevt_pxa_osmr0);
165} 150}
166 151
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 07c08151dfe..1c6602cf50e 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -30,8 +30,8 @@
30#include <linux/ata_platform.h> 30#include <linux/ata_platform.h>
31#include <linux/amba/mmci.h> 31#include <linux/amba/mmci.h>
32#include <linux/gfp.h> 32#include <linux/gfp.h>
33#include <linux/clkdev.h>
33 34
34#include <asm/clkdev.h>
35#include <asm/system.h> 35#include <asm/system.h>
36#include <mach/hardware.h> 36#include <mach/hardware.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
@@ -47,15 +47,13 @@
47 47
48#include <asm/hardware/gic.h> 48#include <asm/hardware/gic.h>
49 49
50#include <mach/clkdev.h>
51#include <mach/platform.h> 50#include <mach/platform.h>
52#include <mach/irqs.h> 51#include <mach/irqs.h>
53#include <plat/timer-sp.h> 52#include <asm/hardware/timer-sp.h>
54 53
55#include "core.h" 54#include <plat/sched_clock.h>
56 55
57/* used by entry-macro.S and platsmp.c */ 56#include "core.h"
58void __iomem *gic_cpu_base_addr;
59 57
60#ifdef CONFIG_ZONE_DMA 58#ifdef CONFIG_ZONE_DMA
61/* 59/*
@@ -658,6 +656,12 @@ void realview_leds_event(led_event_t ledevt)
658#endif /* CONFIG_LEDS */ 656#endif /* CONFIG_LEDS */
659 657
660/* 658/*
659 * The sched_clock counter
660 */
661#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + \
662 REALVIEW_SYS_24MHz_OFFSET)
663
664/*
661 * Where is the timer (VA)? 665 * Where is the timer (VA)?
662 */ 666 */
663void __iomem *timer0_va_base; 667void __iomem *timer0_va_base;
@@ -672,6 +676,8 @@ void __init realview_timer_init(unsigned int timer_irq)
672{ 676{
673 u32 val; 677 u32 val;
674 678
679 versatile_sched_clock_init(REFCOUNTER, 24000000);
680
675 /* 681 /*
676 * set clock frequency: 682 * set clock frequency:
677 * REALVIEW_REFCLK is 32KHz 683 * REALVIEW_REFCLK is 32KHz
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 781bca68a9f..693239ddc39 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -53,7 +53,6 @@ extern struct platform_device realview_i2c_device;
53extern struct mmci_platform_data realview_mmc0_plat_data; 53extern struct mmci_platform_data realview_mmc0_plat_data;
54extern struct mmci_platform_data realview_mmc1_plat_data; 54extern struct mmci_platform_data realview_mmc1_plat_data;
55extern struct clcd_board clcd_plat_data; 55extern struct clcd_board clcd_plat_data;
56extern void __iomem *gic_cpu_base_addr;
57extern void __iomem *timer0_va_base; 56extern void __iomem *timer0_va_base;
58extern void __iomem *timer1_va_base; 57extern void __iomem *timer1_va_base;
59extern void __iomem *timer2_va_base; 58extern void __iomem *timer2_va_base;
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index f95521a5e5c..a87523d095e 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -11,14 +11,11 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/completion.h>
15 14
16#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
17 16
18extern volatile int pen_release; 17extern volatile int pen_release;
19 18
20static DECLARE_COMPLETION(cpu_killed);
21
22static inline void cpu_enter_lowpower(void) 19static inline void cpu_enter_lowpower(void)
23{ 20{
24 unsigned int v; 21 unsigned int v;
@@ -34,10 +31,10 @@ static inline void cpu_enter_lowpower(void)
34 " bic %0, %0, #0x20\n" 31 " bic %0, %0, #0x20\n"
35 " mcr p15, 0, %0, c1, c0, 1\n" 32 " mcr p15, 0, %0, c1, c0, 1\n"
36 " mrc p15, 0, %0, c1, c0, 0\n" 33 " mrc p15, 0, %0, c1, c0, 0\n"
37 " bic %0, %0, #0x04\n" 34 " bic %0, %0, %2\n"
38 " mcr p15, 0, %0, c1, c0, 0\n" 35 " mcr p15, 0, %0, c1, c0, 0\n"
39 : "=&r" (v) 36 : "=&r" (v)
40 : "r" (0) 37 : "r" (0), "Ir" (CR_C)
41 : "cc"); 38 : "cc");
42} 39}
43 40
@@ -46,17 +43,17 @@ static inline void cpu_leave_lowpower(void)
46 unsigned int v; 43 unsigned int v;
47 44
48 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n" 45 asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
49 " orr %0, %0, #0x04\n" 46 " orr %0, %0, %1\n"
50 " mcr p15, 0, %0, c1, c0, 0\n" 47 " mcr p15, 0, %0, c1, c0, 0\n"
51 " mrc p15, 0, %0, c1, c0, 1\n" 48 " mrc p15, 0, %0, c1, c0, 1\n"
52 " orr %0, %0, #0x20\n" 49 " orr %0, %0, #0x20\n"
53 " mcr p15, 0, %0, c1, c0, 1\n" 50 " mcr p15, 0, %0, c1, c0, 1\n"
54 : "=&r" (v) 51 : "=&r" (v)
55 : 52 : "Ir" (CR_C)
56 : "cc"); 53 : "cc");
57} 54}
58 55
59static inline void platform_do_lowpower(unsigned int cpu) 56static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
60{ 57{
61 /* 58 /*
62 * there is no power-control hardware on this platform, so all 59 * there is no power-control hardware on this platform, so all
@@ -80,22 +77,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
80 } 77 }
81 78
82 /* 79 /*
83 * getting here, means that we have come out of WFI without 80 * Getting here, means that we have come out of WFI without
84 * having been woken up - this shouldn't happen 81 * having been woken up - this shouldn't happen
85 * 82 *
86 * The trouble is, letting people know about this is not really 83 * Just note it happening - when we're woken, we can report
87 * possible, since we are currently running incoherently, and 84 * its occurrence.
88 * therefore cannot safely call printk() or anything else
89 */ 85 */
90#ifdef DEBUG 86 (*spurious)++;
91 printk("CPU%u: spurious wakeup call\n", cpu);
92#endif
93 } 87 }
94} 88}
95 89
96int platform_cpu_kill(unsigned int cpu) 90int platform_cpu_kill(unsigned int cpu)
97{ 91{
98 return wait_for_completion_timeout(&cpu_killed, 5000); 92 return 1;
99} 93}
100 94
101/* 95/*
@@ -105,30 +99,22 @@ int platform_cpu_kill(unsigned int cpu)
105 */ 99 */
106void platform_cpu_die(unsigned int cpu) 100void platform_cpu_die(unsigned int cpu)
107{ 101{
108#ifdef DEBUG 102 int spurious = 0;
109 unsigned int this_cpu = hard_smp_processor_id();
110
111 if (cpu != this_cpu) {
112 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
113 this_cpu, cpu);
114 BUG();
115 }
116#endif
117
118 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
119 complete(&cpu_killed);
120 103
121 /* 104 /*
122 * we're ready for shutdown now, so do it 105 * we're ready for shutdown now, so do it
123 */ 106 */
124 cpu_enter_lowpower(); 107 cpu_enter_lowpower();
125 platform_do_lowpower(cpu); 108 platform_do_lowpower(cpu, &spurious);
126 109
127 /* 110 /*
128 * bring this CPU back into the world of cache 111 * bring this CPU back into the world of cache
129 * coherency, and then restore interrupts 112 * coherency, and then restore interrupts
130 */ 113 */
131 cpu_leave_lowpower(); 114 cpu_leave_lowpower();
115
116 if (spurious)
117 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
132} 118}
133 119
134int platform_cpu_disable(unsigned int cpu) 120int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-realview/include/mach/entry-macro.S b/arch/arm/mach-realview/include/mach/entry-macro.S
index 340a5c27694..4071164aeba 100644
--- a/arch/arm/mach-realview/include/mach/entry-macro.S
+++ b/arch/arm/mach-realview/include/mach/entry-macro.S
@@ -8,74 +8,11 @@
8 * warranty of any kind, whether express or implied. 8 * warranty of any kind, whether express or implied.
9 */ 9 */
10#include <mach/hardware.h> 10#include <mach/hardware.h>
11#include <asm/hardware/gic.h> 11#include <asm/hardware/entry-macro-gic.S>
12 12
13 .macro disable_fiq 13 .macro disable_fiq
14 .endm 14 .endm
15 15
16 .macro get_irqnr_preamble, base, tmp
17 ldr \base, =gic_cpu_base_addr
18 ldr \base, [\base]
19 .endm
20
21 .macro arch_ret_to_user, tmp1, tmp2 16 .macro arch_ret_to_user, tmp1, tmp2
22 .endm 17 .endm
23 18
24 /*
25 * The interrupt numbering scheme is defined in the
26 * interrupt controller spec. To wit:
27 *
28 * Interrupts 0-15 are IPI
29 * 16-28 are reserved
30 * 29-31 are local. We allow 30 to be used for the watchdog.
31 * 32-1020 are global
32 * 1021-1022 are reserved
33 * 1023 is "spurious" (no interrupt)
34 *
35 * For now, we ignore all local interrupts so only return an interrupt if it's
36 * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
37 *
38 * A simple read from the controller will tell us the number of the highest
39 * priority enabled interrupt. We then just need to check whether it is in the
40 * valid range for an IRQ (30-1020 inclusive).
41 */
42
43 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
44
45 ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
46
47 ldr \tmp, =1021
48
49 bic \irqnr, \irqstat, #0x1c00
50
51 cmp \irqnr, #29
52 cmpcc \irqnr, \irqnr
53 cmpne \irqnr, \tmp
54 cmpcs \irqnr, \irqnr
55
56 .endm
57
58 /* We assume that irqstat (the raw value of the IRQ acknowledge
59 * register) is preserved from the macro above.
60 * If there is an IPI, we immediately signal end of interrupt on the
61 * controller, since this requires the original irqstat value which
62 * we won't easily be able to recreate later.
63 */
64
65 .macro test_for_ipi, irqnr, irqstat, base, tmp
66 bic \irqnr, \irqstat, #0x1c00
67 cmp \irqnr, #16
68 strcc \irqstat, [\base, #GIC_CPU_EOI]
69 cmpcs \irqnr, \irqnr
70 .endm
71
72 /* As above, this assumes that irqstat and base are preserved.. */
73
74 .macro test_for_ltirq, irqnr, irqstat, base, tmp
75 bic \irqnr, \irqstat, #0x1c00
76 mov \tmp, #0
77 cmp \irqnr, #29
78 moveq \tmp, #1
79 streq \irqstat, [\base, #GIC_CPU_EOI]
80 cmp \tmp, #0
81 .endm
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h
index d3cd265cb05..c8221b38ee7 100644
--- a/arch/arm/mach-realview/include/mach/smp.h
+++ b/arch/arm/mach-realview/include/mach/smp.h
@@ -2,14 +2,13 @@
2#define ASMARM_ARCH_SMP_H 2#define ASMARM_ARCH_SMP_H
3 3
4#include <asm/hardware/gic.h> 4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6 5
7/* 6/*
8 * We use IRQ1 as the IPI 7 * We use IRQ1 as the IPI
9 */ 8 */
10static inline void smp_cross_call(const struct cpumask *mask) 9static inline void smp_cross_call(const struct cpumask *mask, int ipi)
11{ 10{
12 gic_raise_softirq(mask, 1); 11 gic_raise_softirq(mask, ipi);
13} 12}
14 13
15#endif 14#endif
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 009265818d5..a22bf67f2f7 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -19,7 +19,6 @@
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/localtimer.h>
23#include <asm/unified.h> 22#include <asm/unified.h>
24 23
25#include <mach/board-eb.h> 24#include <mach/board-eb.h>
@@ -37,6 +36,19 @@ extern void realview_secondary_startup(void);
37 */ 36 */
38volatile int __cpuinitdata pen_release = -1; 37volatile int __cpuinitdata pen_release = -1;
39 38
39/*
40 * Write pen_release in a way that is guaranteed to be visible to all
41 * observers, irrespective of whether they're taking part in coherency
42 * or not. This is necessary for the hotplug code to work reliably.
43 */
44static void write_pen_release(int val)
45{
46 pen_release = val;
47 smp_wmb();
48 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
49 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
50}
51
40static void __iomem *scu_base_addr(void) 52static void __iomem *scu_base_addr(void)
41{ 53{
42 if (machine_is_realview_eb_mp()) 54 if (machine_is_realview_eb_mp())
@@ -50,33 +62,22 @@ static void __iomem *scu_base_addr(void)
50 return (void __iomem *)0; 62 return (void __iomem *)0;
51} 63}
52 64
53static inline unsigned int get_core_count(void)
54{
55 void __iomem *scu_base = scu_base_addr();
56 if (scu_base)
57 return scu_get_core_count(scu_base);
58 return 1;
59}
60
61static DEFINE_SPINLOCK(boot_lock); 65static DEFINE_SPINLOCK(boot_lock);
62 66
63void __cpuinit platform_secondary_init(unsigned int cpu) 67void __cpuinit platform_secondary_init(unsigned int cpu)
64{ 68{
65 trace_hardirqs_off();
66
67 /* 69 /*
68 * if any interrupts are already enabled for the primary 70 * if any interrupts are already enabled for the primary
69 * core (e.g. timer irq), then they will not have been enabled 71 * core (e.g. timer irq), then they will not have been enabled
70 * for us: do so 72 * for us: do so
71 */ 73 */
72 gic_cpu_init(0, gic_cpu_base_addr); 74 gic_secondary_init(0);
73 75
74 /* 76 /*
75 * let the primary processor know we're out of the 77 * let the primary processor know we're out of the
76 * pen, then head off into the C entry point 78 * pen, then head off into the C entry point
77 */ 79 */
78 pen_release = -1; 80 write_pen_release(-1);
79 smp_wmb();
80 81
81 /* 82 /*
82 * Synchronise with the boot thread. 83 * Synchronise with the boot thread.
@@ -103,20 +104,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
103 * Note that "pen_release" is the hardware CPU ID, whereas 104 * Note that "pen_release" is the hardware CPU ID, whereas
104 * "cpu" is Linux's internal ID. 105 * "cpu" is Linux's internal ID.
105 */ 106 */
106 pen_release = cpu; 107 write_pen_release(cpu);
107 flush_cache_all();
108 108
109 /* 109 /*
110 * XXX 110 * Send the secondary CPU a soft interrupt, thereby causing
111 * 111 * the boot monitor to read the system wide flags register,
112 * This is a later addition to the booting protocol: the 112 * and branch to the address found there.
113 * bootMonitor now puts secondary cores into WFI, so
114 * poke_milo() no longer gets the cores moving; we need
115 * to send a soft interrupt to wake the secondary core.
116 * Use smp_cross_call() for this, since there's little
117 * point duplicating the code here
118 */ 113 */
119 smp_cross_call(cpumask_of(cpu)); 114 smp_cross_call(cpumask_of(cpu), 1);
120 115
121 timeout = jiffies + (1 * HZ); 116 timeout = jiffies + (1 * HZ);
122 while (time_before(jiffies, timeout)) { 117 while (time_before(jiffies, timeout)) {
@@ -136,48 +131,18 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
136 return pen_release != -1 ? -ENOSYS : 0; 131 return pen_release != -1 ? -ENOSYS : 0;
137} 132}
138 133
139static void __init poke_milo(void)
140{
141 /* nobody is to be released from the pen yet */
142 pen_release = -1;
143
144 /*
145 * Write the address of secondary startup into the system-wide flags
146 * register. The BootMonitor waits for this register to become
147 * non-zero.
148 */
149 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
150 __io_address(REALVIEW_SYS_FLAGSSET));
151
152 mb();
153}
154
155/* 134/*
156 * Initialise the CPU possible map early - this describes the CPUs 135 * Initialise the CPU possible map early - this describes the CPUs
157 * which may be present or become present in the system. 136 * which may be present or become present in the system.
158 */ 137 */
159void __init smp_init_cpus(void) 138void __init smp_init_cpus(void)
160{ 139{
161 unsigned int i, ncores = get_core_count(); 140 void __iomem *scu_base = scu_base_addr();
141 unsigned int i, ncores;
162 142
163 for (i = 0; i < ncores; i++) 143 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
164 set_cpu_possible(i, true);
165}
166
167void __init smp_prepare_cpus(unsigned int max_cpus)
168{
169 unsigned int ncores = get_core_count();
170 unsigned int cpu = smp_processor_id();
171 int i;
172 144
173 /* sanity check */ 145 /* sanity check */
174 if (ncores == 0) {
175 printk(KERN_ERR
176 "Realview: strange CM count of 0? Default to 1\n");
177
178 ncores = 1;
179 }
180
181 if (ncores > NR_CPUS) { 146 if (ncores > NR_CPUS) {
182 printk(KERN_WARNING 147 printk(KERN_WARNING
183 "Realview: no. of cores (%d) greater than configured " 148 "Realview: no. of cores (%d) greater than configured "
@@ -186,13 +151,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
186 ncores = NR_CPUS; 151 ncores = NR_CPUS;
187 } 152 }
188 153
189 smp_store_cpu_info(cpu); 154 for (i = 0; i < ncores; i++)
155 set_cpu_possible(i, true);
156}
190 157
191 /* 158void __init platform_smp_prepare_cpus(unsigned int max_cpus)
192 * are we trying to boot more cores than exist? 159{
193 */ 160 int i;
194 if (max_cpus > ncores)
195 max_cpus = ncores;
196 161
197 /* 162 /*
198 * Initialise the present map, which describes the set of CPUs 163 * Initialise the present map, which describes the set of CPUs
@@ -201,21 +166,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
201 for (i = 0; i < max_cpus; i++) 166 for (i = 0; i < max_cpus; i++)
202 set_cpu_present(i, true); 167 set_cpu_present(i, true);
203 168
169 scu_enable(scu_base_addr());
170
204 /* 171 /*
205 * Initialise the SCU if there are more than one CPU and let 172 * Write the address of secondary startup into the
206 * them know where to start. Note that, on modern versions of 173 * system-wide flags register. The BootMonitor waits
207 * MILO, the "poke" doesn't actually do anything until each 174 * until it receives a soft interrupt, and then the
208 * individual core is sent a soft interrupt to get it out of 175 * secondary CPU branches to this address.
209 * WFI
210 */ 176 */
211 if (max_cpus > 1) { 177 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
212 /* 178 __io_address(REALVIEW_SYS_FLAGSSET));
213 * Enable the local timer or broadcast device for the
214 * boot CPU, but only if we have more than one CPU.
215 */
216 percpu_timer_setup();
217
218 scu_enable(scu_base_addr());
219 poke_milo();
220 }
221} 179}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index f2697106f80..6ef5c5e528b 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -364,21 +364,19 @@ static void __init gic_init_irq(void)
364 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); 364 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
365 365
366 /* core tile GIC, primary */ 366 /* core tile GIC, primary */
367 gic_cpu_base_addr = __io_address(REALVIEW_EB11MP_GIC_CPU_BASE); 367 gic_init(0, 29, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE),
368 gic_dist_init(0, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE), 29); 368 __io_address(REALVIEW_EB11MP_GIC_CPU_BASE));
369 gic_cpu_init(0, gic_cpu_base_addr);
370 369
371#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB 370#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
372 /* board GIC, secondary */ 371 /* board GIC, secondary */
373 gic_dist_init(1, __io_address(REALVIEW_EB_GIC_DIST_BASE), 64); 372 gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE),
374 gic_cpu_init(1, __io_address(REALVIEW_EB_GIC_CPU_BASE)); 373 __io_address(REALVIEW_EB_GIC_CPU_BASE));
375 gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1); 374 gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
376#endif 375#endif
377 } else { 376 } else {
378 /* board GIC, primary */ 377 /* board GIC, primary */
379 gic_cpu_base_addr = __io_address(REALVIEW_EB_GIC_CPU_BASE); 378 gic_init(0, 29, __io_address(REALVIEW_EB_GIC_DIST_BASE),
380 gic_dist_init(0, __io_address(REALVIEW_EB_GIC_DIST_BASE), 29); 379 __io_address(REALVIEW_EB_GIC_CPU_BASE));
381 gic_cpu_init(0, gic_cpu_base_addr);
382 } 380 }
383} 381}
384 382
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index a4125619d71..cbdc97a5685 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -304,13 +304,14 @@ static struct platform_device char_lcd_device = {
304static void __init gic_init_irq(void) 304static void __init gic_init_irq(void)
305{ 305{
306 /* ARM1176 DevChip GIC, primary */ 306 /* ARM1176 DevChip GIC, primary */
307 gic_cpu_base_addr = __io_address(REALVIEW_DC1176_GIC_CPU_BASE); 307 gic_init(0, IRQ_DC1176_GIC_START,
308 gic_dist_init(0, __io_address(REALVIEW_DC1176_GIC_DIST_BASE), IRQ_DC1176_GIC_START); 308 __io_address(REALVIEW_DC1176_GIC_DIST_BASE),
309 gic_cpu_init(0, gic_cpu_base_addr); 309 __io_address(REALVIEW_DC1176_GIC_CPU_BASE));
310 310
311 /* board GIC, secondary */ 311 /* board GIC, secondary */
312 gic_dist_init(1, __io_address(REALVIEW_PB1176_GIC_DIST_BASE), IRQ_PB1176_GIC_START); 312 gic_init(1, IRQ_PB1176_GIC_START,
313 gic_cpu_init(1, __io_address(REALVIEW_PB1176_GIC_CPU_BASE)); 313 __io_address(REALVIEW_PB1176_GIC_DIST_BASE),
314 __io_address(REALVIEW_PB1176_GIC_CPU_BASE));
314 gic_cascade_irq(1, IRQ_DC1176_PB_IRQ1); 315 gic_cascade_irq(1, IRQ_DC1176_PB_IRQ1);
315} 316}
316 317
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 117b95b2ca1..8e8ab7d29a6 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -309,13 +309,13 @@ static void __init gic_init_irq(void)
309 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); 309 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
310 310
311 /* ARM11MPCore test chip GIC, primary */ 311 /* ARM11MPCore test chip GIC, primary */
312 gic_cpu_base_addr = __io_address(REALVIEW_TC11MP_GIC_CPU_BASE); 312 gic_init(0, 29, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE),
313 gic_dist_init(0, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE), 29); 313 __io_address(REALVIEW_TC11MP_GIC_CPU_BASE));
314 gic_cpu_init(0, gic_cpu_base_addr);
315 314
316 /* board GIC, secondary */ 315 /* board GIC, secondary */
317 gic_dist_init(1, __io_address(REALVIEW_PB11MP_GIC_DIST_BASE), IRQ_PB11MP_GIC_START); 316 gic_init(1, IRQ_PB11MP_GIC_START,
318 gic_cpu_init(1, __io_address(REALVIEW_PB11MP_GIC_CPU_BASE)); 317 __io_address(REALVIEW_PB11MP_GIC_DIST_BASE),
318 __io_address(REALVIEW_PB11MP_GIC_CPU_BASE));
319 gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1); 319 gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
320} 320}
321 321
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 929b8dc12e8..841118e3e11 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -273,9 +273,9 @@ static struct platform_device pmu_device = {
273static void __init gic_init_irq(void) 273static void __init gic_init_irq(void)
274{ 274{
275 /* ARM PB-A8 on-board GIC */ 275 /* ARM PB-A8 on-board GIC */
276 gic_cpu_base_addr = __io_address(REALVIEW_PBA8_GIC_CPU_BASE); 276 gic_init(0, IRQ_PBA8_GIC_START,
277 gic_dist_init(0, __io_address(REALVIEW_PBA8_GIC_DIST_BASE), IRQ_PBA8_GIC_START); 277 __io_address(REALVIEW_PBA8_GIC_DIST_BASE),
278 gic_cpu_init(0, __io_address(REALVIEW_PBA8_GIC_CPU_BASE)); 278 __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
279} 279}
280 280
281static void __init realview_pba8_timer_init(void) 281static void __init realview_pba8_timer_init(void)
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index b9f9e20031a..02b755b009d 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -313,15 +313,12 @@ static void __init gic_init_irq(void)
313{ 313{
314 /* ARM PBX on-board GIC */ 314 /* ARM PBX on-board GIC */
315 if (core_tile_pbx11mp() || core_tile_pbxa9mp()) { 315 if (core_tile_pbx11mp() || core_tile_pbxa9mp()) {
316 gic_cpu_base_addr = __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE); 316 gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
317 gic_dist_init(0, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE), 317 __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
318 29);
319 gic_cpu_init(0, __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
320 } else { 318 } else {
321 gic_cpu_base_addr = __io_address(REALVIEW_PBX_GIC_CPU_BASE); 319 gic_init(0, IRQ_PBX_GIC_START,
322 gic_dist_init(0, __io_address(REALVIEW_PBX_GIC_DIST_BASE), 320 __io_address(REALVIEW_PBX_GIC_DIST_BASE),
323 IRQ_PBX_GIC_START); 321 __io_address(REALVIEW_PBX_GIC_CPU_BASE));
324 gic_cpu_init(0, __io_address(REALVIEW_PBX_GIC_CPU_BASE));
325 } 322 }
326} 323}
327 324
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index fa2e5bffbb8..e82ab4aa7ab 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -28,9 +28,16 @@ config S3C2412_DMA
28 28
29config S3C2412_PM 29config S3C2412_PM
30 bool 30 bool
31 select S3C2412_PM_SLEEP
31 help 32 help
32 Internal config node to apply S3C2412 power management 33 Internal config node to apply S3C2412 power management
33 34
35config S3C2412_PM_SLEEP
36 bool
37 help
38 Internal config node to apply sleep for S3C2412 power management.
39 Can be selected by another SoCs with similar sleep procedure.
40
34# Note, the S3C2412 IOtiming support is in plat-s3c24xx 41# Note, the S3C2412 IOtiming support is in plat-s3c24xx
35 42
36config S3C2412_CPUFREQ 43config S3C2412_CPUFREQ
@@ -52,7 +59,7 @@ config MACH_JIVE
52 Say Y here if you are using the Logitech Jive. 59 Say Y here if you are using the Logitech Jive.
53 60
54config MACH_JIVE_SHOW_BOOTLOADER 61config MACH_JIVE_SHOW_BOOTLOADER
55 bool "Allow access to bootloader partitions in MTD" 62 bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
56 depends on MACH_JIVE && EXPERIMENTAL 63 depends on MACH_JIVE && EXPERIMENTAL
57 64
58config MACH_SMDK2413 65config MACH_SMDK2413
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index 530ec46cbae..6c48a91ea39 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_CPU_S3C2412) += irq.o
14obj-$(CONFIG_CPU_S3C2412) += clock.o 14obj-$(CONFIG_CPU_S3C2412) += clock.o
15obj-$(CONFIG_CPU_S3C2412) += gpio.o 15obj-$(CONFIG_CPU_S3C2412) += gpio.o
16obj-$(CONFIG_S3C2412_DMA) += dma.o 16obj-$(CONFIG_S3C2412_DMA) += dma.o
17obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o 17obj-$(CONFIG_S3C2412_PM) += pm.o
18obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o
18obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o 19obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o
19 20
20# Machine support 21# Machine support
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
index 27b3e7c9d61..df8d14974c9 100644
--- a/arch/arm/mach-s3c2416/Kconfig
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -27,6 +27,7 @@ config S3C2416_DMA
27 27
28config S3C2416_PM 28config S3C2416_PM
29 bool 29 bool
30 select S3C2412_PM_SLEEP
30 help 31 help
31 Internal config node to apply S3C2416 power management 32 Internal config node to apply S3C2416 power management
32 33
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 28677caf361..461aa035afc 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -378,6 +378,12 @@ static struct max8998_regulator_data aquila_regulators[] = {
378static struct max8998_platform_data aquila_max8998_pdata = { 378static struct max8998_platform_data aquila_max8998_pdata = {
379 .num_regulators = ARRAY_SIZE(aquila_regulators), 379 .num_regulators = ARRAY_SIZE(aquila_regulators),
380 .regulators = aquila_regulators, 380 .regulators = aquila_regulators,
381 .buck1_set1 = S5PV210_GPH0(3),
382 .buck1_set2 = S5PV210_GPH0(4),
383 .buck2_set3 = S5PV210_GPH0(5),
384 .buck1_max_voltage1 = 1200000,
385 .buck1_max_voltage2 = 1200000,
386 .buck2_max_voltage = 1200000,
381}; 387};
382#endif 388#endif
383 389
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index b1dcf964a76..e22d5112fd4 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -518,6 +518,12 @@ static struct max8998_regulator_data goni_regulators[] = {
518static struct max8998_platform_data goni_max8998_pdata = { 518static struct max8998_platform_data goni_max8998_pdata = {
519 .num_regulators = ARRAY_SIZE(goni_regulators), 519 .num_regulators = ARRAY_SIZE(goni_regulators),
520 .regulators = goni_regulators, 520 .regulators = goni_regulators,
521 .buck1_set1 = S5PV210_GPH0(3),
522 .buck1_set2 = S5PV210_GPH0(4),
523 .buck2_set3 = S5PV210_GPH0(5),
524 .buck1_max_voltage1 = 1200000,
525 .buck1_max_voltage2 = 1200000,
526 .buck2_max_voltage = 1200000,
521}; 527};
522#endif 528#endif
523 529
diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c
index 82ce4aa6d61..72ab289e781 100644
--- a/arch/arm/mach-s5pv310/cpu.c
+++ b/arch/arm/mach-s5pv310/cpu.c
@@ -24,8 +24,6 @@
24 24
25#include <mach/regs-irq.h> 25#include <mach/regs-irq.h>
26 26
27void __iomem *gic_cpu_base_addr;
28
29extern int combiner_init(unsigned int combiner_nr, void __iomem *base, 27extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
30 unsigned int irq_start); 28 unsigned int irq_start);
31extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq); 29extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
@@ -122,9 +120,7 @@ void __init s5pv310_init_irq(void)
122{ 120{
123 int irq; 121 int irq;
124 122
125 gic_cpu_base_addr = S5P_VA_GIC_CPU; 123 gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
126 gic_dist_init(0, S5P_VA_GIC_DIST, IRQ_LOCALTIMER);
127 gic_cpu_init(0, S5P_VA_GIC_CPU);
128 124
129 for (irq = 0; irq < MAX_COMBINER_NR; irq++) { 125 for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
130 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), 126 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
diff --git a/arch/arm/mach-s5pv310/hotplug.c b/arch/arm/mach-s5pv310/hotplug.c
index 03652c3605f..afa5392d9fc 100644
--- a/arch/arm/mach-s5pv310/hotplug.c
+++ b/arch/arm/mach-s5pv310/hotplug.c
@@ -13,14 +13,11 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/completion.h>
17 16
18#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
19 18
20extern volatile int pen_release; 19extern volatile int pen_release;
21 20
22static DECLARE_COMPLETION(cpu_killed);
23
24static inline void cpu_enter_lowpower(void) 21static inline void cpu_enter_lowpower(void)
25{ 22{
26 unsigned int v; 23 unsigned int v;
@@ -33,13 +30,13 @@ static inline void cpu_enter_lowpower(void)
33 * Turn off coherency 30 * Turn off coherency
34 */ 31 */
35 " mrc p15, 0, %0, c1, c0, 1\n" 32 " mrc p15, 0, %0, c1, c0, 1\n"
36 " bic %0, %0, #0x20\n" 33 " bic %0, %0, %2\n"
37 " mcr p15, 0, %0, c1, c0, 1\n" 34 " mcr p15, 0, %0, c1, c0, 1\n"
38 " mrc p15, 0, %0, c1, c0, 0\n" 35 " mrc p15, 0, %0, c1, c0, 0\n"
39 " bic %0, %0, #0x04\n" 36 " bic %0, %0, #0x04\n"
40 " mcr p15, 0, %0, c1, c0, 0\n" 37 " mcr p15, 0, %0, c1, c0, 0\n"
41 : "=&r" (v) 38 : "=&r" (v)
42 : "r" (0) 39 : "r" (0), "Ir" (CR_C)
43 : "cc"); 40 : "cc");
44} 41}
45 42
@@ -49,17 +46,17 @@ static inline void cpu_leave_lowpower(void)
49 46
50 asm volatile( 47 asm volatile(
51 "mrc p15, 0, %0, c1, c0, 0\n" 48 "mrc p15, 0, %0, c1, c0, 0\n"
52 " orr %0, %0, #0x04\n" 49 " orr %0, %0, %1\n"
53 " mcr p15, 0, %0, c1, c0, 0\n" 50 " mcr p15, 0, %0, c1, c0, 0\n"
54 " mrc p15, 0, %0, c1, c0, 1\n" 51 " mrc p15, 0, %0, c1, c0, 1\n"
55 " orr %0, %0, #0x20\n" 52 " orr %0, %0, #0x20\n"
56 " mcr p15, 0, %0, c1, c0, 1\n" 53 " mcr p15, 0, %0, c1, c0, 1\n"
57 : "=&r" (v) 54 : "=&r" (v)
58 : 55 : "Ir" (CR_C)
59 : "cc"); 56 : "cc");
60} 57}
61 58
62static inline void platform_do_lowpower(unsigned int cpu) 59static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
63{ 60{
64 /* 61 /*
65 * there is no power-control hardware on this platform, so all 62 * there is no power-control hardware on this platform, so all
@@ -83,22 +80,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
83 } 80 }
84 81
85 /* 82 /*
86 * getting here, means that we have come out of WFI without 83 * Getting here, means that we have come out of WFI without
87 * having been woken up - this shouldn't happen 84 * having been woken up - this shouldn't happen
88 * 85 *
89 * The trouble is, letting people know about this is not really 86 * Just note it happening - when we're woken, we can report
90 * possible, since we are currently running incoherently, and 87 * its occurrence.
91 * therefore cannot safely call printk() or anything else
92 */ 88 */
93#ifdef DEBUG 89 (*spurious)++;
94 printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
95#endif
96 } 90 }
97} 91}
98 92
99int platform_cpu_kill(unsigned int cpu) 93int platform_cpu_kill(unsigned int cpu)
100{ 94{
101 return wait_for_completion_timeout(&cpu_killed, 5000); 95 return 1;
102} 96}
103 97
104/* 98/*
@@ -108,30 +102,22 @@ int platform_cpu_kill(unsigned int cpu)
108 */ 102 */
109void platform_cpu_die(unsigned int cpu) 103void platform_cpu_die(unsigned int cpu)
110{ 104{
111#ifdef DEBUG 105 int spurious = 0;
112 unsigned int this_cpu = hard_smp_processor_id();
113
114 if (cpu != this_cpu) {
115 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
116 this_cpu, cpu);
117 BUG();
118 }
119#endif
120
121 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
122 complete(&cpu_killed);
123 106
124 /* 107 /*
125 * we're ready for shutdown now, so do it 108 * we're ready for shutdown now, so do it
126 */ 109 */
127 cpu_enter_lowpower(); 110 cpu_enter_lowpower();
128 platform_do_lowpower(cpu); 111 platform_do_lowpower(cpu, &spurious);
129 112
130 /* 113 /*
131 * bring this CPU back into the world of cache 114 * bring this CPU back into the world of cache
132 * coherency, and then restore interrupts 115 * coherency, and then restore interrupts
133 */ 116 */
134 cpu_leave_lowpower(); 117 cpu_leave_lowpower();
118
119 if (spurious)
120 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
135} 121}
136 122
137int platform_cpu_disable(unsigned int cpu) 123int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h
index b7ec252384f..393ccbd52c4 100644
--- a/arch/arm/mach-s5pv310/include/mach/smp.h
+++ b/arch/arm/mach-s5pv310/include/mach/smp.h
@@ -7,16 +7,13 @@
7#define ASM_ARCH_SMP_H __FILE__ 7#define ASM_ARCH_SMP_H __FILE__
8 8
9#include <asm/hardware/gic.h> 9#include <asm/hardware/gic.h>
10#include <asm/smp_mpidr.h>
11
12extern void __iomem *gic_cpu_base_addr;
13 10
14/* 11/*
15 * We use IRQ1 as the IPI 12 * We use IRQ1 as the IPI
16 */ 13 */
17static inline void smp_cross_call(const struct cpumask *mask) 14static inline void smp_cross_call(const struct cpumask *mask, int ipi)
18{ 15{
19 gic_raise_softirq(mask, 1); 16 gic_raise_softirq(mask, ipi);
20} 17}
21 18
22#endif 19#endif
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c
index d357c198ede..34093b069f6 100644
--- a/arch/arm/mach-s5pv310/platsmp.c
+++ b/arch/arm/mach-s5pv310/platsmp.c
@@ -22,7 +22,6 @@
22#include <linux/io.h> 22#include <linux/io.h>
23 23
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27#include <asm/unified.h> 26#include <asm/unified.h>
28 27
@@ -38,6 +37,19 @@ extern void s5pv310_secondary_startup(void);
38 37
39volatile int __cpuinitdata pen_release = -1; 38volatile int __cpuinitdata pen_release = -1;
40 39
40/*
41 * Write pen_release in a way that is guaranteed to be visible to all
42 * observers, irrespective of whether they're taking part in coherency
43 * or not. This is necessary for the hotplug code to work reliably.
44 */
45static void write_pen_release(int val)
46{
47 pen_release = val;
48 smp_wmb();
49 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
50 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
51}
52
41static void __iomem *scu_base_addr(void) 53static void __iomem *scu_base_addr(void)
42{ 54{
43 return (void __iomem *)(S5P_VA_SCU); 55 return (void __iomem *)(S5P_VA_SCU);
@@ -47,21 +59,18 @@ static DEFINE_SPINLOCK(boot_lock);
47 59
48void __cpuinit platform_secondary_init(unsigned int cpu) 60void __cpuinit platform_secondary_init(unsigned int cpu)
49{ 61{
50 trace_hardirqs_off();
51
52 /* 62 /*
53 * if any interrupts are already enabled for the primary 63 * if any interrupts are already enabled for the primary
54 * core (e.g. timer irq), then they will not have been enabled 64 * core (e.g. timer irq), then they will not have been enabled
55 * for us: do so 65 * for us: do so
56 */ 66 */
57 gic_cpu_init(0, gic_cpu_base_addr); 67 gic_secondary_init(0);
58 68
59 /* 69 /*
60 * let the primary processor know we're out of the 70 * let the primary processor know we're out of the
61 * pen, then head off into the C entry point 71 * pen, then head off into the C entry point
62 */ 72 */
63 pen_release = -1; 73 write_pen_release(-1);
64 smp_wmb();
65 74
66 /* 75 /*
67 * Synchronise with the boot thread. 76 * Synchronise with the boot thread.
@@ -88,16 +97,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
88 * Note that "pen_release" is the hardware CPU ID, whereas 97 * Note that "pen_release" is the hardware CPU ID, whereas
89 * "cpu" is Linux's internal ID. 98 * "cpu" is Linux's internal ID.
90 */ 99 */
91 pen_release = cpu; 100 write_pen_release(cpu);
92 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
93 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
94 101
95 /* 102 /*
96 * Send the secondary CPU a soft interrupt, thereby causing 103 * Send the secondary CPU a soft interrupt, thereby causing
97 * the boot monitor to read the system wide flags register, 104 * the boot monitor to read the system wide flags register,
98 * and branch to the address found there. 105 * and branch to the address found there.
99 */ 106 */
100 smp_cross_call(cpumask_of(cpu)); 107 smp_cross_call(cpumask_of(cpu), 1);
101 108
102 timeout = jiffies + (1 * HZ); 109 timeout = jiffies + (1 * HZ);
103 while (time_before(jiffies, timeout)) { 110 while (time_before(jiffies, timeout)) {
@@ -130,13 +137,6 @@ void __init smp_init_cpus(void)
130 ncores = scu_base ? scu_get_core_count(scu_base) : 1; 137 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
131 138
132 /* sanity check */ 139 /* sanity check */
133 if (ncores == 0) {
134 printk(KERN_ERR
135 "S5PV310: strange CM count of 0? Default to 1\n");
136
137 ncores = 1;
138 }
139
140 if (ncores > NR_CPUS) { 140 if (ncores > NR_CPUS) {
141 printk(KERN_WARNING 141 printk(KERN_WARNING
142 "S5PV310: no. of cores (%d) greater than configured " 142 "S5PV310: no. of cores (%d) greater than configured "
@@ -149,18 +149,10 @@ void __init smp_init_cpus(void)
149 set_cpu_possible(i, true); 149 set_cpu_possible(i, true);
150} 150}
151 151
152void __init smp_prepare_cpus(unsigned int max_cpus) 152void __init platform_smp_prepare_cpus(unsigned int max_cpus)
153{ 153{
154 unsigned int ncores = num_possible_cpus();
155 unsigned int cpu = smp_processor_id();
156 int i; 154 int i;
157 155
158 smp_store_cpu_info(cpu);
159
160 /* are we trying to boot more cores than exist? */
161 if (max_cpus > ncores)
162 max_cpus = ncores;
163
164 /* 156 /*
165 * Initialise the present map, which describes the set of CPUs 157 * Initialise the present map, which describes the set of CPUs
166 * actually populated at the present time. 158 * actually populated at the present time.
@@ -168,25 +160,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
168 for (i = 0; i < max_cpus; i++) 160 for (i = 0; i < max_cpus; i++)
169 set_cpu_present(i, true); 161 set_cpu_present(i, true);
170 162
163 scu_enable(scu_base_addr());
164
171 /* 165 /*
172 * Initialise the SCU if there are more than one CPU and let 166 * Write the address of secondary startup into the
173 * them know where to start. 167 * system-wide flags register. The boot monitor waits
168 * until it receives a soft interrupt, and then the
169 * secondary CPU branches to this address.
174 */ 170 */
175 if (max_cpus > 1) {
176 /*
177 * Enable the local timer or broadcast device for the
178 * boot CPU, but only if we have more than one CPU.
179 */
180 percpu_timer_setup();
181
182 scu_enable(scu_base_addr());
183
184 /*
185 * Write the address of secondary startup into the
186 * system-wide flags register. The boot monitor waits
187 * until it receives a soft interrupt, and then the
188 * secondary CPU branches to this address.
189 */
190 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); 171 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
191 }
192} 172}
diff --git a/arch/arm/mach-s5pv310/time.c b/arch/arm/mach-s5pv310/time.c
index 01b012ad1bf..b262d461533 100644
--- a/arch/arm/mach-s5pv310/time.c
+++ b/arch/arm/mach-s5pv310/time.c
@@ -211,7 +211,6 @@ struct clocksource pwm_clocksource = {
211 .rating = 250, 211 .rating = 250,
212 .read = s5pv310_pwm4_read, 212 .read = s5pv310_pwm4_read,
213 .mask = CLOCKSOURCE_MASK(32), 213 .mask = CLOCKSOURCE_MASK(32),
214 .shift = 20,
215 .flags = CLOCK_SOURCE_IS_CONTINUOUS , 214 .flags = CLOCK_SOURCE_IS_CONTINUOUS ,
216}; 215};
217 216
@@ -230,10 +229,7 @@ static void __init s5pv310_clocksource_init(void)
230 s5pv310_pwm_init(4, ~0); 229 s5pv310_pwm_init(4, ~0);
231 s5pv310_pwm_start(4, 1); 230 s5pv310_pwm_start(4, 1);
232 231
233 pwm_clocksource.mult = 232 if (clocksource_register_hz(&pwm_clocksource, clock_rate))
234 clocksource_khz2mult(clock_rate/1000, pwm_clocksource.shift);
235
236 if (clocksource_register(&pwm_clocksource))
237 panic("%s: can't register clocksource\n", pwm_clocksource.name); 233 panic("%s: can't register clocksource\n", pwm_clocksource.name);
238} 234}
239 235
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 5da8c35aa0d..42625e4d949 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -118,6 +118,16 @@ config SA1100_LART
118 (also known as the LART). See <http://www.lartmaker.nl/> for 118 (also known as the LART). See <http://www.lartmaker.nl/> for
119 information on the LART. 119 information on the LART.
120 120
121config SA1100_NANOENGINE
122 bool "nanoEngine"
123 select CPU_FREQ_SA1110
124 select PCI
125 select PCI_NANOENGINE
126 help
127 Say Y here if you are using the Bright Star Engineering nanoEngine.
128 See <http://www.brightstareng.com/arm/nanoeng.htm> for information
129 on the BSE nanoEngine.
130
121config SA1100_PLEB 131config SA1100_PLEB
122 bool "PLEB" 132 bool "PLEB"
123 select CPU_FREQ_SA1100 133 select CPU_FREQ_SA1100
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index 89349c1dd7a..e697691eed2 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -37,6 +37,9 @@ obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
37obj-$(CONFIG_SA1100_LART) += lart.o 37obj-$(CONFIG_SA1100_LART) += lart.o
38led-$(CONFIG_SA1100_LART) += leds-lart.o 38led-$(CONFIG_SA1100_LART) += leds-lart.o
39 39
40obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o
41obj-$(CONFIG_PCI_NANOENGINE) += pci-nanoengine.o
42
40obj-$(CONFIG_SA1100_PLEB) += pleb.o 43obj-$(CONFIG_SA1100_PLEB) += pleb.o
41 44
42obj-$(CONFIG_SA1100_SHANNON) += shannon.o 45obj-$(CONFIG_SA1100_SHANNON) += shannon.o
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index 96f7dc103b5..07d4e8ba371 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -94,48 +94,47 @@
94 94
95#include "generic.h" 95#include "generic.h"
96 96
97typedef struct { 97struct sa1100_dram_regs {
98 int speed; 98 int speed;
99 u32 mdcnfg; 99 u32 mdcnfg;
100 u32 mdcas0; 100 u32 mdcas0;
101 u32 mdcas1; 101 u32 mdcas1;
102 u32 mdcas2; 102 u32 mdcas2;
103} sa1100_dram_regs_t; 103};
104 104
105 105
106static struct cpufreq_driver sa1100_driver; 106static struct cpufreq_driver sa1100_driver;
107 107
108static sa1100_dram_regs_t sa1100_dram_settings[] = 108static struct sa1100_dram_regs sa1100_dram_settings[] = {
109{ 109 /*speed, mdcnfg, mdcas0, mdcas1, mdcas2, clock freq */
110 /* speed, mdcnfg, mdcas0, mdcas1, mdcas2 clock frequency */ 110 { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 59.0 MHz */
111 { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 59.0 MHz */ 111 { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 73.7 MHz */
112 { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 73.7 MHz */ 112 { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 88.5 MHz */
113 { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 88.5 MHz */ 113 {103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 103.2 MHz */
114 { 103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 103.2 MHz */ 114 {118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff},/* 118.0 MHz */
115 { 118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 118.0 MHz */ 115 {132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff},/* 132.7 MHz */
116 { 132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 132.7 MHz */ 116 {147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff},/* 147.5 MHz */
117 { 147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff }, /* 147.5 MHz */ 117 {162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff},/* 162.2 MHz */
118 { 162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff }, /* 162.2 MHz */ 118 {176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff},/* 176.9 MHz */
119 { 176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff }, /* 176.9 MHz */ 119 {191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff},/* 191.7 MHz */
120 { 191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff }, /* 191.7 MHz */ 120 {206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 206.4 MHz */
121 { 206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 206.4 MHz */ 121 {221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 221.2 MHz */
122 { 221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 221.2 MHz */ 122 {235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1},/* 235.9 MHz */
123 { 235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1 }, /* 235.9 MHz */ 123 {250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 250.7 MHz */
124 { 250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 250.7 MHz */ 124 {265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 265.4 MHz */
125 { 265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 265.4 MHz */ 125 {280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87},/* 280.2 MHz */
126 { 280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87 }, /* 280.2 MHz */
127 { 0, 0, 0, 0, 0 } /* last entry */ 126 { 0, 0, 0, 0, 0 } /* last entry */
128}; 127};
129 128
130static void sa1100_update_dram_timings(int current_speed, int new_speed) 129static void sa1100_update_dram_timings(int current_speed, int new_speed)
131{ 130{
132 sa1100_dram_regs_t *settings = sa1100_dram_settings; 131 struct sa1100_dram_regs *settings = sa1100_dram_settings;
133 132
134 /* find speed */ 133 /* find speed */
135 while (settings->speed != 0) { 134 while (settings->speed != 0) {
136 if(new_speed == settings->speed) 135 if (new_speed == settings->speed)
137 break; 136 break;
138 137
139 settings++; 138 settings++;
140 } 139 }
141 140
@@ -149,7 +148,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
149 /* We're going FASTER, so first relax the memory 148 /* We're going FASTER, so first relax the memory
150 * timings before changing the core frequency 149 * timings before changing the core frequency
151 */ 150 */
152 151
153 /* Half the memory access clock */ 152 /* Half the memory access clock */
154 MDCNFG |= MDCNFG_CDB2; 153 MDCNFG |= MDCNFG_CDB2;
155 154
@@ -187,7 +186,7 @@ static int sa1100_target(struct cpufreq_policy *policy,
187 struct cpufreq_freqs freqs; 186 struct cpufreq_freqs freqs;
188 187
189 new_ppcr = sa11x0_freq_to_ppcr(target_freq); 188 new_ppcr = sa11x0_freq_to_ppcr(target_freq);
190 switch(relation){ 189 switch (relation) {
191 case CPUFREQ_RELATION_L: 190 case CPUFREQ_RELATION_L:
192 if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) 191 if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
193 new_ppcr--; 192 new_ppcr--;
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 7252874d328..675bf8ef97e 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -16,28 +16,24 @@
16 * 16 *
17 * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type 17 * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
18 */ 18 */
19#include <linux/moduleparam.h>
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/cpufreq.h> 19#include <linux/cpufreq.h>
24#include <linux/delay.h> 20#include <linux/delay.h>
25#include <linux/init.h> 21#include <linux/init.h>
26#include <linux/io.h> 22#include <linux/kernel.h>
23#include <linux/moduleparam.h>
24#include <linux/types.h>
27 25
28#include <mach/hardware.h>
29#include <asm/cputype.h> 26#include <asm/cputype.h>
30#include <asm/mach-types.h> 27#include <asm/mach-types.h>
31#include <asm/system.h> 28
29#include <mach/hardware.h>
32 30
33#include "generic.h" 31#include "generic.h"
34 32
35#undef DEBUG 33#undef DEBUG
36 34
37static struct cpufreq_driver sa1110_driver;
38
39struct sdram_params { 35struct sdram_params {
40 const char name[16]; 36 const char name[20];
41 u_char rows; /* bits */ 37 u_char rows; /* bits */
42 u_char cas_latency; /* cycles */ 38 u_char cas_latency; /* cycles */
43 u_char tck; /* clock cycle time (ns) */ 39 u_char tck; /* clock cycle time (ns) */
@@ -107,6 +103,15 @@ static struct sdram_params sdram_tbl[] __initdata = {
107 .twr = 8, 103 .twr = 8,
108 .refresh = 64000, 104 .refresh = 64000,
109 .cas_latency = 3, 105 .cas_latency = 3,
106 }, { /* Micron MT48LC8M16A2TG-75 */
107 .name = "MT48LC8M16A2TG-75",
108 .rows = 12,
109 .tck = 8,
110 .trcd = 20,
111 .trp = 20,
112 .twr = 8,
113 .refresh = 64000,
114 .cas_latency = 3,
110 }, 115 },
111}; 116};
112 117
@@ -180,11 +185,13 @@ sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
180 sd->mdrefr |= MDREFR_K1DB2; 185 sd->mdrefr |= MDREFR_K1DB2;
181 186
182 /* initial number of '1's in MDCAS + 1 */ 187 /* initial number of '1's in MDCAS + 1 */
183 set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz)); 188 set_mdcas(sd->mdcas, sd_khz >= 62000,
189 ns_to_cycles(sdram->trcd, mem_khz));
184 190
185#ifdef DEBUG 191#ifdef DEBUG
186 printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n", 192 printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
187 sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]); 193 sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1],
194 sd->mdcas[2]);
188#endif 195#endif
189} 196}
190 197
@@ -213,7 +220,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
213 220
214#ifdef DEBUG 221#ifdef DEBUG
215 mdelay(250); 222 mdelay(250);
216 printk("new dri value = %d\n", dri); 223 printk(KERN_DEBUG "new dri value = %d\n", dri);
217#endif 224#endif
218 225
219 sdram_set_refresh(dri); 226 sdram_set_refresh(dri);
@@ -232,7 +239,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
232 unsigned long flags; 239 unsigned long flags;
233 unsigned int ppcr, unused; 240 unsigned int ppcr, unused;
234 241
235 switch(relation){ 242 switch (relation) {
236 case CPUFREQ_RELATION_L: 243 case CPUFREQ_RELATION_L:
237 ppcr = sa11x0_freq_to_ppcr(target_freq); 244 ppcr = sa11x0_freq_to_ppcr(target_freq);
238 if (sa11x0_ppcr_to_freq(ppcr) > policy->max) 245 if (sa11x0_ppcr_to_freq(ppcr) > policy->max)
@@ -280,11 +287,10 @@ static int sa1110_target(struct cpufreq_policy *policy,
280 * We wait 20ms to be safe. 287 * We wait 20ms to be safe.
281 */ 288 */
282 sdram_set_refresh(2); 289 sdram_set_refresh(2);
283 if (!irqs_disabled()) { 290 if (!irqs_disabled())
284 msleep(20); 291 msleep(20);
285 } else { 292 else
286 mdelay(20); 293 mdelay(20);
287 }
288 294
289 /* 295 /*
290 * Reprogram the DRAM timings with interrupts disabled, and 296 * Reprogram the DRAM timings with interrupts disabled, and
@@ -295,7 +301,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
295 local_irq_save(flags); 301 local_irq_save(flags);
296 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); 302 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
297 udelay(10); 303 udelay(10);
298 __asm__ __volatile__(" \n\ 304 __asm__ __volatile__("\n\
299 b 2f \n\ 305 b 2f \n\
300 .align 5 \n\ 306 .align 5 \n\
3011: str %3, [%1, #0] @ MDCNFG \n\ 3071: str %3, [%1, #0] @ MDCNFG \n\
@@ -336,7 +342,9 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
336 return 0; 342 return 0;
337} 343}
338 344
339static struct cpufreq_driver sa1110_driver = { 345/* sa1110_driver needs __refdata because it must remain after init registers
346 * it with cpufreq_register_driver() */
347static struct cpufreq_driver sa1110_driver __refdata = {
340 .flags = CPUFREQ_STICKY, 348 .flags = CPUFREQ_STICKY,
341 .verify = sa11x0_verify_speed, 349 .verify = sa11x0_verify_speed,
342 .target = sa1110_target, 350 .target = sa1110_target,
@@ -349,7 +357,8 @@ static struct sdram_params *sa1110_find_sdram(const char *name)
349{ 357{
350 struct sdram_params *sdram; 358 struct sdram_params *sdram;
351 359
352 for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl); sdram++) 360 for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl);
361 sdram++)
353 if (strcmp(name, sdram->name) == 0) 362 if (strcmp(name, sdram->name) == 0)
354 return sdram; 363 return sdram;
355 364
@@ -369,14 +378,14 @@ static int __init sa1110_clk_init(void)
369 if (!name[0]) { 378 if (!name[0]) {
370 if (machine_is_assabet()) 379 if (machine_is_assabet())
371 name = "TC59SM716-CL3"; 380 name = "TC59SM716-CL3";
372
373 if (machine_is_pt_system3()) 381 if (machine_is_pt_system3())
374 name = "K4S641632D"; 382 name = "K4S641632D";
375
376 if (machine_is_h3100()) 383 if (machine_is_h3100())
377 name = "KM416S4030CT"; 384 name = "KM416S4030CT";
378 if (machine_is_jornada720()) 385 if (machine_is_jornada720())
379 name = "K4S281632B-1H"; 386 name = "K4S281632B-1H";
387 if (machine_is_nanoengine())
388 name = "MT48LC8M16A2TG-75";
380 } 389 }
381 390
382 sdram = sa1110_find_sdram(name); 391 sdram = sa1110_find_sdram(name);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3c1fcd69671..59d14f0fdcf 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -16,9 +16,7 @@
16#include <linux/pm.h> 16#include <linux/pm.h>
17#include <linux/cpufreq.h> 17#include <linux/cpufreq.h>
18#include <linux/ioport.h> 18#include <linux/ioport.h>
19#include <linux/sched.h> /* just for sched_clock() - funny that */
20#include <linux/platform_device.h> 19#include <linux/platform_device.h>
21#include <linux/cnt32_to_63.h>
22 20
23#include <asm/div64.h> 21#include <asm/div64.h>
24#include <mach/hardware.h> 22#include <mach/hardware.h>
@@ -110,27 +108,6 @@ unsigned int sa11x0_getspeed(unsigned int cpu)
110} 108}
111 109
112/* 110/*
113 * This is the SA11x0 sched_clock implementation. This has
114 * a resolution of 271ns, and a maximum value of 32025597s (370 days).
115 *
116 * The return value is guaranteed to be monotonic in that range as
117 * long as there is always less than 582 seconds between successive
118 * calls to this function.
119 *
120 * ( * 1E9 / 3686400 => * 78125 / 288)
121 */
122unsigned long long sched_clock(void)
123{
124 unsigned long long v = cnt32_to_63(OSCR);
125
126 /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
127 v *= 78125<<1;
128 do_div(v, 288<<1);
129
130 return v;
131}
132
133/*
134 * Default power-off for SA1100 111 * Default power-off for SA1100
135 */ 112 */
136static void sa1100_power_off(void) 113static void sa1100_power_off(void)
@@ -163,10 +140,15 @@ static void sa11x0_register_device(struct platform_device *dev, void *data)
163 140
164static struct resource sa11x0udc_resources[] = { 141static struct resource sa11x0udc_resources[] = {
165 [0] = { 142 [0] = {
166 .start = 0x80000000, 143 .start = __PREG(Ser0UDCCR),
167 .end = 0x8000ffff, 144 .end = __PREG(Ser0UDCCR) + 0xffff,
168 .flags = IORESOURCE_MEM, 145 .flags = IORESOURCE_MEM,
169 }, 146 },
147 [1] = {
148 .start = IRQ_Ser0UDC,
149 .end = IRQ_Ser0UDC,
150 .flags = IORESOURCE_IRQ,
151 },
170}; 152};
171 153
172static u64 sa11x0udc_dma_mask = 0xffffffffUL; 154static u64 sa11x0udc_dma_mask = 0xffffffffUL;
@@ -184,10 +166,15 @@ static struct platform_device sa11x0udc_device = {
184 166
185static struct resource sa11x0uart1_resources[] = { 167static struct resource sa11x0uart1_resources[] = {
186 [0] = { 168 [0] = {
187 .start = 0x80010000, 169 .start = __PREG(Ser1UTCR0),
188 .end = 0x8001ffff, 170 .end = __PREG(Ser1UTCR0) + 0xffff,
189 .flags = IORESOURCE_MEM, 171 .flags = IORESOURCE_MEM,
190 }, 172 },
173 [1] = {
174 .start = IRQ_Ser1UART,
175 .end = IRQ_Ser1UART,
176 .flags = IORESOURCE_IRQ,
177 },
191}; 178};
192 179
193static struct platform_device sa11x0uart1_device = { 180static struct platform_device sa11x0uart1_device = {
@@ -199,10 +186,15 @@ static struct platform_device sa11x0uart1_device = {
199 186
200static struct resource sa11x0uart3_resources[] = { 187static struct resource sa11x0uart3_resources[] = {
201 [0] = { 188 [0] = {
202 .start = 0x80050000, 189 .start = __PREG(Ser3UTCR0),
203 .end = 0x8005ffff, 190 .end = __PREG(Ser3UTCR0) + 0xffff,
204 .flags = IORESOURCE_MEM, 191 .flags = IORESOURCE_MEM,
205 }, 192 },
193 [1] = {
194 .start = IRQ_Ser3UART,
195 .end = IRQ_Ser3UART,
196 .flags = IORESOURCE_IRQ,
197 },
206}; 198};
207 199
208static struct platform_device sa11x0uart3_device = { 200static struct platform_device sa11x0uart3_device = {
@@ -214,10 +206,15 @@ static struct platform_device sa11x0uart3_device = {
214 206
215static struct resource sa11x0mcp_resources[] = { 207static struct resource sa11x0mcp_resources[] = {
216 [0] = { 208 [0] = {
217 .start = 0x80060000, 209 .start = __PREG(Ser4MCCR0),
218 .end = 0x8006ffff, 210 .end = __PREG(Ser4MCCR0) + 0xffff,
219 .flags = IORESOURCE_MEM, 211 .flags = IORESOURCE_MEM,
220 }, 212 },
213 [1] = {
214 .start = IRQ_Ser4MCP,
215 .end = IRQ_Ser4MCP,
216 .flags = IORESOURCE_IRQ,
217 },
221}; 218};
222 219
223static u64 sa11x0mcp_dma_mask = 0xffffffffUL; 220static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
@@ -244,6 +241,11 @@ static struct resource sa11x0ssp_resources[] = {
244 .end = 0x8007ffff, 241 .end = 0x8007ffff,
245 .flags = IORESOURCE_MEM, 242 .flags = IORESOURCE_MEM,
246 }, 243 },
244 [1] = {
245 .start = IRQ_Ser4SSP,
246 .end = IRQ_Ser4SSP,
247 .flags = IORESOURCE_IRQ,
248 },
247}; 249};
248 250
249static u64 sa11x0ssp_dma_mask = 0xffffffffUL; 251static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index 99f5856d8de..967ae768439 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -76,4 +76,12 @@ static inline unsigned long get_clock_tick_rate(void)
76#include "SA-1101.h" 76#include "SA-1101.h"
77#endif 77#endif
78 78
79#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI)
80#define PCIBIOS_MIN_IO 0
81#define PCIBIOS_MIN_MEM 0
82#define pcibios_assign_all_busses() 1
83#define HAVE_ARCH_PCI_SET_DMA_MASK 1
84#endif
85
86
79#endif /* _ASM_ARCH_HARDWARE_H */ 87#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h
new file mode 100644
index 00000000000..14f8382d066
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h
@@ -0,0 +1,52 @@
1/*
2 * arch/arm/mach-sa1100/include/mach/nanoengine.h
3 *
4 * This file contains the hardware specific definitions for nanoEngine.
5 * Only include this file from SA1100-specific files.
6 *
7 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14#ifndef __ASM_ARCH_NANOENGINE_H
15#define __ASM_ARCH_NANOENGINE_H
16
17#include <mach/irqs.h>
18
19#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/
20#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */
21#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */
22#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */
23#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */
24#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */
25
26#define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0
27#define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11
28#define NANOENGINE_IRQ_GPIO_PC_READY1 IRQ_GPIO12
29#define NANOENGINE_IRQ_GPIO_PC_CD0 IRQ_GPIO13
30#define NANOENGINE_IRQ_GPIO_PC_CD1 IRQ_GPIO14
31
32/*
33 * nanoEngine Memory Map:
34 *
35 * 0000.0000 - 003F.0000 - 4 MB Flash
36 * C000.0000 - C1FF.FFFF - 32 MB SDRAM
37 * 1860.0000 - 186F.FFFF - 1 MB Internal PCI Memory Read/Write
38 * 18A1.0000 - 18A1.FFFF - 64 KB Internal PCI Config Space
39 * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode
40 * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode
41 *
42 */
43
44#define NANO_PCI_MEM_RW_PHYS 0x18600000
45#define NANO_PCI_MEM_RW_VIRT 0xf1000000
46#define NANO_PCI_MEM_RW_SIZE SZ_1M
47#define NANO_PCI_CONFIG_SPACE_PHYS 0x18A10000
48#define NANO_PCI_CONFIG_SPACE_VIRT 0xf2000000
49#define NANO_PCI_CONFIG_SPACE_SIZE SZ_64K
50
51#endif
52
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
new file mode 100644
index 00000000000..72087f0658b
--- /dev/null
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -0,0 +1,119 @@
1/*
2 * linux/arch/arm/mach-sa1100/nanoengine.c
3 *
4 * Bright Star Engineering's nanoEngine board init code.
5 *
6 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/partitions.h>
18#include <linux/root_dev.h>
19
20#include <asm/mach-types.h>
21#include <asm/setup.h>
22
23#include <asm/mach/arch.h>
24#include <asm/mach/flash.h>
25#include <asm/mach/map.h>
26#include <asm/mach/serial_sa1100.h>
27
28#include <mach/hardware.h>
29#include <mach/nanoengine.h>
30
31#include "generic.h"
32
33/* Flash bank 0 */
34static struct mtd_partition nanoengine_partitions[] = {
35 {
36 .name = "nanoEngine boot firmware and parameter table",
37 .size = 0x00010000, /* 32K */
38 .offset = 0,
39 .mask_flags = MTD_WRITEABLE,
40 }, {
41 .name = "kernel/initrd reserved",
42 .size = 0x002f0000,
43 .offset = 0x00010000,
44 .mask_flags = MTD_WRITEABLE,
45 }, {
46 .name = "experimental filesystem allocation",
47 .size = 0x00100000,
48 .offset = 0x00300000,
49 .mask_flags = MTD_WRITEABLE,
50 }
51};
52
53static struct flash_platform_data nanoengine_flash_data = {
54 .map_name = "jedec_probe",
55 .parts = nanoengine_partitions,
56 .nr_parts = ARRAY_SIZE(nanoengine_partitions),
57};
58
59static struct resource nanoengine_flash_resources[] = {
60 {
61 .start = SA1100_CS0_PHYS,
62 .end = SA1100_CS0_PHYS + SZ_32M - 1,
63 .flags = IORESOURCE_MEM,
64 }, {
65 .start = SA1100_CS1_PHYS,
66 .end = SA1100_CS1_PHYS + SZ_32M - 1,
67 .flags = IORESOURCE_MEM,
68 }
69};
70
71static struct map_desc nanoengine_io_desc[] __initdata = {
72 {
73 /* System Registers */
74 .virtual = 0xf0000000,
75 .pfn = __phys_to_pfn(0x10000000),
76 .length = 0x00100000,
77 .type = MT_DEVICE
78 }, {
79 /* Internal PCI Memory Read/Write */
80 .virtual = NANO_PCI_MEM_RW_VIRT,
81 .pfn = __phys_to_pfn(NANO_PCI_MEM_RW_PHYS),
82 .length = NANO_PCI_MEM_RW_SIZE,
83 .type = MT_DEVICE
84 }, {
85 /* Internal PCI Config Space */
86 .virtual = NANO_PCI_CONFIG_SPACE_VIRT,
87 .pfn = __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS),
88 .length = NANO_PCI_CONFIG_SPACE_SIZE,
89 .type = MT_DEVICE
90 }
91};
92
93static void __init nanoengine_map_io(void)
94{
95 sa1100_map_io();
96 iotable_init(nanoengine_io_desc, ARRAY_SIZE(nanoengine_io_desc));
97
98 sa1100_register_uart(0, 1);
99 sa1100_register_uart(1, 2);
100 sa1100_register_uart(2, 3);
101 Ser1SDCR0 |= SDCR0_UART;
102 /* disable IRDA -- UART2 is used as a normal serial port */
103 Ser2UTCR4 = 0;
104 Ser2HSCR0 = 0;
105}
106
107static void __init nanoengine_init(void)
108{
109 sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
110 ARRAY_SIZE(nanoengine_flash_resources));
111}
112
113MACHINE_START(NANOENGINE, "BSE nanoEngine")
114 .boot_params = 0xc0000000,
115 .map_io = nanoengine_map_io,
116 .init_irq = sa1100_init_irq,
117 .timer = &sa1100_timer,
118 .init_machine = nanoengine_init,
119MACHINE_END
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
new file mode 100644
index 00000000000..fba7a913f12
--- /dev/null
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -0,0 +1,284 @@
1/*
2 * linux/arch/arm/mach-sa1100/pci-nanoengine.c
3 *
4 * PCI functions for BSE nanoEngine PCI
5 *
6 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#include <linux/kernel.h>
23#include <linux/irq.h>
24#include <linux/pci.h>
25#include <linux/spinlock.h>
26
27#include <asm/mach/pci.h>
28#include <asm/mach-types.h>
29
30#include <mach/nanoengine.h>
31
32static DEFINE_SPINLOCK(nano_lock);
33
34static int nanoengine_get_pci_address(struct pci_bus *bus,
35 unsigned int devfn, int where, unsigned long *address)
36{
37 int ret = PCIBIOS_DEVICE_NOT_FOUND;
38 unsigned int busnr = bus->number;
39
40 *address = NANO_PCI_CONFIG_SPACE_VIRT +
41 ((bus->number << 16) | (devfn << 8) | (where & ~3));
42
43 ret = (busnr > 255 || devfn > 255 || where > 255) ?
44 PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
45
46 return ret;
47}
48
49static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
50 int size, u32 *val)
51{
52 int ret;
53 unsigned long address;
54 unsigned long flags;
55 u32 v;
56
57 /* nanoEngine PCI bridge does not return -1 for a non-existing
58 * device. We must fake the answer. We know that the only valid
59 * device is device zero at bus 0, which is the network chip. */
60 if (bus->number != 0 || (devfn >> 3) != 0) {
61 v = -1;
62 nanoengine_get_pci_address(bus, devfn, where, &address);
63 goto exit_function;
64 }
65
66 spin_lock_irqsave(&nano_lock, flags);
67
68 ret = nanoengine_get_pci_address(bus, devfn, where, &address);
69 if (ret != PCIBIOS_SUCCESSFUL)
70 return ret;
71 v = __raw_readl(address);
72
73 spin_unlock_irqrestore(&nano_lock, flags);
74
75 v >>= ((where & 3) * 8);
76 v &= (unsigned long)(-1) >> ((4 - size) * 8);
77
78exit_function:
79 *val = v;
80 return PCIBIOS_SUCCESSFUL;
81}
82
83static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
84 int size, u32 val)
85{
86 int ret;
87 unsigned long address;
88 unsigned long flags;
89 unsigned shift;
90 u32 v;
91
92 shift = (where & 3) * 8;
93
94 spin_lock_irqsave(&nano_lock, flags);
95
96 ret = nanoengine_get_pci_address(bus, devfn, where, &address);
97 if (ret != PCIBIOS_SUCCESSFUL)
98 return ret;
99 v = __raw_readl(address);
100 switch (size) {
101 case 1:
102 v &= ~(0xFF << shift);
103 v |= val << shift;
104 break;
105 case 2:
106 v &= ~(0xFFFF << shift);
107 v |= val << shift;
108 break;
109 case 4:
110 v = val;
111 break;
112 }
113 __raw_writel(v, address);
114
115 spin_unlock_irqrestore(&nano_lock, flags);
116
117 return PCIBIOS_SUCCESSFUL;
118}
119
120static struct pci_ops pci_nano_ops = {
121 .read = nanoengine_read_config,
122 .write = nanoengine_write_config,
123};
124
125static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
126{
127 return NANOENGINE_IRQ_GPIO_PCI;
128}
129
130struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys)
131{
132 return pci_scan_bus(sys->busnr, &pci_nano_ops, sys);
133}
134
135static struct resource pci_io_ports = {
136 .name = "PCI IO",
137 .start = 0x400,
138 .end = 0x7FF,
139 .flags = IORESOURCE_IO,
140};
141
142static struct resource pci_non_prefetchable_memory = {
143 .name = "PCI non-prefetchable",
144 .start = NANO_PCI_MEM_RW_PHYS,
145 /* nanoEngine documentation says there is a 1 Megabyte window here,
146 * but PCI reports just 128 + 8 kbytes. */
147 .end = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1,
148/* .end = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/
149 .flags = IORESOURCE_MEM,
150};
151
152/*
153 * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it
154 * overlaps with previously defined memory.
155 *
156 * Here is what happens:
157 *
158# dmesg
159...
160pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
161pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
162pci 0000:00:00.0: reg 14: [io 0x0000-0x003f]
163pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
164pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
165pci 0000:00:00.0: supports D1 D2
166pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
167pci 0000:00:00.0: PME# disabled
168PCI: bus0: Fast back to back transfers enabled
169pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000)
170pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
171pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
172pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
173pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
174pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f]
175pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f])
176 *
177 * On the other hand, if we do not request the prefetchable memory resource,
178 * linux will alloc it first and the two non-prefetchable memory areas that
179 * are our real interest will not be mapped. So we choose to map it to an
180 * unused area. It gets recognized as expansion ROM, but becomes disabled.
181 *
182 * Here is what happens then:
183 *
184# dmesg
185...
186pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
187pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
188pci 0000:00:00.0: reg 14: [io 0x0000-0x003f]
189pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
190pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
191pci 0000:00:00.0: supports D1 D2
192pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
193pci 0000:00:00.0: PME# disabled
194PCI: bus0: Fast back to back transfers enabled
195pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref]
196pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
197pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
198pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
199pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
200pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f]
201pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f])
202
203# lspci -vv -s 0000:00:00.0
20400:00.0 Class 0200: Device 8086:1209 (rev 09)
205 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
206 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx-
207 Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes
208 Interrupt: pin A routed to IRQ 0
209 Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K]
210 Region 1: I/O ports at 0400 [size=64]
211 Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K]
212 [virtual] Expansion ROM at 78000000 [disabled] [size=1M]
213 Capabilities: [dc] Power Management version 2
214 Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
215 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME-
216 Kernel driver in use: e100
217 Kernel modules: e100
218 *
219 */
220static struct resource pci_prefetchable_memory = {
221 .name = "PCI prefetchable",
222 .start = 0x78000000,
223 .end = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1,
224 .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
225};
226
227static int __init pci_nanoengine_setup_resources(struct resource **resource)
228{
229 if (request_resource(&ioport_resource, &pci_io_ports)) {
230 printk(KERN_ERR "PCI: unable to allocate io port region\n");
231 return -EBUSY;
232 }
233 if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) {
234 release_resource(&pci_io_ports);
235 printk(KERN_ERR "PCI: unable to allocate non prefetchable\n");
236 return -EBUSY;
237 }
238 if (request_resource(&iomem_resource, &pci_prefetchable_memory)) {
239 release_resource(&pci_io_ports);
240 release_resource(&pci_non_prefetchable_memory);
241 printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
242 return -EBUSY;
243 }
244 resource[0] = &pci_io_ports;
245 resource[1] = &pci_non_prefetchable_memory;
246 resource[2] = &pci_prefetchable_memory;
247
248 return 1;
249}
250
251int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
252{
253 int ret = 0;
254
255 if (nr == 0) {
256 sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
257 sys->io_offset = 0x400;
258 ret = pci_nanoengine_setup_resources(sys->resource);
259 /* Enable alternate memory bus master mode, see
260 * "Intel StrongARM SA1110 Developer's Manual",
261 * section 10.8, "Alternate Memory Bus Master Mode". */
262 GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
263 GAFR |= GPIO_MBGNT | GPIO_MBREQ;
264 TUCR |= TUCR_MBGPIO;
265 }
266
267 return ret;
268}
269
270static struct hw_pci nanoengine_pci __initdata = {
271 .map_irq = pci_nanoengine_map_irq,
272 .nr_controllers = 1,
273 .scan = pci_nanoengine_scan_bus,
274 .setup = pci_nanoengine_setup,
275};
276
277static int __init nanoengine_pci_init(void)
278{
279 if (machine_is_nanoengine())
280 pci_common_init(&nanoengine_pci);
281 return 0;
282}
283
284subsys_initcall(nanoengine_pci_init);
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 27692d0ffbe..cfb76077bd2 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -166,9 +166,6 @@ static void __init simpad_map_io(void)
166 PCFR = 0; 166 PCFR = 0;
167 PSDR = 0; 167 PSDR = 0;
168 168
169 sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
170 ARRAY_SIZE(simpad_flash_resources));
171 sa11x0_register_mcp(&simpad_mcp_data);
172} 169}
173 170
174static void simpad_power_off(void) 171static void simpad_power_off(void)
@@ -216,6 +213,10 @@ static int __init simpad_init(void)
216 213
217 pm_power_off = simpad_power_off; 214 pm_power_off = simpad_power_off;
218 215
216 sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
217 ARRAY_SIZE(simpad_flash_resources));
218 sa11x0_register_mcp(&simpad_mcp_data);
219
219 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 220 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
220 if(ret) 221 if(ret)
221 printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device"); 222 printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 74b6e0e570b..ae4f3d80416 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -12,12 +12,39 @@
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/sched.h> /* just for sched_clock() - funny that */
15#include <linux/timex.h> 16#include <linux/timex.h>
16#include <linux/clockchips.h> 17#include <linux/clockchips.h>
17 18
18#include <asm/mach/time.h> 19#include <asm/mach/time.h>
20#include <asm/sched_clock.h>
19#include <mach/hardware.h> 21#include <mach/hardware.h>
20 22
23/*
24 * This is the SA11x0 sched_clock implementation.
25 */
26static DEFINE_CLOCK_DATA(cd);
27
28/*
29 * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz,
30 * NSEC_PER_SEC, 60).
31 * This gives a resolution of about 271ns and a wrap period of about 19min.
32 */
33#define SC_MULT 2275555556u
34#define SC_SHIFT 23
35
36unsigned long long notrace sched_clock(void)
37{
38 u32 cyc = OSCR;
39 return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
40}
41
42static void notrace sa1100_update_sched_clock(void)
43{
44 u32 cyc = OSCR;
45 update_sched_clock(&cd, cyc, (u32)~0);
46}
47
21#define MIN_OSCR_DELTA 2 48#define MIN_OSCR_DELTA 2
22 49
23static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) 50static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
@@ -81,7 +108,6 @@ static struct clocksource cksrc_sa1100_oscr = {
81 .rating = 200, 108 .rating = 200,
82 .read = sa1100_read_oscr, 109 .read = sa1100_read_oscr,
83 .mask = CLOCKSOURCE_MASK(32), 110 .mask = CLOCKSOURCE_MASK(32),
84 .shift = 20,
85 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 111 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
86}; 112};
87 113
@@ -97,6 +123,9 @@ static void __init sa1100_timer_init(void)
97 OIER = 0; /* disable any timer interrupts */ 123 OIER = 0; /* disable any timer interrupts */
98 OSSR = 0xf; /* clear status on all timers */ 124 OSSR = 0xf; /* clear status on all timers */
99 125
126 init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32,
127 3686400, SC_MULT, SC_SHIFT);
128
100 ckevt_sa1100_osmr0.mult = 129 ckevt_sa1100_osmr0.mult =
101 div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift); 130 div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift);
102 ckevt_sa1100_osmr0.max_delta_ns = 131 ckevt_sa1100_osmr0.max_delta_ns =
@@ -105,12 +134,9 @@ static void __init sa1100_timer_init(void)
105 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1; 134 clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1;
106 ckevt_sa1100_osmr0.cpumask = cpumask_of(0); 135 ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
107 136
108 cksrc_sa1100_oscr.mult =
109 clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_sa1100_oscr.shift);
110
111 setup_irq(IRQ_OST0, &sa1100_timer_irq); 137 setup_irq(IRQ_OST0, &sa1100_timer_irq);
112 138
113 clocksource_register(&cksrc_sa1100_oscr); 139 clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE);
114 clockevents_register_device(&ckevt_sa1100_osmr0); 140 clockevents_register_device(&ckevt_sa1100_osmr0);
115} 141}
116 142
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 51dcd59eda6..63293335724 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -6,7 +6,7 @@ config ARCH_SH7367
6 bool "SH-Mobile G3 (SH7367)" 6 bool "SH-Mobile G3 (SH7367)"
7 select CPU_V6 7 select CPU_V6
8 select HAVE_CLK 8 select HAVE_CLK
9 select COMMON_CLKDEV 9 select CLKDEV_LOOKUP
10 select SH_CLK_CPG 10 select SH_CLK_CPG
11 select GENERIC_CLOCKEVENTS 11 select GENERIC_CLOCKEVENTS
12 12
@@ -14,7 +14,7 @@ config ARCH_SH7377
14 bool "SH-Mobile G4 (SH7377)" 14 bool "SH-Mobile G4 (SH7377)"
15 select CPU_V7 15 select CPU_V7
16 select HAVE_CLK 16 select HAVE_CLK
17 select COMMON_CLKDEV 17 select CLKDEV_LOOKUP
18 select SH_CLK_CPG 18 select SH_CLK_CPG
19 select GENERIC_CLOCKEVENTS 19 select GENERIC_CLOCKEVENTS
20 20
@@ -22,7 +22,7 @@ config ARCH_SH7372
22 bool "SH-Mobile AP4 (SH7372)" 22 bool "SH-Mobile AP4 (SH7372)"
23 select CPU_V7 23 select CPU_V7
24 select HAVE_CLK 24 select HAVE_CLK
25 select COMMON_CLKDEV 25 select CLKDEV_LOOKUP
26 select SH_CLK_CPG 26 select SH_CLK_CPG
27 select GENERIC_CLOCKEVENTS 27 select GENERIC_CLOCKEVENTS
28 28
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index d440e5f456a..ac429ff2c20 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -61,6 +61,7 @@
61#include <asm/mach/arch.h> 61#include <asm/mach/arch.h>
62#include <asm/mach/map.h> 62#include <asm/mach/map.h>
63#include <asm/mach/time.h> 63#include <asm/mach/time.h>
64#include <asm/setup.h>
64 65
65/* 66/*
66 * Address Interface BusWidth note 67 * Address Interface BusWidth note
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index 9f78729098f..6b186aefcbd 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -20,8 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/sh_clk.h> 22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
23#include <mach/common.h> 24#include <mach/common.h>
24#include <asm/clkdev.h>
25 25
26/* SH7367 registers */ 26/* SH7367 registers */
27#define RTFRQCR 0xe6150000 27#define RTFRQCR 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 3aa02606943..d98deb497c2 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -20,8 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/sh_clk.h> 22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
23#include <mach/common.h> 24#include <mach/common.h>
24#include <asm/clkdev.h>
25 25
26/* SH7372 registers */ 26/* SH7372 registers */
27#define FRQCRA 0xe6150000 27#define FRQCRA 0xe6150000
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index f91395aeb9a..95942466e63 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -20,8 +20,8 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/sh_clk.h> 22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
23#include <mach/common.h> 24#include <mach/common.h>
24#include <asm/clkdev.h>
25 25
26/* SH7377 registers */ 26/* SH7377 registers */
27#define RTFRQCR 0xe6150000 27#define RTFRQCR 0xe6150000
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
index a285d13c741..f428c4db2b6 100644
--- a/arch/arm/mach-shmobile/include/mach/entry-macro.S
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
@@ -1,4 +1,5 @@
1/* 1/*
2 * Copyright (C) 2010 Magnus Damm
2 * Copyright (C) 2008 Renesas Solutions Corp. 3 * Copyright (C) 2008 Renesas Solutions Corp.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
@@ -14,24 +15,45 @@
14 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */ 17 */
17#include <mach/hardware.h>
18#include <mach/irqs.h> 18#include <mach/irqs.h>
19 19
20#define INTCA_BASE 0xe6980000
21#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
22#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
23#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
24#define INTLVLB_OFFS 0x00000034 /* previous priority level */
25
20 .macro disable_fiq 26 .macro disable_fiq
21 .endm 27 .endm
22 28
23 .macro get_irqnr_preamble, base, tmp 29 .macro get_irqnr_preamble, base, tmp
24 ldr \base, =INTFLGA 30 ldr \base, =INTCA_BASE
25 .endm 31 .endm
26 32
27 .macro arch_ret_to_user, tmp1, tmp2 33 .macro arch_ret_to_user, tmp1, tmp2
28 .endm 34 .endm
29 35
30 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 36 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
31 ldr \irqnr, [\base] 37 /* The single INTFLGA read access below results in the following:
38 *
39 * 1. INTLVLB is updated with old priority value from INTLVLA
40 * 2. Highest priority interrupt is accepted
41 * 3. INTLVLA is updated to contain priority of accepted interrupt
42 * 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
43 */
44 ldr \irqnr, [\base, #INTFLGA_OFFS]
45
46 /* Restore INTLVLA with the value saved in INTLVLB.
47 * This is required to support interrupt priorities properly.
48 */
49 ldrb \tmp, [\base, #INTLVLB_OFFS]
50 strb \tmp, [\base, #INTLVLA_OFFS]
51
52 /* Handle invalid vector number case */
32 cmp \irqnr, #0 53 cmp \irqnr, #0
33 beq 1000f 54 beq 1000f
34 /* intevt to irq number */ 55
56 /* Convert vector to irq number, same as the evt2irq() macro */
35 lsr \irqnr, \irqnr, #0x5 57 lsr \irqnr, \irqnr, #0x5
36 subs \irqnr, \irqnr, #16 58 subs \irqnr, \irqnr, #16
37 59
diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
new file mode 100644
index 00000000000..e3ebfa73956
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
@@ -0,0 +1,87 @@
1LIST "partner-jet-setup.txt"
2LIST "(C) Copyright 2010 Renesas Solutions Corp"
3LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
4
5LIST "RWT Setting"
6EW 0xE6020004, 0xA500
7EW 0xE6030004, 0xA500
8
9DD 0x01001000, 0x01001000
10
11LIST "GPIO Setting"
12EB 0xE6051013, 0xA2
13
14LIST "CPG"
15ED 0xE6150080, 0x00000180
16ED 0xE61500C0, 0x00000002
17
18WAIT 1, 0xFE40009C
19
20LIST "FRQCR"
21ED 0xE6150000, 0x2D1305C3
22ED 0xE61500E0, 0x9E40358E
23ED 0xE6150004, 0x80331050
24
25WAIT 1, 0xFE40009C
26
27ED 0xE61500E4, 0x00002000
28
29WAIT 1, 0xFE40009C
30
31LIST "PLL"
32ED 0xE6150028, 0x00004000
33
34WAIT 1, 0xFE40009C
35
36ED 0xE615002C, 0x93000040
37
38WAIT 1, 0xFE40009C
39
40LIST "BSC"
41ED 0xFEC10000, 0x00E0001B
42
43LIST "SBSC1"
44ED 0xFE400354, 0x01AD8000
45ED 0xFE400354, 0x01AD8001
46
47WAIT 5, 0xFE40009C
48
49ED 0xFE400008, 0xBCC90151
50ED 0xFE400040, 0x41774113
51ED 0xFE400044, 0x2712E229
52ED 0xFE400048, 0x20C18505
53ED 0xFE40004C, 0x00110209
54ED 0xFE400010, 0x00000087
55
56WAIT 10, 0xFE40009C
57
58ED 0xFE400084, 0x0000003F
59EB 0xFE500000, 0x00
60
61WAIT 5, 0xFE40009C
62
63ED 0xFE400084, 0x0000FF0A
64EB 0xFE500000, 0x00
65
66WAIT 1, 0xFE40009C
67
68ED 0xFE400084, 0x00002201
69EB 0xFE500000, 0x00
70ED 0xFE400084, 0x00000302
71EB 0xFE500000, 0x00
72EB 0xFE5C0000, 0x00
73ED 0xFE400008, 0xBCC90159
74ED 0xFE40008C, 0x88800004
75ED 0xFE400094, 0x00000004
76ED 0xFE400028, 0xA55A0032
77ED 0xFE40002C, 0xA55A000C
78ED 0xFE400020, 0xA55A2048
79ED 0xFE400008, 0xBCC90959
80
81LIST "Change CPGA setting"
82ED 0xE61500E0, 0x9E40352E
83ED 0xE6150004, 0x80331050
84
85WAIT 1, 0xFE40009C
86
87ED 0xE6150354, 0x00000002
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
index 4aecf6e3a85..2b8fd8b942f 100644
--- a/arch/arm/mach-shmobile/include/mach/vmalloc.h
+++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h
@@ -2,6 +2,6 @@
2#define __ASM_MACH_VMALLOC_H 2#define __ASM_MACH_VMALLOC_H
3 3
4/* Vmalloc at ... - 0xe5ffffff */ 4/* Vmalloc at ... - 0xe5ffffff */
5#define VMALLOC_END 0xe6000000 5#define VMALLOC_END 0xe6000000UL
6 6
7#endif /* __ASM_MACH_VMALLOC_H */ 7#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot.h b/arch/arm/mach-shmobile/include/mach/zboot.h
new file mode 100644
index 00000000000..3ad86b7708e
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot.h
@@ -0,0 +1,20 @@
1#ifndef ZBOOT_H
2#define ZBOOT_H
3
4#include <asm/mach-types.h>
5#include <mach/zboot_macros.h>
6
7/**************************************************
8 *
9 * board specific settings
10 *
11 **************************************************/
12
13#ifdef CONFIG_MACH_AP4EVB
14#define MACH_TYPE MACH_TYPE_AP4EVB
15#include "mach/head-ap4evb.txt"
16#else
17#error "unsupported board."
18#endif
19
20#endif /* ZBOOT_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot_macros.h b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
new file mode 100644
index 00000000000..aa6111fbc98
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
@@ -0,0 +1,65 @@
1#ifndef __ZBOOT_MACRO_H
2#define __ZBOOT_MACRO_H
3
4/* The LIST command is used to include comments in the script */
5.macro LIST comment
6.endm
7
8/* The ED command is used to write a 32-bit word */
9.macro ED, addr, data
10 LDR r0, 1f
11 LDR r1, 2f
12 STR r1, [r0]
13 B 3f
141 : .long \addr
152 : .long \data
163 :
17.endm
18
19/* The EW command is used to write a 16-bit word */
20.macro EW, addr, data
21 LDR r0, 1f
22 LDR r1, 2f
23 STRH r1, [r0]
24 B 3f
251 : .long \addr
262 : .long \data
273 :
28.endm
29
30/* The EB command is used to write an 8-bit word */
31.macro EB, addr, data
32 LDR r0, 1f
33 LDR r1, 2f
34 STRB r1, [r0]
35 B 3f
361 : .long \addr
372 : .long \data
383 :
39.endm
40
41/* The WAIT command is used to delay the execution */
42.macro WAIT, time, reg
43 LDR r1, 1f
44 LDR r0, 2f
45 STR r0, [r1]
4610 :
47 LDR r0, [r1]
48 CMP r0, #0x00000000
49 BNE 10b
50 NOP
51 B 3f
521 : .long \reg
532 : .long \time * 100
543 :
55.endm
56
57/* The DD command is used to read a 32-bit word */
58.macro DD, start, end
59 LDR r1, 1f
60 B 2f
611 : .long \start
622 :
63.endm
64
65#endif /* __ZBOOT_MACRO_H */
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
index ba32a15127a..3970a9cdce2 100644
--- a/arch/arm/mach-tcc8k/clock.c
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -12,8 +12,7 @@
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15 15#include <linux/clkdev.h>
16#include <asm/clkdev.h>
17 16
18#include <mach/clock.h> 17#include <mach/clock.h>
19#include <mach/irqs.h> 18#include <mach/irqs.h>
diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c
index 78d06008841..e0a8d609afe 100644
--- a/arch/arm/mach-tcc8k/time.c
+++ b/arch/arm/mach-tcc8k/time.c
@@ -35,7 +35,6 @@ static struct clocksource clocksource_tcc = {
35 .rating = 200, 35 .rating = 200,
36 .read = tcc_get_cycles, 36 .read = tcc_get_cycles,
37 .mask = CLOCKSOURCE_MASK(32), 37 .mask = CLOCKSOURCE_MASK(32),
38 .shift = 28,
39 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 38 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
40}; 39};
41 40
@@ -103,9 +102,7 @@ static int __init tcc_clockevent_init(struct clk *clock)
103{ 102{
104 unsigned int c = clk_get_rate(clock); 103 unsigned int c = clk_get_rate(clock);
105 104
106 clocksource_tcc.mult = clocksource_hz2mult(c, 105 clocksource_register_hz(&clocksource_tcc, c);
107 clocksource_tcc.shift);
108 clocksource_register(&clocksource_tcc);
109 106
110 clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC, 107 clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
111 clockevent_tcc.shift); 108 clockevent_tcc.shift);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index ae19f95585b..77948e0f490 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -25,7 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/seq_file.h> 26#include <linux/seq_file.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <asm/clkdev.h> 28#include <linux/clkdev.h>
29 29
30#include "clock.h" 30#include "clock.h"
31#include "board.h" 31#include "board.h"
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 94fd859770f..083a4cfc6cf 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -21,7 +21,7 @@
21#define __MACH_TEGRA_CLOCK_H 21#define __MACH_TEGRA_CLOCK_H
22 22
23#include <linux/list.h> 23#include <linux/list.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25 25
26#define DIV_BUS (1 << 0) 26#define DIV_BUS (1 << 0)
27#define DIV_U71 (1 << 1) 27#define DIV_U71 (1 << 1)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index 8e7f115aa21..a5cb1ce76ff 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -11,12 +11,9 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/completion.h>
15 14
16#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
17 16
18static DECLARE_COMPLETION(cpu_killed);
19
20static inline void cpu_enter_lowpower(void) 17static inline void cpu_enter_lowpower(void)
21{ 18{
22 unsigned int v; 19 unsigned int v;
@@ -29,13 +26,13 @@ static inline void cpu_enter_lowpower(void)
29 * Turn off coherency 26 * Turn off coherency
30 */ 27 */
31 " mrc p15, 0, %0, c1, c0, 1\n" 28 " mrc p15, 0, %0, c1, c0, 1\n"
32 " bic %0, %0, #0x20\n" 29 " bic %0, %0, %2\n"
33 " mcr p15, 0, %0, c1, c0, 1\n" 30 " mcr p15, 0, %0, c1, c0, 1\n"
34 " mrc p15, 0, %0, c1, c0, 0\n" 31 " mrc p15, 0, %0, c1, c0, 0\n"
35 " bic %0, %0, #0x04\n" 32 " bic %0, %0, #0x04\n"
36 " mcr p15, 0, %0, c1, c0, 0\n" 33 " mcr p15, 0, %0, c1, c0, 0\n"
37 : "=&r" (v) 34 : "=&r" (v)
38 : "r" (0) 35 : "r" (0), "Ir" (CR_C)
39 : "cc"); 36 : "cc");
40} 37}
41 38
@@ -45,17 +42,17 @@ static inline void cpu_leave_lowpower(void)
45 42
46 asm volatile( 43 asm volatile(
47 "mrc p15, 0, %0, c1, c0, 0\n" 44 "mrc p15, 0, %0, c1, c0, 0\n"
48 " orr %0, %0, #0x04\n" 45 " orr %0, %0, %1\n"
49 " mcr p15, 0, %0, c1, c0, 0\n" 46 " mcr p15, 0, %0, c1, c0, 0\n"
50 " mrc p15, 0, %0, c1, c0, 1\n" 47 " mrc p15, 0, %0, c1, c0, 1\n"
51 " orr %0, %0, #0x20\n" 48 " orr %0, %0, #0x20\n"
52 " mcr p15, 0, %0, c1, c0, 1\n" 49 " mcr p15, 0, %0, c1, c0, 1\n"
53 : "=&r" (v) 50 : "=&r" (v)
54 : 51 : "Ir" (CR_C)
55 : "cc"); 52 : "cc");
56} 53}
57 54
58static inline void platform_do_lowpower(unsigned int cpu) 55static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
59{ 56{
60 /* 57 /*
61 * there is no power-control hardware on this platform, so all 58 * there is no power-control hardware on this platform, so all
@@ -79,22 +76,19 @@ static inline void platform_do_lowpower(unsigned int cpu)
79 /*}*/ 76 /*}*/
80 77
81 /* 78 /*
82 * getting here, means that we have come out of WFI without 79 * Getting here, means that we have come out of WFI without
83 * having been woken up - this shouldn't happen 80 * having been woken up - this shouldn't happen
84 * 81 *
85 * The trouble is, letting people know about this is not really 82 * Just note it happening - when we're woken, we can report
86 * possible, since we are currently running incoherently, and 83 * its occurrence.
87 * therefore cannot safely call printk() or anything else
88 */ 84 */
89#ifdef DEBUG 85 (*spurious)++;
90 printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
91#endif
92 } 86 }
93} 87}
94 88
95int platform_cpu_kill(unsigned int cpu) 89int platform_cpu_kill(unsigned int cpu)
96{ 90{
97 return wait_for_completion_timeout(&cpu_killed, 5000); 91 return 1;
98} 92}
99 93
100/* 94/*
@@ -104,30 +98,22 @@ int platform_cpu_kill(unsigned int cpu)
104 */ 98 */
105void platform_cpu_die(unsigned int cpu) 99void platform_cpu_die(unsigned int cpu)
106{ 100{
107#ifdef DEBUG 101 int spurious = 0;
108 unsigned int this_cpu = hard_smp_processor_id();
109
110 if (cpu != this_cpu) {
111 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
112 this_cpu, cpu);
113 BUG();
114 }
115#endif
116
117 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
118 complete(&cpu_killed);
119 102
120 /* 103 /*
121 * we're ready for shutdown now, so do it 104 * we're ready for shutdown now, so do it
122 */ 105 */
123 cpu_enter_lowpower(); 106 cpu_enter_lowpower();
124 platform_do_lowpower(cpu); 107 platform_do_lowpower(cpu, &spurious);
125 108
126 /* 109 /*
127 * bring this CPU back into the world of cache 110 * bring this CPU back into the world of cache
128 * coherency, and then restore interrupts 111 * coherency, and then restore interrupts
129 */ 112 */
130 cpu_leave_lowpower(); 113 cpu_leave_lowpower();
114
115 if (spurious)
116 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
131} 117}
132 118
133int platform_cpu_disable(unsigned int cpu) 119int platform_cpu_disable(unsigned int cpu)
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
index 2ba9e5c9d2f..dd165c53889 100644
--- a/arch/arm/mach-tegra/include/mach/entry-macro.S
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -16,8 +16,8 @@
16#include <mach/io.h> 16#include <mach/io.h>
17 17
18#if defined(CONFIG_ARM_GIC) 18#if defined(CONFIG_ARM_GIC)
19 19#define HAVE_GET_IRQNR_PREAMBLE
20#include <asm/hardware/gic.h> 20#include <asm/hardware/entry-macro-gic.S>
21 21
22 /* Uses the GIC interrupt controller built into the cpu */ 22 /* Uses the GIC interrupt controller built into the cpu */
23#define ICTRL_BASE (IO_CPU_VIRT + 0x100) 23#define ICTRL_BASE (IO_CPU_VIRT + 0x100)
@@ -32,68 +32,6 @@
32 32
33 .macro arch_ret_to_user, tmp1, tmp2 33 .macro arch_ret_to_user, tmp1, tmp2
34 .endm 34 .endm
35
36 /*
37 * The interrupt numbering scheme is defined in the
38 * interrupt controller spec. To wit:
39 *
40 * Interrupts 0-15 are IPI
41 * 16-28 are reserved
42 * 29-31 are local. We allow 30 to be used for the watchdog.
43 * 32-1020 are global
44 * 1021-1022 are reserved
45 * 1023 is "spurious" (no interrupt)
46 *
47 * For now, we ignore all local interrupts so only return an interrupt
48 * if it's between 30 and 1020. The test_for_ipi routine below will
49 * pick up on IPIs.
50 *
51 * A simple read from the controller will tell us the number of the
52 * highest priority enabled interrupt. We then just need to check
53 * whether it is in the valid range for an IRQ (30-1020 inclusive).
54 */
55
56 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
57
58 /* bits 12-10 = src CPU, 9-0 = int # */
59 ldr \irqstat, [\base, #GIC_CPU_INTACK]
60
61 ldr \tmp, =1021
62
63 bic \irqnr, \irqstat, #0x1c00
64
65 cmp \irqnr, #29
66 cmpcc \irqnr, \irqnr
67 cmpne \irqnr, \tmp
68 cmpcs \irqnr, \irqnr
69
70 .endm
71
72 /* We assume that irqstat (the raw value of the IRQ acknowledge
73 * register) is preserved from the macro above.
74 * If there is an IPI, we immediately signal end of interrupt on the
75 * controller, since this requires the original irqstat value which
76 * we won't easily be able to recreate later.
77 */
78
79 .macro test_for_ipi, irqnr, irqstat, base, tmp
80 bic \irqnr, \irqstat, #0x1c00
81 cmp \irqnr, #16
82 strcc \irqstat, [\base, #GIC_CPU_EOI]
83 cmpcs \irqnr, \irqnr
84 .endm
85
86 /* As above, this assumes that irqstat and base are preserved.. */
87
88 .macro test_for_ltirq, irqnr, irqstat, base, tmp
89 bic \irqnr, \irqstat, #0x1c00
90 mov \tmp, #0
91 cmp \irqnr, #29
92 moveq \tmp, #1
93 streq \irqstat, [\base, #GIC_CPU_EOI]
94 cmp \tmp, #0
95 .endm
96
97#else 35#else
98 /* legacy interrupt controller for AP16 */ 36 /* legacy interrupt controller for AP16 */
99 .macro disable_fiq 37 .macro disable_fiq
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
index f0981b1ac59..4cea2230c8d 100644
--- a/arch/arm/mach-tegra/include/mach/io.h
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -65,8 +65,8 @@
65 65
66#ifndef __ASSEMBLER__ 66#ifndef __ASSEMBLER__
67 67
68#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t) 68#define __arch_ioremap tegra_ioremap
69#define __arch_iounmap(v) tegra_iounmap(v) 69#define __arch_iounmap tegra_iounmap
70 70
71void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type); 71void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
72void tegra_iounmap(volatile void __iomem *addr); 72void tegra_iounmap(volatile void __iomem *addr);
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
index e4a34a35a54..c8221b38ee7 100644
--- a/arch/arm/mach-tegra/include/mach/smp.h
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -2,21 +2,13 @@
2#define ASMARM_ARCH_SMP_H 2#define ASMARM_ARCH_SMP_H
3 3
4#include <asm/hardware/gic.h> 4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6 5
7/* 6/*
8 * We use IRQ1 as the IPI 7 * We use IRQ1 as the IPI
9 */ 8 */
10static inline void smp_cross_call(const struct cpumask *mask) 9static inline void smp_cross_call(const struct cpumask *mask, int ipi)
11{
12 gic_raise_softirq(mask, 1);
13}
14
15/*
16 * Do nothing on MPcore.
17 */
18static inline void smp_cross_call_done(cpumask_t callmap)
19{ 10{
11 gic_raise_softirq(mask, ipi);
20} 12}
21 13
22#endif 14#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 50a8dfb9a0c..5407de01abf 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -94,8 +94,8 @@ void __init tegra_init_irq(void)
94 writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS); 94 writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS);
95 } 95 }
96 96
97 gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29); 97 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
98 gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); 98 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
99 99
100 gic = get_irq_chip(29); 100 gic = get_irq_chip(29);
101 gic_unmask_irq = gic->unmask; 101 gic_unmask_irq = gic->unmask;
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 1c0fd92cab3..ec1f68924ed 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -22,7 +22,6 @@
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27 26
28#include <mach/iomap.h> 27#include <mach/iomap.h>
@@ -41,14 +40,12 @@ static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
41 40
42void __cpuinit platform_secondary_init(unsigned int cpu) 41void __cpuinit platform_secondary_init(unsigned int cpu)
43{ 42{
44 trace_hardirqs_off();
45
46 /* 43 /*
47 * if any interrupts are already enabled for the primary 44 * if any interrupts are already enabled for the primary
48 * core (e.g. timer irq), then they will not have been enabled 45 * core (e.g. timer irq), then they will not have been enabled
49 * for us: do so 46 * for us: do so
50 */ 47 */
51 gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100); 48 gic_secondary_init(0);
52 49
53 /* 50 /*
54 * Synchronise with the boot thread. 51 * Synchronise with the boot thread.
@@ -117,24 +114,20 @@ void __init smp_init_cpus(void)
117{ 114{
118 unsigned int i, ncores = scu_get_core_count(scu_base); 115 unsigned int i, ncores = scu_get_core_count(scu_base);
119 116
117 if (ncores > NR_CPUS) {
118 printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
119 ncores, NR_CPUS);
120 ncores = NR_CPUS;
121 }
122
120 for (i = 0; i < ncores; i++) 123 for (i = 0; i < ncores; i++)
121 cpu_set(i, cpu_possible_map); 124 cpu_set(i, cpu_possible_map);
122} 125}
123 126
124void __init smp_prepare_cpus(unsigned int max_cpus) 127void __init platform_smp_prepare_cpus(unsigned int max_cpus)
125{ 128{
126 unsigned int ncores = scu_get_core_count(scu_base);
127 unsigned int cpu = smp_processor_id();
128 int i; 129 int i;
129 130
130 smp_store_cpu_info(cpu);
131
132 /*
133 * are we trying to boot more cores than exist?
134 */
135 if (max_cpus > ncores)
136 max_cpus = ncores;
137
138 /* 131 /*
139 * Initialise the present map, which describes the set of CPUs 132 * Initialise the present map, which describes the set of CPUs
140 * actually populated at the present time. 133 * actually populated at the present time.
@@ -142,15 +135,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
142 for (i = 0; i < max_cpus; i++) 135 for (i = 0; i < max_cpus; i++)
143 set_cpu_present(i, true); 136 set_cpu_present(i, true);
144 137
145 /* 138 scu_enable(scu_base);
146 * Initialise the SCU if there are more than one CPU and let
147 * them know where to start. Note that, on modern versions of
148 * MILO, the "poke" doesn't actually do anything until each
149 * individual core is sent a soft interrupt to get it out of
150 * WFI
151 */
152 if (max_cpus > 1) {
153 percpu_timer_setup();
154 scu_enable(scu_base);
155 }
156} 139}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ae3b308e22a..f0dae6d8ba5 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -24,8 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/hrtimer.h> 26#include <linux/hrtimer.h>
27 27#include <linux/clkdev.h>
28#include <asm/clkdev.h>
29 28
30#include <mach/iomap.h> 29#include <mach/iomap.h>
31 30
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 9057d6fd1d3..7b8ad1f98f4 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/sched.h>
21#include <linux/time.h> 22#include <linux/time.h>
22#include <linux/interrupt.h> 23#include <linux/interrupt.h>
23#include <linux/irq.h> 24#include <linux/irq.h>
@@ -25,10 +26,10 @@
25#include <linux/clocksource.h> 26#include <linux/clocksource.h>
26#include <linux/clk.h> 27#include <linux/clk.h>
27#include <linux/io.h> 28#include <linux/io.h>
28#include <linux/cnt32_to_63.h>
29 29
30#include <asm/mach/time.h> 30#include <asm/mach/time.h>
31#include <asm/localtimer.h> 31#include <asm/localtimer.h>
32#include <asm/sched_clock.h>
32 33
33#include <mach/iomap.h> 34#include <mach/iomap.h>
34#include <mach/irqs.h> 35#include <mach/irqs.h>
@@ -91,7 +92,7 @@ static void tegra_timer_set_mode(enum clock_event_mode mode,
91 92
92static cycle_t tegra_clocksource_read(struct clocksource *cs) 93static cycle_t tegra_clocksource_read(struct clocksource *cs)
93{ 94{
94 return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US)); 95 return timer_readl(TIMERUS_CNTR_1US);
95} 96}
96 97
97static struct clock_event_device tegra_clockevent = { 98static struct clock_event_device tegra_clockevent = {
@@ -106,14 +107,29 @@ static struct clocksource tegra_clocksource = {
106 .name = "timer_us", 107 .name = "timer_us",
107 .rating = 300, 108 .rating = 300,
108 .read = tegra_clocksource_read, 109 .read = tegra_clocksource_read,
109 .mask = 0x7FFFFFFFFFFFFFFFULL, 110 .mask = CLOCKSOURCE_MASK(32),
110 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 111 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
111}; 112};
112 113
113unsigned long long sched_clock(void) 114static DEFINE_CLOCK_DATA(cd);
115
116/*
117 * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
118 * This gives a resolution of about 1us and a wrap period of about 1h11min.
119 */
120#define SC_MULT 4194304000u
121#define SC_SHIFT 22
122
123unsigned long long notrace sched_clock(void)
114{ 124{
115 return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource), 125 u32 cyc = timer_readl(TIMERUS_CNTR_1US);
116 tegra_clocksource.mult, tegra_clocksource.shift); 126 return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
127}
128
129static void notrace tegra_update_sched_clock(void)
130{
131 u32 cyc = timer_readl(TIMERUS_CNTR_1US);
132 update_sched_clock(&cd, cyc, (u32)~0);
117} 133}
118 134
119static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id) 135static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
@@ -158,6 +174,9 @@ static void __init tegra_init_timer(void)
158 WARN(1, "Unknown clock rate"); 174 WARN(1, "Unknown clock rate");
159 } 175 }
160 176
177 init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32,
178 1000000, SC_MULT, SC_SHIFT);
179
161 if (clocksource_register_hz(&tegra_clocksource, 1000000)) { 180 if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
162 printk(KERN_ERR "Failed to register clocksource\n"); 181 printk(KERN_ERR "Failed to register clocksource\n");
163 BUG(); 182 BUG();
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
index 7458fc6df5c..fabcc49abe8 100644
--- a/arch/arm/mach-u300/clock.c
+++ b/arch/arm/mach-u300/clock.c
@@ -25,8 +25,8 @@
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/seq_file.h> 27#include <linux/seq_file.h>
28#include <linux/clkdev.h>
28 29
29#include <asm/clkdev.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/syscon.h> 31#include <mach/syscon.h>
32 32
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index 3fc4472719b..3ec58bd2d6e 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -9,6 +9,7 @@
9 * Author: Linus Walleij <linus.walleij@stericsson.com> 9 * Author: Linus Walleij <linus.walleij@stericsson.com>
10 */ 10 */
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/sched.h>
12#include <linux/time.h> 13#include <linux/time.h>
13#include <linux/timex.h> 14#include <linux/timex.h>
14#include <linux/clockchips.h> 15#include <linux/clockchips.h>
@@ -21,6 +22,7 @@
21#include <mach/hardware.h> 22#include <mach/hardware.h>
22 23
23/* Generic stuff */ 24/* Generic stuff */
25#include <asm/sched_clock.h>
24#include <asm/mach/map.h> 26#include <asm/mach/map.h>
25#include <asm/mach/time.h> 27#include <asm/mach/time.h>
26#include <asm/mach/irq.h> 28#include <asm/mach/irq.h>
@@ -352,12 +354,18 @@ static struct clocksource clocksource_u300_1mhz = {
352 * this wraps around for now, since it is just a relative time 354 * this wraps around for now, since it is just a relative time
353 * stamp. (Inspired by OMAP implementation.) 355 * stamp. (Inspired by OMAP implementation.)
354 */ 356 */
357static DEFINE_CLOCK_DATA(cd);
358
355unsigned long long notrace sched_clock(void) 359unsigned long long notrace sched_clock(void)
356{ 360{
357 return clocksource_cyc2ns(clocksource_u300_1mhz.read( 361 u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
358 &clocksource_u300_1mhz), 362 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
359 clocksource_u300_1mhz.mult, 363}
360 clocksource_u300_1mhz.shift); 364
365static void notrace u300_update_sched_clock(void)
366{
367 u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
368 update_sched_clock(&cd, cyc, (u32)~0);
361} 369}
362 370
363 371
@@ -375,6 +383,8 @@ static void __init u300_timer_init(void)
375 clk_enable(clk); 383 clk_enable(clk);
376 rate = clk_get_rate(clk); 384 rate = clk_get_rate(clk);
377 385
386 init_sched_clock(&cd, u300_update_sched_clock, 32, rate);
387
378 /* 388 /*
379 * Disable the "OS" and "DD" timers - these are designed for Symbian! 389 * Disable the "OS" and "DD" timers - these are designed for Symbian!
380 * Example usage in cnh1601578 cpu subsystem pd_timer_app.c 390 * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
@@ -412,9 +422,7 @@ static void __init u300_timer_init(void)
412 writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, 422 writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
413 U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); 423 U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
414 424
415 clocksource_calc_mult_shift(&clocksource_u300_1mhz, 425 if (clocksource_register_hz(&clocksource_u300_1mhz, rate))
416 rate, APPTIMER_MIN_RANGE);
417 if (clocksource_register(&clocksource_u300_1mhz))
418 printk(KERN_ERR "timer: failed to initialize clock " 426 printk(KERN_ERR "timer: failed to initialize clock "
419 "source %s\n", clocksource_u300_1mhz.name); 427 "source %s\n", clocksource_u300_1mhz.name);
420 428
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 912d1cc18c5..ccff2dae167 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -13,8 +13,7 @@
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/io.h> 15#include <linux/io.h>
16 16#include <linux/clkdev.h>
17#include <asm/clkdev.h>
18 17
19#include <plat/mtu.h> 18#include <plat/mtu.h>
20#include <mach/hardware.h> 19#include <mach/hardware.h>
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index a3700bc374d..5730409c0f7 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -52,8 +52,8 @@ void __init ux500_map_io(void)
52 52
53void __init ux500_init_irq(void) 53void __init ux500_init_irq(void)
54{ 54{
55 gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29); 55 gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE),
56 gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); 56 __io_address(UX500_GIC_CPU_BASE));
57 57
58 /* 58 /*
59 * Init clocks here so that they are available for system timer 59 * Init clocks here so that they are available for system timer
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
index a6be2cdf2b2..64fa451edcf 100644
--- a/arch/arm/mach-ux500/headsmp.S
+++ b/arch/arm/mach-ux500/headsmp.S
@@ -23,7 +23,6 @@ ENTRY(u8500_secondary_startup)
23 ldmia r4, {r5, r6} 23 ldmia r4, {r5, r6}
24 sub r4, r4, r5 24 sub r4, r4, r5
25 add r6, r6, r4 25 add r6, r6, r4
26 dsb
27pen: ldr r7, [r6] 26pen: ldr r7, [r6]
28 cmp r7, r0 27 cmp r7, r0
29 bne pen 28 bne pen
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
index b782a03024b..dd8037ebccf 100644
--- a/arch/arm/mach-ux500/hotplug.c
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -11,14 +11,11 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/completion.h>
15 14
16#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
17 16
18extern volatile int pen_release; 17extern volatile int pen_release;
19 18
20static DECLARE_COMPLETION(cpu_killed);
21
22static inline void platform_do_lowpower(unsigned int cpu) 19static inline void platform_do_lowpower(unsigned int cpu)
23{ 20{
24 flush_cache_all(); 21 flush_cache_all();
@@ -38,7 +35,7 @@ static inline void platform_do_lowpower(unsigned int cpu)
38 35
39int platform_cpu_kill(unsigned int cpu) 36int platform_cpu_kill(unsigned int cpu)
40{ 37{
41 return wait_for_completion_timeout(&cpu_killed, 5000); 38 return 1;
42} 39}
43 40
44/* 41/*
@@ -48,19 +45,6 @@ int platform_cpu_kill(unsigned int cpu)
48 */ 45 */
49void platform_cpu_die(unsigned int cpu) 46void platform_cpu_die(unsigned int cpu)
50{ 47{
51#ifdef DEBUG
52 unsigned int this_cpu = hard_smp_processor_id();
53
54 if (cpu != this_cpu) {
55 printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
56 this_cpu, cpu);
57 BUG();
58 }
59#endif
60
61 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
62 complete(&cpu_killed);
63
64 /* directly enter low power state, skipping secure registers */ 48 /* directly enter low power state, skipping secure registers */
65 platform_do_lowpower(cpu); 49 platform_do_lowpower(cpu);
66} 50}
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S
index 60ea88db828..a37f585a3ec 100644
--- a/arch/arm/mach-ux500/include/mach/entry-macro.S
+++ b/arch/arm/mach-ux500/include/mach/entry-macro.S
@@ -11,7 +11,8 @@
11 * warranty of any kind, whether express or implied. 11 * warranty of any kind, whether express or implied.
12 */ 12 */
13#include <mach/hardware.h> 13#include <mach/hardware.h>
14#include <asm/hardware/gic.h> 14#define HAVE_GET_IRQNR_PREAMBLE
15#include <asm/hardware/entry-macro-gic.S>
15 16
16 .macro disable_fiq 17 .macro disable_fiq
17 .endm 18 .endm
@@ -22,68 +23,3 @@
22 23
23 .macro arch_ret_to_user, tmp1, tmp2 24 .macro arch_ret_to_user, tmp1, tmp2
24 .endm 25 .endm
25
26 /*
27 * The interrupt numbering scheme is defined in the
28 * interrupt controller spec. To wit:
29 *
30 * Interrupts 0-15 are IPI
31 * 16-28 are reserved
32 * 29-31 are local. We allow 30 to be used for the watchdog.
33 * 32-1020 are global
34 * 1021-1022 are reserved
35 * 1023 is "spurious" (no interrupt)
36 *
37 * For now, we ignore all local interrupts so only return an
38 * interrupt if it's between 30 and 1020. The test_for_ipi
39 * routine below will pick up on IPIs.
40 *
41 * A simple read from the controller will tell us the number
42 * of the highest priority enabled interrupt. We then just
43 * need to check whether it is in the valid range for an
44 * IRQ (30-1020 inclusive).
45 */
46
47 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
48
49 /* bits 12-10 = src CPU, 9-0 = int # */
50 ldr \irqstat, [\base, #GIC_CPU_INTACK]
51
52 ldr \tmp, =1021
53
54 bic \irqnr, \irqstat, #0x1c00
55
56 cmp \irqnr, #29
57 cmpcc \irqnr, \irqnr
58 cmpne \irqnr, \tmp
59 cmpcs \irqnr, \irqnr
60
61 .endm
62
63 /* We assume that irqstat (the raw value of the IRQ
64 * acknowledge register) is preserved from the macro above.
65 * If there is an IPI, we immediately signal end of
66 * interrupt on the controller, since this requires the
67 * original irqstat value which we won't easily be able
68 * to recreate later.
69 */
70
71 .macro test_for_ipi, irqnr, irqstat, base, tmp
72 bic \irqnr, \irqstat, #0x1c00
73 cmp \irqnr, #16
74 strcc \irqstat, [\base, #GIC_CPU_EOI]
75 cmpcs \irqnr, \irqnr
76 .endm
77
78 /* As above, this assumes that irqstat and base
79 * are preserved..
80 */
81
82 .macro test_for_ltirq, irqnr, irqstat, base, tmp
83 bic \irqnr, \irqstat, #0x1c00
84 mov \tmp, #0
85 cmp \irqnr, #29
86 moveq \tmp, #1
87 streq \irqstat, [\base, #GIC_CPU_EOI]
88 cmp \tmp, #0
89 .endm
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
index 197e8417375..ca2b15b1b3b 100644
--- a/arch/arm/mach-ux500/include/mach/smp.h
+++ b/arch/arm/mach-ux500/include/mach/smp.h
@@ -10,7 +10,6 @@
10#define ASMARM_ARCH_SMP_H 10#define ASMARM_ARCH_SMP_H
11 11
12#include <asm/hardware/gic.h> 12#include <asm/hardware/gic.h>
13#include <asm/smp_mpidr.h>
14 13
15/* This is required to wakeup the secondary core */ 14/* This is required to wakeup the secondary core */
16extern void u8500_secondary_startup(void); 15extern void u8500_secondary_startup(void);
@@ -18,8 +17,8 @@ extern void u8500_secondary_startup(void);
18/* 17/*
19 * We use IRQ1 as the IPI 18 * We use IRQ1 as the IPI
20 */ 19 */
21static inline void smp_cross_call(const struct cpumask *mask) 20static inline void smp_cross_call(const struct cpumask *mask, int ipi)
22{ 21{
23 gic_raise_softirq(mask, 1); 22 gic_raise_softirq(mask, ipi);
24} 23}
25#endif 24#endif
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index ade2e17f253..d77e76cb7ed 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -18,7 +18,6 @@
18#include <linux/io.h> 18#include <linux/io.h>
19 19
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/localtimer.h>
22#include <asm/smp_scu.h> 21#include <asm/smp_scu.h>
23#include <mach/hardware.h> 22#include <mach/hardware.h>
24 23
@@ -28,29 +27,35 @@
28 */ 27 */
29volatile int pen_release = -1; 28volatile int pen_release = -1;
30 29
31static unsigned int __init get_core_count(void) 30/*
31 * Write pen_release in a way that is guaranteed to be visible to all
32 * observers, irrespective of whether they're taking part in coherency
33 * or not. This is necessary for the hotplug code to work reliably.
34 */
35static void write_pen_release(int val)
32{ 36{
33 return scu_get_core_count(__io_address(UX500_SCU_BASE)); 37 pen_release = val;
38 smp_wmb();
39 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
40 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
34} 41}
35 42
36static DEFINE_SPINLOCK(boot_lock); 43static DEFINE_SPINLOCK(boot_lock);
37 44
38void __cpuinit platform_secondary_init(unsigned int cpu) 45void __cpuinit platform_secondary_init(unsigned int cpu)
39{ 46{
40 trace_hardirqs_off();
41
42 /* 47 /*
43 * if any interrupts are already enabled for the primary 48 * if any interrupts are already enabled for the primary
44 * core (e.g. timer irq), then they will not have been enabled 49 * core (e.g. timer irq), then they will not have been enabled
45 * for us: do so 50 * for us: do so
46 */ 51 */
47 gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE)); 52 gic_secondary_init(0);
48 53
49 /* 54 /*
50 * let the primary processor know we're out of the 55 * let the primary processor know we're out of the
51 * pen, then head off into the C entry point 56 * pen, then head off into the C entry point
52 */ 57 */
53 pen_release = -1; 58 write_pen_release(-1);
54 59
55 /* 60 /*
56 * Synchronise with the boot thread. 61 * Synchronise with the boot thread.
@@ -74,11 +79,9 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
74 * the holding pen - release it, then wait for it to flag 79 * the holding pen - release it, then wait for it to flag
75 * that it has been released by resetting pen_release. 80 * that it has been released by resetting pen_release.
76 */ 81 */
77 pen_release = cpu; 82 write_pen_release(cpu);
78 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
79 outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
80 83
81 smp_cross_call(cpumask_of(cpu)); 84 smp_cross_call(cpumask_of(cpu), 1);
82 85
83 timeout = jiffies + (1 * HZ); 86 timeout = jiffies + (1 * HZ);
84 while (time_before(jiffies, timeout)) { 87 while (time_before(jiffies, timeout)) {
@@ -97,9 +100,6 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
97 100
98static void __init wakeup_secondary(void) 101static void __init wakeup_secondary(void)
99{ 102{
100 /* nobody is to be released from the pen yet */
101 pen_release = -1;
102
103 /* 103 /*
104 * write the address of secondary startup into the backup ram register 104 * write the address of secondary startup into the backup ram register
105 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the 105 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
@@ -126,40 +126,26 @@ static void __init wakeup_secondary(void)
126 */ 126 */
127void __init smp_init_cpus(void) 127void __init smp_init_cpus(void)
128{ 128{
129 unsigned int i, ncores = get_core_count(); 129 unsigned int i, ncores;
130 130
131 for (i = 0; i < ncores; i++) 131 ncores = scu_get_core_count(__io_address(UX500_SCU_BASE));
132 set_cpu_possible(i, true);
133}
134
135void __init smp_prepare_cpus(unsigned int max_cpus)
136{
137 unsigned int ncores = get_core_count();
138 unsigned int cpu = smp_processor_id();
139 int i;
140 132
141 /* sanity check */ 133 /* sanity check */
142 if (ncores == 0) { 134 if (ncores > NR_CPUS) {
143 printk(KERN_ERR
144 "U8500: strange CM count of 0? Default to 1\n");
145 ncores = 1;
146 }
147
148 if (ncores > num_possible_cpus()) {
149 printk(KERN_WARNING 135 printk(KERN_WARNING
150 "U8500: no. of cores (%d) greater than configured " 136 "U8500: no. of cores (%d) greater than configured "
151 "maximum of %d - clipping\n", 137 "maximum of %d - clipping\n",
152 ncores, num_possible_cpus()); 138 ncores, NR_CPUS);
153 ncores = num_possible_cpus(); 139 ncores = NR_CPUS;
154 } 140 }
155 141
156 smp_store_cpu_info(cpu); 142 for (i = 0; i < ncores; i++)
143 set_cpu_possible(i, true);
144}
157 145
158 /* 146void __init platform_smp_prepare_cpus(unsigned int max_cpus)
159 * are we trying to boot more cores than exist? 147{
160 */ 148 int i;
161 if (max_cpus > ncores)
162 max_cpus = ncores;
163 149
164 /* 150 /*
165 * Initialise the present map, which describes the set of CPUs 151 * Initialise the present map, which describes the set of CPUs
@@ -168,13 +154,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
168 for (i = 0; i < max_cpus; i++) 154 for (i = 0; i < max_cpus; i++)
169 set_cpu_present(i, true); 155 set_cpu_present(i, true);
170 156
171 if (max_cpus > 1) { 157 scu_enable(__io_address(UX500_SCU_BASE));
172 /* 158 wakeup_secondary();
173 * Enable the local timer or broadcast device for the
174 * boot CPU, but only if we have more than one CPU.
175 */
176 percpu_timer_setup();
177 scu_enable(__io_address(UX500_SCU_BASE));
178 wakeup_secondary();
179 }
180} 159}
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index c781f30c836..3f7b5e9d83c 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -4,6 +4,7 @@ menu "Versatile platform type"
4config ARCH_VERSATILE_PB 4config ARCH_VERSATILE_PB
5 bool "Support Versatile/PB platform" 5 bool "Support Versatile/PB platform"
6 select CPU_ARM926T 6 select CPU_ARM926T
7 select MIGHT_HAVE_PCI
7 default y 8 default y
8 help 9 help
9 Include support for the ARM(R) Versatile/PB platform. 10 Include support for the ARM(R) Versatile/PB platform.
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index e38acb0f89c..13a83e45a33 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -31,8 +31,8 @@
31#include <linux/amba/pl022.h> 31#include <linux/amba/pl022.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/gfp.h> 33#include <linux/gfp.h>
34#include <linux/clkdev.h>
34 35
35#include <asm/clkdev.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/leds.h> 38#include <asm/leds.h>
@@ -46,10 +46,11 @@
46#include <asm/mach/irq.h> 46#include <asm/mach/irq.h>
47#include <asm/mach/time.h> 47#include <asm/mach/time.h>
48#include <asm/mach/map.h> 48#include <asm/mach/map.h>
49#include <mach/clkdev.h>
50#include <mach/hardware.h> 49#include <mach/hardware.h>
51#include <mach/platform.h> 50#include <mach/platform.h>
52#include <plat/timer-sp.h> 51#include <asm/hardware/timer-sp.h>
52
53#include <plat/sched_clock.h>
53 54
54#include "core.h" 55#include "core.h"
55 56
@@ -886,6 +887,12 @@ void __init versatile_init(void)
886} 887}
887 888
888/* 889/*
890 * The sched_clock counter
891 */
892#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + \
893 VERSATILE_SYS_24MHz_OFFSET)
894
895/*
889 * Where is the timer (VA)? 896 * Where is the timer (VA)?
890 */ 897 */
891#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE) 898#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
@@ -900,6 +907,8 @@ static void __init versatile_timer_init(void)
900{ 907{
901 u32 val; 908 u32 val;
902 909
910 versatile_sched_clock_init(REFCOUNTER, 24000000);
911
903 /* 912 /*
904 * set clock frequency: 913 * set clock frequency:
905 * VERSATILE_REFCLK is 32KHz 914 * VERSATILE_REFCLK is 32KHz
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
index 1b71b77ade2..2c0ac7de281 100644
--- a/arch/arm/mach-vexpress/Makefile
+++ b/arch/arm/mach-vexpress/Makefile
@@ -5,4 +5,5 @@
5obj-y := v2m.o 5obj-y := v2m.o
6obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o 6obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o 7obj-$(CONFIG_SMP) += platsmp.o headsmp.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
8obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 9obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index 57dd95ce41f..362780d868d 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -22,5 +22,3 @@ struct map_desc;
22 22
23void v2m_map_io(struct map_desc *tile, size_t num); 23void v2m_map_io(struct map_desc *tile, size_t num);
24extern struct sys_timer v2m_timer; 24extern struct sys_timer v2m_timer;
25
26extern void __iomem *gic_cpu_base_addr;
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index fd25ccd7272..e628402b754 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -8,8 +8,8 @@
8#include <linux/platform_device.h> 8#include <linux/platform_device.h>
9#include <linux/amba/bus.h> 9#include <linux/amba/bus.h>
10#include <linux/amba/clcd.h> 10#include <linux/amba/clcd.h>
11#include <linux/clkdev.h>
11 12
12#include <asm/clkdev.h>
13#include <asm/pgtable.h> 13#include <asm/pgtable.h>
14#include <asm/hardware/arm_timer.h> 14#include <asm/hardware/arm_timer.h>
15#include <asm/hardware/cache-l2x0.h> 15#include <asm/hardware/cache-l2x0.h>
@@ -18,10 +18,9 @@
18#include <asm/pmu.h> 18#include <asm/pmu.h>
19#include <asm/smp_twd.h> 19#include <asm/smp_twd.h>
20 20
21#include <mach/clkdev.h>
22#include <mach/ct-ca9x4.h> 21#include <mach/ct-ca9x4.h>
23 22
24#include <plat/timer-sp.h> 23#include <asm/hardware/timer-sp.h>
25 24
26#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
27#include <asm/mach/map.h> 26#include <asm/mach/map.h>
@@ -60,13 +59,10 @@ static void __init ct_ca9x4_map_io(void)
60 v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); 59 v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
61} 60}
62 61
63void __iomem *gic_cpu_base_addr;
64
65static void __init ct_ca9x4_init_irq(void) 62static void __init ct_ca9x4_init_irq(void)
66{ 63{
67 gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU); 64 gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
68 gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29); 65 MMIO_P2V(A9_MPCORE_GIC_CPU));
69 gic_cpu_init(0, gic_cpu_base_addr);
70} 66}
71 67
72#if 0 68#if 0
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
new file mode 100644
index 00000000000..ea4cbfb90a6
--- /dev/null
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -0,0 +1,128 @@
1/*
2 * linux/arch/arm/mach-realview/hotplug.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/smp.h>
14
15#include <asm/cacheflush.h>
16
17extern volatile int pen_release;
18
19static inline void cpu_enter_lowpower(void)
20{
21 unsigned int v;
22
23 flush_cache_all();
24 asm volatile(
25 "mcr p15, 0, %1, c7, c5, 0\n"
26 " mcr p15, 0, %1, c7, c10, 4\n"
27 /*
28 * Turn off coherency
29 */
30 " mrc p15, 0, %0, c1, c0, 1\n"
31 " bic %0, %0, %3\n"
32 " mcr p15, 0, %0, c1, c0, 1\n"
33 " mrc p15, 0, %0, c1, c0, 0\n"
34 " bic %0, %0, %2\n"
35 " mcr p15, 0, %0, c1, c0, 0\n"
36 : "=&r" (v)
37 : "r" (0), "Ir" (CR_C), "Ir" (0x40)
38 : "cc");
39}
40
41static inline void cpu_leave_lowpower(void)
42{
43 unsigned int v;
44
45 asm volatile(
46 "mrc p15, 0, %0, c1, c0, 0\n"
47 " orr %0, %0, %1\n"
48 " mcr p15, 0, %0, c1, c0, 0\n"
49 " mrc p15, 0, %0, c1, c0, 1\n"
50 " orr %0, %0, %2\n"
51 " mcr p15, 0, %0, c1, c0, 1\n"
52 : "=&r" (v)
53 : "Ir" (CR_C), "Ir" (0x40)
54 : "cc");
55}
56
57static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
58{
59 /*
60 * there is no power-control hardware on this platform, so all
61 * we can do is put the core into WFI; this is safe as the calling
62 * code will have already disabled interrupts
63 */
64 for (;;) {
65 /*
66 * here's the WFI
67 */
68 asm(".word 0xe320f003\n"
69 :
70 :
71 : "memory", "cc");
72
73 if (pen_release == cpu) {
74 /*
75 * OK, proper wakeup, we're done
76 */
77 break;
78 }
79
80 /*
81 * Getting here, means that we have come out of WFI without
82 * having been woken up - this shouldn't happen
83 *
84 * Just note it happening - when we're woken, we can report
85 * its occurrence.
86 */
87 (*spurious)++;
88 }
89}
90
91int platform_cpu_kill(unsigned int cpu)
92{
93 return 1;
94}
95
96/*
97 * platform-specific code to shutdown a CPU
98 *
99 * Called with IRQs disabled
100 */
101void platform_cpu_die(unsigned int cpu)
102{
103 int spurious = 0;
104
105 /*
106 * we're ready for shutdown now, so do it
107 */
108 cpu_enter_lowpower();
109 platform_do_lowpower(cpu, &spurious);
110
111 /*
112 * bring this CPU back into the world of cache
113 * coherency, and then restore interrupts
114 */
115 cpu_leave_lowpower();
116
117 if (spurious)
118 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
119}
120
121int platform_cpu_disable(unsigned int cpu)
122{
123 /*
124 * we don't allow CPU 0 to be shutdown (it is still too special
125 * e.g. clock tick interrupts)
126 */
127 return cpu == 0 ? -EPERM : 0;
128}
diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S
index 20e9fb514f0..73c11297509 100644
--- a/arch/arm/mach-vexpress/include/mach/entry-macro.S
+++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S
@@ -1,67 +1,7 @@
1#include <asm/hardware/gic.h> 1#include <asm/hardware/entry-macro-gic.S>
2 2
3 .macro disable_fiq 3 .macro disable_fiq
4 .endm 4 .endm
5 5
6 .macro get_irqnr_preamble, base, tmp
7 ldr \base, =gic_cpu_base_addr
8 ldr \base, [\base]
9 .endm
10
11 .macro arch_ret_to_user, tmp1, tmp2 6 .macro arch_ret_to_user, tmp1, tmp2
12 .endm 7 .endm
13
14 /*
15 * The interrupt numbering scheme is defined in the
16 * interrupt controller spec. To wit:
17 *
18 * Interrupts 0-15 are IPI
19 * 16-28 are reserved
20 * 29-31 are local. We allow 30 to be used for the watchdog.
21 * 32-1020 are global
22 * 1021-1022 are reserved
23 * 1023 is "spurious" (no interrupt)
24 *
25 * For now, we ignore all local interrupts so only return an interrupt if it's
26 * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
27 *
28 * A simple read from the controller will tell us the number of the highest
29 * priority enabled interrupt. We then just need to check whether it is in the
30 * valid range for an IRQ (30-1020 inclusive).
31 */
32
33 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
34 ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
35 ldr \tmp, =1021
36 bic \irqnr, \irqstat, #0x1c00
37 cmp \irqnr, #29
38 cmpcc \irqnr, \irqnr
39 cmpne \irqnr, \tmp
40 cmpcs \irqnr, \irqnr
41 .endm
42
43 /* We assume that irqstat (the raw value of the IRQ acknowledge
44 * register) is preserved from the macro above.
45 * If there is an IPI, we immediately signal end of interrupt on the
46 * controller, since this requires the original irqstat value which
47 * we won't easily be able to recreate later.
48 */
49
50 .macro test_for_ipi, irqnr, irqstat, base, tmp
51 bic \irqnr, \irqstat, #0x1c00
52 cmp \irqnr, #16
53 strcc \irqstat, [\base, #GIC_CPU_EOI]
54 cmpcs \irqnr, \irqnr
55 .endm
56
57 /* As above, this assumes that irqstat and base are preserved.. */
58
59 .macro test_for_ltirq, irqnr, irqstat, base, tmp
60 bic \irqnr, \irqstat, #0x1c00
61 mov \tmp, #0
62 cmp \irqnr, #29
63 moveq \tmp, #1
64 streq \irqstat, [\base, #GIC_CPU_EOI]
65 cmp \tmp, #0
66 .endm
67
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
index 5a6da4fd247..4c05e4a9713 100644
--- a/arch/arm/mach-vexpress/include/mach/smp.h
+++ b/arch/arm/mach-vexpress/include/mach/smp.h
@@ -2,13 +2,12 @@
2#define __MACH_SMP_H 2#define __MACH_SMP_H
3 3
4#include <asm/hardware/gic.h> 4#include <asm/hardware/gic.h>
5#include <asm/smp_mpidr.h>
6 5
7/* 6/*
8 * We use IRQ1 as the IPI 7 * We use IRQ1 as the IPI
9 */ 8 */
10static inline void smp_cross_call(const struct cpumask *mask) 9static inline void smp_cross_call(const struct cpumask *mask, int ipi)
11{ 10{
12 gic_raise_softirq(mask, 1); 11 gic_raise_softirq(mask, ipi);
13} 12}
14#endif 13#endif
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 670970699ba..b1687b6abe6 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -17,7 +17,6 @@
17#include <linux/io.h> 17#include <linux/io.h>
18 18
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <asm/localtimer.h>
21#include <asm/smp_scu.h> 20#include <asm/smp_scu.h>
22#include <asm/unified.h> 21#include <asm/unified.h>
23 22
@@ -35,6 +34,19 @@ extern void vexpress_secondary_startup(void);
35 */ 34 */
36volatile int __cpuinitdata pen_release = -1; 35volatile int __cpuinitdata pen_release = -1;
37 36
37/*
38 * Write pen_release in a way that is guaranteed to be visible to all
39 * observers, irrespective of whether they're taking part in coherency
40 * or not. This is necessary for the hotplug code to work reliably.
41 */
42static void write_pen_release(int val)
43{
44 pen_release = val;
45 smp_wmb();
46 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
47 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
48}
49
38static void __iomem *scu_base_addr(void) 50static void __iomem *scu_base_addr(void)
39{ 51{
40 return MMIO_P2V(A9_MPCORE_SCU); 52 return MMIO_P2V(A9_MPCORE_SCU);
@@ -44,21 +56,18 @@ static DEFINE_SPINLOCK(boot_lock);
44 56
45void __cpuinit platform_secondary_init(unsigned int cpu) 57void __cpuinit platform_secondary_init(unsigned int cpu)
46{ 58{
47 trace_hardirqs_off();
48
49 /* 59 /*
50 * if any interrupts are already enabled for the primary 60 * if any interrupts are already enabled for the primary
51 * core (e.g. timer irq), then they will not have been enabled 61 * core (e.g. timer irq), then they will not have been enabled
52 * for us: do so 62 * for us: do so
53 */ 63 */
54 gic_cpu_init(0, gic_cpu_base_addr); 64 gic_secondary_init(0);
55 65
56 /* 66 /*
57 * let the primary processor know we're out of the 67 * let the primary processor know we're out of the
58 * pen, then head off into the C entry point 68 * pen, then head off into the C entry point
59 */ 69 */
60 pen_release = -1; 70 write_pen_release(-1);
61 smp_wmb();
62 71
63 /* 72 /*
64 * Synchronise with the boot thread. 73 * Synchronise with the boot thread.
@@ -83,16 +92,14 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
83 * since we haven't sent them a soft interrupt, they shouldn't 92 * since we haven't sent them a soft interrupt, they shouldn't
84 * be there. 93 * be there.
85 */ 94 */
86 pen_release = cpu; 95 write_pen_release(cpu);
87 __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
88 outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
89 96
90 /* 97 /*
91 * Send the secondary CPU a soft interrupt, thereby causing 98 * Send the secondary CPU a soft interrupt, thereby causing
92 * the boot monitor to read the system wide flags register, 99 * the boot monitor to read the system wide flags register,
93 * and branch to the address found there. 100 * and branch to the address found there.
94 */ 101 */
95 smp_cross_call(cpumask_of(cpu)); 102 smp_cross_call(cpumask_of(cpu), 1);
96 103
97 timeout = jiffies + (1 * HZ); 104 timeout = jiffies + (1 * HZ);
98 while (time_before(jiffies, timeout)) { 105 while (time_before(jiffies, timeout)) {
@@ -124,13 +131,6 @@ void __init smp_init_cpus(void)
124 ncores = scu_base ? scu_get_core_count(scu_base) : 1; 131 ncores = scu_base ? scu_get_core_count(scu_base) : 1;
125 132
126 /* sanity check */ 133 /* sanity check */
127 if (ncores == 0) {
128 printk(KERN_ERR
129 "vexpress: strange CM count of 0? Default to 1\n");
130
131 ncores = 1;
132 }
133
134 if (ncores > NR_CPUS) { 134 if (ncores > NR_CPUS) {
135 printk(KERN_WARNING 135 printk(KERN_WARNING
136 "vexpress: no. of cores (%d) greater than configured " 136 "vexpress: no. of cores (%d) greater than configured "
@@ -143,20 +143,10 @@ void __init smp_init_cpus(void)
143 set_cpu_possible(i, true); 143 set_cpu_possible(i, true);
144} 144}
145 145
146void __init smp_prepare_cpus(unsigned int max_cpus) 146void __init platform_smp_prepare_cpus(unsigned int max_cpus)
147{ 147{
148 unsigned int ncores = num_possible_cpus();
149 unsigned int cpu = smp_processor_id();
150 int i; 148 int i;
151 149
152 smp_store_cpu_info(cpu);
153
154 /*
155 * are we trying to boot more cores than exist?
156 */
157 if (max_cpus > ncores)
158 max_cpus = ncores;
159
160 /* 150 /*
161 * Initialise the present map, which describes the set of CPUs 151 * Initialise the present map, which describes the set of CPUs
162 * actually populated at the present time. 152 * actually populated at the present time.
@@ -164,27 +154,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
164 for (i = 0; i < max_cpus; i++) 154 for (i = 0; i < max_cpus; i++)
165 set_cpu_present(i, true); 155 set_cpu_present(i, true);
166 156
157 scu_enable(scu_base_addr());
158
167 /* 159 /*
168 * Initialise the SCU if there are more than one CPU and let 160 * Write the address of secondary startup into the
169 * them know where to start. 161 * system-wide flags register. The boot monitor waits
162 * until it receives a soft interrupt, and then the
163 * secondary CPU branches to this address.
170 */ 164 */
171 if (max_cpus > 1) { 165 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
172 /* 166 writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
173 * Enable the local timer or broadcast device for the 167 MMIO_P2V(V2M_SYS_FLAGSSET));
174 * boot CPU, but only if we have more than one CPU.
175 */
176 percpu_timer_setup();
177
178 scu_enable(scu_base_addr());
179
180 /*
181 * Write the address of secondary startup into the
182 * system-wide flags register. The boot monitor waits
183 * until it receives a soft interrupt, and then the
184 * secondary CPU branches to this address.
185 */
186 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
187 writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
188 MMIO_P2V(V2M_SYS_FLAGSSET));
189 }
190} 168}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 7eaa232180a..a9ed3428a2f 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -11,18 +11,18 @@
11#include <linux/spinlock.h> 11#include <linux/spinlock.h>
12#include <linux/sysdev.h> 12#include <linux/sysdev.h>
13#include <linux/usb/isp1760.h> 13#include <linux/usb/isp1760.h>
14#include <linux/clkdev.h>
14 15
15#include <asm/clkdev.h>
16#include <asm/sizes.h> 16#include <asm/sizes.h>
17#include <asm/mach/flash.h> 17#include <asm/mach/flash.h>
18#include <asm/mach/map.h> 18#include <asm/mach/map.h>
19#include <asm/mach/time.h> 19#include <asm/mach/time.h>
20#include <asm/hardware/arm_timer.h> 20#include <asm/hardware/arm_timer.h>
21#include <asm/hardware/timer-sp.h>
21 22
22#include <mach/clkdev.h>
23#include <mach/motherboard.h> 23#include <mach/motherboard.h>
24 24
25#include <plat/timer-sp.h> 25#include <plat/sched_clock.h>
26 26
27#include "core.h" 27#include "core.h"
28 28
@@ -50,6 +50,8 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
50 50
51static void __init v2m_timer_init(void) 51static void __init v2m_timer_init(void)
52{ 52{
53 versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
54
53 writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); 55 writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
54 writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); 56 writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
55 57
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
index c56ddab3d91..b88a1b16b2e 100644
--- a/arch/arm/mach-w90x900/clock.h
+++ b/arch/arm/mach-w90x900/clock.h
@@ -10,7 +10,7 @@
10 * the Free Software Foundation; either version 2 of the License. 10 * the Free Software Foundation; either version 2 of the License.
11 */ 11 */
12 12
13#include <asm/clkdev.h> 13#include <linux/clkdev.h>
14 14
15void nuc900_clk_enable(struct clk *clk, int enable); 15void nuc900_clk_enable(struct clk *clk, int enable);
16void nuc900_subclk_enable(struct clk *clk, int enable); 16void nuc900_subclk_enable(struct clk *clk, int enable);
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index b80f769bc13..4b089cb930d 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -153,7 +153,6 @@ static struct clocksource clocksource_nuc900 = {
153 .rating = 200, 153 .rating = 200,
154 .read = nuc900_get_cycles, 154 .read = nuc900_get_cycles,
155 .mask = CLOCKSOURCE_MASK(TDR_SHIFT), 155 .mask = CLOCKSOURCE_MASK(TDR_SHIFT),
156 .shift = 10,
157 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 156 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
158}; 157};
159 158
@@ -176,9 +175,7 @@ static void __init nuc900_clocksource_init(void)
176 val |= (COUNTEN | PERIOD | PRESCALE); 175 val |= (COUNTEN | PERIOD | PRESCALE);
177 __raw_writel(val, REG_TCSR1); 176 __raw_writel(val, REG_TCSR1);
178 177
179 clocksource_nuc900.mult = 178 clocksource_register_hz(&clocksource_nuc900, rate);
180 clocksource_khz2mult((rate / 1000), clocksource_nuc900.shift);
181 clocksource_register(&clocksource_nuc900);
182} 179}
183 180
184static void __init nuc900_timer_init(void) 181static void __init nuc900_timer_init(void)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index a099efed0e6..49db8b3e4a4 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -605,6 +605,14 @@ config CPU_CP15_MPU
605 help 605 help
606 Processor has the CP15 register, which has MPU related registers. 606 Processor has the CP15 register, which has MPU related registers.
607 607
608config CPU_USE_DOMAINS
609 bool
610 depends on MMU
611 default y if !CPU_32v6K
612 help
613 This option enables or disables the use of domain switching
614 via the set_fs() function.
615
608# 616#
609# CPU supports 36-bit I/O 617# CPU supports 36-bit I/O
610# 618#
@@ -634,6 +642,33 @@ config ARM_THUMBEE
634 Say Y here if you have a CPU with the ThumbEE extension and code to 642 Say Y here if you have a CPU with the ThumbEE extension and code to
635 make use of it. Say N for code that can run on CPUs without ThumbEE. 643 make use of it. Say N for code that can run on CPUs without ThumbEE.
636 644
645config SWP_EMULATE
646 bool "Emulate SWP/SWPB instructions"
647 depends on CPU_V7
648 select HAVE_PROC_CPU if PROC_FS
649 default y if SMP
650 help
651 ARMv6 architecture deprecates use of the SWP/SWPB instructions.
652 ARMv7 multiprocessing extensions introduce the ability to disable
653 these instructions, triggering an undefined instruction exception
654 when executed. Say Y here to enable software emulation of these
655 instructions for userspace (not kernel) using LDREX/STREX.
656 Also creates /proc/cpu/swp_emulation for statistics.
657
658 In some older versions of glibc [<=2.8] SWP is used during futex
659 trylock() operations with the assumption that the code will not
660 be preempted. This invalid assumption may be more likely to fail
661 with SWP emulation enabled, leading to deadlock of the user
662 application.
663
664 NOTE: when accessing uncached shared regions, LDREX/STREX rely
665 on an external transaction monitoring block called a global
666 monitor to maintain update atomicity. If your system does not
667 implement a global monitor, this option can cause programs that
668 perform SWP operations to uncached memory to deadlock.
669
670 If unsure, say Y.
671
637config CPU_BIG_ENDIAN 672config CPU_BIG_ENDIAN
638 bool "Build big-endian kernel" 673 bool "Build big-endian kernel"
639 depends on ARCH_SUPPORTS_BIG_ENDIAN 674 depends on ARCH_SUPPORTS_BIG_ENDIAN
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index d63b6c41375..00d74a04af3 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -5,8 +5,8 @@
5obj-y := dma-mapping.o extable.o fault.o init.o \ 5obj-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 ioremap.o mmap.o \ 8obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
9 pgd.o mmu.o vmregion.o 9 mmap.o pgd.o mmu.o vmregion.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/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 6e77c042d8e..e0b0e7a4ec6 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -13,13 +13,9 @@
13 */ 13 */
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/highmem.h>
16#include <asm/cacheflush.h> 17#include <asm/cacheflush.h>
17#include <asm/kmap_types.h>
18#include <asm/fixmap.h>
19#include <asm/pgtable.h>
20#include <asm/tlbflush.h>
21#include <plat/cache-feroceon-l2.h> 18#include <plat/cache-feroceon-l2.h>
22#include "mm.h"
23 19
24/* 20/*
25 * Low-level cache maintenance operations. 21 * Low-level cache maintenance operations.
@@ -39,27 +35,30 @@
39 * between which we don't want to be preempted. 35 * between which we don't want to be preempted.
40 */ 36 */
41 37
42static inline unsigned long l2_start_va(unsigned long paddr) 38static inline unsigned long l2_get_va(unsigned long paddr)
43{ 39{
44#ifdef CONFIG_HIGHMEM 40#ifdef CONFIG_HIGHMEM
45 /* 41 /*
46 * Let's do our own fixmap stuff in a minimal way here.
47 * Because range ops can't be done on physical addresses, 42 * Because range ops can't be done on physical addresses,
48 * we simply install a virtual mapping for it only for the 43 * we simply install a virtual mapping for it only for the
49 * TLB lookup to occur, hence no need to flush the untouched 44 * TLB lookup to occur, hence no need to flush the untouched
50 * memory mapping. This is protected with the disabling of 45 * memory mapping afterwards (note: a cache flush may happen
51 * interrupts by the caller. 46 * in some circumstances depending on the path taken in kunmap_atomic).
52 */ 47 */
53 unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id(); 48 void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT);
54 unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); 49 return (unsigned long)vaddr + (paddr & ~PAGE_MASK);
55 set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
56 local_flush_tlb_kernel_page(vaddr);
57 return vaddr + (paddr & ~PAGE_MASK);
58#else 50#else
59 return __phys_to_virt(paddr); 51 return __phys_to_virt(paddr);
60#endif 52#endif
61} 53}
62 54
55static inline void l2_put_va(unsigned long vaddr)
56{
57#ifdef CONFIG_HIGHMEM
58 kunmap_atomic((void *)vaddr);
59#endif
60}
61
63static inline void l2_clean_pa(unsigned long addr) 62static inline void l2_clean_pa(unsigned long addr)
64{ 63{
65 __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); 64 __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
@@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
76 */ 75 */
77 BUG_ON((start ^ end) >> PAGE_SHIFT); 76 BUG_ON((start ^ end) >> PAGE_SHIFT);
78 77
79 raw_local_irq_save(flags); 78 va_start = l2_get_va(start);
80 va_start = l2_start_va(start);
81 va_end = va_start + (end - start); 79 va_end = va_start + (end - start);
80 raw_local_irq_save(flags);
82 __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" 81 __asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
83 "mcr p15, 1, %1, c15, c9, 5" 82 "mcr p15, 1, %1, c15, c9, 5"
84 : : "r" (va_start), "r" (va_end)); 83 : : "r" (va_start), "r" (va_end));
85 raw_local_irq_restore(flags); 84 raw_local_irq_restore(flags);
85 l2_put_va(va_start);
86} 86}
87 87
88static inline void l2_clean_inv_pa(unsigned long addr) 88static inline void l2_clean_inv_pa(unsigned long addr)
@@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
106 */ 106 */
107 BUG_ON((start ^ end) >> PAGE_SHIFT); 107 BUG_ON((start ^ end) >> PAGE_SHIFT);
108 108
109 raw_local_irq_save(flags); 109 va_start = l2_get_va(start);
110 va_start = l2_start_va(start);
111 va_end = va_start + (end - start); 110 va_end = va_start + (end - start);
111 raw_local_irq_save(flags);
112 __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" 112 __asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
113 "mcr p15, 1, %1, c15, c11, 5" 113 "mcr p15, 1, %1, c15, c11, 5"
114 : : "r" (va_start), "r" (va_end)); 114 : : "r" (va_start), "r" (va_end));
115 raw_local_irq_restore(flags); 115 raw_local_irq_restore(flags);
116 l2_put_va(va_start);
116} 117}
117 118
118static inline void l2_inv_all(void) 119static inline void l2_inv_all(void)
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
index c3154928bcc..5a32020471e 100644
--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -17,14 +17,10 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/highmem.h>
20#include <asm/system.h> 21#include <asm/system.h>
21#include <asm/cputype.h> 22#include <asm/cputype.h>
22#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
23#include <asm/kmap_types.h>
24#include <asm/fixmap.h>
25#include <asm/pgtable.h>
26#include <asm/tlbflush.h>
27#include "mm.h"
28 24
29#define CR_L2 (1 << 26) 25#define CR_L2 (1 << 26)
30 26
@@ -71,16 +67,15 @@ static inline void xsc3_l2_inv_all(void)
71 dsb(); 67 dsb();
72} 68}
73 69
70static inline void l2_unmap_va(unsigned long va)
71{
74#ifdef CONFIG_HIGHMEM 72#ifdef CONFIG_HIGHMEM
75#define l2_map_save_flags(x) raw_local_save_flags(x) 73 if (va != -1)
76#define l2_map_restore_flags(x) raw_local_irq_restore(x) 74 kunmap_atomic((void *)va);
77#else
78#define l2_map_save_flags(x) ((x) = 0)
79#define l2_map_restore_flags(x) ((void)(x))
80#endif 75#endif
76}
81 77
82static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, 78static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va)
83 unsigned long flags)
84{ 79{
85#ifdef CONFIG_HIGHMEM 80#ifdef CONFIG_HIGHMEM
86 unsigned long va = prev_va & PAGE_MASK; 81 unsigned long va = prev_va & PAGE_MASK;
@@ -89,17 +84,10 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
89 /* 84 /*
90 * Switching to a new page. Because cache ops are 85 * Switching to a new page. Because cache ops are
91 * using virtual addresses only, we must put a mapping 86 * using virtual addresses only, we must put a mapping
92 * in place for it. We also enable interrupts for a 87 * in place for it.
93 * short while and disable them again to protect this
94 * mapping.
95 */ 88 */
96 unsigned long idx; 89 l2_unmap_va(prev_va);
97 raw_local_irq_restore(flags); 90 va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT);
98 idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
99 va = __fix_to_virt(FIX_KMAP_BEGIN + idx);
100 raw_local_irq_restore(flags | PSR_I_BIT);
101 set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0);
102 local_flush_tlb_kernel_page(va);
103 } 91 }
104 return va + (pa_offset >> (32 - PAGE_SHIFT)); 92 return va + (pa_offset >> (32 - PAGE_SHIFT));
105#else 93#else
@@ -109,7 +97,7 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
109 97
110static void xsc3_l2_inv_range(unsigned long start, unsigned long end) 98static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
111{ 99{
112 unsigned long vaddr, flags; 100 unsigned long vaddr;
113 101
114 if (start == 0 && end == -1ul) { 102 if (start == 0 && end == -1ul) {
115 xsc3_l2_inv_all(); 103 xsc3_l2_inv_all();
@@ -117,13 +105,12 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
117 } 105 }
118 106
119 vaddr = -1; /* to force the first mapping */ 107 vaddr = -1; /* to force the first mapping */
120 l2_map_save_flags(flags);
121 108
122 /* 109 /*
123 * Clean and invalidate partial first cache line. 110 * Clean and invalidate partial first cache line.
124 */ 111 */
125 if (start & (CACHE_LINE_SIZE - 1)) { 112 if (start & (CACHE_LINE_SIZE - 1)) {
126 vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags); 113 vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr);
127 xsc3_l2_clean_mva(vaddr); 114 xsc3_l2_clean_mva(vaddr);
128 xsc3_l2_inv_mva(vaddr); 115 xsc3_l2_inv_mva(vaddr);
129 start = (start | (CACHE_LINE_SIZE - 1)) + 1; 116 start = (start | (CACHE_LINE_SIZE - 1)) + 1;
@@ -133,7 +120,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
133 * Invalidate all full cache lines between 'start' and 'end'. 120 * Invalidate all full cache lines between 'start' and 'end'.
134 */ 121 */
135 while (start < (end & ~(CACHE_LINE_SIZE - 1))) { 122 while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
136 vaddr = l2_map_va(start, vaddr, flags); 123 vaddr = l2_map_va(start, vaddr);
137 xsc3_l2_inv_mva(vaddr); 124 xsc3_l2_inv_mva(vaddr);
138 start += CACHE_LINE_SIZE; 125 start += CACHE_LINE_SIZE;
139 } 126 }
@@ -142,31 +129,30 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
142 * Clean and invalidate partial last cache line. 129 * Clean and invalidate partial last cache line.
143 */ 130 */
144 if (start < end) { 131 if (start < end) {
145 vaddr = l2_map_va(start, vaddr, flags); 132 vaddr = l2_map_va(start, vaddr);
146 xsc3_l2_clean_mva(vaddr); 133 xsc3_l2_clean_mva(vaddr);
147 xsc3_l2_inv_mva(vaddr); 134 xsc3_l2_inv_mva(vaddr);
148 } 135 }
149 136
150 l2_map_restore_flags(flags); 137 l2_unmap_va(vaddr);
151 138
152 dsb(); 139 dsb();
153} 140}
154 141
155static void xsc3_l2_clean_range(unsigned long start, unsigned long end) 142static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
156{ 143{
157 unsigned long vaddr, flags; 144 unsigned long vaddr;
158 145
159 vaddr = -1; /* to force the first mapping */ 146 vaddr = -1; /* to force the first mapping */
160 l2_map_save_flags(flags);
161 147
162 start &= ~(CACHE_LINE_SIZE - 1); 148 start &= ~(CACHE_LINE_SIZE - 1);
163 while (start < end) { 149 while (start < end) {
164 vaddr = l2_map_va(start, vaddr, flags); 150 vaddr = l2_map_va(start, vaddr);
165 xsc3_l2_clean_mva(vaddr); 151 xsc3_l2_clean_mva(vaddr);
166 start += CACHE_LINE_SIZE; 152 start += CACHE_LINE_SIZE;
167 } 153 }
168 154
169 l2_map_restore_flags(flags); 155 l2_unmap_va(vaddr);
170 156
171 dsb(); 157 dsb();
172} 158}
@@ -193,7 +179,7 @@ static inline void xsc3_l2_flush_all(void)
193 179
194static void xsc3_l2_flush_range(unsigned long start, unsigned long end) 180static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
195{ 181{
196 unsigned long vaddr, flags; 182 unsigned long vaddr;
197 183
198 if (start == 0 && end == -1ul) { 184 if (start == 0 && end == -1ul) {
199 xsc3_l2_flush_all(); 185 xsc3_l2_flush_all();
@@ -201,17 +187,16 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
201 } 187 }
202 188
203 vaddr = -1; /* to force the first mapping */ 189 vaddr = -1; /* to force the first mapping */
204 l2_map_save_flags(flags);
205 190
206 start &= ~(CACHE_LINE_SIZE - 1); 191 start &= ~(CACHE_LINE_SIZE - 1);
207 while (start < end) { 192 while (start < end) {
208 vaddr = l2_map_va(start, vaddr, flags); 193 vaddr = l2_map_va(start, vaddr);
209 xsc3_l2_clean_mva(vaddr); 194 xsc3_l2_clean_mva(vaddr);
210 xsc3_l2_inv_mva(vaddr); 195 xsc3_l2_inv_mva(vaddr);
211 start += CACHE_LINE_SIZE; 196 start += CACHE_LINE_SIZE;
212 } 197 }
213 198
214 l2_map_restore_flags(flags); 199 l2_unmap_va(vaddr);
215 200
216 dsb(); 201 dsb();
217} 202}
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ac6a36142fc..6b48e0a3d7a 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/highmem.h>
20 21
21#include <asm/memory.h> 22#include <asm/memory.h>
22#include <asm/highmem.h> 23#include <asm/highmem.h>
@@ -311,7 +312,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
311 addr = page_address(page); 312 addr = page_address(page);
312 313
313 if (addr) 314 if (addr)
314 *handle = page_to_dma(dev, page); 315 *handle = pfn_to_dma(dev, page_to_pfn(page));
315 316
316 return addr; 317 return addr;
317} 318}
@@ -406,7 +407,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
406 if (!arch_is_coherent()) 407 if (!arch_is_coherent())
407 __dma_free_remap(cpu_addr, size); 408 __dma_free_remap(cpu_addr, size);
408 409
409 __dma_free_buffer(dma_to_page(dev, handle), size); 410 __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
410} 411}
411EXPORT_SYMBOL(dma_free_coherent); 412EXPORT_SYMBOL(dma_free_coherent);
412 413
@@ -480,10 +481,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
480 op(vaddr, len, dir); 481 op(vaddr, len, dir);
481 kunmap_high(page); 482 kunmap_high(page);
482 } else if (cache_is_vipt()) { 483 } else if (cache_is_vipt()) {
483 pte_t saved_pte; 484 /* unmapped pages might still be cached */
484 vaddr = kmap_high_l1_vipt(page, &saved_pte); 485 vaddr = kmap_atomic(page);
485 op(vaddr + offset, len, dir); 486 op(vaddr + offset, len, dir);
486 kunmap_high_l1_vipt(page, saved_pte); 487 kunmap_atomic(vaddr);
487 } 488 }
488 } else { 489 } else {
489 vaddr = page_address(page) + offset; 490 vaddr = page_address(page) + offset;
@@ -554,17 +555,20 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
554 struct scatterlist *s; 555 struct scatterlist *s;
555 int i, j; 556 int i, j;
556 557
558 BUG_ON(!valid_dma_direction(dir));
559
557 for_each_sg(sg, s, nents, i) { 560 for_each_sg(sg, s, nents, i) {
558 s->dma_address = dma_map_page(dev, sg_page(s), s->offset, 561 s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
559 s->length, dir); 562 s->length, dir);
560 if (dma_mapping_error(dev, s->dma_address)) 563 if (dma_mapping_error(dev, s->dma_address))
561 goto bad_mapping; 564 goto bad_mapping;
562 } 565 }
566 debug_dma_map_sg(dev, sg, nents, nents, dir);
563 return nents; 567 return nents;
564 568
565 bad_mapping: 569 bad_mapping:
566 for_each_sg(sg, s, i, j) 570 for_each_sg(sg, s, i, j)
567 dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir); 571 __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
568 return 0; 572 return 0;
569} 573}
570EXPORT_SYMBOL(dma_map_sg); 574EXPORT_SYMBOL(dma_map_sg);
@@ -585,8 +589,10 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
585 struct scatterlist *s; 589 struct scatterlist *s;
586 int i; 590 int i;
587 591
592 debug_dma_unmap_sg(dev, sg, nents, dir);
593
588 for_each_sg(sg, s, nents, i) 594 for_each_sg(sg, s, nents, i)
589 dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir); 595 __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
590} 596}
591EXPORT_SYMBOL(dma_unmap_sg); 597EXPORT_SYMBOL(dma_unmap_sg);
592 598
@@ -611,6 +617,8 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
611 __dma_page_dev_to_cpu(sg_page(s), s->offset, 617 __dma_page_dev_to_cpu(sg_page(s), s->offset,
612 s->length, dir); 618 s->length, dir);
613 } 619 }
620
621 debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
614} 622}
615EXPORT_SYMBOL(dma_sync_sg_for_cpu); 623EXPORT_SYMBOL(dma_sync_sg_for_cpu);
616 624
@@ -635,5 +643,16 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
635 __dma_page_cpu_to_dev(sg_page(s), s->offset, 643 __dma_page_cpu_to_dev(sg_page(s), s->offset,
636 s->length, dir); 644 s->length, dir);
637 } 645 }
646
647 debug_dma_sync_sg_for_device(dev, sg, nents, dir);
638} 648}
639EXPORT_SYMBOL(dma_sync_sg_for_device); 649EXPORT_SYMBOL(dma_sync_sg_for_device);
650
651#define PREALLOC_DMA_DEBUG_ENTRIES 4096
652
653static int __init dma_debug_do_init(void)
654{
655 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
656 return 0;
657}
658fs_initcall(dma_debug_do_init);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 83e59f87042..01210dba022 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -26,7 +26,7 @@
26 26
27#include "mm.h" 27#include "mm.h"
28 28
29static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE; 29static pteval_t shared_pte_mask = L_PTE_MT_BUFFERABLE;
30 30
31#if __LINUX_ARM_ARCH__ < 6 31#if __LINUX_ARM_ARCH__ < 6
32/* 32/*
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 1e21e125fe3..f10f9bac220 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -108,7 +108,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
108 108
109 pte = pte_offset_map(pmd, addr); 109 pte = pte_offset_map(pmd, addr);
110 printk(", *pte=%08lx", pte_val(*pte)); 110 printk(", *pte=%08lx", pte_val(*pte));
111 printk(", *ppte=%08lx", pte_val(pte[-PTRS_PER_PTE])); 111 printk(", *ppte=%08lx", pte_val(pte[PTE_HWTABLE_PTRS]));
112 pte_unmap(pte); 112 pte_unmap(pte);
113 } while(0); 113 } while(0);
114 114
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 391ffae7509..c29f2839f1d 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/pagemap.h> 12#include <linux/pagemap.h>
13#include <linux/highmem.h>
13 14
14#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
15#include <asm/cachetype.h> 16#include <asm/cachetype.h>
@@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
180 __cpuc_flush_dcache_area(addr, PAGE_SIZE); 181 __cpuc_flush_dcache_area(addr, PAGE_SIZE);
181 kunmap_high(page); 182 kunmap_high(page);
182 } else if (cache_is_vipt()) { 183 } else if (cache_is_vipt()) {
183 pte_t saved_pte; 184 /* unmapped pages might still be cached */
184 addr = kmap_high_l1_vipt(page, &saved_pte); 185 addr = kmap_atomic(page);
185 __cpuc_flush_dcache_area(addr, PAGE_SIZE); 186 __cpuc_flush_dcache_area(addr, PAGE_SIZE);
186 kunmap_high_l1_vipt(page, saved_pte); 187 kunmap_atomic(addr);
187 } 188 }
188 } 189 }
189 190
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index c435fd9e1da..807c0573abb 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -140,90 +140,3 @@ struct page *kmap_atomic_to_page(const void *ptr)
140 pte = TOP_PTE(vaddr); 140 pte = TOP_PTE(vaddr);
141 return pte_page(*pte); 141 return pte_page(*pte);
142} 142}
143
144#ifdef CONFIG_CPU_CACHE_VIPT
145
146#include <linux/percpu.h>
147
148/*
149 * The VIVT cache of a highmem page is always flushed before the page
150 * is unmapped. Hence unmapped highmem pages need no cache maintenance
151 * in that case.
152 *
153 * However unmapped pages may still be cached with a VIPT cache, and
154 * it is not possible to perform cache maintenance on them using physical
155 * addresses unfortunately. So we have no choice but to set up a temporary
156 * virtual mapping for that purpose.
157 *
158 * Yet this VIPT cache maintenance may be triggered from DMA support
159 * functions which are possibly called from interrupt context. As we don't
160 * want to keep interrupt disabled all the time when such maintenance is
161 * taking place, we therefore allow for some reentrancy by preserving and
162 * restoring the previous fixmap entry before the interrupted context is
163 * resumed. If the reentrancy depth is 0 then there is no need to restore
164 * the previous fixmap, and leaving the current one in place allow it to
165 * be reused the next time without a TLB flush (common with DMA).
166 */
167
168static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
169
170void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
171{
172 unsigned int idx, cpu;
173 int *depth;
174 unsigned long vaddr, flags;
175 pte_t pte, *ptep;
176
177 if (!in_interrupt())
178 preempt_disable();
179
180 cpu = smp_processor_id();
181 depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
182
183 idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
184 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
185 ptep = TOP_PTE(vaddr);
186 pte = mk_pte(page, kmap_prot);
187
188 raw_local_irq_save(flags);
189 (*depth)++;
190 if (pte_val(*ptep) == pte_val(pte)) {
191 *saved_pte = pte;
192 } else {
193 *saved_pte = *ptep;
194 set_pte_ext(ptep, pte, 0);
195 local_flush_tlb_kernel_page(vaddr);
196 }
197 raw_local_irq_restore(flags);
198
199 return (void *)vaddr;
200}
201
202void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
203{
204 unsigned int idx, cpu = smp_processor_id();
205 int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
206 unsigned long vaddr, flags;
207 pte_t pte, *ptep;
208
209 idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
210 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
211 ptep = TOP_PTE(vaddr);
212 pte = mk_pte(page, kmap_prot);
213
214 BUG_ON(pte_val(*ptep) != pte_val(pte));
215 BUG_ON(*depth <= 0);
216
217 raw_local_irq_save(flags);
218 (*depth)--;
219 if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
220 set_pte_ext(ptep, saved_pte, 0);
221 local_flush_tlb_kernel_page(vaddr);
222 }
223 raw_local_irq_restore(flags);
224
225 if (!in_interrupt())
226 preempt_enable();
227}
228
229#endif /* CONFIG_CPU_CACHE_VIPT */
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
new file mode 100644
index 00000000000..57299446f78
--- /dev/null
+++ b/arch/arm/mm/idmap.c
@@ -0,0 +1,67 @@
1#include <linux/kernel.h>
2
3#include <asm/cputype.h>
4#include <asm/pgalloc.h>
5#include <asm/pgtable.h>
6
7static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
8 unsigned long prot)
9{
10 pmd_t *pmd = pmd_offset(pgd, addr);
11
12 addr = (addr & PMD_MASK) | prot;
13 pmd[0] = __pmd(addr);
14 addr += SECTION_SIZE;
15 pmd[1] = __pmd(addr);
16 flush_pmd_entry(pmd);
17}
18
19void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
20{
21 unsigned long prot, next;
22
23 prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
24 if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
25 prot |= PMD_BIT4;
26
27 pgd += pgd_index(addr);
28 do {
29 next = pgd_addr_end(addr, end);
30 idmap_add_pmd(pgd, addr, next, prot);
31 } while (pgd++, addr = next, addr != end);
32}
33
34#ifdef CONFIG_SMP
35static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end)
36{
37 pmd_t *pmd = pmd_offset(pgd, addr);
38 pmd_clear(pmd);
39}
40
41void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
42{
43 unsigned long next;
44
45 pgd += pgd_index(addr);
46 do {
47 next = pgd_addr_end(addr, end);
48 idmap_del_pmd(pgd, addr, next);
49 } while (pgd++, addr = next, addr != end);
50}
51#endif
52
53/*
54 * In order to soft-boot, we need to insert a 1:1 mapping in place of
55 * the user-mode pages. This will then ensure that we have predictable
56 * results when turning the mmu off
57 */
58void setup_mm_for_reboot(char mode)
59{
60 /*
61 * We need to access to user-mode page tables here. For kernel threads
62 * we don't have any user-mode mappings so we use the context that we
63 * "borrowed".
64 */
65 identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
66 local_flush_tlb_all();
67}
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 55c17a6fb22..ab506272b2d 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -204,12 +204,8 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
204 /* 204 /*
205 * Don't allow RAM to be mapped - this causes problems with ARMv6+ 205 * Don't allow RAM to be mapped - this causes problems with ARMv6+
206 */ 206 */
207 if (pfn_valid(pfn)) { 207 if (WARN_ON(pfn_valid(pfn)))
208 printk(KERN_WARNING "BUG: Your driver calls ioremap() on system memory. This leads\n" 208 return NULL;
209 "to architecturally unpredictable behaviour on ARMv6+, and ioremap()\n"
210 "will fail in the next kernel release. Please fix your driver.\n");
211 WARN_ON(1);
212 }
213 209
214 type = get_mem_type(mtype); 210 type = get_mem_type(mtype);
215 if (!type) 211 if (!type)
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 6630620380a..36960df5fb7 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -16,7 +16,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
16} 16}
17 17
18struct mem_type { 18struct mem_type {
19 unsigned int prot_pte; 19 pteval_t prot_pte;
20 unsigned int prot_l1; 20 unsigned int prot_l1;
21 unsigned int prot_sect; 21 unsigned int prot_sect;
22 unsigned int domain; 22 unsigned int domain;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 72ad3e1f56c..3c67e92f7d5 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -24,6 +24,7 @@
24#include <asm/smp_plat.h> 24#include <asm/smp_plat.h>
25#include <asm/tlb.h> 25#include <asm/tlb.h>
26#include <asm/highmem.h> 26#include <asm/highmem.h>
27#include <asm/traps.h>
27 28
28#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
29#include <asm/mach/map.h> 30#include <asm/mach/map.h>
@@ -62,7 +63,7 @@ struct cachepolicy {
62 const char policy[16]; 63 const char policy[16];
63 unsigned int cr_mask; 64 unsigned int cr_mask;
64 unsigned int pmd; 65 unsigned int pmd;
65 unsigned int pte; 66 pteval_t pte;
66}; 67};
67 68
68static struct cachepolicy cache_policies[] __initdata = { 69static struct cachepolicy cache_policies[] __initdata = {
@@ -190,7 +191,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
190} 191}
191#endif 192#endif
192 193
193#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE 194#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
194#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE 195#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
195 196
196static struct mem_type mem_types[] = { 197static struct mem_type mem_types[] = {
@@ -235,19 +236,18 @@ static struct mem_type mem_types[] = {
235 }, 236 },
236 [MT_LOW_VECTORS] = { 237 [MT_LOW_VECTORS] = {
237 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 238 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
238 L_PTE_EXEC, 239 L_PTE_RDONLY,
239 .prot_l1 = PMD_TYPE_TABLE, 240 .prot_l1 = PMD_TYPE_TABLE,
240 .domain = DOMAIN_USER, 241 .domain = DOMAIN_USER,
241 }, 242 },
242 [MT_HIGH_VECTORS] = { 243 [MT_HIGH_VECTORS] = {
243 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 244 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
244 L_PTE_USER | L_PTE_EXEC, 245 L_PTE_USER | L_PTE_RDONLY,
245 .prot_l1 = PMD_TYPE_TABLE, 246 .prot_l1 = PMD_TYPE_TABLE,
246 .domain = DOMAIN_USER, 247 .domain = DOMAIN_USER,
247 }, 248 },
248 [MT_MEMORY] = { 249 [MT_MEMORY] = {
249 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 250 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
250 L_PTE_WRITE | L_PTE_EXEC,
251 .prot_l1 = PMD_TYPE_TABLE, 251 .prot_l1 = PMD_TYPE_TABLE,
252 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, 252 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
253 .domain = DOMAIN_KERNEL, 253 .domain = DOMAIN_KERNEL,
@@ -258,21 +258,20 @@ static struct mem_type mem_types[] = {
258 }, 258 },
259 [MT_MEMORY_NONCACHED] = { 259 [MT_MEMORY_NONCACHED] = {
260 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 260 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
261 L_PTE_WRITE | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, 261 L_PTE_MT_BUFFERABLE,
262 .prot_l1 = PMD_TYPE_TABLE, 262 .prot_l1 = PMD_TYPE_TABLE,
263 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, 263 .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
264 .domain = DOMAIN_KERNEL, 264 .domain = DOMAIN_KERNEL,
265 }, 265 },
266 [MT_MEMORY_DTCM] = { 266 [MT_MEMORY_DTCM] = {
267 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 267 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
268 L_PTE_WRITE, 268 L_PTE_XN,
269 .prot_l1 = PMD_TYPE_TABLE, 269 .prot_l1 = PMD_TYPE_TABLE,
270 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, 270 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
271 .domain = DOMAIN_KERNEL, 271 .domain = DOMAIN_KERNEL,
272 }, 272 },
273 [MT_MEMORY_ITCM] = { 273 [MT_MEMORY_ITCM] = {
274 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 274 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
275 L_PTE_WRITE | L_PTE_EXEC,
276 .prot_l1 = PMD_TYPE_TABLE, 275 .prot_l1 = PMD_TYPE_TABLE,
277 .domain = DOMAIN_KERNEL, 276 .domain = DOMAIN_KERNEL,
278 }, 277 },
@@ -479,7 +478,7 @@ static void __init build_mem_type_table(void)
479 478
480 pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot); 479 pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
481 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | 480 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
482 L_PTE_DIRTY | L_PTE_WRITE | kern_pgprot); 481 L_PTE_DIRTY | kern_pgprot);
483 482
484 mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; 483 mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
485 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; 484 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
@@ -535,7 +534,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
535{ 534{
536 if (pmd_none(*pmd)) { 535 if (pmd_none(*pmd)) {
537 pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t)); 536 pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
538 __pmd_populate(pmd, __pa(pte) | prot); 537 __pmd_populate(pmd, __pa(pte), prot);
539 } 538 }
540 BUG_ON(pmd_bad(*pmd)); 539 BUG_ON(pmd_bad(*pmd));
541 return pte_offset_kernel(pmd, addr); 540 return pte_offset_kernel(pmd, addr);
@@ -553,7 +552,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
553} 552}
554 553
555static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, 554static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
556 unsigned long end, unsigned long phys, 555 unsigned long end, phys_addr_t phys,
557 const struct mem_type *type) 556 const struct mem_type *type)
558{ 557{
559 pmd_t *pmd = pmd_offset(pgd, addr); 558 pmd_t *pmd = pmd_offset(pgd, addr);
@@ -588,7 +587,8 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
588static void __init create_36bit_mapping(struct map_desc *md, 587static void __init create_36bit_mapping(struct map_desc *md,
589 const struct mem_type *type) 588 const struct mem_type *type)
590{ 589{
591 unsigned long phys, addr, length, end; 590 unsigned long addr, length, end;
591 phys_addr_t phys;
592 pgd_t *pgd; 592 pgd_t *pgd;
593 593
594 addr = md->virtual; 594 addr = md->virtual;
@@ -914,12 +914,11 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
914{ 914{
915 struct map_desc map; 915 struct map_desc map;
916 unsigned long addr; 916 unsigned long addr;
917 void *vectors;
918 917
919 /* 918 /*
920 * Allocate the vector page early. 919 * Allocate the vector page early.
921 */ 920 */
922 vectors = early_alloc(PAGE_SIZE); 921 vectors_page = early_alloc(PAGE_SIZE);
923 922
924 for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) 923 for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
925 pmd_clear(pmd_off_k(addr)); 924 pmd_clear(pmd_off_k(addr));
@@ -959,7 +958,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
959 * location (0xffff0000). If we aren't using high-vectors, also 958 * location (0xffff0000). If we aren't using high-vectors, also
960 * create a mapping at the low-vectors virtual address. 959 * create a mapping at the low-vectors virtual address.
961 */ 960 */
962 map.pfn = __phys_to_pfn(virt_to_phys(vectors)); 961 map.pfn = __phys_to_pfn(virt_to_phys(vectors_page));
963 map.virtual = 0xffff0000; 962 map.virtual = 0xffff0000;
964 map.length = PAGE_SIZE; 963 map.length = PAGE_SIZE;
965 map.type = MT_HIGH_VECTORS; 964 map.type = MT_HIGH_VECTORS;
@@ -1044,38 +1043,3 @@ void __init paging_init(struct machine_desc *mdesc)
1044 empty_zero_page = virt_to_page(zero_page); 1043 empty_zero_page = virt_to_page(zero_page);
1045 __flush_dcache_page(NULL, empty_zero_page); 1044 __flush_dcache_page(NULL, empty_zero_page);
1046} 1045}
1047
1048/*
1049 * In order to soft-boot, we need to insert a 1:1 mapping in place of
1050 * the user-mode pages. This will then ensure that we have predictable
1051 * results when turning the mmu off
1052 */
1053void setup_mm_for_reboot(char mode)
1054{
1055 unsigned long base_pmdval;
1056 pgd_t *pgd;
1057 int i;
1058
1059 /*
1060 * We need to access to user-mode page tables here. For kernel threads
1061 * we don't have any user-mode mappings so we use the context that we
1062 * "borrowed".
1063 */
1064 pgd = current->active_mm->pgd;
1065
1066 base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
1067 if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
1068 base_pmdval |= PMD_BIT4;
1069
1070 for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
1071 unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval;
1072 pmd_t *pmd;
1073
1074 pmd = pmd_off(pgd, i << PGDIR_SHIFT);
1075 pmd[0] = __pmd(pmdval);
1076 pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
1077 flush_pmd_entry(pmd);
1078 }
1079
1080 local_flush_tlb_all();
1081}
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 69bbfc6645a..93292a18cf7 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -17,12 +17,10 @@
17 17
18#include "mm.h" 18#include "mm.h"
19 19
20#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
21
22/* 20/*
23 * need to get a 16k page for level 1 21 * need to get a 16k page for level 1
24 */ 22 */
25pgd_t *get_pgd_slow(struct mm_struct *mm) 23pgd_t *pgd_alloc(struct mm_struct *mm)
26{ 24{
27 pgd_t *new_pgd, *init_pgd; 25 pgd_t *new_pgd, *init_pgd;
28 pmd_t *new_pmd, *init_pmd; 26 pmd_t *new_pmd, *init_pmd;
@@ -32,14 +30,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
32 if (!new_pgd) 30 if (!new_pgd)
33 goto no_pgd; 31 goto no_pgd;
34 32
35 memset(new_pgd, 0, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); 33 memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
36 34
37 /* 35 /*
38 * Copy over the kernel and IO PGD entries 36 * Copy over the kernel and IO PGD entries
39 */ 37 */
40 init_pgd = pgd_offset_k(0); 38 init_pgd = pgd_offset_k(0);
41 memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, 39 memcpy(new_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD,
42 (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); 40 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
43 41
44 clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); 42 clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
45 43
@@ -73,28 +71,29 @@ no_pgd:
73 return NULL; 71 return NULL;
74} 72}
75 73
76void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) 74void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
77{ 75{
76 pgd_t *pgd;
78 pmd_t *pmd; 77 pmd_t *pmd;
79 pgtable_t pte; 78 pgtable_t pte;
80 79
81 if (!pgd) 80 if (!pgd_base)
82 return; 81 return;
83 82
84 /* pgd is always present and good */ 83 pgd = pgd_base + pgd_index(0);
85 pmd = pmd_off(pgd, 0); 84 if (pgd_none_or_clear_bad(pgd))
86 if (pmd_none(*pmd)) 85 goto no_pgd;
87 goto free; 86
88 if (pmd_bad(*pmd)) { 87 pmd = pmd_offset(pgd, 0);
89 pmd_ERROR(*pmd); 88 if (pmd_none_or_clear_bad(pmd))
90 pmd_clear(pmd); 89 goto no_pmd;
91 goto free;
92 }
93 90
94 pte = pmd_pgtable(*pmd); 91 pte = pmd_pgtable(*pmd);
95 pmd_clear(pmd); 92 pmd_clear(pmd);
96 pte_free(mm, pte); 93 pte_free(mm, pte);
94no_pmd:
95 pgd_clear(pgd);
97 pmd_free(mm, pmd); 96 pmd_free(mm, pmd);
98free: 97no_pgd:
99 free_pages((unsigned long) pgd, 2); 98 free_pages((unsigned long) pgd_base, 2);
100} 99}
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index b795afd0a2c..e32fa499194 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -91,7 +91,7 @@
91#if L_PTE_SHARED != PTE_EXT_SHARED 91#if L_PTE_SHARED != PTE_EXT_SHARED
92#error PTE shared bit mismatch 92#error PTE shared bit mismatch
93#endif 93#endif
94#if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ 94#if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
95 L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED 95 L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
96#error Invalid Linux PTE bit settings 96#error Invalid Linux PTE bit settings
97#endif 97#endif
@@ -109,6 +109,10 @@
109 * 110x 0 1 0 r/w r/o 109 * 110x 0 1 0 r/w r/o
110 * 11x0 0 1 0 r/w r/o 110 * 11x0 0 1 0 r/w r/o
111 * 1111 0 1 1 r/w r/w 111 * 1111 0 1 1 r/w r/w
112 *
113 * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
114 * 110x 1 1 1 r/o r/o
115 * 11x0 1 1 1 r/o r/o
112 */ 116 */
113 .macro armv6_mt_table pfx 117 .macro armv6_mt_table pfx
114\pfx\()_mt_table: 118\pfx\()_mt_table:
@@ -131,7 +135,7 @@
131 .endm 135 .endm
132 136
133 .macro armv6_set_pte_ext pfx 137 .macro armv6_set_pte_ext pfx
134 str r1, [r0], #-2048 @ linux version 138 str r1, [r0], #2048 @ linux version
135 139
136 bic r3, r1, #0x000003fc 140 bic r3, r1, #0x000003fc
137 bic r3, r3, #PTE_TYPE_MASK 141 bic r3, r3, #PTE_TYPE_MASK
@@ -142,17 +146,20 @@
142 and r2, r1, #L_PTE_MT_MASK 146 and r2, r1, #L_PTE_MT_MASK
143 ldr r2, [ip, r2] 147 ldr r2, [ip, r2]
144 148
145 tst r1, #L_PTE_WRITE 149 eor r1, r1, #L_PTE_DIRTY
146 tstne r1, #L_PTE_DIRTY 150 tst r1, #L_PTE_DIRTY|L_PTE_RDONLY
147 orreq r3, r3, #PTE_EXT_APX 151 orrne r3, r3, #PTE_EXT_APX
148 152
149 tst r1, #L_PTE_USER 153 tst r1, #L_PTE_USER
150 orrne r3, r3, #PTE_EXT_AP1 154 orrne r3, r3, #PTE_EXT_AP1
155#ifdef CONFIG_CPU_USE_DOMAINS
156 @ allow kernel read/write access to read-only user pages
151 tstne r3, #PTE_EXT_APX 157 tstne r3, #PTE_EXT_APX
152 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 158 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
159#endif
153 160
154 tst r1, #L_PTE_EXEC 161 tst r1, #L_PTE_XN
155 orreq r3, r3, #PTE_EXT_XN 162 orrne r3, r3, #PTE_EXT_XN
156 163
157 orr r3, r3, r2 164 orr r3, r3, r2
158 165
@@ -180,9 +187,9 @@
180 * 1111 0xff r/w r/w 187 * 1111 0xff r/w r/w
181 */ 188 */
182 .macro armv3_set_pte_ext wc_disable=1 189 .macro armv3_set_pte_ext wc_disable=1
183 str r1, [r0], #-2048 @ linux version 190 str r1, [r0], #2048 @ linux version
184 191
185 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY 192 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
186 193
187 bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits 194 bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
188 bic r2, r2, #PTE_TYPE_MASK 195 bic r2, r2, #PTE_TYPE_MASK
@@ -191,7 +198,7 @@
191 tst r3, #L_PTE_USER @ user? 198 tst r3, #L_PTE_USER @ user?
192 orrne r2, r2, #PTE_SMALL_AP_URO_SRW 199 orrne r2, r2, #PTE_SMALL_AP_URO_SRW
193 200
194 tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? 201 tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
195 orreq r2, r2, #PTE_SMALL_AP_UNO_SRW 202 orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
196 203
197 tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? 204 tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
@@ -203,7 +210,7 @@
203 bicne r2, r2, #PTE_BUFFERABLE 210 bicne r2, r2, #PTE_BUFFERABLE
204#endif 211#endif
205 .endif 212 .endif
206 str r2, [r0] @ hardware version 213 str r2, [r0] @ hardware version
207 .endm 214 .endm
208 215
209 216
@@ -223,9 +230,9 @@
223 * 1111 11 r/w r/w 230 * 1111 11 r/w r/w
224 */ 231 */
225 .macro xscale_set_pte_ext_prologue 232 .macro xscale_set_pte_ext_prologue
226 str r1, [r0], #-2048 @ linux version 233 str r1, [r0] @ linux version
227 234
228 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY 235 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
229 236
230 bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits 237 bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
231 orr r2, r2, #PTE_TYPE_EXT @ extended page 238 orr r2, r2, #PTE_TYPE_EXT @ extended page
@@ -233,7 +240,7 @@
233 tst r3, #L_PTE_USER @ user? 240 tst r3, #L_PTE_USER @ user?
234 orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w 241 orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w
235 242
236 tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? 243 tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
237 orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w 244 orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w
238 @ combined with user -> user r/w 245 @ combined with user -> user r/w
239 .endm 246 .endm
@@ -242,7 +249,7 @@
242 tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? 249 tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
243 movne r2, #0 @ no -> fault 250 movne r2, #0 @ no -> fault
244 251
245 str r2, [r0] @ hardware version 252 str r2, [r0, #2048]! @ hardware version
246 mov ip, #0 253 mov ip, #0
247 mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line 254 mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
248 mcr p15, 0, ip, c7, c10, 4 @ data write barrier 255 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 9b9ff5d949f..b49fab21517 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -124,15 +124,13 @@ ENDPROC(cpu_v7_switch_mm)
124 * Set a level 2 translation table entry. 124 * Set a level 2 translation table entry.
125 * 125 *
126 * - ptep - pointer to level 2 translation table entry 126 * - ptep - pointer to level 2 translation table entry
127 * (hardware version is stored at -1024 bytes) 127 * (hardware version is stored at +2048 bytes)
128 * - pte - PTE value to store 128 * - pte - PTE value to store
129 * - ext - value for extended PTE bits 129 * - ext - value for extended PTE bits
130 */ 130 */
131ENTRY(cpu_v7_set_pte_ext) 131ENTRY(cpu_v7_set_pte_ext)
132#ifdef CONFIG_MMU 132#ifdef CONFIG_MMU
133 ARM( str r1, [r0], #-2048 ) @ linux version 133 str r1, [r0] @ linux version
134 THUMB( str r1, [r0] ) @ linux version
135 THUMB( sub r0, r0, #2048 )
136 134
137 bic r3, r1, #0x000003f0 135 bic r3, r1, #0x000003f0
138 bic r3, r3, #PTE_TYPE_MASK 136 bic r3, r3, #PTE_TYPE_MASK
@@ -142,23 +140,26 @@ ENTRY(cpu_v7_set_pte_ext)
142 tst r1, #1 << 4 140 tst r1, #1 << 4
143 orrne r3, r3, #PTE_EXT_TEX(1) 141 orrne r3, r3, #PTE_EXT_TEX(1)
144 142
145 tst r1, #L_PTE_WRITE 143 eor r1, r1, #L_PTE_DIRTY
146 tstne r1, #L_PTE_DIRTY 144 tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
147 orreq r3, r3, #PTE_EXT_APX 145 orrne r3, r3, #PTE_EXT_APX
148 146
149 tst r1, #L_PTE_USER 147 tst r1, #L_PTE_USER
150 orrne r3, r3, #PTE_EXT_AP1 148 orrne r3, r3, #PTE_EXT_AP1
149#ifdef CONFIG_CPU_USE_DOMAINS
150 @ allow kernel read/write access to read-only user pages
151 tstne r3, #PTE_EXT_APX 151 tstne r3, #PTE_EXT_APX
152 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 152 bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
153#endif
153 154
154 tst r1, #L_PTE_EXEC 155 tst r1, #L_PTE_XN
155 orreq r3, r3, #PTE_EXT_XN 156 orrne r3, r3, #PTE_EXT_XN
156 157
157 tst r1, #L_PTE_YOUNG 158 tst r1, #L_PTE_YOUNG
158 tstne r1, #L_PTE_PRESENT 159 tstne r1, #L_PTE_PRESENT
159 moveq r3, #0 160 moveq r3, #0
160 161
161 str r3, [r0] 162 str r3, [r0, #2048]!
162 mcr p15, 0, r0, c7, c10, 1 @ flush_pte 163 mcr p15, 0, r0, c7, c10, 1 @ flush_pte
163#endif 164#endif
164 mov pc, lr 165 mov pc, lr
@@ -273,8 +274,6 @@ __v7_setup:
273 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) 274 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
274 ALT_UP(orr r4, r4, #TTB_FLAGS_UP) 275 ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
275 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 276 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
276 mov r10, #0x1f @ domains 0, 1 = manager
277 mcr p15, 0, r10, c3, c0, 0 @ load domain access register
278 /* 277 /*
279 * Memory region attributes with SCTLR.TRE=1 278 * Memory region attributes with SCTLR.TRE=1
280 * 279 *
@@ -313,6 +312,10 @@ __v7_setup:
313#ifdef CONFIG_CPU_ENDIAN_BE8 312#ifdef CONFIG_CPU_ENDIAN_BE8
314 orr r6, r6, #1 << 25 @ big-endian page tables 313 orr r6, r6, #1 << 25 @ big-endian page tables
315#endif 314#endif
315#ifdef CONFIG_SWP_EMULATE
316 orr r5, r5, #(1 << 10) @ set SW bit in "clear"
317 bic r6, r6, #(1 << 10) @ clear it in "mmuset"
318#endif
316 mrc p15, 0, r0, c1, c0, 0 @ read control register 319 mrc p15, 0, r0, c1, c0, 0 @ read control register
317 bic r0, r0, r5 @ clear bits them 320 bic r0, r0, r5 @ clear bits them
318 orr r0, r0, r6 @ set them 321 orr r0, r0, r6 @ set them
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 523408c0bb3..5a37c5e45c4 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -500,8 +500,8 @@ ENTRY(cpu_xscale_set_pte_ext)
500 @ 500 @
501 @ Erratum 40: must set memory to write-through for user read-only pages 501 @ Erratum 40: must set memory to write-through for user read-only pages
502 @ 502 @
503 and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2) 503 and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_RDONLY) & ~(4 << 2)
504 teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER 504 teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER | L_PTE_RDONLY
505 505
506 moveq r1, #L_PTE_MT_WRITETHROUGH 506 moveq r1, #L_PTE_MT_WRITETHROUGH
507 and r1, r1, #L_PTE_MT_MASK 507 and r1, r1, #L_PTE_MT_MASK
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 558cdfaf76b..07f23bb42be 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/time.h> 18#include <linux/time.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/sched.h>
20#include <linux/timex.h> 21#include <linux/timex.h>
21#include <linux/sched.h> 22#include <linux/sched.h>
22#include <linux/io.h> 23#include <linux/io.h>
@@ -24,6 +25,7 @@
24#include <linux/clockchips.h> 25#include <linux/clockchips.h>
25#include <mach/hardware.h> 26#include <mach/hardware.h>
26#include <asm/irq.h> 27#include <asm/irq.h>
28#include <asm/sched_clock.h>
27#include <asm/uaccess.h> 29#include <asm/uaccess.h>
28#include <asm/mach/irq.h> 30#include <asm/mach/irq.h>
29#include <asm/mach/time.h> 31#include <asm/mach/time.h>
@@ -50,15 +52,21 @@ static struct clocksource iop_clocksource = {
50 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 52 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
51}; 53};
52 54
55static DEFINE_CLOCK_DATA(cd);
56
53/* 57/*
54 * IOP sched_clock() implementation via its clocksource. 58 * IOP sched_clock() implementation via its clocksource.
55 */ 59 */
56unsigned long long sched_clock(void) 60unsigned long long notrace sched_clock(void)
57{ 61{
58 cycle_t cyc = iop_clocksource_read(NULL); 62 u32 cyc = 0xffffffffu - read_tcr1();
59 struct clocksource *cs = &iop_clocksource; 63 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
64}
60 65
61 return clocksource_cyc2ns(cyc, cs->mult, cs->shift); 66static void notrace iop_update_sched_clock(void)
67{
68 u32 cyc = 0xffffffffu - read_tcr1();
69 update_sched_clock(&cd, cyc, (u32)~0);
62} 70}
63 71
64/* 72/*
@@ -88,6 +96,7 @@ static void iop_set_mode(enum clock_event_mode mode,
88 case CLOCK_EVT_MODE_PERIODIC: 96 case CLOCK_EVT_MODE_PERIODIC:
89 write_tmr0(tmr & ~IOP_TMR_EN); 97 write_tmr0(tmr & ~IOP_TMR_EN);
90 write_tcr0(ticks_per_jiffy - 1); 98 write_tcr0(ticks_per_jiffy - 1);
99 write_trr0(ticks_per_jiffy - 1);
91 tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN); 100 tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
92 break; 101 break;
93 case CLOCK_EVT_MODE_ONESHOT: 102 case CLOCK_EVT_MODE_ONESHOT:
@@ -143,6 +152,8 @@ void __init iop_init_time(unsigned long tick_rate)
143{ 152{
144 u32 timer_ctl; 153 u32 timer_ctl;
145 154
155 init_sched_clock(&cd, iop_update_sched_clock, 32, tick_rate);
156
146 ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ); 157 ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
147 iop_tick_rate = tick_rate; 158 iop_tick_rate = tick_rate;
148 159
@@ -153,6 +164,7 @@ void __init iop_init_time(unsigned long tick_rate)
153 * Set up interrupting clockevent timer 0. 164 * Set up interrupting clockevent timer 0.
154 */ 165 */
155 write_tmr0(timer_ctl & ~IOP_TMR_EN); 166 write_tmr0(timer_ctl & ~IOP_TMR_EN);
167 write_tisr(1);
156 setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq); 168 setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
157 clockevents_calc_mult_shift(&iop_clockevent, 169 clockevents_calc_mult_shift(&iop_clockevent,
158 tick_rate, IOP_MIN_RANGE); 170 tick_rate, IOP_MIN_RANGE);
@@ -162,9 +174,6 @@ void __init iop_init_time(unsigned long tick_rate)
162 clockevent_delta2ns(0xf, &iop_clockevent); 174 clockevent_delta2ns(0xf, &iop_clockevent);
163 iop_clockevent.cpumask = cpumask_of(0); 175 iop_clockevent.cpumask = cpumask_of(0);
164 clockevents_register_device(&iop_clockevent); 176 clockevents_register_device(&iop_clockevent);
165 write_trr0(ticks_per_jiffy - 1);
166 write_tcr0(ticks_per_jiffy - 1);
167 write_tmr0(timer_ctl);
168 177
169 /* 178 /*
170 * Set up free-running clocksource timer 1. 179 * Set up free-running clocksource timer 1.
@@ -172,7 +181,5 @@ void __init iop_init_time(unsigned long tick_rate)
172 write_trr1(0xffffffff); 181 write_trr1(0xffffffff);
173 write_tcr1(0xffffffff); 182 write_tcr1(0xffffffff);
174 write_tmr1(timer_ctl); 183 write_tmr1(timer_ctl);
175 clocksource_calc_mult_shift(&iop_clocksource, tick_rate, 184 clocksource_register_hz(&iop_clocksource, tick_rate);
176 IOP_MIN_RANGE);
177 clocksource_register(&iop_clocksource);
178} 185}
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
index ee9582f4972..d69d343ff61 100644
--- a/arch/arm/plat-mxc/epit.c
+++ b/arch/arm/plat-mxc/epit.c
@@ -93,7 +93,6 @@ static struct clocksource clocksource_epit = {
93 .rating = 200, 93 .rating = 200,
94 .read = epit_read, 94 .read = epit_read,
95 .mask = CLOCKSOURCE_MASK(32), 95 .mask = CLOCKSOURCE_MASK(32),
96 .shift = 20,
97 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 96 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
98}; 97};
99 98
@@ -101,9 +100,7 @@ static int __init epit_clocksource_init(struct clk *timer_clk)
101{ 100{
102 unsigned int c = clk_get_rate(timer_clk); 101 unsigned int c = clk_get_rate(timer_clk);
103 102
104 clocksource_epit.mult = clocksource_hz2mult(c, 103 clocksource_register_hz(&clocksource_epit, c);
105 clocksource_epit.shift);
106 clocksource_register(&clocksource_epit);
107 104
108 return 0; 105 return 0;
109} 106}
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index f9a1b059a76..9f0c2610595 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -120,7 +120,6 @@ static struct clocksource clocksource_mxc = {
120 .rating = 200, 120 .rating = 200,
121 .read = mx1_2_get_cycles, 121 .read = mx1_2_get_cycles,
122 .mask = CLOCKSOURCE_MASK(32), 122 .mask = CLOCKSOURCE_MASK(32),
123 .shift = 20,
124 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 123 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
125}; 124};
126 125
@@ -131,9 +130,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
131 if (timer_is_v2()) 130 if (timer_is_v2())
132 clocksource_mxc.read = v2_get_cycles; 131 clocksource_mxc.read = v2_get_cycles;
133 132
134 clocksource_mxc.mult = clocksource_hz2mult(c, 133 clocksource_register_hz(&clocksource_mxc, c);
135 clocksource_mxc.shift);
136 clocksource_register(&clocksource_mxc);
137 134
138 return 0; 135 return 0;
139} 136}
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index 5da3f97c537..187f4e84bb2 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -14,6 +14,7 @@ if PLAT_NOMADIK
14 14
15config HAS_MTU 15config HAS_MTU
16 bool 16 bool
17 select HAVE_SCHED_CLOCK
17 help 18 help
18 Support for Multi Timer Unit. MTU provides access 19 Support for Multi Timer Unit. MTU provides access
19 to multiple interrupt generating programmable 20 to multiple interrupt generating programmable
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 63cdc6025bd..41723402006 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -17,9 +17,9 @@
17#include <linux/clk.h> 17#include <linux/clk.h>
18#include <linux/jiffies.h> 18#include <linux/jiffies.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/cnt32_to_63.h> 20#include <linux/sched.h>
21#include <linux/timer.h>
22#include <asm/mach/time.h> 21#include <asm/mach/time.h>
22#include <asm/sched_clock.h>
23 23
24#include <plat/mtu.h> 24#include <plat/mtu.h>
25 25
@@ -52,81 +52,24 @@ static struct clocksource nmdk_clksrc = {
52 * Override the global weak sched_clock symbol with this 52 * Override the global weak sched_clock symbol with this
53 * local implementation which uses the clocksource to get some 53 * local implementation which uses the clocksource to get some
54 * better resolution when scheduling the kernel. 54 * better resolution when scheduling the kernel.
55 *
56 * Because the hardware timer period may be quite short
57 * (32.3 secs on the 133 MHz MTU timer selection on ux500)
58 * and because cnt32_to_63() needs to be called at least once per
59 * half period to work properly, a kernel keepwarm() timer is set up
60 * to ensure this requirement is always met.
61 *
62 * Also the sched_clock timer will wrap around at some point,
63 * here we set it to run continously for a year.
64 */ 55 */
65#define SCHED_CLOCK_MIN_WRAP 3600*24*365 56static DEFINE_CLOCK_DATA(cd);
66static struct timer_list cnt32_to_63_keepwarm_timer;
67static u32 sched_mult;
68static u32 sched_shift;
69 57
70unsigned long long notrace sched_clock(void) 58unsigned long long notrace sched_clock(void)
71{ 59{
72 u64 cycles; 60 u32 cyc;
73 61
74 if (unlikely(!mtu_base)) 62 if (unlikely(!mtu_base))
75 return 0; 63 return 0;
76 64
77 cycles = cnt32_to_63(-readl(mtu_base + MTU_VAL(0))); 65 cyc = -readl(mtu_base + MTU_VAL(0));
78 /* 66 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
79 * sched_mult is guaranteed to be even so will
80 * shift out bit 63
81 */
82 return (cycles * sched_mult) >> sched_shift;
83} 67}
84 68
85/* Just kick sched_clock every so often */ 69static void notrace nomadik_update_sched_clock(void)
86static void cnt32_to_63_keepwarm(unsigned long data)
87{ 70{
88 mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data)); 71 u32 cyc = -readl(mtu_base + MTU_VAL(0));
89 (void) sched_clock(); 72 update_sched_clock(&cd, cyc, (u32)~0);
90}
91
92/*
93 * Set up a timer to keep sched_clock():s 32_to_63 algorithm warm
94 * once in half a 32bit timer wrap interval.
95 */
96static void __init nmdk_sched_clock_init(unsigned long rate)
97{
98 u32 v;
99 unsigned long delta;
100 u64 days;
101
102 /* Find the apropriate mult and shift factors */
103 clocks_calc_mult_shift(&sched_mult, &sched_shift,
104 rate, NSEC_PER_SEC, SCHED_CLOCK_MIN_WRAP);
105 /* We need to multiply by an even number to get rid of bit 63 */
106 if (sched_mult & 1)
107 sched_mult++;
108
109 /* Let's see what we get, take max counter and scale it */
110 days = (0xFFFFFFFFFFFFFFFFLLU * sched_mult) >> sched_shift;
111 do_div(days, NSEC_PER_SEC);
112 do_div(days, (3600*24));
113
114 pr_info("sched_clock: using %d bits @ %lu Hz wrap in %lu days\n",
115 (64 - sched_shift), rate, (unsigned long) days);
116
117 /*
118 * Program a timer to kick us at half 32bit wraparound
119 * Formula: seconds per wrap = (2^32) / f
120 */
121 v = 0xFFFFFFFFUL / rate;
122 /* We want half of the wrap time to keep cnt32_to_63 warm */
123 v /= 2;
124 pr_debug("sched_clock: prescaled timer rate: %lu Hz, "
125 "initialize keepwarm timer every %d seconds\n", rate, v);
126 /* Convert seconds to jiffies */
127 delta = msecs_to_jiffies(v*1000);
128 setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, delta);
129 mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + delta));
130} 73}
131 74
132/* Clockevent device: use one-shot mode */ 75/* Clockevent device: use one-shot mode */
@@ -222,7 +165,6 @@ void __init nmdk_timer_init(void)
222 } else { 165 } else {
223 cr |= MTU_CRn_PRESCALE_1; 166 cr |= MTU_CRn_PRESCALE_1;
224 } 167 }
225 clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
226 168
227 /* Timer 0 is the free running clocksource */ 169 /* Timer 0 is the free running clocksource */
228 writel(cr, mtu_base + MTU_CR(0)); 170 writel(cr, mtu_base + MTU_CR(0));
@@ -233,11 +175,11 @@ void __init nmdk_timer_init(void)
233 /* Now the clock source is ready */ 175 /* Now the clock source is ready */
234 nmdk_clksrc.read = nmdk_read_timer; 176 nmdk_clksrc.read = nmdk_read_timer;
235 177
236 if (clocksource_register(&nmdk_clksrc)) 178 if (clocksource_register_hz(&nmdk_clksrc, rate))
237 pr_err("timer: failed to initialize clock source %s\n", 179 pr_err("timer: failed to initialize clock source %s\n",
238 nmdk_clksrc.name); 180 nmdk_clksrc.name);
239 181
240 nmdk_sched_clock_init(rate); 182 init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
241 183
242 /* Timer 1 is used for events */ 184 /* Timer 1 is used for events */
243 185
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 92c5bb7909f..c9408434a85 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -11,13 +11,13 @@ choice
11 11
12config ARCH_OMAP1 12config ARCH_OMAP1
13 bool "TI OMAP1" 13 bool "TI OMAP1"
14 select COMMON_CLKDEV 14 select CLKDEV_LOOKUP
15 help 15 help
16 "Systems based on omap7xx, omap15xx or omap16xx" 16 "Systems based on omap7xx, omap15xx or omap16xx"
17 17
18config ARCH_OMAP2PLUS 18config ARCH_OMAP2PLUS
19 bool "TI OMAP2/3/4" 19 bool "TI OMAP2/3/4"
20 select COMMON_CLKDEV 20 select CLKDEV_LOOKUP
21 help 21 help
22 "Systems based on OMAP2, OMAP3 or OMAP4" 22 "Systems based on OMAP2, OMAP3 or OMAP4"
23 23
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 8722a136f3a..ea4644021fb 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -15,8 +15,11 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/clk.h> 17#include <linux/clk.h>
18#include <linux/io.h>
19#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/io.h>
20#include <linux/sched.h>
21
22#include <asm/sched_clock.h>
20 23
21#include <plat/common.h> 24#include <plat/common.h>
22#include <plat/board.h> 25#include <plat/board.h>
@@ -45,7 +48,7 @@
45static u32 offset_32k __read_mostly; 48static u32 offset_32k __read_mostly;
46 49
47#ifdef CONFIG_ARCH_OMAP16XX 50#ifdef CONFIG_ARCH_OMAP16XX
48static cycle_t omap16xx_32k_read(struct clocksource *cs) 51static cycle_t notrace omap16xx_32k_read(struct clocksource *cs)
49{ 52{
50 return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k; 53 return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
51} 54}
@@ -54,7 +57,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
54#endif 57#endif
55 58
56#ifdef CONFIG_ARCH_OMAP2420 59#ifdef CONFIG_ARCH_OMAP2420
57static cycle_t omap2420_32k_read(struct clocksource *cs) 60static cycle_t notrace omap2420_32k_read(struct clocksource *cs)
58{ 61{
59 return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k; 62 return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
60} 63}
@@ -63,7 +66,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
63#endif 66#endif
64 67
65#ifdef CONFIG_ARCH_OMAP2430 68#ifdef CONFIG_ARCH_OMAP2430
66static cycle_t omap2430_32k_read(struct clocksource *cs) 69static cycle_t notrace omap2430_32k_read(struct clocksource *cs)
67{ 70{
68 return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k; 71 return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
69} 72}
@@ -72,7 +75,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
72#endif 75#endif
73 76
74#ifdef CONFIG_ARCH_OMAP3 77#ifdef CONFIG_ARCH_OMAP3
75static cycle_t omap34xx_32k_read(struct clocksource *cs) 78static cycle_t notrace omap34xx_32k_read(struct clocksource *cs)
76{ 79{
77 return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k; 80 return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
78} 81}
@@ -81,7 +84,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
81#endif 84#endif
82 85
83#ifdef CONFIG_ARCH_OMAP4 86#ifdef CONFIG_ARCH_OMAP4
84static cycle_t omap44xx_32k_read(struct clocksource *cs) 87static cycle_t notrace omap44xx_32k_read(struct clocksource *cs)
85{ 88{
86 return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k; 89 return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
87} 90}
@@ -93,7 +96,7 @@ static cycle_t omap44xx_32k_read(struct clocksource *cs)
93 * Kernel assumes that sched_clock can be called early but may not have 96 * Kernel assumes that sched_clock can be called early but may not have
94 * things ready yet. 97 * things ready yet.
95 */ 98 */
96static cycle_t omap_32k_read_dummy(struct clocksource *cs) 99static cycle_t notrace omap_32k_read_dummy(struct clocksource *cs)
97{ 100{
98 return 0; 101 return 0;
99} 102}
@@ -103,7 +106,6 @@ static struct clocksource clocksource_32k = {
103 .rating = 250, 106 .rating = 250,
104 .read = omap_32k_read_dummy, 107 .read = omap_32k_read_dummy,
105 .mask = CLOCKSOURCE_MASK(32), 108 .mask = CLOCKSOURCE_MASK(32),
106 .shift = 10,
107 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 109 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
108}; 110};
109 111
@@ -111,10 +113,25 @@ static struct clocksource clocksource_32k = {
111 * Returns current time from boot in nsecs. It's OK for this to wrap 113 * Returns current time from boot in nsecs. It's OK for this to wrap
112 * around for now, as it's just a relative time stamp. 114 * around for now, as it's just a relative time stamp.
113 */ 115 */
114unsigned long long sched_clock(void) 116static DEFINE_CLOCK_DATA(cd);
117
118/*
119 * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60).
120 * This gives a resolution of about 30us and a wrap period of about 36hrs.
121 */
122#define SC_MULT 4000000000u
123#define SC_SHIFT 17
124
125unsigned long long notrace sched_clock(void)
126{
127 u32 cyc = clocksource_32k.read(&clocksource_32k);
128 return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
129}
130
131static void notrace omap_update_sched_clock(void)
115{ 132{
116 return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k), 133 u32 cyc = clocksource_32k.read(&clocksource_32k);
117 clocksource_32k.mult, clocksource_32k.shift); 134 update_sched_clock(&cd, cyc, (u32)~0);
118} 135}
119 136
120/** 137/**
@@ -168,13 +185,13 @@ static int __init omap_init_clocksource_32k(void)
168 if (!IS_ERR(sync_32k_ick)) 185 if (!IS_ERR(sync_32k_ick))
169 clk_enable(sync_32k_ick); 186 clk_enable(sync_32k_ick);
170 187
171 clocksource_32k.mult = clocksource_hz2mult(32768,
172 clocksource_32k.shift);
173
174 offset_32k = clocksource_32k.read(&clocksource_32k); 188 offset_32k = clocksource_32k.read(&clocksource_32k);
175 189
176 if (clocksource_register(&clocksource_32k)) 190 if (clocksource_register_hz(&clocksource_32k, 32768))
177 printk(err, clocksource_32k.name); 191 printk(err, clocksource_32k.name);
192
193 init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
194 32768, SC_MULT, SC_SHIFT);
178 } 195 }
179 return 0; 196 return 0;
180} 197}
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index bb937f3fabe..4b2028ab4d2 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -8,7 +8,7 @@
8#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H 8#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
9#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H 9#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
10 10
11#include <asm/clkdev.h> 11#include <linux/clkdev.h>
12 12
13struct omap_clk { 13struct omap_clk {
14 u16 cpu; 14 u16 cpu;
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
index 128b549c279..204865f91d9 100644
--- a/arch/arm/plat-omap/include/plat/io.h
+++ b/arch/arm/plat-omap/include/plat/io.h
@@ -294,8 +294,8 @@ static inline void omap44xx_map_common_io(void)
294extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, 294extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
295 struct omap_sdrc_params *sdrc_cs1); 295 struct omap_sdrc_params *sdrc_cs1);
296 296
297#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t) 297#define __arch_ioremap omap_ioremap
298#define __arch_iounmap(v) omap_iounmap(v) 298#define __arch_iounmap omap_iounmap
299 299
300void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type); 300void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
301void omap_iounmap(volatile void __iomem *addr); 301void omap_iounmap(volatile void __iomem *addr);
diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h
index d5306bee44b..f8d922fb558 100644
--- a/arch/arm/plat-omap/include/plat/memory.h
+++ b/arch/arm/plat-omap/include/plat/memory.h
@@ -61,17 +61,17 @@
61#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET) 61#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
62#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0)) 62#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
63 63
64#define __arch_page_to_dma(dev, page) \ 64#define __arch_pfn_to_dma(dev, pfn) \
65 ({ dma_addr_t __dma = page_to_phys(page); \ 65 ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
66 if (is_lbus_device(dev)) \ 66 if (is_lbus_device(dev)) \
67 __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ 67 __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
68 __dma; }) 68 __dma; })
69 69
70#define __arch_dma_to_page(dev, addr) \ 70#define __arch_dma_to_pfn(dev, addr) \
71 ({ dma_addr_t __dma = addr; \ 71 ({ dma_addr_t __dma = addr; \
72 if (is_lbus_device(dev)) \ 72 if (is_lbus_device(dev)) \
73 __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \ 73 __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \
74 phys_to_page(__dma); \ 74 __phys_to_pfn(__dma); \
75 }) 75 })
76 76
77#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \ 77#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index ecd6a488c49..7a10257909e 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -18,7 +18,6 @@
18#define OMAP_ARCH_SMP_H 18#define OMAP_ARCH_SMP_H
19 19
20#include <asm/hardware/gic.h> 20#include <asm/hardware/gic.h>
21#include <asm/smp_mpidr.h>
22 21
23/* Needed for secondary core boot */ 22/* Needed for secondary core boot */
24extern void omap_secondary_startup(void); 23extern void omap_secondary_startup(void);
@@ -29,9 +28,9 @@ extern u32 omap_read_auxcoreboot0(void);
29/* 28/*
30 * We use Soft IRQ1 as the IPI 29 * We use Soft IRQ1 as the IPI
31 */ 30 */
32static inline void smp_cross_call(const struct cpumask *mask) 31static inline void smp_cross_call(const struct cpumask *mask, int ipi)
33{ 32{
34 gic_raise_softirq(mask, 1); 33 gic_raise_softirq(mask, ipi);
35} 34}
36 35
37#endif 36#endif
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
index 715a30177f2..c3da2478b2a 100644
--- a/arch/arm/plat-orion/time.c
+++ b/arch/arm/plat-orion/time.c
@@ -13,11 +13,11 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/cnt32_to_63.h>
17#include <linux/timer.h> 16#include <linux/timer.h>
18#include <linux/clockchips.h> 17#include <linux/clockchips.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/irq.h> 19#include <linux/irq.h>
20#include <asm/sched_clock.h>
21#include <asm/mach/time.h> 21#include <asm/mach/time.h>
22#include <mach/bridge-regs.h> 22#include <mach/bridge-regs.h>
23#include <mach/hardware.h> 23#include <mach/hardware.h>
@@ -44,52 +44,26 @@ static u32 ticks_per_jiffy;
44 44
45/* 45/*
46 * Orion's sched_clock implementation. It has a resolution of 46 * Orion's sched_clock implementation. It has a resolution of
47 * at least 7.5ns (133MHz TCLK) and a maximum value of 834 days. 47 * at least 7.5ns (133MHz TCLK).
48 *
49 * Because the hardware timer period is quite short (21 secs if
50 * 200MHz TCLK) and because cnt32_to_63() needs to be called at
51 * least once per half period to work properly, a kernel timer is
52 * set up to ensure this requirement is always met.
53 */ 48 */
54#define TCLK2NS_SCALE_FACTOR 8 49static DEFINE_CLOCK_DATA(cd);
55
56static unsigned long tclk2ns_scale;
57 50
58unsigned long long sched_clock(void) 51unsigned long long notrace sched_clock(void)
59{ 52{
60 unsigned long long v = cnt32_to_63(0xffffffff - readl(TIMER0_VAL)); 53 u32 cyc = 0xffffffff - readl(TIMER0_VAL);
61 return (v * tclk2ns_scale) >> TCLK2NS_SCALE_FACTOR; 54 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
62} 55}
63 56
64static struct timer_list cnt32_to_63_keepwarm_timer;
65 57
66static void cnt32_to_63_keepwarm(unsigned long data) 58static void notrace orion_update_sched_clock(void)
67{ 59{
68 mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data)); 60 u32 cyc = 0xffffffff - readl(TIMER0_VAL);
69 (void) sched_clock(); 61 update_sched_clock(&cd, cyc, (u32)~0);
70} 62}
71 63
72static void __init setup_sched_clock(unsigned long tclk) 64static void __init setup_sched_clock(unsigned long tclk)
73{ 65{
74 unsigned long long v; 66 init_sched_clock(&cd, orion_update_sched_clock, 32, tclk);
75 unsigned long data;
76
77 v = NSEC_PER_SEC;
78 v <<= TCLK2NS_SCALE_FACTOR;
79 v += tclk/2;
80 do_div(v, tclk);
81 /*
82 * We want an even value to automatically clear the top bit
83 * returned by cnt32_to_63() without an additional run time
84 * instruction. So if the LSB is 1 then round it up.
85 */
86 if (v & 1)
87 v++;
88 tclk2ns_scale = v;
89
90 data = (0xffffffffUL / tclk / 2 - 2) * HZ;
91 setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);
92 mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));
93} 67}
94 68
95/* 69/*
@@ -102,7 +76,6 @@ static cycle_t orion_clksrc_read(struct clocksource *cs)
102 76
103static struct clocksource orion_clksrc = { 77static struct clocksource orion_clksrc = {
104 .name = "orion_clocksource", 78 .name = "orion_clocksource",
105 .shift = 20,
106 .rating = 300, 79 .rating = 300,
107 .read = orion_clksrc_read, 80 .read = orion_clksrc_read,
108 .mask = CLOCKSOURCE_MASK(32), 81 .mask = CLOCKSOURCE_MASK(32),
@@ -245,8 +218,7 @@ void __init orion_time_init(unsigned int irq, unsigned int tclk)
245 writel(u & ~BRIDGE_INT_TIMER0, BRIDGE_MASK); 218 writel(u & ~BRIDGE_INT_TIMER0, BRIDGE_MASK);
246 u = readl(TIMER_CTRL); 219 u = readl(TIMER_CTRL);
247 writel(u | TIMER0_EN | TIMER0_RELOAD_EN, TIMER_CTRL); 220 writel(u | TIMER0_EN | TIMER0_RELOAD_EN, TIMER_CTRL);
248 orion_clksrc.mult = clocksource_hz2mult(tclk, orion_clksrc.shift); 221 clocksource_register_hz(&orion_clksrc, tclk);
249 clocksource_register(&orion_clksrc);
250 222
251 /* 223 /*
252 * Setup clockevent timer (interrupt-driven.) 224 * Setup clockevent timer (interrupt-driven.)
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 5a27b1b538f..eb105e61c74 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -8,7 +8,7 @@ config PLAT_S3C24XX
8 default y 8 default y
9 select NO_IOPORT 9 select NO_IOPORT
10 select ARCH_REQUIRE_GPIOLIB 10 select ARCH_REQUIRE_GPIOLIB
11 select S3C_DEVICE_NAND 11 select S3C_DEV_NAND
12 select S3C_GPIO_CFG_S3C24XX 12 select S3C_GPIO_CFG_S3C24XX
13 help 13 help
14 Base platform code for any Samsung S3C24XX device 14 Base platform code for any Samsung S3C24XX device
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
index 298bafc0a52..2572260f990 100644
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -15,7 +15,7 @@
15#define __PLAT_CLOCK_H 15#define __PLAT_CLOCK_H
16 16
17#include <linux/list.h> 17#include <linux/list.h>
18#include <asm/clkdev.h> 18#include <linux/clkdev.h>
19#include <linux/types.h> 19#include <linux/types.h>
20 20
21/* clk structure flags */ 21/* clk structure flags */
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index ab211652e4c..839c88df999 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -81,8 +81,6 @@ static struct clocksource clksrc = {
81 .rating = 200, /* its a pretty decent clock */ 81 .rating = 200, /* its a pretty decent clock */
82 .read = clocksource_read_cycles, 82 .read = clocksource_read_cycles,
83 .mask = 0xFFFF, /* 16 bits */ 83 .mask = 0xFFFF, /* 16 bits */
84 .mult = 0, /* to be computed */
85 .shift = 0, /* to be computed */
86 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 84 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
87}; 85};
88 86
@@ -105,10 +103,8 @@ static void spear_clocksource_init(void)
105 val |= CTRL_ENABLE ; 103 val |= CTRL_ENABLE ;
106 writew(val, gpt_base + CR(CLKSRC)); 104 writew(val, gpt_base + CR(CLKSRC));
107 105
108 clocksource_calc_mult_shift(&clksrc, tick_rate, SPEAR_MIN_RANGE);
109
110 /* register the clocksource */ 106 /* register the clocksource */
111 clocksource_register(&clksrc); 107 clocksource_register_hz(&clksrc, tick_rate);
112} 108}
113 109
114static struct clock_event_device clkevt = { 110static struct clock_event_device clkevt = {
diff --git a/arch/arm/plat-stmp3xxx/clock.c b/arch/arm/plat-stmp3xxx/clock.c
index e593a2a801c..2e712e17ce7 100644
--- a/arch/arm/plat-stmp3xxx/clock.c
+++ b/arch/arm/plat-stmp3xxx/clock.c
@@ -25,9 +25,9 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/clkdev.h>
28 29
29#include <asm/mach-types.h> 30#include <asm/mach-types.h>
30#include <asm/clkdev.h>
31#include <mach/platform.h> 31#include <mach/platform.h>
32#include <mach/regs-clkctrl.h> 32#include <mach/regs-clkctrl.h>
33 33
diff --git a/arch/arm/plat-stmp3xxx/timer.c b/arch/arm/plat-stmp3xxx/timer.c
index 063c7bc0e74..c395630a6ed 100644
--- a/arch/arm/plat-stmp3xxx/timer.c
+++ b/arch/arm/plat-stmp3xxx/timer.c
@@ -89,7 +89,6 @@ static struct clocksource cksrc_stmp3xxx = {
89 .rating = 250, 89 .rating = 250,
90 .read = stmp3xxx_clock_read, 90 .read = stmp3xxx_clock_read,
91 .mask = CLOCKSOURCE_MASK(16), 91 .mask = CLOCKSOURCE_MASK(16),
92 .shift = 10,
93 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 92 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
94}; 93};
95 94
@@ -106,8 +105,6 @@ static struct irqaction stmp3xxx_timer_irq = {
106 */ 105 */
107static void __init stmp3xxx_init_timer(void) 106static void __init stmp3xxx_init_timer(void)
108{ 107{
109 cksrc_stmp3xxx.mult = clocksource_hz2mult(CLOCK_TICK_RATE,
110 cksrc_stmp3xxx.shift);
111 ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 108 ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
112 ckevt_timrot.shift); 109 ckevt_timrot.shift);
113 ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot); 110 ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
@@ -140,7 +137,7 @@ static void __init stmp3xxx_init_timer(void)
140 137
141 setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq); 138 setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq);
142 139
143 clocksource_register(&cksrc_stmp3xxx); 140 clocksource_register_hz(&cksrc_stmp3xxx, CLOCK_TICK_RATE);
144 clockevents_register_device(&ckevt_timrot); 141 clockevents_register_device(&ckevt_timrot);
145} 142}
146 143
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 5cf88e8427b..16dde081993 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -1,7 +1,7 @@
1obj-y := clock.o 1obj-y := clock.o
2obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o 2ifneq ($(CONFIG_ARCH_INTEGRATOR),y)
3obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o 3obj-y += sched-clock.o
4obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o 4endif
5ifeq ($(CONFIG_LEDS_CLASS),y) 5ifeq ($(CONFIG_LEDS_CLASS),y)
6obj-$(CONFIG_ARCH_REALVIEW) += leds.o 6obj-$(CONFIG_ARCH_REALVIEW) += leds.o
7obj-$(CONFIG_ARCH_VERSATILE) += leds.o 7obj-$(CONFIG_ARCH_VERSATILE) += leds.o
diff --git a/arch/arm/plat-versatile/include/plat/sched_clock.h b/arch/arm/plat-versatile/include/plat/sched_clock.h
new file mode 100644
index 00000000000..5c3e4fc9fa0
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/sched_clock.h
@@ -0,0 +1,6 @@
1#ifndef ARM_PLAT_SCHED_CLOCK_H
2#define ARM_PLAT_SCHED_CLOCK_H
3
4void versatile_sched_clock_init(void __iomem *, unsigned long);
5
6#endif
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
index 9696ddc238c..3d6a4c292ca 100644
--- a/arch/arm/plat-versatile/sched-clock.c
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -18,37 +18,41 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21#include <linux/cnt32_to_63.h>
22#include <linux/io.h> 21#include <linux/io.h>
23#include <linux/sched.h> 22#include <linux/sched.h>
24#include <asm/div64.h>
25 23
26#include <mach/hardware.h> 24#include <asm/sched_clock.h>
27#include <mach/platform.h> 25#include <plat/sched_clock.h>
28 26
29#ifdef VERSATILE_SYS_BASE 27static DEFINE_CLOCK_DATA(cd);
30#define REFCOUNTER (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) 28static void __iomem *ctr;
31#endif
32
33#ifdef REALVIEW_SYS_BASE
34#define REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
35#endif
36 29
37/* 30/*
38 * This is the Realview and Versatile sched_clock implementation. This 31 * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60).
39 * has a resolution of 41.7ns, and a maximum value of about 35583 days. 32 * This gives a resolution of about 41ns and a wrap period of about 178s.
40 *
41 * The return value is guaranteed to be monotonic in that range as
42 * long as there is always less than 89 seconds between successive
43 * calls to this function.
44 */ 33 */
45unsigned long long sched_clock(void) 34#define SC_MULT 2796202667u
35#define SC_SHIFT 26
36
37unsigned long long notrace sched_clock(void)
46{ 38{
47 unsigned long long v = cnt32_to_63(readl(REFCOUNTER)); 39 if (ctr) {
40 u32 cyc = readl(ctr);
41 return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0,
42 SC_MULT, SC_SHIFT);
43 } else
44 return 0;
45}
48 46
49 /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ 47static void notrace versatile_update_sched_clock(void)
50 v *= 125<<1; 48{
51 do_div(v, 3<<1); 49 u32 cyc = readl(ctr);
50 update_sched_clock(&cd, cyc, (u32)~0);
51}
52 52
53 return v; 53void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
54{
55 ctr = reg;
56 init_fixed_sched_clock(&cd, versatile_update_sched_clock,
57 32, rate, SC_MULT, SC_SHIFT);
54} 58}
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 8063a322c79..0797cb528b4 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -10,9 +10,12 @@
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/cpu.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/notifier.h>
14#include <linux/signal.h> 16#include <linux/signal.h>
15#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/smp.h>
16#include <linux/init.h> 19#include <linux/init.h>
17 20
18#include <asm/cputype.h> 21#include <asm/cputype.h>
@@ -484,7 +487,24 @@ void vfp_flush_hwstate(struct thread_info *thread)
484 put_cpu(); 487 put_cpu();
485} 488}
486 489
487#include <linux/smp.h> 490/*
491 * VFP hardware can lose all context when a CPU goes offline.
492 * Safely clear our held state when a CPU has been killed, and
493 * re-enable access to VFP when the CPU comes back online.
494 *
495 * Both CPU_DYING and CPU_STARTING are called on the CPU which
496 * is being offlined/onlined.
497 */
498static int vfp_hotplug(struct notifier_block *b, unsigned long action,
499 void *hcpu)
500{
501 if (action == CPU_DYING || action == CPU_DYING_FROZEN) {
502 unsigned int cpu = (long)hcpu;
503 last_VFP_context[cpu] = NULL;
504 } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
505 vfp_enable(NULL);
506 return NOTIFY_OK;
507}
488 508
489/* 509/*
490 * VFP support code initialisation. 510 * VFP support code initialisation.
@@ -514,6 +534,8 @@ static int __init vfp_init(void)
514 else if (vfpsid & FPSID_NODOUBLE) { 534 else if (vfpsid & FPSID_NODOUBLE) {
515 printk("no double precision support\n"); 535 printk("no double precision support\n");
516 } else { 536 } else {
537 hotcpu_notifier(vfp_hotplug, 0);
538
517 smp_call_function(vfp_enable, NULL, 1); 539 smp_call_function(vfp_enable, NULL, 1);
518 540
519 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ 541 VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 67a2fa2caa4..0a9b5b8b2a1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -19,6 +19,8 @@ config MIPS
19 select GENERIC_ATOMIC64 if !64BIT 19 select GENERIC_ATOMIC64 if !64BIT
20 select HAVE_DMA_ATTRS 20 select HAVE_DMA_ATTRS
21 select HAVE_DMA_API_DEBUG 21 select HAVE_DMA_API_DEBUG
22 select HAVE_GENERIC_HARDIRQS
23 select GENERIC_IRQ_PROBE
22 24
23menu "Machine selection" 25menu "Machine selection"
24 26
@@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB
1664 1666
1665endchoice 1667endchoice
1666 1668
1669config FORCE_MAX_ZONEORDER
1670 int "Maximum zone order"
1671 range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
1672 default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
1673 range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
1674 default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
1675 range 11 64
1676 default "11"
1677 help
1678 The kernel memory allocator divides physically contiguous memory
1679 blocks into "zones", where each zone is a power of two number of
1680 pages. This option selects the largest power of two that the kernel
1681 keeps in the memory allocator. If you need to allocate very large
1682 blocks of physically contiguous memory, then you may need to
1683 increase this value.
1684
1685 This config option is actually maximum order plus one. For example,
1686 a value of 11 means that the largest free memory block is 2^10 pages.
1687
1688 The page size is not necessarily 4KB. Keep this in mind
1689 when choosing a value for this option.
1690
1667config BOARD_SCACHE 1691config BOARD_SCACHE
1668 bool 1692 bool
1669 1693
@@ -1922,20 +1946,6 @@ config CPU_R4400_WORKAROUNDS
1922 bool 1946 bool
1923 1947
1924# 1948#
1925# Use the generic interrupt handling code in kernel/irq/:
1926#
1927config GENERIC_HARDIRQS
1928 bool
1929 default y
1930
1931config GENERIC_IRQ_PROBE
1932 bool
1933 default y
1934
1935config IRQ_PER_CPU
1936 bool
1937
1938#
1939# - Highmem only makes sense for the 32-bit kernel. 1949# - Highmem only makes sense for the 32-bit kernel.
1940# - The current highmem code will only work properly on physically indexed 1950# - The current highmem code will only work properly on physically indexed
1941# caches such as R3000, SB1, R7000 or those that look like they're virtually 1951# caches such as R3000, SB1, R7000 or those that look like they're virtually
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 3691630931d..9e7814db3d0 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -27,6 +27,7 @@
27static void alchemy_8250_pm(struct uart_port *port, unsigned int state, 27static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
28 unsigned int old_state) 28 unsigned int old_state)
29{ 29{
30#ifdef CONFIG_SERIAL_8250
30 switch (state) { 31 switch (state) {
31 case 0: 32 case 0:
32 if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { 33 if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
@@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
49 serial8250_do_pm(port, state, old_state); 50 serial8250_do_pm(port, state, old_state);
50 break; 51 break;
51 } 52 }
53#endif
52} 54}
53 55
54#define PORT(_base, _irq) \ 56#define PORT(_base, _irq) \
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
index b30df5c97ad..baeb2138505 100644
--- a/arch/mips/alchemy/devboards/prom.c
+++ b/arch/mips/alchemy/devboards/prom.c
@@ -54,10 +54,9 @@ void __init prom_init(void)
54 54
55 prom_init_cmdline(); 55 prom_init_cmdline();
56 memsize_str = prom_getenv("memsize"); 56 memsize_str = prom_getenv("memsize");
57 if (!memsize_str) 57 if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
58 memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; 58 memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
59 else 59
60 strict_strtoul(memsize_str, 0, &memsize);
61 add_memory_region(0, memsize, BOOT_MEM_RAM); 60 add_memory_region(0, memsize, BOOT_MEM_RAM);
62} 61}
63 62
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c
index fc0e7154e8d..2ca4ada1c29 100644
--- a/arch/mips/ar7/clock.c
+++ b/arch/mips/ar7/clock.c
@@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
239 calculate(base_clock, frequency, &prediv, &postdiv, &mul); 239 calculate(base_clock, frequency, &prediv, &postdiv, &mul);
240 240
241 writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); 241 writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl);
242 msleep(1); 242 mdelay(1);
243 writel(4, &clock->pll); 243 writel(4, &clock->pll);
244 while (readl(&clock->pll) & PLL_STATUS) 244 while (readl(&clock->pll) & PLL_STATUS)
245 ; 245 ;
246 writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); 246 writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll);
247 msleep(75); 247 mdelay(75);
248} 248}
249 249
250static void __init tnetd7300_init_clocks(void) 250static void __init tnetd7300_init_clocks(void)
@@ -456,7 +456,7 @@ void clk_put(struct clk *clk)
456} 456}
457EXPORT_SYMBOL(clk_put); 457EXPORT_SYMBOL(clk_put);
458 458
459int __init ar7_init_clocks(void) 459void __init ar7_init_clocks(void)
460{ 460{
461 switch (ar7_chip_id()) { 461 switch (ar7_chip_id()) {
462 case AR7_CHIP_7100: 462 case AR7_CHIP_7100:
@@ -472,7 +472,4 @@ int __init ar7_init_clocks(void)
472 } 472 }
473 /* adjust vbus clock rate */ 473 /* adjust vbus clock rate */
474 vbus_clk.rate = bus_clk.rate / 2; 474 vbus_clk.rate = bus_clk.rate / 2;
475
476 return 0;
477} 475}
478arch_initcall(ar7_init_clocks);
diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c
index 5fb8a013408..22c93213b23 100644
--- a/arch/mips/ar7/time.c
+++ b/arch/mips/ar7/time.c
@@ -30,6 +30,9 @@ void __init plat_time_init(void)
30{ 30{
31 struct clk *cpu_clk; 31 struct clk *cpu_clk;
32 32
33 /* Initialize ar7 clocks so the CPU clock frequency is correct */
34 ar7_init_clocks();
35
33 cpu_clk = clk_get(NULL, "cpu"); 36 cpu_clk = clk_get(NULL, "cpu");
34 if (IS_ERR(cpu_clk)) { 37 if (IS_ERR(cpu_clk)) {
35 printk(KERN_ERR "unable to get cpu clock\n"); 38 printk(KERN_ERR "unable to get cpu clock\n");
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index b1aee33efd1..c95f90bf734 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -32,7 +32,6 @@
32#include <asm/reboot.h> 32#include <asm/reboot.h>
33#include <asm/time.h> 33#include <asm/time.h>
34#include <bcm47xx.h> 34#include <bcm47xx.h>
35#include <asm/fw/cfe/cfe_api.h>
36#include <asm/mach-bcm47xx/nvram.h> 35#include <asm/mach-bcm47xx/nvram.h>
37 36
38struct ssb_bus ssb_bcm47xx; 37struct ssb_bus ssb_bcm47xx;
@@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void)
57 cpu_relax(); 56 cpu_relax();
58} 57}
59 58
60static void str2eaddr(char *str, char *dest) 59#define READ_FROM_NVRAM(_outvar, name, buf) \
61{ 60 if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
62 int i = 0; 61 sprom->_outvar = simple_strtoul(buf, NULL, 0);
63 62
64 if (str == NULL) { 63static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
65 memset(dest, 0, 6); 64{
66 return; 65 char buf[100];
66 u32 boardflags;
67
68 memset(sprom, 0, sizeof(struct ssb_sprom));
69
70 sprom->revision = 1; /* Fallback: Old hardware does not define this. */
71 READ_FROM_NVRAM(revision, "sromrev", buf);
72 if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
73 nvram_parse_macaddr(buf, sprom->il0mac);
74 if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
75 nvram_parse_macaddr(buf, sprom->et0mac);
76 if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
77 nvram_parse_macaddr(buf, sprom->et1mac);
78 READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
79 READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
80 READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
81 READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
82 READ_FROM_NVRAM(board_rev, "boardrev", buf);
83 READ_FROM_NVRAM(country_code, "ccode", buf);
84 READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
85 READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
86 READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
87 READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
88 READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
89 READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
90 READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
91 READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
92 READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
93 READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
94 READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
95 READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
96 READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
97 READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
98 READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
99 READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
100 READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
101 READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
102 READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
103 READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
104 READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
105 READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
106 READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
107 READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
108 READ_FROM_NVRAM(tri2g, "tri2g", buf);
109 READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
110 READ_FROM_NVRAM(tri5g, "tri5g", buf);
111 READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
112 READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
113 READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
114 READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
115 READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
116 READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
117 READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
118 READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
119 READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
120 READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
121 READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
122 READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
123 READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
124 READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
125 READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
126 READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
127
128 if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
129 boardflags = simple_strtoul(buf, NULL, 0);
130 if (boardflags) {
131 sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
132 sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
133 }
67 } 134 }
68 135 if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
69 for (;;) { 136 boardflags = simple_strtoul(buf, NULL, 0);
70 dest[i++] = (char) simple_strtoul(str, NULL, 16); 137 if (boardflags) {
71 str += 2; 138 sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
72 if (!*str++ || i == 6) 139 sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
73 break; 140 }
74 } 141 }
75} 142}
76 143
77static int bcm47xx_get_invariants(struct ssb_bus *bus, 144static int bcm47xx_get_invariants(struct ssb_bus *bus,
78 struct ssb_init_invariants *iv) 145 struct ssb_init_invariants *iv)
79{ 146{
80 char buf[100]; 147 char buf[20];
81 148
82 /* Fill boardinfo structure */ 149 /* Fill boardinfo structure */
83 memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); 150 memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
84 151
85 if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 || 152 if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
86 nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) 153 iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
87 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); 154 else
88 if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 || 155 iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
89 nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) 156 if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
90 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); 157 iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
91 if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 || 158 if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
92 nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
93 iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); 159 iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
94 160
95 /* Fill sprom structure */ 161 bcm47xx_fill_sprom(&iv->sprom);
96 memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
97 iv->sprom.revision = 3;
98
99 if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
100 nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
101 str2eaddr(buf, iv->sprom.et0mac);
102 162
103 if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 || 163 if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
104 nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) 164 iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
105 str2eaddr(buf, iv->sprom.et1mac);
106
107 if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
108 nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
109 iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
110
111 if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
112 nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
113 iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
114
115 if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
116 nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
117 iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
118
119 if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
120 nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
121 iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
122 165
123 return 0; 166 return 0;
124} 167}
@@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
126void __init plat_mem_setup(void) 169void __init plat_mem_setup(void)
127{ 170{
128 int err; 171 int err;
172 char buf[100];
173 struct ssb_mipscore *mcore;
129 174
130 err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, 175 err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
131 bcm47xx_get_invariants); 176 bcm47xx_get_invariants);
132 if (err) 177 if (err)
133 panic("Failed to initialize SSB bus (err %d)\n", err); 178 panic("Failed to initialize SSB bus (err %d)\n", err);
134 179
180 mcore = &ssb_bcm47xx.mipscore;
181 if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
182 if (strstr(buf, "console=ttyS1")) {
183 struct ssb_serial_port port;
184
185 printk(KERN_DEBUG "Swapping serial ports!\n");
186 /* swap serial ports */
187 memcpy(&port, &mcore->serial_ports[0], sizeof(port));
188 memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
189 sizeof(port));
190 memcpy(&mcore->serial_ports[1], &port, sizeof(port));
191 }
192 }
193
135 _machine_restart = bcm47xx_machine_restart; 194 _machine_restart = bcm47xx_machine_restart;
136 _machine_halt = bcm47xx_machine_halt; 195 _machine_halt = bcm47xx_machine_halt;
137 pm_power_off = bcm47xx_machine_halt; 196 pm_power_off = bcm47xx_machine_halt;
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 06d59dcbe24..86877539c6e 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -111,8 +111,8 @@
111 * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM 111 * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
112 */ 112 */
113 113
114#define PRID_IMP_BMIPS4KC 0x4000 114#define PRID_IMP_BMIPS32_REV4 0x4000
115#define PRID_IMP_BMIPS32 0x8000 115#define PRID_IMP_BMIPS32_REV8 0x8000
116#define PRID_IMP_BMIPS3300 0x9000 116#define PRID_IMP_BMIPS3300 0x9000
117#define PRID_IMP_BMIPS3300_ALT 0x9100 117#define PRID_IMP_BMIPS3300_ALT 0x9100
118#define PRID_IMP_BMIPS3300_BUG 0x0000 118#define PRID_IMP_BMIPS3300_BUG 0x0000
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index fd1d39eb743..455c0ac7d4e 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32;
249 249
250#define SET_PERSONALITY(ex) \ 250#define SET_PERSONALITY(ex) \
251do { \ 251do { \
252 set_personality(PER_LINUX); \ 252 if (personality(current->personality) != PER_LINUX) \
253 set_personality(PER_LINUX); \
253 \ 254 \
254 current->thread.abi = &mips_abi; \ 255 current->thread.abi = &mips_abi; \
255} while (0) 256} while (0)
@@ -296,6 +297,8 @@ do { \
296 297
297#define SET_PERSONALITY(ex) \ 298#define SET_PERSONALITY(ex) \
298do { \ 299do { \
300 unsigned int p; \
301 \
299 clear_thread_flag(TIF_32BIT_REGS); \ 302 clear_thread_flag(TIF_32BIT_REGS); \
300 clear_thread_flag(TIF_32BIT_ADDR); \ 303 clear_thread_flag(TIF_32BIT_ADDR); \
301 \ 304 \
@@ -304,7 +307,8 @@ do { \
304 else \ 307 else \
305 current->thread.abi = &mips_abi; \ 308 current->thread.abi = &mips_abi; \
306 \ 309 \
307 if (current->personality != PER_LINUX32) \ 310 p = personality(current->personality); \
311 if (p != PER_LINUX32 && p != PER_LINUX) \
308 set_personality(PER_LINUX); \ 312 set_personality(PER_LINUX); \
309} while (0) 313} while (0)
310 314
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index c98bf514ec7..5b017f23e24 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val, \
329 "dsrl32 %L0, %L0, 0" "\n\t" \ 329 "dsrl32 %L0, %L0, 0" "\n\t" \
330 "dsll32 %M0, %M0, 0" "\n\t" \ 330 "dsll32 %M0, %M0, 0" "\n\t" \
331 "or %L0, %L0, %M0" "\n\t" \ 331 "or %L0, %L0, %M0" "\n\t" \
332 ".set push" "\n\t" \
333 ".set noreorder" "\n\t" \
334 ".set nomacro" "\n\t" \
332 "sd %L0, %2" "\n\t" \ 335 "sd %L0, %2" "\n\t" \
336 ".set pop" "\n\t" \
333 ".set mips0" "\n" \ 337 ".set mips0" "\n" \
334 : "=r" (__tmp) \ 338 : "=r" (__tmp) \
335 : "0" (__val), "m" (*__mem)); \ 339 : "0" (__val), "R" (*__mem)); \
336 if (irq) \ 340 if (irq) \
337 local_irq_restore(__flags); \ 341 local_irq_restore(__flags); \
338 } else \ 342 } else \
@@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
355 local_irq_save(__flags); \ 359 local_irq_save(__flags); \
356 __asm__ __volatile__( \ 360 __asm__ __volatile__( \
357 ".set mips3" "\t\t# __readq" "\n\t" \ 361 ".set mips3" "\t\t# __readq" "\n\t" \
362 ".set push" "\n\t" \
363 ".set noreorder" "\n\t" \
364 ".set nomacro" "\n\t" \
358 "ld %L0, %1" "\n\t" \ 365 "ld %L0, %1" "\n\t" \
366 ".set pop" "\n\t" \
359 "dsra32 %M0, %L0, 0" "\n\t" \ 367 "dsra32 %M0, %L0, 0" "\n\t" \
360 "sll %L0, %L0, 0" "\n\t" \ 368 "sll %L0, %L0, 0" "\n\t" \
361 ".set mips0" "\n" \ 369 ".set mips0" "\n" \
362 : "=r" (__val) \ 370 : "=r" (__val) \
363 : "m" (*__mem)); \ 371 : "R" (*__mem)); \
364 if (irq) \ 372 if (irq) \
365 local_irq_restore(__flags); \ 373 local_irq_restore(__flags); \
366 } else { \ 374 } else { \
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
index 7919d76186b..07d3fadb244 100644
--- a/arch/mips/include/asm/mach-ar7/ar7.h
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit)
201} 201}
202 202
203int __init ar7_gpio_init(void); 203int __init ar7_gpio_init(void);
204 204void __init ar7_init_clocks(void);
205int __init ar7_gpio_init(void);
206 205
207#endif /* __AR7_H__ */ 206#endif /* __AR7_H__ */
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h
index c58ebd8bc15..9759588ba3c 100644
--- a/arch/mips/include/asm/mach-bcm47xx/nvram.h
+++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
@@ -12,6 +12,7 @@
12#define __NVRAM_H 12#define __NVRAM_H
13 13
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/kernel.h>
15 16
16struct nvram_header { 17struct nvram_header {
17 u32 magic; 18 u32 magic;
@@ -36,4 +37,10 @@ struct nvram_header {
36 37
37extern int nvram_getenv(char *name, char *val, size_t val_len); 38extern int nvram_getenv(char *name, char *val, size_t val_len);
38 39
40static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
41{
42 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
43 &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
44}
45
39#endif 46#endif
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 5742bb4d78f..5c0a3575877 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Copyright (c) 2009 Qi Hardware inc., 6 * Copyright (c) 2009 Qi Hardware inc.,
7 * Author: Xiangfu Liu <xiangfu@qi-hardware.com> 7 * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
8 * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de> 8 * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 or later 11 * it under the terms of the GNU General Public License version 2 or later
@@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = {
235 QI_LB60_GPIO_KEYIN(3), 235 QI_LB60_GPIO_KEYIN(3),
236 QI_LB60_GPIO_KEYIN(4), 236 QI_LB60_GPIO_KEYIN(4),
237 QI_LB60_GPIO_KEYIN(5), 237 QI_LB60_GPIO_KEYIN(5),
238 QI_LB60_GPIO_KEYIN(7), 238 QI_LB60_GPIO_KEYIN(6),
239 QI_LB60_GPIO_KEYIN8, 239 QI_LB60_GPIO_KEYIN8,
240}; 240};
241 241
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 95bc2b5b14f..1cc9e544d16 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = {
208 208
209/* PCM */ 209/* PCM */
210struct platform_device jz4740_pcm_device = { 210struct platform_device jz4740_pcm_device = {
211 .name = "jz4740-pcm", 211 .name = "jz4740-pcm-audio",
212 .id = -1, 212 .id = -1,
213}; 213};
214 214
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
index cfeac15eb2e..4a70407f55b 100644
--- a/arch/mips/jz4740/prom.c
+++ b/arch/mips/jz4740/prom.c
@@ -23,7 +23,7 @@
23#include <asm/bootinfo.h> 23#include <asm/bootinfo.h>
24#include <asm/mach-jz4740/base.h> 24#include <asm/mach-jz4740/base.h>
25 25
26void jz4740_init_cmdline(int argc, char *argv[]) 26static __init void jz4740_init_cmdline(int argc, char *argv[])
27{ 27{
28 unsigned int count = COMMAND_LINE_SIZE - 1; 28 unsigned int count = COMMAND_LINE_SIZE - 1;
29 int i; 29 int i;
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 2f4d7a99bcc..98c5a9737c1 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
32 cnt = read_c0_count(); 32 cnt = read_c0_count();
33 cnt += delta; 33 cnt += delta;
34 write_c0_compare(cnt); 34 write_c0_compare(cnt);
35 res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; 35 res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
36 return res; 36 return res;
37} 37}
38 38
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 71620e19827..68dae7b6b5d 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
905{ 905{
906 decode_configs(c); 906 decode_configs(c);
907 switch (c->processor_id & 0xff00) { 907 switch (c->processor_id & 0xff00) {
908 case PRID_IMP_BMIPS32: 908 case PRID_IMP_BMIPS32_REV4:
909 case PRID_IMP_BMIPS32_REV8:
909 c->cputype = CPU_BMIPS32; 910 c->cputype = CPU_BMIPS32;
910 __cpu_name[cpu] = "Broadcom BMIPS32"; 911 __cpu_name[cpu] = "Broadcom BMIPS32";
911 break; 912 break;
@@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
933 __cpu_name[cpu] = "Broadcom BMIPS5000"; 934 __cpu_name[cpu] = "Broadcom BMIPS5000";
934 c->options |= MIPS_CPU_ULRI; 935 c->options |= MIPS_CPU_ULRI;
935 break; 936 break;
936 case PRID_IMP_BMIPS4KC:
937 c->cputype = CPU_4KC;
938 __cpu_name[cpu] = "MIPS 4Kc";
939 break;
940 } 937 }
941} 938}
942 939
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 6343b4a5b83..876a75cc376 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
251 251
252SYSCALL_DEFINE1(32_personality, unsigned long, personality) 252SYSCALL_DEFINE1(32_personality, unsigned long, personality)
253{ 253{
254 unsigned int p = personality & 0xffffffff;
254 int ret; 255 int ret;
255 personality &= 0xffffffff; 256
256 if (personality(current->personality) == PER_LINUX32 && 257 if (personality(current->personality) == PER_LINUX32 &&
257 personality == PER_LINUX) 258 personality(p) == PER_LINUX)
258 personality = PER_LINUX32; 259 p = (p & ~PER_MASK) | PER_LINUX32;
259 ret = sys_personality(personality); 260 ret = sys_personality(p);
260 if (ret == PER_LINUX32) 261 if (ret != -1 && personality(ret) == PER_LINUX32)
261 ret = PER_LINUX; 262 ret = (ret & ~PER_MASK) | PER_LINUX;
262 return ret; 263 return ret;
263} 264}
264 265
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 99960940d4a..ae167df73dd 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
142 childregs->regs[7] = 0; /* Clear error flag */ 142 childregs->regs[7] = 0; /* Clear error flag */
143 143
144 childregs->regs[2] = 0; /* Child gets zero as return value */ 144 childregs->regs[2] = 0; /* Child gets zero as return value */
145 regs->regs[2] = p->pid;
146 145
147 if (childregs->cp0_status & ST0_CU0) { 146 if (childregs->cp0_status & ST0_CU0) {
148 childregs->regs[28] = (unsigned long) ti; 147 childregs->regs[28] = (unsigned long) ti;
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index e000b278f02..9dbe5836895 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -100,7 +100,7 @@ void __init device_tree_init(void)
100 return; 100 return;
101 101
102 base = virt_to_phys((void *)initial_boot_params); 102 base = virt_to_phys((void *)initial_boot_params);
103 size = initial_boot_params->totalsize; 103 size = be32_to_cpu(initial_boot_params->totalsize);
104 104
105 /* Before we do anything, lets reserve the dt blob */ 105 /* Before we do anything, lets reserve the dt blob */
106 reserve_mem_mach(base, size); 106 reserve_mem_mach(base, size);
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 43e7cdc5ded..c0e81418ba2 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void)
153{ 153{
154 extern int gic_present; 154 extern int gic_present;
155 155
156 /* This is Malta specific: IPI,performance and timer inetrrupts */ 156 /* This is Malta specific: IPI,performance and timer interrupts */
157 if (gic_present) 157 if (gic_present)
158 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | 158 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
159 STATUSF_IP6 | STATUSF_IP7); 159 STATUSF_IP6 | STATUSF_IP7);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 8e9fbe75894..e9710430254 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void);
83extern asmlinkage void handle_reserved(void); 83extern asmlinkage void handle_reserved(void);
84 84
85extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, 85extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
86 struct mips_fpu_struct *ctx, int has_fpu); 86 struct mips_fpu_struct *ctx, int has_fpu,
87 void *__user *fault_addr);
87 88
88void (*board_be_init)(void); 89void (*board_be_init)(void);
89int (*board_be_handler)(struct pt_regs *regs, int is_fixup); 90int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs)
661 force_sig_info(SIGFPE, &info, current); 662 force_sig_info(SIGFPE, &info, current);
662} 663}
663 664
665static int process_fpemu_return(int sig, void __user *fault_addr)
666{
667 if (sig == SIGSEGV || sig == SIGBUS) {
668 struct siginfo si = {0};
669 si.si_addr = fault_addr;
670 si.si_signo = sig;
671 if (sig == SIGSEGV) {
672 if (find_vma(current->mm, (unsigned long)fault_addr))
673 si.si_code = SEGV_ACCERR;
674 else
675 si.si_code = SEGV_MAPERR;
676 } else {
677 si.si_code = BUS_ADRERR;
678 }
679 force_sig_info(sig, &si, current);
680 return 1;
681 } else if (sig) {
682 force_sig(sig, current);
683 return 1;
684 } else {
685 return 0;
686 }
687}
688
664/* 689/*
665 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX 690 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
666 */ 691 */
667asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) 692asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
668{ 693{
669 siginfo_t info; 694 siginfo_t info = {0};
670 695
671 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) 696 if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
672 == NOTIFY_STOP) 697 == NOTIFY_STOP)
@@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
675 700
676 if (fcr31 & FPU_CSR_UNI_X) { 701 if (fcr31 & FPU_CSR_UNI_X) {
677 int sig; 702 int sig;
703 void __user *fault_addr = NULL;
678 704
679 /* 705 /*
680 * Unimplemented operation exception. If we've got the full 706 * Unimplemented operation exception. If we've got the full
@@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
690 lose_fpu(1); 716 lose_fpu(1);
691 717
692 /* Run the emulator */ 718 /* Run the emulator */
693 sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1); 719 sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
720 &fault_addr);
694 721
695 /* 722 /*
696 * We can't allow the emulated instruction to leave any of 723 * We can't allow the emulated instruction to leave any of
@@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
702 own_fpu(1); /* Using the FPU again. */ 729 own_fpu(1); /* Using the FPU again. */
703 730
704 /* If something went wrong, signal */ 731 /* If something went wrong, signal */
705 if (sig) 732 process_fpemu_return(sig, fault_addr);
706 force_sig(sig, current);
707 733
708 return; 734 return;
709 } else if (fcr31 & FPU_CSR_INV_X) 735 } else if (fcr31 & FPU_CSR_INV_X)
@@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
996 1022
997 if (!raw_cpu_has_fpu) { 1023 if (!raw_cpu_has_fpu) {
998 int sig; 1024 int sig;
1025 void __user *fault_addr = NULL;
999 sig = fpu_emulator_cop1Handler(regs, 1026 sig = fpu_emulator_cop1Handler(regs,
1000 &current->thread.fpu, 0); 1027 &current->thread.fpu,
1001 if (sig) 1028 0, &fault_addr);
1002 force_sig(sig, current); 1029 if (!process_fpemu_return(sig, fault_addr))
1003 else
1004 mt_ase_fp_affinity(); 1030 mt_ase_fp_affinity();
1005 } 1031 }
1006 1032
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 3eb3cde2f66..6a1fdfef8fd 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp)
1092 1092
1093 /* this of-course trashes what was there before... */ 1093 /* this of-course trashes what was there before... */
1094 v->pbuffer = vmalloc(P_SIZE); 1094 v->pbuffer = vmalloc(P_SIZE);
1095 if (!v->pbuffer) {
1096 pr_warning("VPE loader: unable to allocate memory\n");
1097 return -ENOMEM;
1098 }
1095 v->plen = P_SIZE; 1099 v->plen = P_SIZE;
1096 v->load_addr = NULL; 1100 v->load_addr = NULL;
1097 v->len = 0; 1101 v->len = 0;
@@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp)
1149 if (ret < 0) 1153 if (ret < 0)
1150 v->shared_ptr = NULL; 1154 v->shared_ptr = NULL;
1151 1155
1152 // cleanup any temp buffers 1156 vfree(v->pbuffer);
1153 if (v->pbuffer)
1154 vfree(v->pbuffer);
1155 v->plen = 0; 1157 v->plen = 0;
1158
1156 return ret; 1159 return ret;
1157} 1160}
1158 1161
@@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
1169 if (v == NULL) 1172 if (v == NULL)
1170 return -ENODEV; 1173 return -ENODEV;
1171 1174
1172 if (v->pbuffer == NULL) {
1173 printk(KERN_ERR "VPE loader: no buffer for program\n");
1174 return -ENOMEM;
1175 }
1176
1177 if ((count + v->len) > v->plen) { 1175 if ((count + v->len) > v->plen) {
1178 printk(KERN_WARNING 1176 printk(KERN_WARNING
1179 "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); 1177 "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 77dc3b20110..606c8a9efe3 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -161,16 +161,16 @@ FEXPORT(__bzero)
161 161
162.Lfwd_fixup: 162.Lfwd_fixup:
163 PTR_L t0, TI_TASK($28) 163 PTR_L t0, TI_TASK($28)
164 LONG_L t0, THREAD_BUADDR(t0)
165 andi a2, 0x3f 164 andi a2, 0x3f
165 LONG_L t0, THREAD_BUADDR(t0)
166 LONG_ADDU a2, t1 166 LONG_ADDU a2, t1
167 jr ra 167 jr ra
168 LONG_SUBU a2, t0 168 LONG_SUBU a2, t0
169 169
170.Lpartial_fixup: 170.Lpartial_fixup:
171 PTR_L t0, TI_TASK($28) 171 PTR_L t0, TI_TASK($28)
172 LONG_L t0, THREAD_BUADDR(t0)
173 andi a2, LONGMASK 172 andi a2, LONGMASK
173 LONG_L t0, THREAD_BUADDR(t0)
174 LONG_ADDU a2, t1 174 LONG_ADDU a2, t1
175 jr ra 175 jr ra
176 LONG_SUBU a2, t0 176 LONG_SUBU a2, t0
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
index ae4cff97a56..11b193f848f 100644
--- a/arch/mips/loongson/common/env.c
+++ b/arch/mips/loongson/common/env.c
@@ -29,9 +29,9 @@ unsigned long memsize, highmemsize;
29 29
30#define parse_even_earlier(res, option, p) \ 30#define parse_even_earlier(res, option, p) \
31do { \ 31do { \
32 int ret; \
32 if (strncmp(option, (char *)p, strlen(option)) == 0) \ 33 if (strncmp(option, (char *)p, strlen(option)) == 0) \
33 strict_strtol((char *)p + strlen(option"="), \ 34 ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \
34 10, &res); \
35} while (0) 35} while (0)
36 36
37void __init prom_init_env(void) 37void __init prom_init_env(void)
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index b2ad1b0910f..d32cb050311 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
64 64
65#if __mips >= 4 && __mips != 32 65#if __mips >= 4 && __mips != 32
66static int fpux_emu(struct pt_regs *, 66static int fpux_emu(struct pt_regs *,
67 struct mips_fpu_struct *, mips_instruction); 67 struct mips_fpu_struct *, mips_instruction, void *__user *);
68#endif 68#endif
69 69
70/* Further private data for which no space exists in mips_fpu_struct */ 70/* Further private data for which no space exists in mips_fpu_struct */
@@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp)
208 * Two instructions if the instruction is in a branch delay slot. 208 * Two instructions if the instruction is in a branch delay slot.
209 */ 209 */
210 210
211static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) 211static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
212 void *__user *fault_addr)
212{ 213{
213 mips_instruction ir; 214 mips_instruction ir;
214 unsigned long emulpc, contpc; 215 unsigned long emulpc, contpc;
215 unsigned int cond; 216 unsigned int cond;
216 217
217 if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { 218 if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
218 MIPS_FPU_EMU_INC_STATS(errors); 219 MIPS_FPU_EMU_INC_STATS(errors);
220 *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
219 return SIGBUS; 221 return SIGBUS;
220 } 222 }
223 if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
224 MIPS_FPU_EMU_INC_STATS(errors);
225 *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
226 return SIGSEGV;
227 }
221 228
222 /* XXX NEC Vr54xx bug workaround */ 229 /* XXX NEC Vr54xx bug workaround */
223 if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) 230 if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
@@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
245#endif 252#endif
246 return SIGILL; 253 return SIGILL;
247 } 254 }
248 if (get_user(ir, (mips_instruction __user *) emulpc)) { 255 if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) {
249 MIPS_FPU_EMU_INC_STATS(errors); 256 MIPS_FPU_EMU_INC_STATS(errors);
257 *fault_addr = (mips_instruction __user *)emulpc;
250 return SIGBUS; 258 return SIGBUS;
251 } 259 }
260 if (__get_user(ir, (mips_instruction __user *) emulpc)) {
261 MIPS_FPU_EMU_INC_STATS(errors);
262 *fault_addr = (mips_instruction __user *)emulpc;
263 return SIGSEGV;
264 }
252 /* __compute_return_epc() will have updated cp0_epc */ 265 /* __compute_return_epc() will have updated cp0_epc */
253 contpc = xcp->cp0_epc; 266 contpc = xcp->cp0_epc;
254 /* In order not to confuse ptrace() et al, tweak context */ 267 /* In order not to confuse ptrace() et al, tweak context */
@@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
269 u64 val; 282 u64 val;
270 283
271 MIPS_FPU_EMU_INC_STATS(loads); 284 MIPS_FPU_EMU_INC_STATS(loads);
272 if (get_user(val, va)) { 285
286 if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
273 MIPS_FPU_EMU_INC_STATS(errors); 287 MIPS_FPU_EMU_INC_STATS(errors);
288 *fault_addr = va;
274 return SIGBUS; 289 return SIGBUS;
275 } 290 }
291 if (__get_user(val, va)) {
292 MIPS_FPU_EMU_INC_STATS(errors);
293 *fault_addr = va;
294 return SIGSEGV;
295 }
276 DITOREG(val, MIPSInst_RT(ir)); 296 DITOREG(val, MIPSInst_RT(ir));
277 break; 297 break;
278 } 298 }
@@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
284 304
285 MIPS_FPU_EMU_INC_STATS(stores); 305 MIPS_FPU_EMU_INC_STATS(stores);
286 DIFROMREG(val, MIPSInst_RT(ir)); 306 DIFROMREG(val, MIPSInst_RT(ir));
287 if (put_user(val, va)) { 307 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
288 MIPS_FPU_EMU_INC_STATS(errors); 308 MIPS_FPU_EMU_INC_STATS(errors);
309 *fault_addr = va;
289 return SIGBUS; 310 return SIGBUS;
290 } 311 }
312 if (__put_user(val, va)) {
313 MIPS_FPU_EMU_INC_STATS(errors);
314 *fault_addr = va;
315 return SIGSEGV;
316 }
291 break; 317 break;
292 } 318 }
293 319
@@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
297 u32 val; 323 u32 val;
298 324
299 MIPS_FPU_EMU_INC_STATS(loads); 325 MIPS_FPU_EMU_INC_STATS(loads);
300 if (get_user(val, va)) { 326 if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
301 MIPS_FPU_EMU_INC_STATS(errors); 327 MIPS_FPU_EMU_INC_STATS(errors);
328 *fault_addr = va;
302 return SIGBUS; 329 return SIGBUS;
303 } 330 }
331 if (__get_user(val, va)) {
332 MIPS_FPU_EMU_INC_STATS(errors);
333 *fault_addr = va;
334 return SIGSEGV;
335 }
304 SITOREG(val, MIPSInst_RT(ir)); 336 SITOREG(val, MIPSInst_RT(ir));
305 break; 337 break;
306 } 338 }
@@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
312 344
313 MIPS_FPU_EMU_INC_STATS(stores); 345 MIPS_FPU_EMU_INC_STATS(stores);
314 SIFROMREG(val, MIPSInst_RT(ir)); 346 SIFROMREG(val, MIPSInst_RT(ir));
315 if (put_user(val, va)) { 347 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
316 MIPS_FPU_EMU_INC_STATS(errors); 348 MIPS_FPU_EMU_INC_STATS(errors);
349 *fault_addr = va;
317 return SIGBUS; 350 return SIGBUS;
318 } 351 }
352 if (__put_user(val, va)) {
353 MIPS_FPU_EMU_INC_STATS(errors);
354 *fault_addr = va;
355 return SIGSEGV;
356 }
319 break; 357 break;
320 } 358 }
321 359
@@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
440 contpc = (xcp->cp0_epc + 478 contpc = (xcp->cp0_epc +
441 (MIPSInst_SIMM(ir) << 2)); 479 (MIPSInst_SIMM(ir) << 2));
442 480
443 if (get_user(ir, 481 if (!access_ok(VERIFY_READ, xcp->cp0_epc,
444 (mips_instruction __user *) xcp->cp0_epc)) { 482 sizeof(mips_instruction))) {
445 MIPS_FPU_EMU_INC_STATS(errors); 483 MIPS_FPU_EMU_INC_STATS(errors);
484 *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
446 return SIGBUS; 485 return SIGBUS;
447 } 486 }
487 if (__get_user(ir,
488 (mips_instruction __user *) xcp->cp0_epc)) {
489 MIPS_FPU_EMU_INC_STATS(errors);
490 *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
491 return SIGSEGV;
492 }
448 493
449 switch (MIPSInst_OPCODE(ir)) { 494 switch (MIPSInst_OPCODE(ir)) {
450 case lwc1_op: 495 case lwc1_op:
@@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
506 551
507#if __mips >= 4 && __mips != 32 552#if __mips >= 4 && __mips != 32
508 case cop1x_op:{ 553 case cop1x_op:{
509 int sig; 554 int sig = fpux_emu(xcp, ctx, ir, fault_addr);
510 555 if (sig)
511 if ((sig = fpux_emu(xcp, ctx, ir)))
512 return sig; 556 return sig;
513 break; 557 break;
514 } 558 }
@@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
604DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); 648DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
605 649
606static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 650static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
607 mips_instruction ir) 651 mips_instruction ir, void *__user *fault_addr)
608{ 652{
609 unsigned rcsr = 0; /* resulting csr */ 653 unsigned rcsr = 0; /* resulting csr */
610 654
@@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
624 xcp->regs[MIPSInst_FT(ir)]); 668 xcp->regs[MIPSInst_FT(ir)]);
625 669
626 MIPS_FPU_EMU_INC_STATS(loads); 670 MIPS_FPU_EMU_INC_STATS(loads);
627 if (get_user(val, va)) { 671 if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
628 MIPS_FPU_EMU_INC_STATS(errors); 672 MIPS_FPU_EMU_INC_STATS(errors);
673 *fault_addr = va;
629 return SIGBUS; 674 return SIGBUS;
630 } 675 }
676 if (__get_user(val, va)) {
677 MIPS_FPU_EMU_INC_STATS(errors);
678 *fault_addr = va;
679 return SIGSEGV;
680 }
631 SITOREG(val, MIPSInst_FD(ir)); 681 SITOREG(val, MIPSInst_FD(ir));
632 break; 682 break;
633 683
@@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
638 MIPS_FPU_EMU_INC_STATS(stores); 688 MIPS_FPU_EMU_INC_STATS(stores);
639 689
640 SIFROMREG(val, MIPSInst_FS(ir)); 690 SIFROMREG(val, MIPSInst_FS(ir));
641 if (put_user(val, va)) { 691 if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
642 MIPS_FPU_EMU_INC_STATS(errors); 692 MIPS_FPU_EMU_INC_STATS(errors);
693 *fault_addr = va;
643 return SIGBUS; 694 return SIGBUS;
644 } 695 }
696 if (put_user(val, va)) {
697 MIPS_FPU_EMU_INC_STATS(errors);
698 *fault_addr = va;
699 return SIGSEGV;
700 }
645 break; 701 break;
646 702
647 case madd_s_op: 703 case madd_s_op:
@@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
701 xcp->regs[MIPSInst_FT(ir)]); 757 xcp->regs[MIPSInst_FT(ir)]);
702 758
703 MIPS_FPU_EMU_INC_STATS(loads); 759 MIPS_FPU_EMU_INC_STATS(loads);
704 if (get_user(val, va)) { 760 if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
705 MIPS_FPU_EMU_INC_STATS(errors); 761 MIPS_FPU_EMU_INC_STATS(errors);
762 *fault_addr = va;
706 return SIGBUS; 763 return SIGBUS;
707 } 764 }
765 if (__get_user(val, va)) {
766 MIPS_FPU_EMU_INC_STATS(errors);
767 *fault_addr = va;
768 return SIGSEGV;
769 }
708 DITOREG(val, MIPSInst_FD(ir)); 770 DITOREG(val, MIPSInst_FD(ir));
709 break; 771 break;
710 772
@@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
714 776
715 MIPS_FPU_EMU_INC_STATS(stores); 777 MIPS_FPU_EMU_INC_STATS(stores);
716 DIFROMREG(val, MIPSInst_FS(ir)); 778 DIFROMREG(val, MIPSInst_FS(ir));
717 if (put_user(val, va)) { 779 if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
718 MIPS_FPU_EMU_INC_STATS(errors); 780 MIPS_FPU_EMU_INC_STATS(errors);
781 *fault_addr = va;
719 return SIGBUS; 782 return SIGBUS;
720 } 783 }
784 if (__put_user(val, va)) {
785 MIPS_FPU_EMU_INC_STATS(errors);
786 *fault_addr = va;
787 return SIGSEGV;
788 }
721 break; 789 break;
722 790
723 case madd_d_op: 791 case madd_d_op:
@@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1242} 1310}
1243 1311
1244int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, 1312int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1245 int has_fpu) 1313 int has_fpu, void *__user *fault_addr)
1246{ 1314{
1247 unsigned long oldepc, prevepc; 1315 unsigned long oldepc, prevepc;
1248 mips_instruction insn; 1316 mips_instruction insn;
@@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1252 do { 1320 do {
1253 prevepc = xcp->cp0_epc; 1321 prevepc = xcp->cp0_epc;
1254 1322
1255 if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { 1323 if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
1256 MIPS_FPU_EMU_INC_STATS(errors); 1324 MIPS_FPU_EMU_INC_STATS(errors);
1325 *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
1257 return SIGBUS; 1326 return SIGBUS;
1258 } 1327 }
1328 if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
1329 MIPS_FPU_EMU_INC_STATS(errors);
1330 *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
1331 return SIGSEGV;
1332 }
1259 if (insn == 0) 1333 if (insn == 0)
1260 xcp->cp0_epc += 4; /* skip nops */ 1334 xcp->cp0_epc += 4; /* skip nops */
1261 else { 1335 else {
@@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
1267 */ 1341 */
1268 /* convert to ieee library modes */ 1342 /* convert to ieee library modes */
1269 ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; 1343 ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
1270 sig = cop1Emulate(xcp, ctx); 1344 sig = cop1Emulate(xcp, ctx, fault_addr);
1271 /* revert to mips rounding mode */ 1345 /* revert to mips rounding mode */
1272 ieee754_csr.rm = mips_rm[ieee754_csr.rm]; 1346 ieee754_csr.rm = mips_rm[ieee754_csr.rm];
1273 } 1347 }
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4fc1a0fbe00..21ea14efb83 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask)
288 return plat_dma_supported(dev, mask); 288 return plat_dma_supported(dev, mask);
289} 289}
290 290
291void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, 291void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
292 enum dma_data_direction direction) 292 enum dma_data_direction direction)
293{ 293{
294 BUG_ON(direction == DMA_NONE); 294 BUG_ON(direction == DMA_NONE);
@@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
298 __dma_sync((unsigned long)vaddr, size, direction); 298 __dma_sync((unsigned long)vaddr, size, direction);
299} 299}
300 300
301EXPORT_SYMBOL(dma_cache_sync);
302
301static struct dma_map_ops mips_default_dma_map_ops = { 303static struct dma_map_ops mips_default_dma_map_ops = {
302 .alloc_coherent = mips_dma_alloc_coherent, 304 .alloc_coherent = mips_dma_alloc_coherent,
303 .free_coherent = mips_dma_free_coherent, 305 .free_coherent = mips_dma_free_coherent,
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 505fecad468..9cca8de0054 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = {
68 */ 68 */
69static inline int mips_sc_is_activated(struct cpuinfo_mips *c) 69static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
70{ 70{
71 unsigned int config2 = read_c0_config2();
72 unsigned int tmp;
73
71 /* Check the bypass bit (L2B) */ 74 /* Check the bypass bit (L2B) */
72 switch (c->cputype) { 75 switch (c->cputype) {
73 case CPU_34K: 76 case CPU_34K:
@@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
83 c->scache.linesz = 2 << tmp; 86 c->scache.linesz = 2 << tmp;
84 else 87 else
85 return 0; 88 return 0;
89 return 1;
86} 90}
87 91
88static inline int __init mips_sc_probe(void) 92static inline int __init mips_sc_probe(void)
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c
index b7f1d9c4a8a..434d7b1a8c6 100644
--- a/arch/mips/pmc-sierra/yosemite/py-console.c
+++ b/arch/mips/pmc-sierra/yosemite/py-console.c
@@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys)
65 65
66 __asm__ __volatile__ ( 66 __asm__ __volatile__ (
67 " .set mips3 \n" 67 " .set mips3 \n"
68 " .set push \n"
69 " .set noreorder \n"
70 " .set nomacro \n"
68 " ld %0, %1 \n" 71 " ld %0, %1 \n"
72 " .set pop \n"
69 " lbu %0, (%0) \n" 73 " lbu %0, (%0) \n"
70 " .set mips0 \n" 74 " .set mips0 \n"
71 : "=r" (res) 75 : "=r" (res)
72 : "m" (vaddr)); 76 : "R" (vaddr));
73 77
74 write_c0_status(sr); 78 write_c0_status(sr);
75 ssnop_4(); 79 ssnop_4();
@@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
89 93
90 __asm__ __volatile__ ( 94 __asm__ __volatile__ (
91 " .set mips3 \n" 95 " .set mips3 \n"
96 " .set push \n"
97 " .set noreorder \n"
98 " .set nomacro \n"
92 " ld %0, %1 \n" 99 " ld %0, %1 \n"
100 " .set pop \n"
93 " sb %2, (%0) \n" 101 " sb %2, (%0) \n"
94 " .set mips0 \n" 102 " .set mips0 \n"
95 : "=&r" (tmp) 103 : "=&r" (tmp)
96 : "m" (vaddr), "r" (c)); 104 : "R" (vaddr), "r" (c));
97 105
98 write_c0_status(sr); 106 write_c0_status(sr);
99 ssnop_4(); 107 ssnop_4();
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index c308989fc46..41707a245de 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
82enum swarm_rtc_type { 82enum swarm_rtc_type {
83 RTC_NONE, 83 RTC_NONE,
84 RTC_XICOR, 84 RTC_XICOR,
85 RTC_M4LT81 85 RTC_M41T81,
86}; 86};
87 87
88enum swarm_rtc_type swarm_rtc_type; 88enum swarm_rtc_type swarm_rtc_type;
@@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts)
96 sec = xicor_get_time(); 96 sec = xicor_get_time();
97 break; 97 break;
98 98
99 case RTC_M4LT81: 99 case RTC_M41T81:
100 sec = m41t81_get_time(); 100 sec = m41t81_get_time();
101 break; 101 break;
102 102
@@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec)
115 case RTC_XICOR: 115 case RTC_XICOR:
116 return xicor_set_time(sec); 116 return xicor_set_time(sec);
117 117
118 case RTC_M4LT81: 118 case RTC_M41T81:
119 return m41t81_set_time(sec); 119 return m41t81_set_time(sec);
120 120
121 case RTC_NONE: 121 case RTC_NONE:
@@ -141,7 +141,7 @@ void __init plat_mem_setup(void)
141 if (xicor_probe()) 141 if (xicor_probe())
142 swarm_rtc_type = RTC_XICOR; 142 swarm_rtc_type = RTC_XICOR;
143 if (m41t81_probe()) 143 if (m41t81_probe())
144 swarm_rtc_type = RTC_M4LT81; 144 swarm_rtc_type = RTC_M41T81;
145 145
146#ifdef CONFIG_VT 146#ifdef CONFIG_VT
147 screen_info = (struct screen_info) { 147 screen_info = (struct screen_info) {
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index c2e44597c22..ac11754ecec 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -459,7 +459,7 @@ void migrate_irqs(void)
459 tmp = CROSS_GxICR(irq, new); 459 tmp = CROSS_GxICR(irq, new);
460 460
461 x &= GxICR_LEVEL | GxICR_ENABLE; 461 x &= GxICR_LEVEL | GxICR_ENABLE;
462 if (GxICR(irq) & GxICR_REQUEST) { 462 if (GxICR(irq) & GxICR_REQUEST)
463 x |= GxICR_REQUEST | GxICR_DETECT; 463 x |= GxICR_REQUEST | GxICR_DETECT;
464 CROSS_GxICR(irq, new) = x; 464 CROSS_GxICR(irq, new) = x;
465 tmp = CROSS_GxICR(irq, new); 465 tmp = CROSS_GxICR(irq, new);
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
index f860a340acc..75da468090b 100644
--- a/arch/mn10300/kernel/time.c
+++ b/arch/mn10300/kernel/time.c
@@ -40,21 +40,17 @@ unsigned long long sched_clock(void)
40 unsigned long long ll; 40 unsigned long long ll;
41 unsigned l[2]; 41 unsigned l[2];
42 } tsc64, result; 42 } tsc64, result;
43 unsigned long tsc, tmp; 43 unsigned long tmp;
44 unsigned product[3]; /* 96-bit intermediate value */ 44 unsigned product[3]; /* 96-bit intermediate value */
45 45
46 /* cnt32_to_63() is not safe with preemption */ 46 /* cnt32_to_63() is not safe with preemption */
47 preempt_disable(); 47 preempt_disable();
48 48
49 /* read the TSC value 49 /* expand the tsc to 64-bits.
50 */
51 tsc = get_cycles();
52
53 /* expand to 64-bits.
54 * - sched_clock() must be called once a minute or better or the 50 * - sched_clock() must be called once a minute or better or the
55 * following will go horribly wrong - see cnt32_to_63() 51 * following will go horribly wrong - see cnt32_to_63()
56 */ 52 */
57 tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL; 53 tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;
58 54
59 preempt_enable(); 55 preempt_enable();
60 56
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index fea833e18ad..e0d703c7fdf 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -63,6 +63,7 @@
63#include <linux/of_gpio.h> 63#include <linux/of_gpio.h>
64#include <linux/kernel.h> 64#include <linux/kernel.h>
65#include <linux/slab.h> 65#include <linux/slab.h>
66#include <linux/fs.h>
66#include <linux/watchdog.h> 67#include <linux/watchdog.h>
67#include <linux/miscdevice.h> 68#include <linux/miscdevice.h>
68#include <linux/uaccess.h> 69#include <linux/uaccess.h>
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 2e9d78d21fd..25cf0b34dff 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -1,7 +1,7 @@
1config SUPERH 1config SUPERH
2 def_bool y 2 def_bool y
3 select EMBEDDED 3 select EMBEDDED
4 select HAVE_CLK 4 select CLKDEV_LOOKUP
5 select HAVE_IDE if HAS_IOPORT 5 select HAVE_IDE if HAS_IOPORT
6 select HAVE_MEMBLOCK 6 select HAVE_MEMBLOCK
7 select HAVE_OPROFILE 7 select HAVE_OPROFILE
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index a5ecfbacaf3..87618c91d17 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -24,10 +24,10 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/usb/r8a66597.h> 25#include <linux/usb/r8a66597.h>
26#include <linux/usb/m66592.h> 26#include <linux/usb/m66592.h>
27#include <linux/clkdev.h>
27#include <net/ax88796.h> 28#include <net/ax88796.h>
28#include <asm/machvec.h> 29#include <asm/machvec.h>
29#include <mach/highlander.h> 30#include <mach/highlander.h>
30#include <asm/clkdev.h>
31#include <asm/clock.h> 31#include <asm/clock.h>
32#include <asm/heartbeat.h> 32#include <asm/heartbeat.h>
33#include <asm/io.h> 33#include <asm/io.h>
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index d961949600f..9070d7e6070 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -140,7 +140,7 @@ void __init init_se7206_IRQ(void)
140 make_se7206_irq(IRQ1_IRQ); /* ATA */ 140 make_se7206_irq(IRQ1_IRQ); /* ATA */
141 make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ 141 make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
142 142
143 __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */ 143 __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */
144 144
145 /* FPGA System register setup*/ 145 /* FPGA System register setup*/
146 __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ 146 __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
index 5645f358128..6ba91868201 100644
--- a/arch/sh/include/asm/clkdev.h
+++ b/arch/sh/include/asm/clkdev.h
@@ -1,9 +1,5 @@
1/* 1/*
2 * arch/sh/include/asm/clkdev.h 2 * Copyright (C) 2010 Paul Mundt <lethal@linux-sh.org>
3 *
4 * Cloned from arch/arm/include/asm/clkdev.h:
5 *
6 * Copyright (C) 2008 Russell King.
7 * 3 *
8 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
@@ -11,25 +7,25 @@
11 * 7 *
12 * Helper for the clk API to assist looking up a struct clk. 8 * Helper for the clk API to assist looking up a struct clk.
13 */ 9 */
14#ifndef __ASM_CLKDEV_H
15#define __ASM_CLKDEV_H
16 10
17struct clk; 11#ifndef __CLKDEV__H_
12#define __CLKDEV__H_
18 13
19struct clk_lookup { 14#include <linux/bootmem.h>
20 struct list_head node; 15#include <linux/mm.h>
21 const char *dev_id; 16#include <linux/slab.h>
22 const char *con_id;
23 struct clk *clk;
24};
25 17
26struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 18#include <asm/clock.h>
27 const char *dev_fmt, ...);
28 19
29void clkdev_add(struct clk_lookup *cl); 20static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
30void clkdev_drop(struct clk_lookup *cl); 21{
22 if (!slab_is_available())
23 return alloc_bootmem_low_pages(size);
24 else
25 return kzalloc(size, GFP_KERNEL);
26}
31 27
32void clkdev_add_table(struct clk_lookup *, size_t); 28#define __clk_put(clk)
33int clk_add_alias(const char *, const char *, char *, struct device *); 29#define __clk_get(clk) ({ 1; })
34 30
35#endif 31#endif /* __CLKDEV_H__ */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 8eed6a48544..cf652217952 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -11,7 +11,7 @@ endif
11 11
12CFLAGS_REMOVE_return_address.o = -pg 12CFLAGS_REMOVE_return_address.o = -pg
13 13
14obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \ 14obj-y := debugtraps.o dma-nommu.o dumpstack.o \
15 idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \ 15 idle.o io.o irq.o irq_$(BITS).o kdebugfs.o \
16 machvec.o nmi_debug.o process.o \ 16 machvec.o nmi_debug.o process.o \
17 process_$(BITS).o ptrace.o ptrace_$(BITS).o \ 17 process_$(BITS).o ptrace.o ptrace_$(BITS).o \
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
deleted file mode 100644
index 1f800ef4a73..00000000000
--- a/arch/sh/kernel/clkdev.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * arch/sh/kernel/clkdev.c
3 *
4 * Cloned from arch/arm/common/clkdev.c:
5 *
6 * Copyright (C) 2008 Russell King.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Helper for the clk API to assist looking up a struct clk.
13 */
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/device.h>
17#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/err.h>
20#include <linux/string.h>
21#include <linux/mutex.h>
22#include <linux/clk.h>
23#include <linux/slab.h>
24#include <linux/bootmem.h>
25#include <linux/mm.h>
26#include <asm/clock.h>
27#include <asm/clkdev.h>
28
29static LIST_HEAD(clocks);
30static DEFINE_MUTEX(clocks_mutex);
31
32/*
33 * Find the correct struct clk for the device and connection ID.
34 * We do slightly fuzzy matching here:
35 * An entry with a NULL ID is assumed to be a wildcard.
36 * If an entry has a device ID, it must match
37 * If an entry has a connection ID, it must match
38 * Then we take the most specific entry - with the following
39 * order of precedence: dev+con > dev only > con only.
40 */
41static struct clk *clk_find(const char *dev_id, const char *con_id)
42{
43 struct clk_lookup *p;
44 struct clk *clk = NULL;
45 int match, best = 0;
46
47 list_for_each_entry(p, &clocks, node) {
48 match = 0;
49 if (p->dev_id) {
50 if (!dev_id || strcmp(p->dev_id, dev_id))
51 continue;
52 match += 2;
53 }
54 if (p->con_id) {
55 if (!con_id || strcmp(p->con_id, con_id))
56 continue;
57 match += 1;
58 }
59 if (match == 0)
60 continue;
61
62 if (match > best) {
63 clk = p->clk;
64 best = match;
65 }
66 }
67 return clk;
68}
69
70struct clk *clk_get_sys(const char *dev_id, const char *con_id)
71{
72 struct clk *clk;
73
74 mutex_lock(&clocks_mutex);
75 clk = clk_find(dev_id, con_id);
76 mutex_unlock(&clocks_mutex);
77
78 return clk ? clk : ERR_PTR(-ENOENT);
79}
80EXPORT_SYMBOL(clk_get_sys);
81
82void clkdev_add(struct clk_lookup *cl)
83{
84 mutex_lock(&clocks_mutex);
85 list_add_tail(&cl->node, &clocks);
86 mutex_unlock(&clocks_mutex);
87}
88EXPORT_SYMBOL(clkdev_add);
89
90void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
91{
92 mutex_lock(&clocks_mutex);
93 while (num--) {
94 list_add_tail(&cl->node, &clocks);
95 cl++;
96 }
97 mutex_unlock(&clocks_mutex);
98}
99
100#define MAX_DEV_ID 20
101#define MAX_CON_ID 16
102
103struct clk_lookup_alloc {
104 struct clk_lookup cl;
105 char dev_id[MAX_DEV_ID];
106 char con_id[MAX_CON_ID];
107};
108
109struct clk_lookup * __init_refok
110clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
111{
112 struct clk_lookup_alloc *cla;
113
114 if (!slab_is_available())
115 cla = alloc_bootmem_low_pages(sizeof(*cla));
116 else
117 cla = kzalloc(sizeof(*cla), GFP_KERNEL);
118
119 if (!cla)
120 return NULL;
121
122 cla->cl.clk = clk;
123 if (con_id) {
124 strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
125 cla->cl.con_id = cla->con_id;
126 }
127
128 if (dev_fmt) {
129 va_list ap;
130
131 va_start(ap, dev_fmt);
132 vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
133 cla->cl.dev_id = cla->dev_id;
134 va_end(ap);
135 }
136
137 return &cla->cl;
138}
139EXPORT_SYMBOL(clkdev_alloc);
140
141int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
142 struct device *dev)
143{
144 struct clk *r = clk_get(dev, id);
145 struct clk_lookup *l;
146
147 if (IS_ERR(r))
148 return PTR_ERR(r);
149
150 l = clkdev_alloc(r, alias, alias_dev_name);
151 clk_put(r);
152 if (!l)
153 return -ENODEV;
154 clkdev_add(l);
155 return 0;
156}
157EXPORT_SYMBOL(clk_add_alias);
158
159/*
160 * clkdev_drop - remove a clock dynamically allocated
161 */
162void clkdev_drop(struct clk_lookup *cl)
163{
164 struct clk_lookup_alloc *cla = container_of(cl, struct clk_lookup_alloc, cl);
165
166 mutex_lock(&clocks_mutex);
167 list_del(&cl->node);
168 mutex_unlock(&clocks_mutex);
169 kfree(cla);
170}
171EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
index e2f63d68da5..dd0e0f21135 100644
--- a/arch/sh/kernel/cpu/clock-cpg.c
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -2,7 +2,7 @@
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/slab.h> 3#include <linux/slab.h>
4#include <linux/io.h> 4#include <linux/io.h>
5#include <asm/clkdev.h> 5#include <linux/clkdev.h>
6#include <asm/clock.h> 6#include <asm/clock.h>
7 7
8static struct clk master_clk = { 8static struct clk master_clk = {
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 50f887dda56..4187cf4fe18 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -48,20 +48,4 @@ int __init clk_init(void)
48 return ret; 48 return ret;
49} 49}
50 50
51/*
52 * Returns a clock. Note that we first try to use device id on the bus
53 * and clock name. If this fails, we try to use clock name only.
54 */
55struct clk *clk_get(struct device *dev, const char *con_id)
56{
57 const char *dev_id = dev ? dev_name(dev) : NULL;
58
59 return clk_get_sys(dev_id, con_id);
60}
61EXPORT_SYMBOL_GPL(clk_get);
62
63void clk_put(struct clk *clk)
64{
65}
66EXPORT_SYMBOL_GPL(clk_put);
67 51
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
index b26264dc2ae..c509c40cba4 100644
--- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
34 34
35static void master_clk_init(struct clk *clk) 35static void master_clk_init(struct clk *clk)
36{ 36{
37 return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; 37 clk->rate = 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
38} 38}
39 39
40static struct clk_ops sh7201_master_clk_ops = { 40static struct clk_ops sh7201_master_clk_ops = {
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index b601fa3978d..3f6f8e98635 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/clkdev.h> 16#include <linux/clkdev.h>
17#include <asm/clock.h> 17#include <asm/clock.h>
18#include <asm/freq.h> 18#include <asm/freq.h>
19 19
@@ -81,8 +81,7 @@ static void shoc_clk_init(struct clk *clk)
81 for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { 81 for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
82 int divisor = frqcr3_divisors[i]; 82 int divisor = frqcr3_divisors[i];
83 83
84 if (clk->ops->set_rate(clk, clk->parent->rate / 84 if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
85 divisor, 0) == 0)
86 break; 85 break;
87 } 86 }
88 87
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
index 71291ae201b..93c646072c1 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25#include <asm/clock.h> 25#include <asm/clock.h>
26 26
27/* SH7343 registers */ 27/* SH7343 registers */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
index 7ce5bbcd408..049dc0628cc 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25#include <asm/clock.h> 25#include <asm/clock.h>
26 26
27/* SH7366 registers */ 27/* SH7366 registers */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 2030f3d9fac..9d23a36f064 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <asm/clkdev.h> 24#include <linux/clkdev.h>
25#include <asm/clock.h> 25#include <asm/clock.h>
26#include <asm/hwblk.h> 26#include <asm/hwblk.h>
27#include <cpu/sh7722.h> 27#include <cpu/sh7722.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index d3938f0d370..55493cd5bd8 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -22,7 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <asm/clkdev.h> 25#include <linux/clkdev.h>
26#include <asm/clock.h> 26#include <asm/clock.h>
27#include <asm/hwblk.h> 27#include <asm/hwblk.h>
28#include <cpu/sh7723.h> 28#include <cpu/sh7723.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 271c0b325a9..d08fa953c88 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -22,7 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <asm/clkdev.h> 25#include <linux/clkdev.h>
26#include <asm/clock.h> 26#include <asm/clock.h>
27#include <asm/hwblk.h> 27#include <asm/hwblk.h>
28#include <cpu/sh7724.h> 28#include <cpu/sh7724.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index ce39a2ae8c6..e073e3eb4c3 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <asm/clkdev.h> 15#include <linux/clkdev.h>
16#include <asm/clock.h> 16#include <asm/clock.h>
17#include <asm/freq.h> 17#include <asm/freq.h>
18 18
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
index 1f1df48008c..599630fc4d3 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/clkdev.h> 16#include <linux/clkdev.h>
17#include <asm/clock.h> 17#include <asm/clock.h>
18#include <asm/freq.h> 18#include <asm/freq.h>
19#include <asm/io.h> 19#include <asm/io.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
index 62d70635006..8894926479a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <asm/clkdev.h> 15#include <linux/clkdev.h>
16#include <asm/clock.h> 16#include <asm/clock.h>
17#include <asm/freq.h> 17#include <asm/freq.h>
18#include <asm/io.h> 18#include <asm/io.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index c3e458aaa2b..2d960247f3e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -14,7 +14,7 @@
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/cpufreq.h> 16#include <linux/cpufreq.h>
17#include <asm/clkdev.h> 17#include <linux/clkdev.h>
18#include <asm/clock.h> 18#include <asm/clock.h>
19#include <asm/freq.h> 19#include <asm/freq.h>
20#include <cpu/sh7785.h> 20#include <cpu/sh7785.h>
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index 597c9fbe49c..42e403be907 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <asm/clkdev.h> 16#include <linux/clkdev.h>
17#include <asm/clock.h> 17#include <asm/clock.h>
18#include <asm/freq.h> 18#include <asm/freq.h>
19 19
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index 4f70df6b616..1afdb93b8cc 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -14,7 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <asm/clkdev.h> 17#include <linux/clkdev.h>
18#include <asm/clock.h> 18#include <asm/clock.h>
19#include <asm/freq.h> 19#include <asm/freq.h>
20 20
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h
index c1ee1d61d44..81d92a45cd4 100644
--- a/arch/tile/include/asm/signal.h
+++ b/arch/tile/include/asm/signal.h
@@ -25,7 +25,7 @@
25 25
26#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 26#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
27struct pt_regs; 27struct pt_regs;
28int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); 28int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
29int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); 29int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
30void do_signal(struct pt_regs *regs); 30void do_signal(struct pt_regs *regs);
31#endif 31#endif
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 543d6a33aa2..dbb0dfc7bec 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
290 return ret; 290 return ret;
291} 291}
292 292
293/* The assembly shim for this function arranges to ignore the return value. */
293long compat_sys_rt_sigreturn(struct pt_regs *regs) 294long compat_sys_rt_sigreturn(struct pt_regs *regs)
294{ 295{
295 struct compat_rt_sigframe __user *frame = 296 struct compat_rt_sigframe __user *frame =
296 (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); 297 (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
297 sigset_t set; 298 sigset_t set;
298 long r0;
299 299
300 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 300 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
301 goto badframe; 301 goto badframe;
@@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
308 recalc_sigpending(); 308 recalc_sigpending();
309 spin_unlock_irq(&current->sighand->siglock); 309 spin_unlock_irq(&current->sighand->siglock);
310 310
311 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 311 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
312 goto badframe; 312 goto badframe;
313 313
314 if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) 314 if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
315 goto badframe; 315 goto badframe;
316 316
317 return r0; 317 return 0;
318 318
319badframe: 319badframe:
320 force_sig(SIGSEGV, current); 320 force_sig(SIGSEGV, current);
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index f5821626247..5eed4a02bf6 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -1342,8 +1342,8 @@ handle_syscall:
1342 lw r20, r20 1342 lw r20, r20
1343 1343
1344 /* Jump to syscall handler. */ 1344 /* Jump to syscall handler. */
1345 jalr r20; .Lhandle_syscall_link: 1345 jalr r20
1346 FEEDBACK_REENTER(handle_syscall) 1346.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
1347 1347
1348 /* 1348 /*
1349 * Write our r0 onto the stack so it gets restored instead 1349 * Write our r0 onto the stack so it gets restored instead
@@ -1352,6 +1352,9 @@ handle_syscall:
1352 PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) 1352 PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
1353 sw r29, r0 1353 sw r29, r0
1354 1354
1355.Lsyscall_sigreturn_skip:
1356 FEEDBACK_REENTER(handle_syscall)
1357
1355 /* Do syscall trace again, if requested. */ 1358 /* Do syscall trace again, if requested. */
1356 lw r30, r31 1359 lw r30, r31
1357 andi r30, r30, _TIF_SYSCALL_TRACE 1360 andi r30, r30, _TIF_SYSCALL_TRACE
@@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
1536 }; \ 1539 }; \
1537 STD_ENDPROC(_##x) 1540 STD_ENDPROC(_##x)
1538 1541
1542/*
1543 * Special-case sigreturn to not write r0 to the stack on return.
1544 * This is technically more efficient, but it also avoids difficulties
1545 * in the 64-bit OS when handling 32-bit compat code, since we must not
1546 * sign-extend r0 for the sigreturn return-value case.
1547 */
1548#define PTREGS_SYSCALL_SIGRETURN(x, reg) \
1549 STD_ENTRY(_##x); \
1550 addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
1551 { \
1552 PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
1553 j x \
1554 }; \
1555 STD_ENDPROC(_##x)
1556
1539PTREGS_SYSCALL(sys_execve, r3) 1557PTREGS_SYSCALL(sys_execve, r3)
1540PTREGS_SYSCALL(sys_sigaltstack, r2) 1558PTREGS_SYSCALL(sys_sigaltstack, r2)
1541PTREGS_SYSCALL(sys_rt_sigreturn, r0) 1559PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
1542PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) 1560PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
1543 1561
1544/* Save additional callee-saves to pt_regs, put address in r4 and jump. */ 1562/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index 8430f45daea..e90eb53173b 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -212,6 +212,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
212 childregs->sp = sp; /* override with new user stack pointer */ 212 childregs->sp = sp; /* override with new user stack pointer */
213 213
214 /* 214 /*
215 * If CLONE_SETTLS is set, set "tp" in the new task to "r4",
216 * which is passed in as arg #5 to sys_clone().
217 */
218 if (clone_flags & CLONE_SETTLS)
219 childregs->tp = regs->regs[4];
220
221 /*
215 * Copy the callee-saved registers from the passed pt_regs struct 222 * Copy the callee-saved registers from the passed pt_regs struct
216 * into the context-switch callee-saved registers area. 223 * into the context-switch callee-saved registers area.
217 * This way when we start the interrupt-return sequence, the 224 * This way when we start the interrupt-return sequence, the
@@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
539 return __switch_to(prev, next, next_current_ksp0(next)); 546 return __switch_to(prev, next, next_current_ksp0(next));
540} 547}
541 548
549/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
542SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, 550SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
543 void __user *, parent_tidptr, void __user *, child_tidptr, 551 void __user *, parent_tidptr, void __user *, child_tidptr,
544 struct pt_regs *, regs) 552 struct pt_regs *, regs)
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index 757407e3669..1260321155f 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
52 */ 52 */
53 53
54int restore_sigcontext(struct pt_regs *regs, 54int restore_sigcontext(struct pt_regs *regs,
55 struct sigcontext __user *sc, long *pr0) 55 struct sigcontext __user *sc)
56{ 56{
57 int err = 0; 57 int err = 0;
58 int i; 58 int i;
@@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,
75 75
76 regs->faultnum = INT_SWINT_1_SIGRETURN; 76 regs->faultnum = INT_SWINT_1_SIGRETURN;
77 77
78 err |= __get_user(*pr0, &sc->gregs[0]);
79 return err; 78 return err;
80} 79}
81 80
82/* sigreturn() returns long since it restores r0 in the interrupted code. */ 81/* The assembly shim for this function arranges to ignore the return value. */
83SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) 82SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
84{ 83{
85 struct rt_sigframe __user *frame = 84 struct rt_sigframe __user *frame =
86 (struct rt_sigframe __user *)(regs->sp); 85 (struct rt_sigframe __user *)(regs->sp);
87 sigset_t set; 86 sigset_t set;
88 long r0;
89 87
90 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 88 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
91 goto badframe; 89 goto badframe;
@@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
98 recalc_sigpending(); 96 recalc_sigpending();
99 spin_unlock_irq(&current->sighand->siglock); 97 spin_unlock_irq(&current->sighand->siglock);
100 98
101 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 99 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
102 goto badframe; 100 goto badframe;
103 101
104 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) 102 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
105 goto badframe; 103 goto badframe;
106 104
107 return r0; 105 return 0;
108 106
109badframe: 107badframe:
110 force_sig(SIGSEGV, current); 108 force_sig(SIGSEGV, current);
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 23f315c9f21..325c05294fc 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
355 if (heap > 0x3fffffffffffUL) 355 if (heap > 0x3fffffffffffUL)
356 error("Destination address too large"); 356 error("Destination address too large");
357#else 357#else
358 if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff)) 358 if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
359 error("Destination address too large"); 359 error("Destination address too large");
360#endif 360#endif
361#ifndef CONFIG_RELOCATABLE 361#ifndef CONFIG_RELOCATABLE
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 5be1542fbfa..e99d55d74df 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -72,6 +72,9 @@ struct e820map {
72#define BIOS_BEGIN 0x000a0000 72#define BIOS_BEGIN 0x000a0000
73#define BIOS_END 0x00100000 73#define BIOS_END 0x00100000
74 74
75#define BIOS_ROM_BASE 0xffe00000
76#define BIOS_ROM_END 0xffffffff
77
75#ifdef __KERNEL__ 78#ifdef __KERNEL__
76/* see comment in arch/x86/kernel/e820.c */ 79/* see comment in arch/x86/kernel/e820.c */
77extern struct e820map e820; 80extern struct e820map e820;
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9e6fe391094..f702f82aa1e 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -79,7 +79,7 @@
79#define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) 79#define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT)
80#define KVM_MIN_FREE_MMU_PAGES 5 80#define KVM_MIN_FREE_MMU_PAGES 5
81#define KVM_REFILL_PAGES 25 81#define KVM_REFILL_PAGES 25
82#define KVM_MAX_CPUID_ENTRIES 40 82#define KVM_MAX_CPUID_ENTRIES 80
83#define KVM_NR_FIXED_MTRR_REGION 88 83#define KVM_NR_FIXED_MTRR_REGION 88
84#define KVM_NR_VAR_MTRR 8 84#define KVM_NR_VAR_MTRR 8
85 85
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9e13763b609..1e994754d32 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
45obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o 45obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
46obj-y += tsc.o io_delay.o rtc.o 46obj-y += tsc.o io_delay.o rtc.o
47obj-y += pci-iommu_table.o 47obj-y += pci-iommu_table.o
48obj-y += resource.o
48 49
49obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o 50obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
50obj-y += process.o 51obj-y += process.o
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 3f838d53739..78218135b48 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void)
1389 1389
1390 setup_apic_nmi_watchdog(NULL); 1390 setup_apic_nmi_watchdog(NULL);
1391 apic_pm_activate(); 1391 apic_pm_activate();
1392
1393 /*
1394 * Now that local APIC setup is completed for BP, configure the fault
1395 * handling for interrupt remapping.
1396 */
1397 if (!smp_processor_id() && intr_remapping_enabled)
1398 enable_drhd_fault_handling();
1399
1392} 1400}
1393 1401
1394#ifdef CONFIG_X86_X2APIC 1402#ifdef CONFIG_X86_X2APIC
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 7cc0a721f62..fadcd743a74 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data)
2430{ 2430{
2431 struct irq_cfg *cfg = data->chip_data; 2431 struct irq_cfg *cfg = data->chip_data;
2432 int i, do_unmask_irq = 0, irq = data->irq; 2432 int i, do_unmask_irq = 0, irq = data->irq;
2433 struct irq_desc *desc = irq_to_desc(irq);
2434 unsigned long v; 2433 unsigned long v;
2435 2434
2436 irq_complete_move(cfg); 2435 irq_complete_move(cfg);
2437#ifdef CONFIG_GENERIC_PENDING_IRQ 2436#ifdef CONFIG_GENERIC_PENDING_IRQ
2438 /* If we are moving the irq we need to mask it */ 2437 /* If we are moving the irq we need to mask it */
2439 if (unlikely(desc->status & IRQ_MOVE_PENDING)) { 2438 if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
2440 do_unmask_irq = 1; 2439 do_unmask_irq = 1;
2441 mask_ioapic(cfg); 2440 mask_ioapic(cfg);
2442 } 2441 }
@@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
3413 msg.data |= MSI_DATA_VECTOR(cfg->vector); 3412 msg.data |= MSI_DATA_VECTOR(cfg->vector);
3414 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; 3413 msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
3415 msg.address_lo |= MSI_ADDR_DEST_ID(dest); 3414 msg.address_lo |= MSI_ADDR_DEST_ID(dest);
3415 msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
3416 3416
3417 dmar_msi_write(irq, &msg); 3417 dmar_msi_write(irq, &msg);
3418 3418
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index f9e4e6a5407..d8c4a6feb28 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void)
79 /* need to update phys_pkg_id */ 79 /* need to update phys_pkg_id */
80 apic->phys_pkg_id = apicid_phys_pkg_id; 80 apic->phys_pkg_id = apicid_phys_pkg_id;
81 } 81 }
82
83 /*
84 * Now that apic routing model is selected, configure the
85 * fault handling for intr remapping.
86 */
87 if (intr_remapping_enabled)
88 enable_drhd_fault_handling();
89} 82}
90 83
91/* Same for both flat and physical. */ 84/* Same for both flat and physical. */
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index bcece91dd31..c0dbd9ac24f 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -60,16 +60,18 @@
60#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) 60#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
61#endif 61#endif
62 62
63/* Number of possible pages in the lowmem region */
64LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
65
63/* Enough space to fit pagetables for the low memory linear map */ 66/* Enough space to fit pagetables for the low memory linear map */
64MAPPING_BEYOND_END = \ 67MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
65 PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
66 68
67/* 69/*
68 * Worst-case size of the kernel mapping we need to make: 70 * Worst-case size of the kernel mapping we need to make:
69 * the worst-case size of the kernel itself, plus the extra we need 71 * a relocatable kernel can live anywhere in lowmem, so we need to be able
70 * to map for the linear map. 72 * to map all of lowmem.
71 */ 73 */
72KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT 74KERNEL_PAGES = LOWMEM_PAGES
73 75
74INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm 76INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
75RESERVE_BRK(pagetables, INIT_MAP_SIZE) 77RESERVE_BRK(pagetables, INIT_MAP_SIZE)
@@ -620,13 +622,13 @@ ENTRY(initial_code)
620__PAGE_ALIGNED_BSS 622__PAGE_ALIGNED_BSS
621 .align PAGE_SIZE_asm 623 .align PAGE_SIZE_asm
622#ifdef CONFIG_X86_PAE 624#ifdef CONFIG_X86_PAE
623initial_pg_pmd: 625ENTRY(initial_pg_pmd)
624 .fill 1024*KPMDS,4,0 626 .fill 1024*KPMDS,4,0
625#else 627#else
626ENTRY(initial_page_table) 628ENTRY(initial_page_table)
627 .fill 1024,4,0 629 .fill 1024,4,0
628#endif 630#endif
629initial_pg_fixmap: 631ENTRY(initial_pg_fixmap)
630 .fill 1024,4,0 632 .fill 1024,4,0
631ENTRY(empty_zero_page) 633ENTRY(empty_zero_page)
632 .fill 4096,1,0 634 .fill 4096,1,0
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index ae03cab4352..4ff5968f12d 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -27,6 +27,9 @@
27#define HPET_DEV_FSB_CAP 0x1000 27#define HPET_DEV_FSB_CAP 0x1000
28#define HPET_DEV_PERI_CAP 0x2000 28#define HPET_DEV_PERI_CAP 0x2000
29 29
30#define HPET_MIN_CYCLES 128
31#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
32
30#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt) 33#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
31 34
32/* 35/*
@@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void)
299 /* Calculate the min / max delta */ 302 /* Calculate the min / max delta */
300 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, 303 hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
301 &hpet_clockevent); 304 &hpet_clockevent);
302 /* 5 usec minimum reprogramming delta. */ 305 /* Setup minimum reprogramming delta. */
303 hpet_clockevent.min_delta_ns = 5000; 306 hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
307 &hpet_clockevent);
304 308
305 /* 309 /*
306 * Start hpet with the boot cpu mask and make it 310 * Start hpet with the boot cpu mask and make it
@@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta,
393 * the wraparound into account) nor a simple count down event 397 * the wraparound into account) nor a simple count down event
394 * mode. Further the write to the comparator register is 398 * mode. Further the write to the comparator register is
395 * delayed internally up to two HPET clock cycles in certain 399 * delayed internally up to two HPET clock cycles in certain
396 * chipsets (ATI, ICH9,10). We worked around that by reading 400 * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
397 * back the compare register, but that required another 401 * longer delays. We worked around that by reading back the
398 * workaround for ICH9,10 chips where the first readout after 402 * compare register, but that required another workaround for
399 * write can return the old stale value. We already have a 403 * ICH9,10 chips where the first readout after write can
400 * minimum delta of 5us enforced, but a NMI or SMI hitting 404 * return the old stale value. We already had a minimum
405 * programming delta of 5us enforced, but a NMI or SMI hitting
401 * between the counter readout and the comparator write can 406 * between the counter readout and the comparator write can
402 * move us behind that point easily. Now instead of reading 407 * move us behind that point easily. Now instead of reading
403 * the compare register back several times, we make the ETIME 408 * the compare register back several times, we make the ETIME
404 * decision based on the following: Return ETIME if the 409 * decision based on the following: Return ETIME if the
405 * counter value after the write is less than 8 HPET cycles 410 * counter value after the write is less than HPET_MIN_CYCLES
406 * away from the event or if the counter is already ahead of 411 * away from the event or if the counter is already ahead of
407 * the event. 412 * the event. The minimum programming delta for the generic
413 * clockevents code is set to 1.5 * HPET_MIN_CYCLES.
408 */ 414 */
409 res = (s32)(cnt - hpet_readl(HPET_COUNTER)); 415 res = (s32)(cnt - hpet_readl(HPET_COUNTER));
410 416
411 return res < 8 ? -ETIME : 0; 417 return res < HPET_MIN_CYCLES ? -ETIME : 0;
412} 418}
413 419
414static void hpet_legacy_set_mode(enum clock_event_mode mode, 420static void hpet_legacy_set_mode(enum clock_event_mode mode,
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index dcb65cc0a05..1a1b606d3e9 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
364 364
365 /* For performance reasons, reuse mc area when possible */ 365 /* For performance reasons, reuse mc area when possible */
366 if (!mc || mc_size > curr_mc_size) { 366 if (!mc || mc_size > curr_mc_size) {
367 if (mc) 367 vfree(mc);
368 vfree(mc);
369 mc = vmalloc(mc_size); 368 mc = vmalloc(mc_size);
370 if (!mc) 369 if (!mc)
371 break; 370 break;
@@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
374 373
375 if (get_ucode_data(mc, ucode_ptr, mc_size) || 374 if (get_ucode_data(mc, ucode_ptr, mc_size) ||
376 microcode_sanity_check(mc) < 0) { 375 microcode_sanity_check(mc) < 0) {
377 vfree(mc);
378 break; 376 break;
379 } 377 }
380 378
381 if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) { 379 if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
382 if (new_mc) 380 vfree(new_mc);
383 vfree(new_mc);
384 new_rev = mc_header.rev; 381 new_rev = mc_header.rev;
385 new_mc = mc; 382 new_mc = mc;
386 mc = NULL; /* trigger new vmalloc */ 383 mc = NULL; /* trigger new vmalloc */
@@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
390 leftover -= mc_size; 387 leftover -= mc_size;
391 } 388 }
392 389
393 if (mc) 390 vfree(mc);
394 vfree(mc);
395 391
396 if (leftover) { 392 if (leftover) {
397 if (new_mc) 393 vfree(new_mc);
398 vfree(new_mc);
399 state = UCODE_ERROR; 394 state = UCODE_ERROR;
400 goto out; 395 goto out;
401 } 396 }
@@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
405 goto out; 400 goto out;
406 } 401 }
407 402
408 if (uci->mc) 403 vfree(uci->mc);
409 vfree(uci->mc);
410 uci->mc = (struct microcode_intel *)new_mc; 404 uci->mc = (struct microcode_intel *)new_mc;
411 405
412 pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", 406 pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c
new file mode 100644
index 00000000000..2a26819bb6a
--- /dev/null
+++ b/arch/x86/kernel/resource.c
@@ -0,0 +1,48 @@
1#include <linux/ioport.h>
2#include <asm/e820.h>
3
4static void resource_clip(struct resource *res, resource_size_t start,
5 resource_size_t end)
6{
7 resource_size_t low = 0, high = 0;
8
9 if (res->end < start || res->start > end)
10 return; /* no conflict */
11
12 if (res->start < start)
13 low = start - res->start;
14
15 if (res->end > end)
16 high = res->end - end;
17
18 /* Keep the area above or below the conflict, whichever is larger */
19 if (low > high)
20 res->end = start - 1;
21 else
22 res->start = end + 1;
23}
24
25static void remove_e820_regions(struct resource *avail)
26{
27 int i;
28 struct e820entry *entry;
29
30 for (i = 0; i < e820.nr_map; i++) {
31 entry = &e820.map[i];
32
33 resource_clip(avail, entry->addr,
34 entry->addr + entry->size - 1);
35 }
36}
37
38void arch_remove_reservations(struct resource *avail)
39{
40 /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
41 if (avail->flags & IORESOURCE_MEM) {
42 if (avail->start < BIOS_END)
43 avail->start = BIOS_END;
44 resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
45
46 remove_e820_regions(avail);
47 }
48}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 21c6746338a..a0f52af256a 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void)
501 return total << PAGE_SHIFT; 501 return total << PAGE_SHIFT;
502} 502}
503 503
504#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF 504/*
505 * Keep the crash kernel below this limit. On 32 bits earlier kernels
506 * would limit the kernel to the low 512 MiB due to mapping restrictions.
507 * On 64 bits, kexec-tools currently limits us to 896 MiB; increase this
508 * limit once kexec-tools are fixed.
509 */
510#ifdef CONFIG_X86_32
511# define CRASH_KERNEL_ADDR_MAX (512 << 20)
512#else
513# define CRASH_KERNEL_ADDR_MAX (896 << 20)
514#endif
515
505static void __init reserve_crashkernel(void) 516static void __init reserve_crashkernel(void)
506{ 517{
507 unsigned long long total_mem; 518 unsigned long long total_mem;
@@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void)
520 const unsigned long long alignment = 16<<20; /* 16M */ 531 const unsigned long long alignment = 16<<20; /* 16M */
521 532
522 /* 533 /*
523 * kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX 534 * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
524 */ 535 */
525 crash_base = memblock_find_in_range(alignment, 536 crash_base = memblock_find_in_range(alignment,
526 DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment); 537 CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
527 538
528 if (crash_base == MEMBLOCK_ERROR) { 539 if (crash_base == MEMBLOCK_ERROR) {
529 pr_info("crashkernel reservation failed - No suitable area found.\n"); 540 pr_info("crashkernel reservation failed - No suitable area found.\n");
@@ -769,7 +780,6 @@ void __init setup_arch(char **cmdline_p)
769 780
770 x86_init.oem.arch_setup(); 781 x86_init.oem.arch_setup();
771 782
772 resource_alloc_from_bottom = 0;
773 iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; 783 iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
774 setup_memory_map(); 784 setup_memory_map();
775 parse_setup_data(); 785 parse_setup_data();
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index 9c253bd65e2..547128546cc 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -394,7 +394,8 @@ static void __init setup_xstate_init(void)
394 * Setup init_xstate_buf to represent the init state of 394 * Setup init_xstate_buf to represent the init state of
395 * all the features managed by the xsave 395 * all the features managed by the xsave
396 */ 396 */
397 init_xstate_buf = alloc_bootmem(xstate_size); 397 init_xstate_buf = alloc_bootmem_align(xstate_size,
398 __alignof__(struct xsave_struct));
398 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; 399 init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
399 400
400 clts(); 401 clts();
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index f628234fbec..3cece05e4ac 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
575 s->pics[1].elcr_mask = 0xde; 575 s->pics[1].elcr_mask = 0xde;
576 s->pics[0].pics_state = s; 576 s->pics[0].pics_state = s;
577 s->pics[1].pics_state = s; 577 s->pics[1].pics_state = s;
578 s->pics[0].isr_ack = 0xff;
579 s->pics[1].isr_ack = 0xff;
578 580
579 /* 581 /*
580 * Initialize PIO device 582 * Initialize PIO device
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index fb8b376bf28..fbb04aee830 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2394,7 +2394,8 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
2394 ASSERT(!VALID_PAGE(root)); 2394 ASSERT(!VALID_PAGE(root));
2395 spin_lock(&vcpu->kvm->mmu_lock); 2395 spin_lock(&vcpu->kvm->mmu_lock);
2396 kvm_mmu_free_some_pages(vcpu); 2396 kvm_mmu_free_some_pages(vcpu);
2397 sp = kvm_mmu_get_page(vcpu, i << 30, i << 30, 2397 sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
2398 i << 30,
2398 PT32_ROOT_LEVEL, 1, ACC_ALL, 2399 PT32_ROOT_LEVEL, 1, ACC_ALL,
2399 NULL); 2400 NULL);
2400 root = __pa(sp->spt); 2401 root = __pa(sp->spt);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1ca12298ffc..b81a9b7c2ca 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
3494static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) 3494static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
3495{ 3495{
3496 switch (func) { 3496 switch (func) {
3497 case 0x00000001:
3498 /* Mask out xsave bit as long as it is not supported by SVM */
3499 entry->ecx &= ~(bit(X86_FEATURE_XSAVE));
3500 break;
3497 case 0x80000001: 3501 case 0x80000001:
3498 if (nested) 3502 if (nested)
3499 entry->ecx |= (1 << 2); /* Set SVM bit */ 3503 entry->ecx |= (1 << 2); /* Set SVM bit */
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ff21fdda0c5..81fcbe9515c 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void)
4227 return PT_PDPE_LEVEL; 4227 return PT_PDPE_LEVEL;
4228} 4228}
4229 4229
4230static inline u32 bit(int bitno)
4231{
4232 return 1 << (bitno & 31);
4233}
4234
4235static void vmx_cpuid_update(struct kvm_vcpu *vcpu) 4230static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
4236{ 4231{
4237 struct kvm_cpuid_entry2 *best; 4232 struct kvm_cpuid_entry2 *best;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cdac9e592aa..b989e1f1e5d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
155 155
156u64 __read_mostly host_xcr0; 156u64 __read_mostly host_xcr0;
157 157
158static inline u32 bit(int bitno)
159{
160 return 1 << (bitno & 31);
161}
162
163static void kvm_on_user_return(struct user_return_notifier *urn) 158static void kvm_on_user_return(struct user_return_notifier *urn)
164{ 159{
165 unsigned slot; 160 unsigned slot;
@@ -4569,9 +4564,11 @@ static void kvm_timer_init(void)
4569#ifdef CONFIG_CPU_FREQ 4564#ifdef CONFIG_CPU_FREQ
4570 struct cpufreq_policy policy; 4565 struct cpufreq_policy policy;
4571 memset(&policy, 0, sizeof(policy)); 4566 memset(&policy, 0, sizeof(policy));
4572 cpufreq_get_policy(&policy, get_cpu()); 4567 cpu = get_cpu();
4568 cpufreq_get_policy(&policy, cpu);
4573 if (policy.cpuinfo.max_freq) 4569 if (policy.cpuinfo.max_freq)
4574 max_tsc_khz = policy.cpuinfo.max_freq; 4570 max_tsc_khz = policy.cpuinfo.max_freq;
4571 put_cpu();
4575#endif 4572#endif
4576 cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, 4573 cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
4577 CPUFREQ_TRANSITION_NOTIFIER); 4574 CPUFREQ_TRANSITION_NOTIFIER);
@@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
5522 5519
5523 mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; 5520 mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
5524 kvm_x86_ops->set_cr4(vcpu, sregs->cr4); 5521 kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
5522 if (sregs->cr4 & X86_CR4_OSXSAVE)
5523 update_cpuid(vcpu);
5525 if (!is_long_mode(vcpu) && is_pae(vcpu)) { 5524 if (!is_long_mode(vcpu) && is_pae(vcpu)) {
5526 load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); 5525 load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
5527 mmu_reset_needed = 1; 5526 mmu_reset_needed = 1;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 2cea414489f..c600da830ce 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
70 return kvm_read_cr0_bits(vcpu, X86_CR0_PG); 70 return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
71} 71}
72 72
73static inline u32 bit(int bitno)
74{
75 return 1 << (bitno & 31);
76}
77
73void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); 78void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
74void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); 79void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
75int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); 80int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 73b1e1a1f48..4996cf5f73a 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3)
531{ 531{
532 lguest_data.pgdir = cr3; 532 lguest_data.pgdir = cr3;
533 lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); 533 lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
534 cr3_changed = true; 534
535 /* These two page tables are simple, linear, and used during boot */
536 if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
537 cr3_changed = true;
535} 538}
536 539
537static unsigned long lguest_read_cr3(void) 540static unsigned long lguest_read_cr3(void)
@@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
703 * to forget all of them. Fortunately, this is very rare. 706 * to forget all of them. Fortunately, this is very rare.
704 * 707 *
705 * ... except in early boot when the kernel sets up the initial pagetables, 708 * ... except in early boot when the kernel sets up the initial pagetables,
706 * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell 709 * which makes booting astonishingly slow: 48 seconds! So we don't even tell
707 * the Host anything changed until we've done the first page table switch, 710 * the Host anything changed until we've done the first real page table switch,
708 * which brings boot back to 0.25 seconds. 711 * which brings boot back to 4.3 seconds.
709 */ 712 */
710static void lguest_set_pte(pte_t *ptep, pte_t pteval) 713static void lguest_set_pte(pte_t *ptep, pte_t pteval)
711{ 714{
@@ -1002,7 +1005,7 @@ static void lguest_time_init(void)
1002 clockevents_register_device(&lguest_clockevent); 1005 clockevents_register_device(&lguest_clockevent);
1003 1006
1004 /* Finally, we unblock the timer interrupt. */ 1007 /* Finally, we unblock the timer interrupt. */
1005 enable_lguest_irq(0); 1008 clear_bit(0, lguest_data.blocked_interrupts);
1006} 1009}
1007 1010
1008/* 1011/*
@@ -1349,9 +1352,6 @@ __init void lguest_init(void)
1349 */ 1352 */
1350 switch_to_new_gdt(0); 1353 switch_to_new_gdt(0);
1351 1354
1352 /* We actually boot with all memory mapped, but let's say 128MB. */
1353 max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
1354
1355 /* 1355 /*
1356 * The Host<->Guest Switcher lives at the top of our address space, and 1356 * The Host<->Guest Switcher lives at the top of our address space, and
1357 * the Host told us how big it is when we made LGUEST_INIT hypercall: 1357 * the Host told us how big it is when we made LGUEST_INIT hypercall:
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index 4f420c2f2d5..e7d5382ef26 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -4,6 +4,7 @@
4#include <asm/asm-offsets.h> 4#include <asm/asm-offsets.h>
5#include <asm/thread_info.h> 5#include <asm/thread_info.h>
6#include <asm/processor-flags.h> 6#include <asm/processor-flags.h>
7#include <asm/pgtable.h>
7 8
8/*G:020 9/*G:020
9 * Our story starts with the kernel booting into startup_32 in 10 * Our story starts with the kernel booting into startup_32 in
@@ -37,9 +38,113 @@ ENTRY(lguest_entry)
37 /* Set up the initial stack so we can run C code. */ 38 /* Set up the initial stack so we can run C code. */
38 movl $(init_thread_union+THREAD_SIZE),%esp 39 movl $(init_thread_union+THREAD_SIZE),%esp
39 40
41 call init_pagetables
42
40 /* Jumps are relative: we're running __PAGE_OFFSET too low. */ 43 /* Jumps are relative: we're running __PAGE_OFFSET too low. */
41 jmp lguest_init+__PAGE_OFFSET 44 jmp lguest_init+__PAGE_OFFSET
42 45
46/*
47 * Initialize page tables. This creates a PDE and a set of page
48 * tables, which are located immediately beyond __brk_base. The variable
49 * _brk_end is set up to point to the first "safe" location.
50 * Mappings are created both at virtual address 0 (identity mapping)
51 * and PAGE_OFFSET for up to _end.
52 *
53 * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they
54 * don't have a stack at this point, so we can't just use call and ret.
55 */
56init_pagetables:
57#if PTRS_PER_PMD > 1
58#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
59#else
60#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
61#endif
62#define pa(X) ((X) - __PAGE_OFFSET)
63
64/* Enough space to fit pagetables for the low memory linear map */
65MAPPING_BEYOND_END = \
66 PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
67#ifdef CONFIG_X86_PAE
68
69 /*
70 * In PAE mode initial_page_table is statically defined to contain
71 * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3
72 * entries). The identity mapping is handled by pointing two PGD entries
73 * to the first kernel PMD.
74 *
75 * Note the upper half of each PMD or PTE are always zero at this stage.
76 */
77
78#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
79
80 xorl %ebx,%ebx /* %ebx is kept at zero */
81
82 movl $pa(__brk_base), %edi
83 movl $pa(initial_pg_pmd), %edx
84 movl $PTE_IDENT_ATTR, %eax
8510:
86 leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */
87 movl %ecx,(%edx) /* Store PMD entry */
88 /* Upper half already zero */
89 addl $8,%edx
90 movl $512,%ecx
9111:
92 stosl
93 xchgl %eax,%ebx
94 stosl
95 xchgl %eax,%ebx
96 addl $0x1000,%eax
97 loop 11b
98
99 /*
100 * End condition: we must map up to the end + MAPPING_BEYOND_END.
101 */
102 movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
103 cmpl %ebp,%eax
104 jb 10b
1051:
106 addl $__PAGE_OFFSET, %edi
107 movl %edi, pa(_brk_end)
108 shrl $12, %eax
109 movl %eax, pa(max_pfn_mapped)
110
111 /* Do early initialization of the fixmap area */
112 movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
113 movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
114#else /* Not PAE */
115
116page_pde_offset = (__PAGE_OFFSET >> 20);
117
118 movl $pa(__brk_base), %edi
119 movl $pa(initial_page_table), %edx
120 movl $PTE_IDENT_ATTR, %eax
12110:
122 leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
123 movl %ecx,(%edx) /* Store identity PDE entry */
124 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
125 addl $4,%edx
126 movl $1024, %ecx
12711:
128 stosl
129 addl $0x1000,%eax
130 loop 11b
131 /*
132 * End condition: we must map up to the end + MAPPING_BEYOND_END.
133 */
134 movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
135 cmpl %ebp,%eax
136 jb 10b
137 addl $__PAGE_OFFSET, %edi
138 movl %edi, pa(_brk_end)
139 shrl $12, %eax
140 movl %eax, pa(max_pfn_mapped)
141
142 /* Do early initialization of the fixmap area */
143 movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
144 movl %eax,pa(initial_page_table+0xffc)
145#endif
146 ret
147
43/*G:055 148/*G:055
44 * We create a macro which puts the assembler code between lgstart_ and lgend_ 149 * We create a macro which puts the assembler code between lgstart_ and lgend_
45 * markers. These templates are put in the .text section: they can't be 150 * markers. These templates are put in the .text section: they can't be
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index a011bcc0f94..7d90d47655b 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -630,21 +630,29 @@ static int __init_ibs_nmi(void)
630 return 0; 630 return 0;
631} 631}
632 632
633/* initialize the APIC for the IBS interrupts if available */ 633/*
634 * check and reserve APIC extended interrupt LVT offset for IBS if
635 * available
636 *
637 * init_ibs() preforms implicitly cpu-local operations, so pin this
638 * thread to its current CPU
639 */
640
634static void init_ibs(void) 641static void init_ibs(void)
635{ 642{
636 ibs_caps = get_ibs_caps(); 643 preempt_disable();
637 644
645 ibs_caps = get_ibs_caps();
638 if (!ibs_caps) 646 if (!ibs_caps)
639 return; 647 goto out;
640 648
641 if (__init_ibs_nmi()) { 649 if (__init_ibs_nmi() < 0)
642 ibs_caps = 0; 650 ibs_caps = 0;
643 return; 651 else
644 } 652 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
645 653
646 printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", 654out:
647 (unsigned)ibs_caps); 655 preempt_enable();
648} 656}
649 657
650static int (*create_arch_files)(struct super_block *sb, struct dentry *root); 658static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index c4bb261c106..b1805b78842 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
65 resource_size_t size, resource_size_t align) 65 resource_size_t size, resource_size_t align)
66{ 66{
67 struct pci_dev *dev = data; 67 struct pci_dev *dev = data;
68 resource_size_t start = round_down(res->end - size + 1, align); 68 resource_size_t start = res->start;
69 69
70 if (res->flags & IORESOURCE_IO) { 70 if (res->flags & IORESOURCE_IO) {
71 71 if (skip_isa_ioresource_align(dev))
72 /* 72 return start;
73 * If we're avoiding ISA aliases, the largest contiguous I/O 73 if (start & 0x300)
74 * port space is 256 bytes. Clearing bits 9 and 10 preserves 74 start = (start + 0x3ff) & ~0x3ff;
75 * all 256-byte and smaller alignments, so the result will
76 * still be correctly aligned.
77 */
78 if (!skip_isa_ioresource_align(dev))
79 start &= ~0x300;
80 } else if (res->flags & IORESOURCE_MEM) {
81 if (start < BIOS_END)
82 start = res->end; /* fail; no space */
83 } 75 }
84 return start; 76 return start;
85} 77}
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index 4a2afa1bac5..b6552b189bc 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
25 25
26export CPPFLAGS_vdso.lds += -P -C 26export CPPFLAGS_vdso.lds += -P -C
27 27
28VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \ 28VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
29 -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 29 -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
30 30
31$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so 31$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
@@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y) += sysenter
69vdso32-images = $(vdso32.so-y:%=vdso32-%.so) 69vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
70 70
71CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) 71CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
72VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1 72VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1
73 73
74# This makes sure the $(obj) subdirectory exists even though vdso32/ 74# This makes sure the $(obj) subdirectory exists even though vdso32/
75# is not a kbuild sub-make subdirectory. 75# is not a kbuild sub-make subdirectory.